tangled
alpha
login
or
join now
flo-bit.dev
/
blento
your personal website on atproto - mirror
blento.app
20
fork
atom
overview
issues
pulls
pipelines
refactor pt7
Florian
2 weeks ago
f1dfd27f
d529a5d5
+46
-24
7 changed files
expand all
collapse all
unified
split
.claude
settings.local.json
src
lib
cards
BlueskyPostCard
BlueskyPostCard.svelte
GameCards
DinoGameCard
DinoGameCard.svelte
TetrisCard
TetrisCard.svelte
LivestreamCard
LivestreamCard.svelte
utils
YoutubeVideoPlayer.svelte
components
bluesky-post
index.ts
+13
-12
.claude/settings.local.json
···
1
1
{
2
2
-
"permissions": {
3
3
-
"allow": [
4
4
-
"Bash(pnpm check:*)",
5
5
-
"mcp__ide__getDiagnostics",
6
6
-
"mcp__plugin_svelte_svelte__svelte-autofixer",
7
7
-
"mcp__plugin_svelte_svelte__list-sections",
8
8
-
"Bash(pkill:*)",
9
9
-
"Bash(timeout 8 pnpm dev:*)",
10
10
-
"Bash(git checkout:*)",
11
11
-
"Bash(npx svelte-kit:*)"
12
12
-
]
13
13
-
}
2
2
+
"permissions": {
3
3
+
"allow": [
4
4
+
"Bash(pnpm check:*)",
5
5
+
"mcp__ide__getDiagnostics",
6
6
+
"mcp__plugin_svelte_svelte__svelte-autofixer",
7
7
+
"mcp__plugin_svelte_svelte__list-sections",
8
8
+
"Bash(pkill:*)",
9
9
+
"Bash(timeout 8 pnpm dev:*)",
10
10
+
"Bash(git checkout:*)",
11
11
+
"Bash(npx svelte-kit:*)",
12
12
+
"Bash(ls:*)"
13
13
+
]
14
14
+
}
14
15
}
+1
-2
src/lib/cards/BlueskyPostCard/BlueskyPostCard.svelte
···
19
19
feed = (
20
20
(await CardDefinitionsByType[item.cardType]?.loadData?.([], {
21
21
did,
22
22
-
handle,
23
23
-
platform: undefined
22
22
+
handle
24
23
})) as any
25
24
).feed;
26
25
+1
src/lib/cards/GameCards/DinoGameCard/DinoGameCard.svelte
···
529
529
</script>
530
530
531
531
<!-- svelte-ignore a11y_no_noninteractive_tabindex a11y_no_noninteractive_element_interactions -->
532
532
+
<!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
532
533
<div
533
534
bind:this={container}
534
535
class="relative h-full w-full overflow-hidden outline-none"
+1
src/lib/cards/GameCards/TetrisCard/TetrisCard.svelte
···
1007
1007
</script>
1008
1008
1009
1009
<!-- svelte-ignore a11y_no_noninteractive_tabindex a11y_no_noninteractive_element_interactions -->
1010
1010
+
<!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
1010
1011
<div
1011
1012
bind:this={container}
1012
1013
class="relative h-full w-full overflow-hidden outline-none"
+2
-3
src/lib/cards/LivestreamCard/LivestreamCard.svelte
···
40
40
if (!latestLivestream) {
41
41
latestLivestream = (await CardDefinitionsByType[item.cardType]?.loadData?.([], {
42
42
did,
43
43
-
handle,
44
44
-
platform: undefined
43
43
+
handle
45
44
})) as
46
45
| {
47
46
createdAt: string;
···
83
82
{:else if latestLivestream.online === false}
84
83
<Badge size="sm" class="accent:text-base-900">ended</Badge>
85
84
{:else}
86
86
-
<div class="h-[22px]"></div>
85
85
+
<div class="h-5.5"></div>
87
86
{/if}
88
87
</div>
89
88
+24
-6
src/lib/cards/utils/YoutubeVideoPlayer.svelte
···
21
21
import { cn } from '@foxui/core';
22
22
import { onDestroy, onMount } from 'svelte';
23
23
24
24
+
// Minimal Plyr interface for what we use
25
25
+
interface PlyrInstance {
26
26
+
source: {
27
27
+
type: string;
28
28
+
sources: { src: string; type: string }[];
29
29
+
};
30
30
+
on: (event: string, callback: () => void) => void;
31
31
+
play: () => void;
32
32
+
destroy: () => void;
33
33
+
}
34
34
+
35
35
+
interface PlyrConstructorType {
36
36
+
new (selector: string, options: Record<string, unknown>): PlyrInstance;
37
37
+
}
38
38
+
24
39
const { class: className }: { class?: string } = $props();
25
40
26
26
-
let Plyr = $state();
41
41
+
let PlyrConstructor: PlyrConstructorType | undefined = $state();
27
42
28
28
-
let player = $state();
43
43
+
let player: PlyrInstance | undefined = $state();
29
44
30
45
onMount(async () => {
31
31
-
if (!Plyr) Plyr = (await import('plyr')).default;
46
46
+
if (!PlyrConstructor) {
47
47
+
const plyrModule = (await import('plyr')) as unknown as { default: PlyrConstructorType };
48
48
+
PlyrConstructor = plyrModule.default;
49
49
+
}
32
50
33
33
-
const player = new Plyr('.js-player', {
51
51
+
player = new PlyrConstructor('.js-player', {
34
52
settings: ['captions', 'quality', 'loop', 'speed'],
35
53
controls: [
36
54
'play-large',
···
59
77
60
78
// when loaded play the video and go fullscreen
61
79
player.on('ready', () => {
62
62
-
player.play();
80
80
+
player?.play();
63
81
//player.fullscreen.enter();
64
82
});
65
83
});
···
87
105
88
106
{#key videoPlayer.id}
89
107
{#if videoPlayer.id}
90
90
-
<div class="fixed inset-0 z-[100] flex h-screen w-screen items-center justify-center">
108
108
+
<div class="fixed inset-0 z-100 flex h-screen w-screen items-center justify-center">
91
109
<button
92
110
onclick={() => videoPlayer.hide()}
93
111
class="absolute inset-0 bg-black/70 backdrop-blur-sm"
+4
-1
src/lib/components/bluesky-post/index.ts
···
127
127
return '';
128
128
}
129
129
130
130
-
const html = RichText({ text: post.record.text, facets: post.record.facets }, baseUrl);
130
130
+
const html = RichText(
131
131
+
{ text: post.record.text as string, facets: post.record.facets as Facet[] },
132
132
+
baseUrl
133
133
+
);
131
134
132
135
return html.replace(/\n/g, '<br>');
133
136
}