diff --git a/website/src/lib/components/self/AppSidebar.svelte b/website/src/lib/components/self/AppSidebar.svelte index 34ab6d4..ffbbfc4 100644 --- a/website/src/lib/components/self/AppSidebar.svelte +++ b/website/src/lib/components/self/AppSidebar.svelte @@ -89,8 +89,10 @@ setOpenMobile(false); } - function handleTradeClick(coinSymbol: string) { - goto(`/coin/${coinSymbol.toLowerCase()}`); + async function handleTradeClick(coinSymbol: string) { + const targetPath = `/coin/${coinSymbol.toLowerCase()}`; + + await goto(targetPath, { invalidateAll: true }); setOpenMobile(false); } @@ -443,11 +445,7 @@ {#snippet child({ props }: { props: MenuButtonProps })} - + Terms of Service @@ -457,11 +455,7 @@ {#snippet child({ props }: { props: MenuButtonProps })} - + Privacy Policy diff --git a/website/src/lib/stores/websocket.ts b/website/src/lib/stores/websocket.ts index 6922dfb..a53ca7f 100644 --- a/website/src/lib/stores/websocket.ts +++ b/website/src/lib/stores/websocket.ts @@ -226,6 +226,10 @@ function connect(): void { } function setCoin(coinSymbol: string): void { + if (activeCoin !== coinSymbol && activeCoin !== '@global') { + unsubscribeFromPriceUpdates(activeCoin); + } + activeCoin = coinSymbol; sendMessage({ type: 'set_coin', coinSymbol }); } diff --git a/website/src/routes/coin/[coinSymbol]/+page.svelte b/website/src/routes/coin/[coinSymbol]/+page.svelte index a54282a..1b5f0fd 100644 --- a/website/src/routes/coin/[coinSymbol]/+page.svelte +++ b/website/src/routes/coin/[coinSymbol]/+page.svelte @@ -26,9 +26,10 @@ import { getPublicUrl, getTimeframeInSeconds } from '$lib/utils.js'; import { websocketController, type PriceUpdate, isConnectedStore } from '$lib/stores/websocket'; import SEO from '$lib/components/self/SEO.svelte'; + import { page } from '$app/state'; const { data } = $props(); - const coinSymbol = data.coinSymbol; + let coinSymbol = $derived(data.coinSymbol); let coin = $state(null); let loading = $state(true); let chartData = $state([]); @@ -63,6 +64,34 @@ }; }); + // Handle route changes to update coin data + $effect(() => { + const currentCoinSymbol = page.params.coinSymbol; + if (currentCoinSymbol && currentCoinSymbol !== coinSymbol) { + loading = true; + coin = null; + chartData = []; + volumeData = []; + userHolding = 0; + + // Unsubscribe from the old coin's updates + websocketController.unsubscribeFromPriceUpdates(coinSymbol.toUpperCase()); + + // Update the data prop which will trigger coinSymbol to update via $derived + data.coinSymbol = currentCoinSymbol; + + // Load new coin data and set up new subscriptions + loadCoinData().then(() => { + loadUserHolding(); + websocketController.setCoin(currentCoinSymbol.toUpperCase()); + websocketController.subscribeToPriceUpdates( + currentCoinSymbol.toUpperCase(), + handlePriceUpdate + ); + }); + } + }); + async function loadCoinData() { try { const response = await fetch(`/api/coin/${coinSymbol}?timeframe=${selectedTimeframe}`);