Skip to content

Commit

Permalink
fix: Remove WS EVLs on Socket Close
Browse files Browse the repository at this point in the history
  • Loading branch information
kiosion committed Mar 5, 2024
1 parent 9b5f8d7 commit 72594ef
Show file tree
Hide file tree
Showing 7 changed files with 122 additions and 103 deletions.
12 changes: 0 additions & 12 deletions svelte-app/src/components/experiments/mag-cursor.svelte
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
<script lang="ts">
import { onMount } from 'svelte';
import { browser } from '$app/environment';
import Divider from '$components/divider.svelte';
import MagButton from '$components/experiments/mag-cursor/button.svelte';
import MagCursor from '$components/experiments/mag-cursor/cursor.svelte';
Expand All @@ -15,14 +11,6 @@
const register = (element: HTMLElement) => targets.push(element);
const buttons = ['Button One', 'Button Two', 'Button Three'];
onMount(() => {
if (!browser) {
return;
}
containerRect = container?.getBoundingClientRect();
});
</script>

<svelte:window on:resize={() => (containerRect = container?.getBoundingClientRect())} />
Expand Down
59 changes: 34 additions & 25 deletions svelte-app/src/components/experiments/toru.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -11,33 +11,42 @@
import type { ToruData } from '$components/experiments/toru';
export let initData: ToruData | undefined;
export let initPromise: Promise<ToruData | undefined>;
onMount(() => initSync((res) => (initData = res)));
let data: ToruData | undefined;
const onUpdate = (res: ToruData) => (data = res);
onMount(() =>
initPromise.then((res) => {
data = res;
initSync(onUpdate);
})
);
beforeNavigate((navigation) => {
if (navigation.to !== navigation.from) {
stopSync();
stopSync(onUpdate);
}
});
onDestroy(() => stopSync());
onDestroy(() => stopSync(onUpdate));
</script>

<Hoverable let:hovered setPointer={!!initData?.url}>
<Hoverable let:hovered setPointer={!!data?.url}>
<div
class="relative block rounded-lg"
class:focus-outline={initData?.url}
tabindex={initData?.url ? 0 : -1}
class:focus-outline={data?.url}
tabindex={data?.url ? 0 : -1}
role="button"
on:click={() => {
if (initData?.url) {
window.open(initData.url, '_blank');
if (data?.url) {
window.open(data.url, '_blank');
}
}}
on:keyup={(e) => {
if (e.key === 'Enter' && initData?.url) {
window.open(initData.url, '_blank');
if (e.key === 'Enter' && data?.url) {
window.open(data.url, '_blank');
}
}}
>
Expand All @@ -53,14 +62,14 @@
<figure
class="flex select-none flex-row items-center justify-start gap-5 px-1 pb-2"
>
{#if initData}
{#if data}
<div class="relative flex-shrink-0 overflow-clip">
<img
src="data:{initData.cover_art.mime_type};base64,{initData.cover_art.data}"
src="data:{data.cover_art.mime_type};base64,{data.cover_art.data}"
alt="Album art for the currently playing track"
class="pointer-events-none aspect-square h-28 w-28 rounded-lg"
/>
{#if initData.playing}
{#if data.playing}
<div
class="absolute left-0 top-0 aspect-square h-full w-full rounded-lg bg-dark/30 transition-colors dark:bg-dark/50"
/>
Expand All @@ -84,32 +93,32 @@
>
<h4
class="line-clamp-2 text-xl font-black decoration-accent-light decoration-2 underline-offset-4 dark:decoration-accent-dark"
class:underline={initData.url && hovered}
class:underline={data.url && hovered}
>
{initData.title ?? 'Unknown title'}
{data.title ?? 'Unknown title'}
</h4>
<p
class="line-clamp-2 text-base decoration-accent-light decoration-2 underline-offset-4 dark:decoration-accent-dark"
class:underline={initData.artist && hovered}
class:underline={data.artist && hovered}
>
{initData.artist ?? ''}
{initData.artist && initData.album ? '' : ''}
{initData.album ?? ''}
{data.artist ?? ''}
{data.artist && data.album ? '' : ''}
{data.album ?? ''}
</p>
</div>

<img
src="data:{initData.cover_art.mime_type};base64,{initData.cover_art.data}"
src="data:{data.cover_art.mime_type};base64,{data.cover_art.data}"
alt="Artist art for the currently playing track"
class="absolute bottom-0 left-0 right-0 top-0 -z-10 h-[150%] w-[150%] opacity-30 blur-xl"
/>
<div
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"
/>
{:else}
<div class="flex-shrink-0 p-4">
<div class="relative flex-shrink-0 overflow-clip">
<div
class="relative flex h-28 w-28 items-center justify-center rounded-lg bg-dark/10 transition-colors dark:bg-light/10"
class="flex h-28 w-28 items-center justify-center rounded-lg bg-dark/10 transition-colors dark:bg-light/10"
>
<Spinner class="ml-0" />
</div>
Expand Down Expand Up @@ -154,10 +163,10 @@
class:opacity-20={hovered}
class:dark:opacity-15={hovered}
>
{#if initData}
{#if data}
<!-- svelte-ignore a11y-missing-attribute -->
<img
src="data:{initData.cover_art.mime_type};base64,{initData.cover_art.data}"
src="data:{data.cover_art.mime_type};base64,{data.cover_art.data}"
class="h-full w-full blur-lg"
/>
{:else}
Expand Down
96 changes: 65 additions & 31 deletions svelte-app/src/components/experiments/toru.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,27 +20,28 @@ let socketInstance: WebSocket | undefined,

const interval = 36_000;

export const initSync = (onUpdate: (data: ToruData) => void) => {
if (!browser || (socketInstance && socketInstance.readyState === WebSocket.OPEN)) {
return;
}

clearInterval(repeat);
const onOpen = () => {
Logger.info('[ToruSync] Connected');
retries = 0;
};

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

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

socketInstance.addEventListener('message', (event: MessageEvent<string | unknown>) => {
if (!event.data || event.data === 'pong') {
const onMessage =
(onUpdate: (data: ToruData) => void) => (e: MessageEvent<string | unknown>) => {
if (!e.data || e.data === 'pong') {
return;
}

try {
const res = JSON.parse(event.data as string) as ToruData;
const res = JSON.parse(e.data as string) as ToruData;

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

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

socketInstance.addEventListener('error', (e) => {
Logger.error('[ToruSync] Error', e);
});
export const initSync = (onUpdate: (data: ToruData) => void) => {
if (!browser || (socketInstance && socketInstance.readyState === WebSocket.OPEN)) {
return;
}

clearInterval(repeat);

socketInstance = new WebSocket('wss://toru.kio.dev/api/v1/ws/kiosion?cover_size=large');

// socketInstance.addEventListener('open', () => {
// Logger.info('[ToruSync] Connected');
// retries = 0;
// });

socketInstance.addEventListener('close', () => {
Logger.info('[ToruSync] Disconnected');
// socketInstance.addEventListener('message', (event: MessageEvent<string | unknown>) => {
// if (!event.data || event.data === 'pong') {
// return;
// }

stop();
// try {
// const res = JSON.parse(event.data as string) as ToruData;

// TODO: Don't run when the socket is closed intentionally
// if (retries < 5) {
// retries++;
// clearTimeout(retry);
// retry = setTimeout(() => {
// initSync(onUpdate);
// }, retries * 1000);
// }
});
// Logger.info('[ToruSync] Received frame');

// if (res.title || res.album || res.artist) {
// onUpdate(res);
// }
// } catch (e) {
// Logger.error('[ToruSync] Error parsing', e);
// }
// });

// socketInstance.addEventListener('error', (e) => {
// Logger.error('[ToruSync] Error', e);
// });

// socketInstance.addEventListener('close', () => {
// Logger.info('[ToruSync] Disconnected');

// stop();
// });

socketInstance.addEventListener('open', onOpen);
socketInstance.addEventListener('message', onMessage(onUpdate));
socketInstance.addEventListener('error', onError);
socketInstance.addEventListener('close', onClose);

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

export const stopSync = () => {
export const stopSync = (onUpdate: (data: ToruData) => void) => {
if (!browser || !socketInstance) {
return;
}
Expand All @@ -89,5 +118,10 @@ export const stopSync = () => {
socketInstance.close();
}

socketInstance.removeEventListener('open', onOpen);
socketInstance.removeEventListener('message', onMessage(onUpdate));
socketInstance.removeEventListener('error', onError);
socketInstance.removeEventListener('close', onClose);

socketInstance = undefined;
};
2 changes: 2 additions & 0 deletions svelte-app/src/lib/consts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ export const LOCAL_SETTINGS_KEY = 'kio-dev-settings';

export const BASE_PAGE_TITLE = 'kio.dev';

export const TORU_API_URL = 'https://toru.kio.dev/api/v1';

interface AppRoute {
name: string;
path: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
</svelte:head>

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

<Divider class="my-8" />

Expand Down
31 changes: 20 additions & 11 deletions svelte-app/src/routes/[[lang=lang]]/experiments/+page.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,28 @@
import { TORU_API_URL } from '$lib/consts';
import Logger from '$lib/logger';

import type { PageLoad } from './$types';
import type { ToruData } from '$components/experiments/toru';

export const load = (async ({ fetch }) => {
let nowPlayingData: ToruData | undefined = undefined;
export const load = (({ fetch }) => {
const nowPlayingData = fetch(`${TORU_API_URL}/kiosion?res=json&cover_size=medium`)
.then((res) => {
if (!res.ok) {
throw new Error('Failed to fetch now playing data');
}

try {
const toruRes = await fetch(
'https://toru.kio.dev/api/v1/kiosion?res=json&cover_size=large'
);
return res
.json()
.then((data) => data.data)
.catch((e) => {
throw new Error('Failed to parse now playing data', e);
});
})
.catch((e) => {
Logger.error(e);

if (toruRes.ok) {
nowPlayingData = await toruRes.json().then((data) => data.data);
}
// eslint-disable-next-line no-empty
} catch {}
return undefined;
}) satisfies Promise<ToruData | undefined>;

return { fetch, nowPlayingData };
}) satisfies PageLoad;
23 changes: 0 additions & 23 deletions svelte-app/types/app/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,31 +23,8 @@ declare global {
}
}

export interface MenuStateOpt {
disabled?: boolean;
icon?: string;
text?: string;
action?: () => void | Promise<void> | undefined;
}

export interface MenuState {
open: boolean;
pos: {
x: number;
y: number;
};
target: HTMLElement;
opts: MenuStateOpt[];
}

// Some internal Sveltekit types
export type RouteFetch = (info: RequestInfo, init?: RequestInit) => Promise<Response>;

export type Subscriber<T> = (value: T) => void;
export type Unsubscriber = () => void;
export type Updater<T> = (value: T) => T;
export type Invalidator<T> = (value?: T) => void;

// Re-exports
export * from '$types/api';
export * from '$types/config';
Expand Down

0 comments on commit 72594ef

Please sign in to comment.