Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgraded a few more components to svelte 5 #6832

Merged
merged 14 commits into from
Nov 18, 2024
72 changes: 38 additions & 34 deletions frontend/app/src/components/App.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<script lang="ts">
import { onMount, setContext } from "svelte";

import { setContext } from "svelte";
import "../i18n/i18n";
import "../utils/markdown";
import "../utils/scream";
Expand Down Expand Up @@ -95,18 +94,41 @@
}

let client: OpenChat = createOpenChatClient();
setContext<OpenChat>("client", client);

let profileTrace = client.showTrace();
let videoCallElement: ActiveCall;
// I can't (yet) find a way to avoid using "any" here. Will try to improve but need to commit this crime for the time being
let videoCallElement: any;
let landingPageRoute = $derived(isLandingPageRoute($pathParams));
let homeRoute = $derived($pathParams.kind === "home_route");
let showLandingPage = $derived(
landingPageRoute || (homeRoute && $identityState.kind === "anon" && $anonUser),
);
let isFirefox = navigator.userAgent.indexOf("Firefox") >= 0;
let burstPath = $derived(
$currentTheme.mode === "dark" ? "/assets/burst_dark" : "/assets/burst_light",
);
let burstUrl = $derived(isFirefox ? `${burstPath}.png` : `${burstPath}.svg`);
let burstFixed = $derived(isScrollingRoute($pathParams));

setContext<OpenChat>("client", client);
let upgrading = $derived(
$identityState.kind === "upgrading_user" || $identityState.kind === "upgrade_user",
);

$: landingPageRoute = isLandingPageRoute($pathParams);
$: homeRoute = $pathParams.kind === "home_route";
$: showLandingPage =
landingPageRoute || (homeRoute && $identityState.kind === "anon" && $anonUser);
$effect(() => {
// subscribe to the rtl store so that we can set the overall page direction at the right time
document.dir = $rtlStore ? "rtl" : "ltr";
});

$effect(() => {
if (!$notFound && showLandingPage) {
document.body.classList.add("landing-page");
} else {
document.body.classList.remove("landing-page");
}
});

onMount(() => {
$effect(() => {
redirectLandingPageLinksIfNecessary();
if (client.captureReferralCode()) {
pageReplace(removeQueryStringParam("ref"));
Expand Down Expand Up @@ -389,25 +411,12 @@
});
}

$: {
if (!$notFound && showLandingPage) {
document.body.classList.add("landing-page");
} else {
document.body.classList.remove("landing-page");
}
}

function calculateHeight() {
// fix the issue with 100vh layouts in various mobile browsers
let vh = window.innerHeight * 0.01;
document.documentElement.style.setProperty("--vh", `${vh}px`);
}

$: {
// subscribe to the rtl store so that we can set the overall page direction at the right time
document.dir = $rtlStore ? "rtl" : "ltr";
}

function unhandledError(ev: Event) {
logger?.error("Unhandled error: ", ev);
if (
Expand Down Expand Up @@ -437,19 +446,14 @@
videoCallElement?.hangup();
}

function joinVideoCall(ev: CustomEvent<ChatIdentifier>) {
function joinVideoCall(chatId: ChatIdentifier) {
incomingVideoCall.set(undefined);
const chat = client.lookupChatSummary(ev.detail);
const chat = client.lookupChatSummary(chatId);
if (chat) {
page(routeForChatIdentifier("none", chat.id));
videoCallElement?.startOrJoinVideoCall(chat, true);
}
}

let isFirefox = navigator.userAgent.indexOf("Firefox") >= 0;
$: burstPath = $currentTheme.mode === "dark" ? "/assets/burst_dark" : "/assets/burst_light";
$: burstUrl = isFirefox ? `${burstPath}.png` : `${burstPath}.svg`;
$: burstFixed = isScrollingRoute($pathParams);
</script>

{#if $currentTheme.burst || landingPageRoute}
Expand All @@ -463,12 +467,12 @@
<Head />

<ActiveCall
on:clearSelection={() => page(routeForScope($chatListScope))}
onClearSelection={() => page(routeForScope($chatListScope))}
bind:this={videoCallElement} />

<VideoCallAccessRequests />

<IncomingCall on:joinVideoCall={joinVideoCall} />
<IncomingCall onJoinVideoCall={joinVideoCall} />

<Witch background />

Expand All @@ -478,7 +482,7 @@

{#if isCanisterUrl}
<SwitchDomain />
{:else if $identityState.kind === "upgrading_user" || $identityState.kind === "upgrade_user"}
{:else if upgrading}
<Upgrading />
{:else if $identityState.kind === "anon" || $identityState.kind === "logging_in" || $identityState.kind === "registering" || $identityState.kind === "logged_in" || $identityState.kind === "loading_user" || $identityState.kind === "challenging"}
{#if !$isLoading || $reviewingTranslations}
Expand All @@ -500,8 +504,8 @@
<Snow />
{/if}

<svelte:window on:resize={resize} on:error={unhandledError} on:orientationchange={resize} />
<svelte:body on:click={() => menuStore.hideMenu()} />
<svelte:window onresize={resize} onerror={unhandledError} onorientationchange={resize} />
<svelte:body onclick={() => menuStore.hideMenu()} />

<style lang="scss">
:global {
Expand Down
22 changes: 12 additions & 10 deletions frontend/app/src/components/Head.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,7 @@

const client = getContext<OpenChat>("client");

let viewPortContent = "width=device-width, initial-scale=1";

$: details = getDetails(
$chatListScopeStore,
$location,
$userStore,
$globalUnreadCount,
$selectedChatStore,
$selectedCommunity,
);
let viewPortContent = $state("width=device-width, initial-scale=1");

type Details = {
title: string;
Expand Down Expand Up @@ -93,6 +84,17 @@
viewPortContent += ", maximum-scale=1";
}
});

let details = $derived(
getDetails(
$chatListScopeStore,
$location,
$userStore,
$globalUnreadCount,
$selectedChatStore,
$selectedCommunity,
),
);
</script>

<svelte:head>
Expand Down
53 changes: 27 additions & 26 deletions frontend/app/src/components/Profiler.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,33 @@
import { profileStore } from "openchat-client";
import Select from "./Select.svelte";

let selectedMethod: string = "";
let selectedMethod: string = $state("");
let dragging = false;
let style = `bottom: 10px; left: 10px;`;

$: methods = Object.keys($profileStore);
$: series = selectedMethod !== "" ? $profileStore[selectedMethod] : [];

$: points = series
.map((n, i) => {
const belowMax = max - n;
const y = (belowMax / range) * 200;
const x = 40 * i;
return `${x},${y}`;
})
.join(" ");

$: average = series.length > 0 ? series.reduce((total, x) => total + x, 0) / series.length : 0;

$: [min, max] = series.reduce(
([min, max], x) => {
return [Math.min(min, x), Math.max(max, x)];
},
[Number.MAX_VALUE, Number.MIN_VALUE],
let style = $state(`bottom: 10px; left: 10px;`);
let methods = $derived(Object.keys($profileStore));
let series = $derived(selectedMethod !== "" ? $profileStore[selectedMethod] : []);
let [min, max] = $derived(
series.reduce(
([min, max], x) => {
return [Math.min(min, x), Math.max(max, x)];
},
[Number.MAX_VALUE, Number.MIN_VALUE],
),
);
let range = $derived(max - min);
let points = $derived(
series
.map((n, i) => {
const belowMax = max - n;
const y = (belowMax / range) * 200;
const x = 40 * i;
return `${x},${y}`;
})
.join(" "),
);
let average = $derived(
series.length > 0 ? series.reduce((total, x) => total + x, 0) / series.length : 0,
);

$: range = max - min;

let offset = { x: 0, y: 0 };

Expand All @@ -49,9 +50,9 @@
}
</script>

<svelte:body on:mouseup={stopDrag} on:mousemove={drag} />
<svelte:body onmouseup={stopDrag} onmousemove={drag} />

<div on:mousedown={startDrag} class="profiler" {style}>
<div onmousedown={startDrag} class="profiler" {style}>
<Select bind:value={selectedMethod}>
<option value={""} selected disabled>Choose metric</option>
{#each methods as method}
Expand Down
11 changes: 8 additions & 3 deletions frontend/app/src/components/Router.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,13 @@
adminRoute,
} from "../routes";

export let showLandingPage: boolean;
interface Props {
showLandingPage: boolean;
}

let { showLandingPage }: Props = $props();

let route: typeof SvelteComponent<object> | undefined = undefined;
let route: typeof SvelteComponent<object> | undefined = $state(undefined);

function parsePathParams(fn: (ctx: PageJS.Context) => RouteParams) {
return (ctx: PageJS.Context, next: () => any) => {
Expand Down Expand Up @@ -219,5 +223,6 @@
</script>

{#if route !== undefined}
<svelte:component this={route} {showLandingPage} on:startVideoCall on:askToSpeak on:hangup />
{@const RouteComponent = route}
<RouteComponent {showLandingPage} on:startVideoCall on:askToSpeak on:hangup />
{/if}
4 changes: 2 additions & 2 deletions frontend/app/src/components/Snow.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import { onMount } from "svelte";
import { snowing } from "../stores/snow";

let flakes: number[] = [];
let flakes: number[] = $state([]);

function reduce() {
if (flakes.length > 10) {
Expand All @@ -24,7 +24,7 @@
<div class="snow">
{#each flakes as _}
<div class="snowflake">
<span />
<span></span>
</div>
{/each}
</div>
Expand Down
15 changes: 10 additions & 5 deletions frontend/app/src/components/UpgradeBanner.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@
let poller = new Poller(checkVersion, VERSION_INTERVAL);
// @ts-ignore
let clientVersion = Version.parse(window.OPENCHAT_WEBSITE_VERSION);
let countdown = 30;
let showBanner = false;
let countdown = $state(30);
let showBanner = $state(false);
let errorCount = 0;

onDestroy(() => poller.stop());

function checkVersion(): Promise<void> {
if (process.env.NODE_ENV !== "production" || $activeVideoCall !== undefined) return Promise.resolve();
if (process.env.NODE_ENV !== "production" || $activeVideoCall !== undefined)
return Promise.resolve();
return getServerVersion().then((serverVersion) => {
if (serverVersion.isGreaterThan(clientVersion)) {
poller.stop();
Expand Down Expand Up @@ -54,6 +55,11 @@
return clientVersion;
});
}

function reload(ev: Event) {
window.location.reload();
ev.preventDefault();
}
</script>

{#if showBanner}
Expand All @@ -62,8 +68,7 @@
<span class="message"
><Translatable resourceKey={i18nKey("updateRequired", { countdown })} /></span>
<span class="update-now">
<a href="/" on:click|preventDefault={() => window.location.reload()}
><Translatable resourceKey={i18nKey("updateNow")} /></a>
<a href="/" onclick={reload}><Translatable resourceKey={i18nKey("updateNow")} /></a>
</span>
</div>
</div>
Expand Down
8 changes: 6 additions & 2 deletions frontend/app/src/components/Witch.svelte
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
<script lang="ts">
export let background = false;
interface Props {
background?: boolean;
}

let { background = false }: Props = $props();
</script>

<div class:background class="witch" />
<div class:background class="witch"></div>

<style lang="scss">
:global(body.witch .witch) {
Expand Down
Loading
Loading