Skip to content

Commit 72594ef

Browse files
committed
fix: Remove WS EVLs on Socket Close
1 parent 9b5f8d7 commit 72594ef

File tree

7 files changed

+122
-103
lines changed

7 files changed

+122
-103
lines changed

svelte-app/src/components/experiments/mag-cursor.svelte

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
11
<script lang="ts">
2-
import { onMount } from 'svelte';
3-
4-
import { browser } from '$app/environment';
5-
62
import Divider from '$components/divider.svelte';
73
import MagButton from '$components/experiments/mag-cursor/button.svelte';
84
import MagCursor from '$components/experiments/mag-cursor/cursor.svelte';
@@ -15,14 +11,6 @@
1511
const register = (element: HTMLElement) => targets.push(element);
1612
1713
const buttons = ['Button One', 'Button Two', 'Button Three'];
18-
19-
onMount(() => {
20-
if (!browser) {
21-
return;
22-
}
23-
24-
containerRect = container?.getBoundingClientRect();
25-
});
2614
</script>
2715

2816
<svelte:window on:resize={() => (containerRect = container?.getBoundingClientRect())} />

svelte-app/src/components/experiments/toru.svelte

Lines changed: 34 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11,33 +11,42 @@
1111
1212
import type { ToruData } from '$components/experiments/toru';
1313
14-
export let initData: ToruData | undefined;
14+
export let initPromise: Promise<ToruData | undefined>;
1515
16-
onMount(() => initSync((res) => (initData = res)));
16+
let data: ToruData | undefined;
17+
18+
const onUpdate = (res: ToruData) => (data = res);
19+
20+
onMount(() =>
21+
initPromise.then((res) => {
22+
data = res;
23+
initSync(onUpdate);
24+
})
25+
);
1726
1827
beforeNavigate((navigation) => {
1928
if (navigation.to !== navigation.from) {
20-
stopSync();
29+
stopSync(onUpdate);
2130
}
2231
});
2332
24-
onDestroy(() => stopSync());
33+
onDestroy(() => stopSync(onUpdate));
2534
</script>
2635

27-
<Hoverable let:hovered setPointer={!!initData?.url}>
36+
<Hoverable let:hovered setPointer={!!data?.url}>
2837
<div
2938
class="relative block rounded-lg"
30-
class:focus-outline={initData?.url}
31-
tabindex={initData?.url ? 0 : -1}
39+
class:focus-outline={data?.url}
40+
tabindex={data?.url ? 0 : -1}
3241
role="button"
3342
on:click={() => {
34-
if (initData?.url) {
35-
window.open(initData.url, '_blank');
43+
if (data?.url) {
44+
window.open(data.url, '_blank');
3645
}
3746
}}
3847
on:keyup={(e) => {
39-
if (e.key === 'Enter' && initData?.url) {
40-
window.open(initData.url, '_blank');
48+
if (e.key === 'Enter' && data?.url) {
49+
window.open(data.url, '_blank');
4150
}
4251
}}
4352
>
@@ -53,14 +62,14 @@
5362
<figure
5463
class="flex select-none flex-row items-center justify-start gap-5 px-1 pb-2"
5564
>
56-
{#if initData}
65+
{#if data}
5766
<div class="relative flex-shrink-0 overflow-clip">
5867
<img
59-
src="data:{initData.cover_art.mime_type};base64,{initData.cover_art.data}"
68+
src="data:{data.cover_art.mime_type};base64,{data.cover_art.data}"
6069
alt="Album art for the currently playing track"
6170
class="pointer-events-none aspect-square h-28 w-28 rounded-lg"
6271
/>
63-
{#if initData.playing}
72+
{#if data.playing}
6473
<div
6574
class="absolute left-0 top-0 aspect-square h-full w-full rounded-lg bg-dark/30 transition-colors dark:bg-dark/50"
6675
/>
@@ -84,32 +93,32 @@
8493
>
8594
<h4
8695
class="line-clamp-2 text-xl font-black decoration-accent-light decoration-2 underline-offset-4 dark:decoration-accent-dark"
87-
class:underline={initData.url && hovered}
96+
class:underline={data.url && hovered}
8897
>
89-
{initData.title ?? 'Unknown title'}
98+
{data.title ?? 'Unknown title'}
9099
</h4>
91100
<p
92101
class="line-clamp-2 text-base decoration-accent-light decoration-2 underline-offset-4 dark:decoration-accent-dark"
93-
class:underline={initData.artist && hovered}
102+
class:underline={data.artist && hovered}
94103
>
95-
{initData.artist ?? ''}
96-
{initData.artist && initData.album ? '' : ''}
97-
{initData.album ?? ''}
104+
{data.artist ?? ''}
105+
{data.artist && data.album ? '' : ''}
106+
{data.album ?? ''}
98107
</p>
99108
</div>
100109

101110
<img
102-
src="data:{initData.cover_art.mime_type};base64,{initData.cover_art.data}"
111+
src="data:{data.cover_art.mime_type};base64,{data.cover_art.data}"
103112
alt="Artist art for the currently playing track"
104113
class="absolute bottom-0 left-0 right-0 top-0 -z-10 h-[150%] w-[150%] opacity-30 blur-xl"
105114
/>
106115
<div
107116
class="absolute bottom-0 left-0 right-0 top-0 -z-20 h-[150%] w-[150%] bg-light blur-xl transition-colors dark:bg-dark"
108117
/>
109118
{:else}
110-
<div class="flex-shrink-0 p-4">
119+
<div class="relative flex-shrink-0 overflow-clip">
111120
<div
112-
class="relative flex h-28 w-28 items-center justify-center rounded-lg bg-dark/10 transition-colors dark:bg-light/10"
121+
class="flex h-28 w-28 items-center justify-center rounded-lg bg-dark/10 transition-colors dark:bg-light/10"
113122
>
114123
<Spinner class="ml-0" />
115124
</div>
@@ -154,10 +163,10 @@
154163
class:opacity-20={hovered}
155164
class:dark:opacity-15={hovered}
156165
>
157-
{#if initData}
166+
{#if data}
158167
<!-- svelte-ignore a11y-missing-attribute -->
159168
<img
160-
src="data:{initData.cover_art.mime_type};base64,{initData.cover_art.data}"
169+
src="data:{data.cover_art.mime_type};base64,{data.cover_art.data}"
161170
class="h-full w-full blur-lg"
162171
/>
163172
{:else}

svelte-app/src/components/experiments/toru.ts

Lines changed: 65 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -20,27 +20,28 @@ let socketInstance: WebSocket | undefined,
2020

2121
const interval = 36_000;
2222

23-
export const initSync = (onUpdate: (data: ToruData) => void) => {
24-
if (!browser || (socketInstance && socketInstance.readyState === WebSocket.OPEN)) {
25-
return;
26-
}
27-
28-
clearInterval(repeat);
23+
const onOpen = () => {
24+
Logger.info('[ToruSync] Connected');
25+
retries = 0;
26+
};
2927

30-
socketInstance = new WebSocket('wss://toru.kio.dev/api/v1/ws/kiosion?cover_size=large');
28+
const onClose = () => {
29+
Logger.info('[ToruSync] Disconnected');
30+
stop();
31+
};
3132

32-
socketInstance.addEventListener('open', () => {
33-
Logger.info('[ToruSync] Connected');
34-
retries = 0;
35-
});
33+
const onError = (e: Event) => {
34+
Logger.error('[ToruSync] Error', e);
35+
};
3636

37-
socketInstance.addEventListener('message', (event: MessageEvent<string | unknown>) => {
38-
if (!event.data || event.data === 'pong') {
37+
const onMessage =
38+
(onUpdate: (data: ToruData) => void) => (e: MessageEvent<string | unknown>) => {
39+
if (!e.data || e.data === 'pong') {
3940
return;
4041
}
4142

4243
try {
43-
const res = JSON.parse(event.data as string) as ToruData;
44+
const res = JSON.parse(e.data as string) as ToruData;
4445

4546
Logger.info('[ToruSync] Received frame');
4647

@@ -50,26 +51,54 @@ export const initSync = (onUpdate: (data: ToruData) => void) => {
5051
} catch (e) {
5152
Logger.error('[ToruSync] Error parsing', e);
5253
}
53-
});
54+
};
5455

55-
socketInstance.addEventListener('error', (e) => {
56-
Logger.error('[ToruSync] Error', e);
57-
});
56+
export const initSync = (onUpdate: (data: ToruData) => void) => {
57+
if (!browser || (socketInstance && socketInstance.readyState === WebSocket.OPEN)) {
58+
return;
59+
}
60+
61+
clearInterval(repeat);
62+
63+
socketInstance = new WebSocket('wss://toru.kio.dev/api/v1/ws/kiosion?cover_size=large');
64+
65+
// socketInstance.addEventListener('open', () => {
66+
// Logger.info('[ToruSync] Connected');
67+
// retries = 0;
68+
// });
5869

59-
socketInstance.addEventListener('close', () => {
60-
Logger.info('[ToruSync] Disconnected');
70+
// socketInstance.addEventListener('message', (event: MessageEvent<string | unknown>) => {
71+
// if (!event.data || event.data === 'pong') {
72+
// return;
73+
// }
6174

62-
stop();
75+
// try {
76+
// const res = JSON.parse(event.data as string) as ToruData;
6377

64-
// TODO: Don't run when the socket is closed intentionally
65-
// if (retries < 5) {
66-
// retries++;
67-
// clearTimeout(retry);
68-
// retry = setTimeout(() => {
69-
// initSync(onUpdate);
70-
// }, retries * 1000);
71-
// }
72-
});
78+
// Logger.info('[ToruSync] Received frame');
79+
80+
// if (res.title || res.album || res.artist) {
81+
// onUpdate(res);
82+
// }
83+
// } catch (e) {
84+
// Logger.error('[ToruSync] Error parsing', e);
85+
// }
86+
// });
87+
88+
// socketInstance.addEventListener('error', (e) => {
89+
// Logger.error('[ToruSync] Error', e);
90+
// });
91+
92+
// socketInstance.addEventListener('close', () => {
93+
// Logger.info('[ToruSync] Disconnected');
94+
95+
// stop();
96+
// });
97+
98+
socketInstance.addEventListener('open', onOpen);
99+
socketInstance.addEventListener('message', onMessage(onUpdate));
100+
socketInstance.addEventListener('error', onError);
101+
socketInstance.addEventListener('close', onClose);
73102

74103
repeat = setInterval(() => {
75104
if (socketInstance && socketInstance.readyState === WebSocket.OPEN) {
@@ -78,7 +107,7 @@ export const initSync = (onUpdate: (data: ToruData) => void) => {
78107
}, interval);
79108
};
80109

81-
export const stopSync = () => {
110+
export const stopSync = (onUpdate: (data: ToruData) => void) => {
82111
if (!browser || !socketInstance) {
83112
return;
84113
}
@@ -89,5 +118,10 @@ export const stopSync = () => {
89118
socketInstance.close();
90119
}
91120

121+
socketInstance.removeEventListener('open', onOpen);
122+
socketInstance.removeEventListener('message', onMessage(onUpdate));
123+
socketInstance.removeEventListener('error', onError);
124+
socketInstance.removeEventListener('close', onClose);
125+
92126
socketInstance = undefined;
93127
};

svelte-app/src/lib/consts.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ export const LOCAL_SETTINGS_KEY = 'kio-dev-settings';
1818

1919
export const BASE_PAGE_TITLE = 'kio.dev';
2020

21+
export const TORU_API_URL = 'https://toru.kio.dev/api/v1';
22+
2123
interface AppRoute {
2224
name: string;
2325
path: string;

svelte-app/src/routes/[[lang=lang]]/experiments/+page.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
</svelte:head>
2828

2929
<HeadedBlock heading={$t('Experiments')}>
30-
<ToruExperiment initData={data.nowPlayingData} />
30+
<ToruExperiment initPromise={data.nowPlayingData} />
3131

3232
<Divider class="my-8" />
3333

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,28 @@
1+
import { TORU_API_URL } from '$lib/consts';
2+
import Logger from '$lib/logger';
3+
14
import type { PageLoad } from './$types';
25
import type { ToruData } from '$components/experiments/toru';
36

4-
export const load = (async ({ fetch }) => {
5-
let nowPlayingData: ToruData | undefined = undefined;
7+
export const load = (({ fetch }) => {
8+
const nowPlayingData = fetch(`${TORU_API_URL}/kiosion?res=json&cover_size=medium`)
9+
.then((res) => {
10+
if (!res.ok) {
11+
throw new Error('Failed to fetch now playing data');
12+
}
613

7-
try {
8-
const toruRes = await fetch(
9-
'https://toru.kio.dev/api/v1/kiosion?res=json&cover_size=large'
10-
);
14+
return res
15+
.json()
16+
.then((data) => data.data)
17+
.catch((e) => {
18+
throw new Error('Failed to parse now playing data', e);
19+
});
20+
})
21+
.catch((e) => {
22+
Logger.error(e);
1123

12-
if (toruRes.ok) {
13-
nowPlayingData = await toruRes.json().then((data) => data.data);
14-
}
15-
// eslint-disable-next-line no-empty
16-
} catch {}
24+
return undefined;
25+
}) satisfies Promise<ToruData | undefined>;
1726

1827
return { fetch, nowPlayingData };
1928
}) satisfies PageLoad;

svelte-app/types/app/index.ts

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -23,31 +23,8 @@ declare global {
2323
}
2424
}
2525

26-
export interface MenuStateOpt {
27-
disabled?: boolean;
28-
icon?: string;
29-
text?: string;
30-
action?: () => void | Promise<void> | undefined;
31-
}
32-
33-
export interface MenuState {
34-
open: boolean;
35-
pos: {
36-
x: number;
37-
y: number;
38-
};
39-
target: HTMLElement;
40-
opts: MenuStateOpt[];
41-
}
42-
43-
// Some internal Sveltekit types
4426
export type RouteFetch = (info: RequestInfo, init?: RequestInit) => Promise<Response>;
4527

46-
export type Subscriber<T> = (value: T) => void;
47-
export type Unsubscriber = () => void;
48-
export type Updater<T> = (value: T) => T;
49-
export type Invalidator<T> = (value?: T) => void;
50-
5128
// Re-exports
5229
export * from '$types/api';
5330
export * from '$types/config';

0 commit comments

Comments
 (0)