aboutsummaryrefslogtreecommitdiffstats
path: root/src/routes
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2024-11-07 21:16:25 -0800
committerAdam Soltys <[email protected]>2024-11-08 09:27:40 -0800
commit32fcc461cd43c8907df5e306d520bb671307eab1 (patch)
tree0253780c569998b6c1a5f43026586e94916c3fee /src/routes
parentbe5aa52cea1d57c875cfb22d25c6a866b8de2239 (diff)
downloadcoinos-ui-32fcc461cd43c8907df5e306d520bb671307eab1.tar.gz
coinos-ui-32fcc461cd43c8907df5e306d520bb671307eab1.zip
svelte 5
Diffstat (limited to 'src/routes')
-rw-r--r--src/routes/(app)/+error.svelte2
-rw-r--r--src/routes/(app)/+layout.svelte20
-rw-r--r--src/routes/(app)/[username]/(profile)/+layout.svelte80
-rw-r--r--src/routes/(app)/[username]/(profile)/+page.svelte24
-rw-r--r--src/routes/(app)/[username]/(profile)/event/[id]/+page.svelte2
-rw-r--r--src/routes/(app)/[username]/(profile)/followers/+page.svelte50
-rw-r--r--src/routes/(app)/[username]/(profile)/follows/+page.svelte54
-rw-r--r--src/routes/(app)/[username]/+layout.svelte6
-rw-r--r--src/routes/(app)/[username]/receive/+page.svelte28
-rw-r--r--src/routes/(app)/account/[id]/+page.svelte36
-rw-r--r--src/routes/(app)/account/import/+page.svelte12
-rw-r--r--src/routes/(app)/account/pass/+page.svelte14
-rw-r--r--src/routes/(app)/account/savings/+page.svelte4
-rw-r--r--src/routes/(app)/account/seed/+page.svelte6
-rw-r--r--src/routes/(app)/admin/+layout.svelte4
-rw-r--r--src/routes/(app)/admin/+page.svelte6
-rw-r--r--src/routes/(app)/ecash/[id]/[...version]/+layout.svelte8
-rw-r--r--src/routes/(app)/ecash/[id]/[...version]/+page.svelte19
-rw-r--r--src/routes/(app)/ecash/[id]/[...version]/swap/+page.svelte2
-rw-r--r--src/routes/(app)/forgot/+page.svelte4
-rw-r--r--src/routes/(app)/fund/[id]/+page.svelte10
-rw-r--r--src/routes/(app)/fund/[id]/sweep/+page.svelte6
-rw-r--r--src/routes/(app)/fund/[id]/withdraw/+page.svelte24
-rw-r--r--src/routes/(app)/generate/+page.svelte12
-rw-r--r--src/routes/(app)/invoice/[id]/[email protected]20
-rw-r--r--src/routes/(app)/invoice/[id]/+page.svelte99
-rw-r--r--src/routes/(app)/invoice/[id]/memo/+page.svelte14
-rw-r--r--src/routes/(app)/invoice/[id]/paid/+page.svelte12
-rw-r--r--src/routes/(app)/invoice/[id]/tip/+page.svelte58
-rw-r--r--src/routes/(app)/items/[id]/+page.svelte9
-rw-r--r--src/routes/(app)/items/create/+page.svelte9
-rw-r--r--src/routes/(app)/ln/[lnurl]/+page.svelte2
-rw-r--r--src/routes/(app)/ln/withdrawal/sent/+page.svelte4
-rw-r--r--src/routes/(app)/messages/+page.svelte16
-rw-r--r--src/routes/(app)/messages/[recipient]/+page.svelte22
-rw-r--r--src/routes/(app)/pay/[username]/[...amount]/+page.svelte39
-rw-r--r--src/routes/(app)/payment/[id]/+page.svelte20
-rw-r--r--src/routes/(app)/payment/[id]/plain/+page.svelte4
-rw-r--r--src/routes/(app)/payments/[...page]/+page.svelte56
-rw-r--r--src/routes/(app)/qr/[text]/+page.svelte6
-rw-r--r--src/routes/(app)/qr/create/+page.svelte18
-rw-r--r--src/routes/(app)/receive/[...token]/+page.svelte23
-rw-r--r--src/routes/(app)/reset/[code]/+page.svelte6
-rw-r--r--src/routes/(app)/scan/[email protected]10
-rw-r--r--src/routes/(app)/scan/+page.svelte8
-rw-r--r--src/routes/(app)/send/+layout.svelte4
-rw-r--r--src/routes/(app)/send/[...text]/+page.svelte25
-rw-r--r--src/routes/(app)/send/bitcoin/[address]/+page.svelte16
-rw-r--r--src/routes/(app)/send/bitcoin/[address]/[amount]/[...feeRate]/+page.svelte27
-rw-r--r--src/routes/(app)/send/ecash/+page.svelte18
-rw-r--r--src/routes/(app)/send/fund/[name]/[...amount]/+page.svelte22
-rw-r--r--src/routes/(app)/send/invoice/[id]/+page.svelte38
-rw-r--r--src/routes/(app)/send/lightning/[payreq]/+page.svelte32
-rw-r--r--src/routes/(app)/sent/[id]/+page.svelte6
-rw-r--r--src/routes/(app)/settings/[...tab]/+page.svelte53
-rw-r--r--src/routes/(app)/settings/[...tab]/_account.svelte50
-rw-r--r--src/routes/(app)/settings/[...tab]/_pos.svelte41
-rw-r--r--src/routes/(app)/settings/[...tab]/_security.svelte87
-rw-r--r--src/routes/(app)/settings/[...tab]/_shopify.svelte20
-rw-r--r--src/routes/(app)/verify/[code]/+page.svelte4
-rw-r--r--src/routes/(static)/+layout.svelte14
-rw-r--r--src/routes/(static)/docs/+page.svelte6
-rw-r--r--src/routes/(static)/login/+page.svelte35
-rw-r--r--src/routes/(static)/register/+page.svelte73
-rw-r--r--src/routes/(static)/support/+page.svelte22
-rw-r--r--src/routes/+error.svelte2
-rw-r--r--src/routes/+layout.svelte12
-rw-r--r--src/routes/+page.svelte26
-rw-r--r--src/routes/map/+page.svelte2
69 files changed, 884 insertions, 639 deletions
diff --git a/src/routes/(app)/+error.svelte b/src/routes/(app)/+error.svelte
index 6ce7979c..b950608b 100644
--- a/src/routes/(app)/+error.svelte
+++ b/src/routes/(app)/+error.svelte
@@ -3,7 +3,7 @@
import Icon from "$comp/Icon.svelte";
import { page } from "$app/stores";
- export let data;
+ let { data } = $props();
let { user } = data;
let link = user ? `/${user.username}` : "/";
diff --git a/src/routes/(app)/+layout.svelte b/src/routes/(app)/+layout.svelte
index 095e597d..c09fc309 100644
--- a/src/routes/(app)/+layout.svelte
+++ b/src/routes/(app)/+layout.svelte
@@ -1,4 +1,6 @@
<script>
+ import { run } from 'svelte/legacy';
+
import { SvelteToast } from "@zerodevx/svelte-toast";
import { onDestroy, onMount } from "svelte";
import { close, connect, send } from "$lib/socket";
@@ -22,12 +24,10 @@
import { t, locale, loading } from "$lib/translations";
import { goto, afterNavigate, preloadData } from "$app/navigation";
- export let data;
+ let { data, children } = $props();
- let { generate, rate, user, subject, token, rates, theme } = data;
- $: theme = $themeStore;
+ let { generate, rate, user, subject, token, rates, theme } = $state(data);
- $: update(data);
let update = (data) => {
({ rate, user, subject, token, rates, theme } = data);
};
@@ -67,7 +67,6 @@
}
});
- $: browser && connect(token);
let lost,
checkTimer,
@@ -93,6 +92,15 @@
clearTimeout(expireTimer);
}
});
+ run(() => {
+ theme = $themeStore;
+ });
+ run(() => {
+ update(data);
+ });
+ run(() => {
+ browser && connect(token);
+ });
</script>
{#if browser && user && $passwordPrompt}
@@ -119,7 +127,7 @@
<main class="pb-20 min-h-dvh" data-theme={theme}>
<AppHeader {user} {subject} />
{#if !$loading}
- <slot />
+ {@render children?.()}
{/if}
</main>
diff --git a/src/routes/(app)/[username]/(profile)/+layout.svelte b/src/routes/(app)/[username]/(profile)/+layout.svelte
index 03cad4ff..65911eee 100644
--- a/src/routes/(app)/[username]/(profile)/+layout.svelte
+++ b/src/routes/(app)/[username]/(profile)/+layout.svelte
@@ -1,4 +1,6 @@
<script>
+ import { run, preventDefault } from 'svelte/legacy';
+
import { invalidate } from "$app/navigation";
import { browser } from "$app/environment";
import { hexToUint8Array } from "uint8array-extras";
@@ -8,7 +10,7 @@
import { bech32m } from "@scure/base";
import { page } from "$app/stores";
- export let data;
+ let { data, children } = $props();
let { encode, toWords } = bech32m;
@@ -22,10 +24,9 @@
follows,
followers,
followList,
- } = data;
- let { currency, npub, username: n, display } = subject;
+ } = $state(data);
+ let { currency, npub, username: n, display } = $state(subject);
- $: refresh(data);
let refresh = (data) => {
({
events,
@@ -41,15 +42,8 @@
({ currency, npub, username: n, display } = subject);
};
- $: stripped = n.replace(/\s/g, "");
- $: username = n.length > 60 ? n.substr(0, 6) : display || stripped;
- $: lnaddr = subject?.anon
- ? subject.lud16 || undefined
- : `${stripped}@${$page.url.host}`;
- $: profile = `${$page.url.host}/${subject.anon ? npub : stripped}`;
- let list = [];
- $: followList.then((l) => (list = l));
+ let list = $state([]);
let follow = async () => {
list = [...list, subject.pubkey];
let tags = await get(
@@ -95,15 +89,14 @@
}
};
- $: following = list.some((t) => t.includes(subject.pubkey));
- let showBio;
+ let showBio = $state();
let toggleBio = () => (showBio = !showBio);
- let showDetails;
+ let showDetails = $state();
let toggleDetails = () => (showDetails = !showDetails);
- let password;
+ let password = $state();
let reset = async () => {
try {
@@ -113,28 +106,41 @@
fail(e.message);
}
};
+ run(() => {
+ refresh(data);
+ });
+ let stripped = $derived(n.replace(/\s/g, ""));
+ let username = $derived(n.length > 60 ? n.substr(0, 6) : display || stripped);
+ let lnaddr = $derived(subject?.anon
+ ? subject.lud16 || undefined
+ : `${stripped}@${$page.url.host}`);
+ let profile = $derived(`${$page.url.host}/${subject.anon ? npub : stripped}`);
+ run(() => {
+ followList.then((l) => (list = l));
+ });
+ let following = $derived(list.some((t) => t.includes(subject.pubkey)));
</script>
<div class="container mx-auto w-full px-4 flex flex-wrap lg:flex-nowrap">
- <div class="hidden lg:block lg:w-[280px] xl:w-[360px]" />
+ <div class="hidden lg:block lg:w-[280px] xl:w-[360px]"></div>
<div
class="w-full lg:w-[280px] xl:w-[360px] lg:absolute space-y-2 left-20 mx-auto"
>
<button
type="button"
- on:click={toggleDetails}
+ onclick={toggleDetails}
class="flex text-3xl font-bold text-center mx-auto justify-center gap-2"
>
<div class="my-auto break-words">{display || username}</div>
- <iconify-icon icon="ph:qr-code-bold" width="32" />
+ <iconify-icon icon="ph:qr-code-bold" width="32"></iconify-icon>
</button>
{#if subject.address || subject.about}
<div
class="text-secondary mx-auto text-center lg:mx-0 break-words space-y-1"
class:line-clamp-2={!showBio}
- on:click={toggleBio}
- on:keydown={toggleBio}
+ onclick={toggleBio}
+ onkeydown={toggleBio}
>
<div>
{subject.address || subject.about}
@@ -177,11 +183,11 @@
{lnaddr}
</div>
<div class="flex mb-auto gap-1">
- <button class="my-auto" on:click={() => copy(lnaddr)}
- ><iconify-icon icon="ph:copy-bold" width="32" /></button
+ <button class="my-auto" onclick={() => copy(lnaddr)}
+ ><iconify-icon icon="ph:copy-bold" width="32"></iconify-icon></button
>
<a href={`/qr/${encodeURIComponent(lnaddr)}`} class="my-auto">
- <iconify-icon icon="ph:qr-code-bold" width="32" />
+ <iconify-icon icon="ph:qr-code-bold" width="32"></iconify-icon>
</a>
</div>
</div>
@@ -194,8 +200,8 @@
{profile}
</div>
<div class="flex mb-auto gap-1">
- <button class="my-auto" on:click={() => copy(profile)}
- ><iconify-icon icon="ph:copy-bold" width="32" /></button
+ <button class="my-auto" onclick={() => copy(profile)}
+ ><iconify-icon icon="ph:copy-bold" width="32"></iconify-icon></button
>
<a
href={`/qr/${encodeURIComponent(
@@ -203,7 +209,7 @@
)}`}
class="my-auto"
>
- <iconify-icon icon="ph:qr-code-bold" width="32" />
+ <iconify-icon icon="ph:qr-code-bold" width="32"></iconify-icon>
</a>
</div>
</div>
@@ -215,11 +221,11 @@
{npub}
</div>
<div class="flex my-auto gap-1">
- <button class="my-auto" on:click={() => copy(npub)}
- ><iconify-icon icon="ph:copy-bold" width="32" /></button
+ <button class="my-auto" onclick={() => copy(npub)}
+ ><iconify-icon icon="ph:copy-bold" width="32"></iconify-icon></button
>
<a href={`/qr/${encodeURIComponent(npub)}`} class="my-auto">
- <iconify-icon icon="ph:qr-code-bold" width="32" />
+ <iconify-icon icon="ph:qr-code-bold" width="32"></iconify-icon>
</a>
</div>
</div>
@@ -230,13 +236,13 @@
<div class="flex flex-wrap gap-2 w-full text-lg">
{#if user && user.username !== subject.username && subject.pubkey}
{#if following}
- <button class="btn" on:click={unfollow}>
- <iconify-icon icon="ph:user-bold" width="32" />
+ <button class="btn" onclick={unfollow}>
+ <iconify-icon icon="ph:user-bold" width="32"></iconify-icon>
<div class="my-auto">{$t("user.unfollow")}</div>
</button>
{:else}
- <button class="btn" on:click={follow}>
- <iconify-icon icon="ph:user-bold" width="32" />
+ <button class="btn" onclick={follow}>
+ <iconify-icon icon="ph:user-bold" width="32"></iconify-icon>
<div class="my-auto">{$t("user.follow")}</div>
</button>
{/if}
@@ -256,14 +262,14 @@
<!-- {/if} -->
{#if user?.admin && user.username !== subject.username}
- <form class="w-full flex" on:submit|preventDefault={reset}>
+ <form class="w-full flex" onsubmit={preventDefault(reset)}>
<input placeholder="Password reset" bind:value={password} />
<button
type="submit"
class="rounded-2xl border py-5 px-6 font-bold hover:opacity-80 flex w-60"
>
<div class="mx-auto flex">
- <iconify-icon icon="ph:clock" width="32" />
+ <iconify-icon icon="ph:clock" width="32"></iconify-icon>
</div>
</button>
</form>
@@ -275,7 +281,7 @@
<div
class="mx-auto space-y-5 lg:max-w-xl xl:max-w-2xl lg:pl-10 mt-5 lg:mt-0"
>
- <slot />
+ {@render children?.()}
</div>
</div>
</div>
diff --git a/src/routes/(app)/[username]/(profile)/+page.svelte b/src/routes/(app)/[username]/(profile)/+page.svelte
index d14f2f58..e956aab7 100644
--- a/src/routes/(app)/[username]/(profile)/+page.svelte
+++ b/src/routes/(app)/[username]/(profile)/+page.svelte
@@ -1,4 +1,6 @@
<script>
+ import { run } from 'svelte/legacy';
+
import { btc, f, sat } from "$lib/utils";
import Icon from "$comp/Icon.svelte";
import Account from "$comp/Account.svelte";
@@ -8,20 +10,22 @@
import { installPrompt } from "$lib/store";
import { afterNavigate, preloadData } from "$app/navigation";
- export let data;
+ let { data } = $props();
afterNavigate(() => {
preloadData(`/${user.username}/receive`);
preloadData("/send");
});
- let { accounts, subject, user, items, rates } = data;
- $: ({ currency } = subject);
- $: rate = rates[currency];
- $: total = items.reduce((a, b) => a + b.price * b.quantity, 0);
+ let { accounts, subject, user, items, rates } = $state(data);
+ let { currency } = $derived(subject);
+ let rate = $derived(rates[currency]);
+ let total = $derived(items.reduce((a, b) => a + b.price * b.quantity, 0));
let refresh = (d) => ({ accounts, items, subject, user, rates } = d);
- $: refresh(data);
+ run(() => {
+ refresh(data);
+ });
let install = async () => {
if (!$installPrompt) return;
@@ -42,14 +46,14 @@
<a href={`/account/savings`} class="contents">
<button class="btn btn-lg w-full rounded-2xl whitespace-nowrap">
- <iconify-icon icon="ph:plus-circle-bold" width="32" />
+ <iconify-icon icon="ph:plus-circle-bold" width="32"></iconify-icon>
{$t("accounts.addAccount")}
</button>
</a>
{#if $installPrompt}
- <button class="btn btn-accent lg:hidden" on:click={install}>
- <iconify-icon icon="ph:floppy-disk-bold" width="32" />
+ <button class="btn btn-accent lg:hidden" onclick={install}>
+ <iconify-icon icon="ph:floppy-disk-bold" width="32"></iconify-icon>
{$t("user.install")}
</button>
{/if}
@@ -64,7 +68,7 @@
{#if total > 0}
<button
class="rounded-2xl py-5 px-6 font-bold hover:bg-neutral-700 flex bg-black text-white mx-auto"
- on:click={checkout}
+ onclick={checkout}
>
<div class="mx-auto flex">
<div class="my-auto text-2xl">
diff --git a/src/routes/(app)/[username]/(profile)/event/[id]/+page.svelte b/src/routes/(app)/[username]/(profile)/event/[id]/+page.svelte
index 74ce1067..9244d392 100644
--- a/src/routes/(app)/[username]/(profile)/event/[id]/+page.svelte
+++ b/src/routes/(app)/[username]/(profile)/event/[id]/+page.svelte
@@ -1,6 +1,6 @@
<script>
import Event from "$comp/Event.svelte";
- export let data;
+ let { data } = $props();
let { event } = data;
</script>
diff --git a/src/routes/(app)/[username]/(profile)/followers/+page.svelte b/src/routes/(app)/[username]/(profile)/followers/+page.svelte
index c0080990..b7ad4948 100644
--- a/src/routes/(app)/[username]/(profile)/followers/+page.svelte
+++ b/src/routes/(app)/[username]/(profile)/followers/+page.svelte
@@ -4,7 +4,7 @@
import { browser } from "$app/environment";
import VirtualScroll from "svelte-virtual-scroll-list";
- export let data;
+ let { data } = $props();
let { followers } = data;
</script>
@@ -17,34 +17,36 @@
<div>Loading followers...</div>
{:then followers}
{#if followers.length}
- <VirtualScroll data={followers} key="pubkey" let:data pageMode={true}>
- <a
- href={`/${data.pubkey}`}
- data-sveltekit-preload-data="tap"
- rel="nofollow"
- >
- <div
- class="flex border-b last:border-b-0 py-4 text-2xl text-secondary"
- :key={data.pubkey}
+ <VirtualScroll data={followers} key="pubkey" pageMode={true}>
+ {#snippet children({ data })}
+ <a
+ href={`/${data.pubkey}`}
+ data-sveltekit-preload-data="tap"
+ rel="nofollow"
>
- <div class="mb-auto mr-2">
- <div class="md:hidden">
- <Avatar size={12} user={data} disabled={true} />
+ <div
+ class="flex border-b last:border-b-0 py-4 text-2xl text-secondary"
+ :key={data.pubkey}
+ >
+ <div class="mb-auto mr-2">
+ <div class="md:hidden">
+ <Avatar size={12} user={data} disabled={true} />
+ </div>
+ <div class="hidden md:block">
+ <Avatar size={20} user={data} disabled={true} />
+ </div>
</div>
- <div class="hidden md:block">
- <Avatar size={20} user={data} disabled={true} />
- </div>
- </div>
- <div class="w-full flex pb-1 text-black my-auto">
- <div>
- <div>{data.display_name || ""}</div>
- <div class="text-secondary text-lg">@{data.name}</div>
+ <div class="w-full flex pb-1 text-black my-auto">
+ <div>
+ <div>{data.display_name || ""}</div>
+ <div class="text-secondary text-lg">@{data.name}</div>
+ </div>
</div>
</div>
- </div>
- </a>
- </VirtualScroll>
+ </a>
+ {/snippet}
+ </VirtualScroll>
{:else}
<div>No followers</div>
{/if}
diff --git a/src/routes/(app)/[username]/(profile)/follows/+page.svelte b/src/routes/(app)/[username]/(profile)/follows/+page.svelte
index 9b2f70d1..ad416500 100644
--- a/src/routes/(app)/[username]/(profile)/follows/+page.svelte
+++ b/src/routes/(app)/[username]/(profile)/follows/+page.svelte
@@ -1,4 +1,6 @@
<script>
+ import { run } from 'svelte/legacy';
+
import { onMount } from "svelte";
import { t } from "$lib/translations";
import Avatar from "$comp/Avatar.svelte";
@@ -6,10 +8,12 @@
import VirtualScroll from "svelte-virtual-scroll-list";
import { invalidate } from "$app/navigation";
- export let data;
- let { follows } = data;
- $: refresh(data);
+ let { data } = $props();
+ let { follows } = $state(data);
let refresh = (data) => ({ follows } = data);
+ run(() => {
+ refresh(data);
+ });
</script>
<div class="px-3 md:px-0 w-full md:w-[400px] mx-auto">
@@ -22,31 +26,33 @@
{:then follows}
{#if follows.length}
{#if browser}
- <VirtualScroll data={follows} key="pubkey" let:data pageMode={true}>
- <a
- href={`/${data.pubkey}`}
- data-sveltekit-preload-data="tap"
- rel="nofollow"
- >
- <div class="flex py-4 text-lg text-secondary" :key={data.pubkey}>
- <div class="mb-auto mr-2">
- <div class="md:hidden">
- <Avatar size={12} user={data} disabled={true} />
- </div>
- <div class="hidden md:block">
- <Avatar size={20} user={data} disabled={true} />
+ <VirtualScroll data={follows} key="pubkey" pageMode={true}>
+ {#snippet children({ data })}
+ <a
+ href={`/${data.pubkey}`}
+ data-sveltekit-preload-data="tap"
+ rel="nofollow"
+ >
+ <div class="flex py-4 text-lg text-secondary" :key={data.pubkey}>
+ <div class="mb-auto mr-2">
+ <div class="md:hidden">
+ <Avatar size={12} user={data} disabled={true} />
+ </div>
+ <div class="hidden md:block">
+ <Avatar size={20} user={data} disabled={true} />
+ </div>
</div>
- </div>
- <div class="w-full flex pb-1 text-black my-auto">
- <div>
- <div>{data.display_name || ""}</div>
- <div class="text-secondary text-base">@{data.name}</div>
+ <div class="w-full flex pb-1 text-black my-auto">
+ <div>
+ <div>{data.display_name || ""}</div>
+ <div class="text-secondary text-base">@{data.name}</div>
+ </div>
</div>
</div>
- </div>
- </a>
- </VirtualScroll>
+ </a>
+ {/snippet}
+ </VirtualScroll>
{/if}
{:else}
<div>No follows</div>
diff --git a/src/routes/(app)/[username]/+layout.svelte b/src/routes/(app)/[username]/+layout.svelte
index ce152831..e3ad7259 100644
--- a/src/routes/(app)/[username]/+layout.svelte
+++ b/src/routes/(app)/[username]/+layout.svelte
@@ -1,9 +1,9 @@
<script>
- export let data;
+ let { data, children, fixed } = $props();
</script>
<div class="content">
- <slot />
+ {@render children?.()}
</div>
-<slot name="fixed" />
+{@render fixed?.()}
diff --git a/src/routes/(app)/[username]/receive/+page.svelte b/src/routes/(app)/[username]/receive/+page.svelte
index e9e5ca43..9a696929 100644
--- a/src/routes/(app)/[username]/receive/+page.svelte
+++ b/src/routes/(app)/[username]/receive/+page.svelte
@@ -1,4 +1,6 @@
<script>
+ import { run } from 'svelte/legacy';
+
import { send } from "$lib/socket";
import { btc, post, copy, f, get, types, sat, s, sats } from "$lib/utils";
import { tick, onMount, onDestroy } from "svelte";
@@ -12,12 +14,11 @@
import { t } from "$lib/translations";
import { goto, invalidate } from "$app/navigation";
- export let data;
+ let { data } = $props();
let showOptions;
- let { id, rates, subject, user, src, text } = data;
- $: refresh(data);
+ let { id, rates, subject, user, src, text } = $state(data);
let refresh = (data) => {
({ id, rates, subject, user, src, text } = data);
};
@@ -29,19 +30,15 @@
let qr;
- $: link = [types.bitcoin, types.liquid].includes(type)
- ? text
- : `lightning:${text}`;
- $: txt = [types.bitcoin, types.liquid].includes(type) ? hash : text;
let aid = subject.id;
- let invoice = {
+ let invoice = $state({
aid,
type: types.lightning,
items: [],
user: subject,
- };
- let amount, amountFiat, tip;
+ });
+ let amount = $state(), amountFiat, tip;
let setType = async (type) => {
invoice.type = type;
@@ -75,10 +72,16 @@
};
let newAmount;
- let settingAmount;
+ let settingAmount = $state();
let toggleAmount = () => (settingAmount = !settingAmount);
- let fiat;
let submit;
+ run(() => {
+ refresh(data);
+ });
+ let link = $derived([types.bitcoin, types.liquid].includes(type)
+ ? text
+ : `lightning:${text}`);
+ let txt = $derived([types.bitcoin, types.liquid].includes(type) ? hash : text);
</script>
<div class="invoice container mx-auto max-w-xl px-4 space-y-2">
@@ -115,7 +118,6 @@
<SetAmount
{currency}
{rate}
- {fiat}
{submit}
{settingAmount}
{setAmount}
diff --git a/src/routes/(app)/account/[id]/+page.svelte b/src/routes/(app)/account/[id]/+page.svelte
index be7d6112..29add530 100644
--- a/src/routes/(app)/account/[id]/+page.svelte
+++ b/src/routes/(app)/account/[id]/+page.svelte
@@ -14,19 +14,19 @@
PUBLIC_COINOS_RELAY as relay,
} from "$env/static/public";
- export let data;
+ let { data } = $props();
let { account, user } = data;
let { id, name, seed } = account;
- let mnemonic, password;
- let passwordPrompt;
- let cancel = () => (passwordPrompt = false);
+ let mnemonic = $state(), password = $state();
+ let passwordPrompt = $state();
+ let cancel = $state(() => (passwordPrompt = false));
let toggle = () => (passwordPrompt = !passwordPrompt);
- let submit = async () => {
+ let submit = $state(async () => {
toggle();
let entropy = await decrypt(seed, password);
mnemonic = entropyToMnemonic(entropy, wordlist);
- };
+ });
let del = async () => {
try {
@@ -37,7 +37,7 @@
}
};
- let nwc;
+ let nwc = $state();
let revealNwc = () =>
(nwc = `nostr+walletconnect://${pk}?relay=${encodeURIComponent(
relay,
@@ -53,17 +53,17 @@
{#if mnemonic}
<Mnemonic {mnemonic} />
- <button on:click={() => copy(mnemonic)} type="button" class="btn">
- <iconify-icon icon="ph:copy-bold" width="32" />
+ <button onclick={() => copy(mnemonic)} type="button" class="btn">
+ <iconify-icon icon="ph:copy-bold" width="32"></iconify-icon>
<div class="my-auto">{$t("accounts.copy")}</div></button
>
{:else if seed}
<button
- on:click={toggle}
+ onclick={toggle}
type="button"
class="flex gap-2 rounded-2xl border py-5 mx-auto px-6 w-full justify-center"
>
- <iconify-icon icon="ph:eye-bold" width="32" />
+ <iconify-icon icon="ph:eye-bold" width="32"></iconify-icon>
<div class="my-auto">{$t("accounts.revealMnemonic")}</div></button
>
{:else if nwc}
@@ -71,26 +71,26 @@
{nwc}
</div>
<button
- on:click={() => copy(nwc)}
+ onclick={() => copy(nwc)}
type="button"
class="flex gap-2 rounded-2xl border py-5 mx-auto px-6 w-full justify-center"
>
- <iconify-icon icon="ph:copy-bold" width="32" />
+ <iconify-icon icon="ph:copy-bold" width="32"></iconify-icon>
<div class="my-auto">{$t("accounts.copy")}</div></button
>
<a href={`/qr/${encodeURIComponent(nwc)}`} class="my-auto block">
<button
- on:click={() => copy(nwc)}
+ onclick={() => copy(nwc)}
type="button"
class="flex gap-2 rounded-2xl border py-5 mx-auto px-6 w-full justify-center"
>
- <iconify-icon icon="ph:qr-code-bold" width="32" />
+ <iconify-icon icon="ph:qr-code-bold" width="32"></iconify-icon>
<div class="my-auto">{$t("user.receive.showQR")}</div></button
>
</a>
{:else}
<button
- on:click={revealNwc}
+ onclick={revealNwc}
type="button"
class="flex gap-2 rounded-2xl border py-5 mx-auto px-6 w-full justify-center"
>
@@ -101,7 +101,7 @@
{#if seed}
<button
- on:click={del}
+ onclick={del}
type="button"
class="flex gap-2 rounded-2xl border py-5 mx-auto px-6 w-full justify-center"
>
@@ -111,7 +111,7 @@
{/if}
</div>
- <div />
+ <div></div>
</form>
</div>
</div>
diff --git a/src/routes/(app)/account/import/+page.svelte b/src/routes/(app)/account/import/+page.svelte
index a1d6549b..b94cc839 100644
--- a/src/routes/(app)/account/import/+page.svelte
+++ b/src/routes/(app)/account/import/+page.svelte
@@ -1,4 +1,6 @@
<script>
+ import { run, preventDefault } from 'svelte/legacy';
+
import { goto } from "$app/navigation";
import { mnemonic } from "$lib/store";
import { fail, focus, versions } from "$lib/utils";
@@ -8,7 +10,7 @@
import { validateMnemonic } from "@scure/bip39";
import { wordlist } from "@scure/bip39/wordlists/english";
- let el, pasted, text;
+ let el = $state(), pasted = $state(), text = $state();
let paste = async () => {
text = await navigator.clipboard.readText();
@@ -26,14 +28,16 @@
}
};
- $: if (browser && pasted && text) form.submit() && (pasted = false);
+ run(() => {
+ if (browser && pasted && text) form.submit() && (pasted = false);
+ });
</script>
<div class="space-y-5">
<h1 class="text-center text-3xl font-semibold">{$t("accounts.import")}</h1>
<div class="container w-full mx-auto text-lg px-4 max-w-xl space-y-2">
- <form on:submit|preventDefault={submit} class="space-y-2">
+ <form onsubmit={preventDefault(submit)} class="space-y-2">
<textarea
use:focus
name="text"
@@ -41,7 +45,7 @@
class="w-full p-4 border rounded-xl h-48 text-xl"
bind:value={text}
autocapitalize="none"
- />
+></textarea>
<button
bind:this={el}
type="submit"
diff --git a/src/routes/(app)/account/pass/+page.svelte b/src/routes/(app)/account/pass/+page.svelte
index 5becf337..62ef9b8e 100644
--- a/src/routes/(app)/account/pass/+page.svelte
+++ b/src/routes/(app)/account/pass/+page.svelte
@@ -1,4 +1,6 @@
<script lang="ts">
+ import { preventDefault } from 'svelte/legacy';
+
import { tick, onMount } from "svelte";
import { t } from "$lib/translations";
import { mnemonic } from "$lib/store";
@@ -15,12 +17,12 @@
import { goto } from "$app/navigation";
import { HDKey } from "@scure/bip32";
- export let data;
+ let { data } = $props();
let { user } = data;
- let submitting;
+ let submitting = $state();
- let confirm, password, revealPassword, revealConfirm;
+ let confirm = $state(), password = $state(), revealPassword = $state(), revealConfirm = $state();
let type = "bitcoin";
let name = $t("accounts.savings");
@@ -70,7 +72,7 @@
</div>
<form
- on:submit|preventDefault={submit}
+ onsubmit={preventDefault(submit)}
class="container w-full mx-auto text-lg px-4 max-w-xl space-y-5"
>
<p class="text-secondary mb-1">
@@ -100,7 +102,7 @@
<button
tabindex="-1"
type="button"
- on:click={() => (revealPassword = !revealPassword)}
+ onclick={() => (revealPassword = !revealPassword)}
class="absolute right-5 -translate-y-1/2 top-1/2"
>
<Icon icon={revealPassword ? "eye" : "eye-off"} />
@@ -129,7 +131,7 @@
<button
type="button"
tabindex="-1"
- on:click={() => (revealConfirm = !revealConfirm)}
+ onclick={() => (revealConfirm = !revealConfirm)}
class="absolute right-5 -translate-y-1/2 top-1/2"
>
<Icon icon={revealConfirm ? "eye" : "eye-off"} />
diff --git a/src/routes/(app)/account/savings/+page.svelte b/src/routes/(app)/account/savings/+page.svelte
index 2461bd20..d0474636 100644
--- a/src/routes/(app)/account/savings/+page.svelte
+++ b/src/routes/(app)/account/savings/+page.svelte
@@ -13,7 +13,7 @@
<a href="/account/seed" class="block">
<div class="card card-side shadow shadow-base-400 p-8 hover:bg-base-200">
<figure class="w-20">
- <iconify-icon icon="ph:file-plus-bold" width="64" />
+ <iconify-icon icon="ph:file-plus-bold" width="64"></iconify-icon>
</figure>
<div>
<div class="text-xl">{$t("accounts.create")}</div>
@@ -24,7 +24,7 @@
<a href="/account/import" class="block">
<div class="card card-side shadow p-8 hover:bg-base-200">
<figure class="w-20">
- <iconify-icon icon="ph:folder-open-bold" width="64" />
+ <iconify-icon icon="ph:folder-open-bold" width="64"></iconify-icon>
</figure>
<div>
<div class="text-xl">{$t("accounts.import")}</div>
diff --git a/src/routes/(app)/account/seed/+page.svelte b/src/routes/(app)/account/seed/+page.svelte
index 5d828369..b3e7d57c 100644
--- a/src/routes/(app)/account/seed/+page.svelte
+++ b/src/routes/(app)/account/seed/+page.svelte
@@ -9,7 +9,7 @@
import { generateMnemonic } from "@scure/bip39";
import { wordlist } from "@scure/bip39/wordlists/english";
- export let data;
+ let { data } = $props();
let { user } = data;
onMount(async () => {
@@ -36,7 +36,7 @@
<button
type="button"
class="flex gap-2 text-center break-all rounded-2xl hover:opacity-80 py-3 px-4 w-full mx-auto justify-center border whitespace-nowrap mb-2"
- on:click={generate}
+ onclick={generate}
>
<Icon icon="random" style="w-8 my-auto" />
<div class="my-auto">{$t("accounts.regenerate")}</div>
@@ -45,7 +45,7 @@
<button
type="button"
class="flex gap-2 text-center break-all rounded-2xl hover:opacity-80 py-3 px-4 w-full mx-auto justify-center border whitespace-nowrap mb-2"
- on:click={() => copy($mnemonic)}
+ onclick={() => copy($mnemonic)}
>
<Icon icon="copy" style="w-8 my-auto" />
<div class="my-auto">
diff --git a/src/routes/(app)/admin/+layout.svelte b/src/routes/(app)/admin/+layout.svelte
index 54905ab0..39cfe5ed 100644
--- a/src/routes/(app)/admin/+layout.svelte
+++ b/src/routes/(app)/admin/+layout.svelte
@@ -1,10 +1,10 @@
<script>
import LandingHeader from "$comp/LandingHeader.svelte";
- export let data;
+ let { data, children } = $props();
let { user } = data;
</script>
<LandingHeader {user} />
<main class="container px-10 md:px-40 mx-auto min-h-[600px] pb-20">
- <slot />
+ {@render children?.()}
</main>
diff --git a/src/routes/(app)/admin/+page.svelte b/src/routes/(app)/admin/+page.svelte
index 214bf5b3..ccaa8794 100644
--- a/src/routes/(app)/admin/+page.svelte
+++ b/src/routes/(app)/admin/+page.svelte
@@ -1,9 +1,9 @@
<script>
import { post } from "$lib/utils";
- export let data;
+ let { data } = $props();
let reset = (username) => post(`/reset`, { password });
let { users } = data;
- let password;
+ let password = $state();
</script>
{#each users as { balance, username, expected }}
@@ -15,7 +15,7 @@
<div>
<button
class="text-sm md:text-lg rounded-full border py-2 px-4 hover:opacity-80 min-w-[72px] bg-black text-white"
- on:click={() => reset(username)}>Reset</button
+ onclick={() => reset(username)}>Reset</button
>
</div>
</div>
diff --git a/src/routes/(app)/ecash/[id]/[...version]/+layout.svelte b/src/routes/(app)/ecash/[id]/[...version]/+layout.svelte
index f9c80329..d0d06046 100644
--- a/src/routes/(app)/ecash/[id]/[...version]/+layout.svelte
+++ b/src/routes/(app)/ecash/[id]/[...version]/+layout.svelte
@@ -3,7 +3,7 @@
import { t } from "$lib/translations";
import Icon from "$comp/Icon.svelte";
- export let data;
+ let { data, children } = $props();
let { id, rates, user, token, total, spent, external, mint } = data;
let currency = user?.currency || "USD";
@@ -11,8 +11,8 @@
let amount = total - spent;
- $: amountFiat = parseFloat(((amount * rate) / sats).toFixed(2));
- $: spentFiat = parseFloat(((spent * rate) / sats).toFixed(2));
+ let amountFiat = $derived(parseFloat(((amount * rate) / sats).toFixed(2)));
+ let spentFiat = $derived(parseFloat(((spent * rate) / sats).toFixed(2)));
</script>
<div class="container px-4 max-w-lg mx-auto space-y-5 mt-20">
@@ -52,5 +52,5 @@
</div>
{/if}
- <slot />
+ {@render children?.()}
</div>
diff --git a/src/routes/(app)/ecash/[id]/[...version]/+page.svelte b/src/routes/(app)/ecash/[id]/[...version]/+page.svelte
index b350b124..47126c78 100644
--- a/src/routes/(app)/ecash/[id]/[...version]/+page.svelte
+++ b/src/routes/(app)/ecash/[id]/[...version]/+page.svelte
@@ -4,11 +4,10 @@
import { t } from "$lib/translations";
import { page } from "$app/stores";
- export let data;
- export let form;
+ let { data, form } = $props();
let link = $page.url.href;
- let { id, total, version, token, external, spent } = data;
+ let { id, total, version, token, external, spent } = $state(data);
</script>
{#if form?.error}
@@ -20,8 +19,8 @@
{/if}
<div class="flex flex-wrap gap-2 text-xl">
- <button type="button" class="btn" on:click={() => copy(link)}>
- <iconify-icon icon="ph:link-bold" width="32" />
+ <button type="button" class="btn" onclick={() => copy(link)}>
+ <iconify-icon icon="ph:link-bold" width="32"></iconify-icon>
<div class="my-auto">{$t("payments.shareLink")}</div>
</button>
@@ -33,7 +32,7 @@
icon="ph:hand-coins-bold"
width="32"
flip="horizontal"
- />
+></iconify-icon>
<div class="my-auto">{$t("payments.swap")}</div>
</button>
</a>
@@ -45,7 +44,7 @@
icon="ph:hand-coins-bold"
width="32"
flip="horizontal"
- />
+></iconify-icon>
<div class="my-auto">{$t("payments.redeem")}</div>
</button>
</form>
@@ -54,7 +53,7 @@
<button
class="btn break-all !h-auto py-5 font-normal leading-normal"
- on:click={() => copy(token)}
+ onclick={() => copy(token)}
>
{token}
</button>
@@ -62,14 +61,14 @@
{#if version === 4}
<a data-sveltekit-reload href={`/ecash/${id}/3`} class="contents">
<button type="button" class="btn">
- <iconify-icon icon="ph:gear-bold" width="32" />
+ <iconify-icon icon="ph:gear-bold" width="32"></iconify-icon>
<div class="my-auto">{$t("payments.legacyVersion")}</div>
</button>
</a>
{:else}
<a data-sveltekit-reload href={`/ecash/${id}`} class="contents">
<button type="button" class="btn">
- <iconify-icon icon="ph:gear-bold" width="32" />
+ <iconify-icon icon="ph:gear-bold" width="32"></iconify-icon>
<div class="my-auto">{$t("payments.newVersion")}</div>
</button>
</a>
diff --git a/src/routes/(app)/ecash/[id]/[...version]/swap/+page.svelte b/src/routes/(app)/ecash/[id]/[...version]/swap/+page.svelte
index ee22cea2..c434c9b4 100644
--- a/src/routes/(app)/ecash/[id]/[...version]/swap/+page.svelte
+++ b/src/routes/(app)/ecash/[id]/[...version]/swap/+page.svelte
@@ -1,5 +1,5 @@
<script>
- export let data;
+ let { data } = $props();
</script>
<div class="text-center">
diff --git a/src/routes/(app)/forgot/+page.svelte b/src/routes/(app)/forgot/+page.svelte
index 378262cc..eb981734 100644
--- a/src/routes/(app)/forgot/+page.svelte
+++ b/src/routes/(app)/forgot/+page.svelte
@@ -6,8 +6,8 @@
import Spinner from "$comp/Spinner.svelte";
import { fly } from "svelte/transition";
- export let form;
- let email;
+ let { form } = $props();
+ let email = $state();
let loading;
</script>
diff --git a/src/routes/(app)/fund/[id]/+page.svelte b/src/routes/(app)/fund/[id]/+page.svelte
index b81e2917..0931075a 100644
--- a/src/routes/(app)/fund/[id]/+page.svelte
+++ b/src/routes/(app)/fund/[id]/+page.svelte
@@ -9,7 +9,7 @@
import { types, copy, f, s, sat, sats } from "$lib/utils";
import { loginRedirect } from "$lib/store";
- export let data;
+ let { data } = $props();
let { amount, src, payments, rates, user } = data;
let { id } = $page.params;
@@ -19,10 +19,10 @@
let currency = user ? user.currency : "CAD";
let rate = rates[currency];
- $: amountFiat = parseFloat(((amount * rate) / sats).toFixed(2));
+ let amountFiat = $derived(parseFloat(((amount * rate) / sats).toFixed(2)));
$loginRedirect = $page.url.pathname;
- let show;
+ let show = $state();
let toggle = () => (show = !show);
</script>
@@ -83,14 +83,14 @@
<div class="flex gap-2" data-sveltekit-prefetch="off">
<button
class="rounded-full border py-3 px-2 font-bold hover:opacity-80 flex gap-1 w-full justify-center"
- on:click={toggle}
+ onclick={toggle}
>
<Icon icon="qr" style="invert" />
{show ? $t("payments.hide") : $t("payments.show")} QR
</button>
<button
class="rounded-full border py-3 px-2 font-bold hover:opacity-80 flex gap-1 w-full justify-center"
- on:click={() => copy($page.url.host + $page.url.pathname)}
+ onclick={() => copy($page.url.host + $page.url.pathname)}
>
<Icon icon="copy" style="w-6" />
{$t("payments.copyLink")}
diff --git a/src/routes/(app)/fund/[id]/sweep/+page.svelte b/src/routes/(app)/fund/[id]/sweep/+page.svelte
index 927c59d3..a34a8610 100644
--- a/src/routes/(app)/fund/[id]/sweep/+page.svelte
+++ b/src/routes/(app)/fund/[id]/sweep/+page.svelte
@@ -4,11 +4,11 @@
import Icon from "$comp/Icon.svelte";
import { t } from "$lib/translations";
- export let data;
+ let { data } = $props();
let { amount, id, user, rates } = data;
let { currency } = user;
- $: rate = rates[currency];
+ let rate = $derived(rates[currency]);
</script>
<div class="container px-4 max-w-xl mx-auto mt-10 space-y-5 text-center">
@@ -33,7 +33,7 @@
</div>
<a href={`/payments`}>
- <div class="opacity-0 w-screen h-screen fixed top-0 left-0 z-50" />
+ <div class="opacity-0 w-screen h-screen fixed top-0 left-0 z-50"></div>
</a>
<div class="flex justify-center">
diff --git a/src/routes/(app)/fund/[id]/withdraw/+page.svelte b/src/routes/(app)/fund/[id]/withdraw/+page.svelte
index 0ad3c2cf..89654d23 100644
--- a/src/routes/(app)/fund/[id]/withdraw/+page.svelte
+++ b/src/routes/(app)/fund/[id]/withdraw/+page.svelte
@@ -1,4 +1,6 @@
<script>
+ import { run } from 'svelte/legacy';
+
import { t } from "$lib/translations";
import { enhance } from "$app/forms";
import Icon from "$comp/Icon.svelte";
@@ -8,25 +10,29 @@
import { back } from "$lib/utils";
import { pin } from "$lib/store";
- export let data;
- export let form;
+ let { data, form } = $props();
let { rates } = data;
- let { amount, id } = $page.params;
- let { currency } = data.user;
- let loading;
+ let { amount, id } = $state($page.params);
+ let { currency } = $state(data.user);
+ let loading = $state();
let submit = () => (loading = true);
- $: update(form);
let update = () => {
if (form?.message.includes("pin")) $pin = undefined;
loading = false;
};
- $: rate = rates[currency];
+ run(() => {
+ update(form);
+ });
+ let rate;
+ run(() => {
+ rate = rates[currency];
+ });
</script>
-<button class="ml-5 md:ml-20 mt-5 md:mt-10 hover:opacity-80" on:click={back}>
+<button class="ml-5 md:ml-20 mt-5 md:mt-10 hover:opacity-80" onclick={back}>
<Icon icon="arrow-left" style="w-10" />
</button>
@@ -39,7 +45,7 @@
<div class="container px-4 mt-20 max-w-xl mx-auto">
<Numpad bind:amount bind:currency bind:rate />
- <form method="POST" use:enhance on:submit={submit}>
+ <form method="POST" use:enhance onsubmit={submit}>
<input name="id" value={id} type="hidden" />
<input name="amount" value={amount} type="hidden" />
<input name="pin" value={$pin} type="hidden" />
diff --git a/src/routes/(app)/generate/+page.svelte b/src/routes/(app)/generate/+page.svelte
index 49d75dc6..72ca2485 100644
--- a/src/routes/(app)/generate/+page.svelte
+++ b/src/routes/(app)/generate/+page.svelte
@@ -1,4 +1,6 @@
<script>
+ import { run } from 'svelte/legacy';
+
import { fail, post, wait } from "$lib/utils";
import { onMount } from "svelte";
import { goto, invalidate } from "$app/navigation";
@@ -8,10 +10,10 @@
import { generate } from "$lib/nostr";
import { browser } from "$app/environment";
- export let data;
- let { user } = data;
+ let { data } = $props();
+ let { user } = $state(data);
- let loaded;
+ let loaded = $state();
let gen = async () => {
if (!browser) return;
@@ -43,7 +45,9 @@
onMount(() => browser && setTimeout(() => (loaded = true) && gen(), 50));
- $: $pin?.length === 6 && gen(user);
+ run(() => {
+ $pin?.length === 6 && gen(user);
+ });
</script>
{#if loaded && user?.haspin && $pin?.length !== 6}
diff --git a/src/routes/(app)/invoice/[id]/[email protected] b/src/routes/(app)/invoice/[id]/[email protected]
index 62c05db1..05fd603f 100644
--- a/src/routes/(app)/invoice/[id]/[email protected]
+++ b/src/routes/(app)/invoice/[id]/[email protected]
@@ -1,4 +1,6 @@
<script>
+ import { run } from 'svelte/legacy';
+
import { SvelteToast } from "@zerodevx/svelte-toast";
import { onDestroy, onMount } from "svelte";
import { close, connect, send } from "$lib/socket";
@@ -22,16 +24,14 @@
import { t, locale, loading } from "$lib/translations";
import { goto, onNavigate } from "$app/navigation";
- export let data;
+ let { data, children } = $props();
- let { generate, rate, user, subject, token, rates, theme } = data;
+ let { generate, rate, user, subject, token, rates, theme } = $state(data);
- $: update(data);
let update = (data) => {
({ rate, user, subject, token, rates, theme } = data);
};
- $: theme = $themeStore;
$themeStore = theme;
onMount(async () => {
@@ -58,7 +58,6 @@
}
});
- $: browser && connect(token);
let lost,
checkTimer,
@@ -84,6 +83,15 @@
clearTimeout(expireTimer);
}
});
+ run(() => {
+ update(data);
+ });
+ run(() => {
+ theme = $themeStore;
+ });
+ run(() => {
+ browser && connect(token);
+ });
</script>
{#if browser && user && $passwordPrompt}
@@ -110,7 +118,7 @@
<main class="min-h-dvh" data-theme={theme}>
<AppHeader {user} {subject} />
{#if !$loading}
- <slot />
+ {@render children?.()}
{/if}
</main>
diff --git a/src/routes/(app)/invoice/[id]/+page.svelte b/src/routes/(app)/invoice/[id]/+page.svelte
index ae208779..fef43e4d 100644
--- a/src/routes/(app)/invoice/[id]/+page.svelte
+++ b/src/routes/(app)/invoice/[id]/+page.svelte
@@ -1,4 +1,6 @@
<script>
+ import { run } from "svelte/legacy";
+
import { enhance } from "$app/forms";
import { send } from "$lib/socket";
import { btc, post, copy, f, get, types, sat, s, sats } from "$lib/utils";
@@ -13,7 +15,7 @@
import { t } from "$lib/translations";
import { goto, invalidate } from "$app/navigation";
- export let data;
+ let { data } = $props();
let showOptions;
@@ -24,8 +26,7 @@
let readingerror = (e) => console.log("nfc error", e);
- $: refresh(data);
- let { invoice, id, subject, user, src } = data;
+ let { invoice, id, subject, user, src } = $state(data);
let {
aid,
amount,
@@ -35,9 +36,9 @@
text,
tip,
user: { username, currency },
- } = invoice;
+ } = $state(invoice);
- let qr;
+ let qr = $state();
let tipPercent = 0;
let refresh = async (data) => {
@@ -64,9 +65,6 @@
tipPercent = (tip / amount) * 100;
};
- $: amountFiat = parseFloat(((amount * rate) / sats).toFixed(2));
- $: tipAmount = ((tip * rate) / sats).toFixed(2);
-
let subbed = {};
onMount(async () => {
@@ -81,11 +79,6 @@
}
});
- $: link = [types.bitcoin, types.liquid].includes(type)
- ? text
- : `lightning:${text}`;
- $: txt = [types.bitcoin, types.liquid].includes(type) ? hash : text;
-
let setType = async (type) => {
invoice.type = type;
({ id } = await post(`/invoice`, {
@@ -96,7 +89,7 @@
goto(`./${id}?options=true`, { invalidateAll: true, noScroll: true });
};
- let setAmount = async () => {
+ let setAmount = $state(async () => {
if (typeof $amountPrompt === "undefined") $amountPrompt = true;
settingAmount = false;
amount = newAmount;
@@ -112,39 +105,57 @@
else url += "?options=true";
goto(url, { invalidateAll: true, noScroll: true });
- };
+ });
- let newAmount;
- let settingAmount;
- let toggleAmount = () => (settingAmount = !settingAmount);
- let fiat;
- let submit;
+ let newAmount = $state();
+ let settingAmount = $state();
+ let toggleAmount = $state(() => (settingAmount = !settingAmount));
+ let fiat = $state(true);
+ let submit = $state();
+ run(() => {
+ refresh(data);
+ });
+ let amountFiat;
+ run(() => {
+ amountFiat = parseFloat(((amount * rate) / sats).toFixed(2));
+ });
+ let tipAmount = $derived(((tip * rate) / sats).toFixed(2));
+ let link;
+ run(() => {
+ link = [types.bitcoin, types.liquid].includes(type)
+ ? text
+ : `lightning:${text}`;
+ });
+ let txt;
+ run(() => {
+ txt = [types.bitcoin, types.liquid].includes(type) ? hash : text;
+ });
</script>
<div class="invoice container mx-auto max-w-xl px-4 space-y-2">
<InvoiceData
- bind:src
- bind:link
- bind:qr
- bind:txt
- bind:invoice
- bind:amount
- bind:amountFiat
- bind:currency
- bind:tip
- bind:rate
- bind:showQr={$showQr}
+ {src}
+ {link}
+ {qr}
+ {txt}
+ {invoice}
+ {amount}
+ {amountFiat}
+ {currency}
+ {tip}
+ {rate}
+ showQr={$showQr}
/>
<InvoiceActions
- bind:toggleAmount
- bind:user
- bind:invoice
+ {toggleAmount}
+ {user}
+ {invoice}
{copy}
- bind:link
- bind:type
+ {link}
+ {type}
{types}
- bind:txt
+ {txt}
t={$t}
bind:showQr={$showQr}
/>
@@ -153,14 +164,14 @@
</div>
<SetAmount
- bind:currency
- bind:rate
- bind:fiat
- bind:submit
- bind:settingAmount
- bind:setAmount
bind:newAmount
- bind:toggleAmount
+ bind:fiat
+ {currency}
+ {rate}
+ {submit}
+ {settingAmount}
+ {setAmount}
+ {toggleAmount}
amountPrompt={$amountPrompt}
t={$t}
/>
diff --git a/src/routes/(app)/invoice/[id]/memo/+page.svelte b/src/routes/(app)/invoice/[id]/memo/+page.svelte
index 4d23ff19..02f4a5d9 100644
--- a/src/routes/(app)/invoice/[id]/memo/+page.svelte
+++ b/src/routes/(app)/invoice/[id]/memo/+page.svelte
@@ -1,4 +1,6 @@
<script>
+ import { run } from 'svelte/legacy';
+
import { onMount } from "svelte";
import { browser } from "$app/environment";
import { invoice as inv, request } from "$lib/store";
@@ -17,11 +19,10 @@
import { enhance } from "$app/forms";
let submitting;
- let submit;
+ let submit = $state();
- export let data;
- $: refresh(data);
- let { invoice, id, user, rates } = data;
+ let { data } = $props();
+ let { invoice, id, user, rates } = $state(data);
let {
amount,
hash,
@@ -34,7 +35,7 @@
text,
tip,
user: { username, currency },
- } = invoice;
+ } = $state(invoice);
invoice.memo = user?.username;
@@ -55,6 +56,9 @@
user: { username },
} = invoice);
};
+ run(() => {
+ refresh(data);
+ });
</script>
<form
diff --git a/src/routes/(app)/invoice/[id]/paid/+page.svelte b/src/routes/(app)/invoice/[id]/paid/+page.svelte
index b3b6e71a..1bbba082 100644
--- a/src/routes/(app)/invoice/[id]/paid/+page.svelte
+++ b/src/routes/(app)/invoice/[id]/paid/+page.svelte
@@ -1,4 +1,6 @@
<script>
+ import { run } from 'svelte/legacy';
+
import { scale } from "svelte/transition";
import Icon from "$comp/Icon.svelte";
import { toast } from "@zerodevx/svelte-toast";
@@ -6,15 +8,17 @@
import { t } from "$lib/translations";
import { fiat, f, s, sat, sats } from "$lib/utils";
- export let data;
- let amount, currency, rate, received, pending, tip, user, id;
- $: update(data);
+ let { data } = $props();
+ let amount, currency = $state(), rate = $state(), received = $state(), pending = $state(), tip = $state(), user = $state(), id;
let update = (data) => {
({ amount, currency, rate, received, pending, tip, user, id } =
data.invoice);
};
toast.pop(0);
+ run(() => {
+ update(data);
+ });
</script>
<div class="container px-4 text-center mx-auto">
@@ -77,7 +81,7 @@
</div>
<a href={`/${user.username}`}>
- <div class="opacity-0 w-screen h-screen fixed top-0 left-0 z-50" />
+ <div class="opacity-0 w-screen h-screen fixed top-0 left-0 z-50"></div>
</a>
<div class="flex justify-center">
diff --git a/src/routes/(app)/invoice/[id]/tip/+page.svelte b/src/routes/(app)/invoice/[id]/tip/+page.svelte
index ff3da46e..53f0eb4b 100644
--- a/src/routes/(app)/invoice/[id]/tip/+page.svelte
+++ b/src/routes/(app)/invoice/[id]/tip/+page.svelte
@@ -1,4 +1,6 @@
<script>
+ import { run, preventDefault } from 'svelte/legacy';
+
import { onMount } from "svelte";
import { browser } from "$app/environment";
import { invoice as inv, request } from "$lib/store";
@@ -11,10 +13,10 @@
import { tick } from "svelte";
const tipAmounts = ["No", "10%", "15%", "20%"];
- let showCustomAmount;
+ let showCustomAmount = $state();
- let customInput;
- let customTipAmount;
+ let customInput = $state();
+ let customTipAmount = $state();
let apply = async () => {
if (customTipAmount > 0) {
@@ -40,7 +42,7 @@
tipPercent = e.target.value;
};
- let submitting;
+ let submitting = $state();
const handleTipButtonClick = async (amount) => {
submitting = true;
if (amount === "No") {
@@ -53,11 +55,10 @@
submit.click();
};
- let submit;
+ let submit = $state();
- export let data;
- $: refresh(data);
- let { invoice, id, user, rates } = data;
+ let { data } = $props();
+ let { invoice, id, user, rates } = $state(data);
let {
aid,
amount,
@@ -70,10 +71,10 @@
text,
tip,
user: { username, currency },
- } = invoice;
+ } = $state(invoice);
let qr;
- let tipPercent = 0;
+ let tipPercent = $state(0);
let fullscreen;
@@ -97,18 +98,27 @@
tipPercent = (tip / amount) * 100;
};
- $: currency = user?.currency || invoice.currency;
- $: rate = invoice.rate * (rates[currency] / rates[invoice.currency]);
- $: tip = Math.round((amount / 100) * tipPercent);
- $: amountFiat = parseFloat(((amount * rate) / sats).toFixed(2));
- $: tipAmount = ((tip * rate) / sats).toFixed(2);
- $: invoiceAmountFiatFormatted = f(amountFiat, currency);
onMount(() => ($request = undefined));
+ run(() => {
+ refresh(data);
+ });
+ run(() => {
+ currency = user?.currency || invoice.currency;
+ });
+ run(() => {
+ rate = invoice.rate * (rates[currency] / rates[invoice.currency]);
+ });
+ run(() => {
+ tip = Math.round((amount / 100) * tipPercent);
+ });
+ let amountFiat = $derived(parseFloat(((amount * rate) / sats).toFixed(2)));
+ let tipAmount = $derived(((tip * rate) / sats).toFixed(2));
+ let invoiceAmountFiatFormatted = $derived(f(amountFiat, currency));
</script>
<div class="container px-4 max-w-lg text-center mx-auto">
@@ -154,10 +164,10 @@
<div class="space-y-2">
{#if tip}
- <button type="button" class="btn" on:click={() => submit.click()}
+ <button type="button" class="btn" onclick={() => submit.click()}
>Next</button
>
- <button type="button" class="btn" on:click={() => (tipPercent = 0)}
+ <button type="button" class="btn" onclick={() => (tipPercent = 0)}
>Reset</button
>
{:else}
@@ -168,14 +178,14 @@
type="button"
class="btn"
class:active={active(amount, tipPercent)}
- on:click={() => handleTipButtonClick(amount)}>{amount}</button
+ onclick={() => handleTipButtonClick(amount)}>{amount}</button
>
{:else}
<button
type="button"
class="btn"
class:active={active(amount, tipPercent)}
- on:click={() => handleTipButtonClick(amount)}>{amount}</button
+ onclick={() => handleTipButtonClick(amount)}>{amount}</button
>
{/if}
{/each}
@@ -186,21 +196,21 @@
<button
type="button"
class="btn"
- on:click={() => (showCustomAmount = true)}>Custom</button
+ onclick={() => (showCustomAmount = true)}>Custom</button
>
</div>
{/if}
- <button type="submit" bind:this={submit} />
+ <button type="submit" bind:this={submit}></button>
</form>
{#if showCustomAmount}
- <form on:submit|preventDefault={apply} class="space-y-2">
+ <form onsubmit={preventDefault(apply)} class="space-y-2">
<input
bind:this={customInput}
type="number"
step="0.01"
- on:input={(e) => handleCustomTipAmount(e)}
+ oninput={(e) => handleCustomTipAmount(e)}
placeholder={$t("payments.amount")}
use:focus
/>
diff --git a/src/routes/(app)/items/[id]/+page.svelte b/src/routes/(app)/items/[id]/+page.svelte
index 65720350..9629f311 100644
--- a/src/routes/(app)/items/[id]/+page.svelte
+++ b/src/routes/(app)/items/[id]/+page.svelte
@@ -1,12 +1,15 @@
<script>
+ import { run } from 'svelte/legacy';
+
import { t } from "$lib/translations";
import ItemForm from "$comp/ItemForm.svelte";
import { fail } from "$lib/utils";
- export let data;
- export let form;
+ let { data, form } = $props();
- $: form?.message && fail(form.message);
+ run(() => {
+ form?.message && fail(form.message);
+ });
let { item, user } = data;
</script>
diff --git a/src/routes/(app)/items/create/+page.svelte b/src/routes/(app)/items/create/+page.svelte
index b82889c9..b756e73e 100644
--- a/src/routes/(app)/items/create/+page.svelte
+++ b/src/routes/(app)/items/create/+page.svelte
@@ -1,12 +1,15 @@
<script>
+ import { run } from 'svelte/legacy';
+
import { t } from "$lib/translations";
import ItemForm from "$comp/ItemForm.svelte";
import { fail } from "$lib/utils";
- export let data;
- export let form;
+ let { data, form } = $props();
- $: form?.message && fail(form.message);
+ run(() => {
+ form?.message && fail(form.message);
+ });
let { user } = data;
let item = {};
</script>
diff --git a/src/routes/(app)/ln/[lnurl]/+page.svelte b/src/routes/(app)/ln/[lnurl]/+page.svelte
index 236a2a25..386df9d2 100644
--- a/src/routes/(app)/ln/[lnurl]/+page.svelte
+++ b/src/routes/(app)/ln/[lnurl]/+page.svelte
@@ -1,7 +1,7 @@
<script>
import Lnurlp from "$comp/Lnurlp.svelte";
import Lnurlw from "$comp/Lnurlw.svelte";
- export let data;
+ let { data } = $props();
let { tag } = data;
</script>
diff --git a/src/routes/(app)/ln/withdrawal/sent/+page.svelte b/src/routes/(app)/ln/withdrawal/sent/+page.svelte
index 143a92f4..e06e3c2c 100644
--- a/src/routes/(app)/ln/withdrawal/sent/+page.svelte
+++ b/src/routes/(app)/ln/withdrawal/sent/+page.svelte
@@ -4,7 +4,7 @@
import { toast } from "@zerodevx/svelte-toast";
import { t } from "$lib/translations";
- export let data;
+ let { data } = $props();
let { user } = data;
toast.pop(0);
</script>
@@ -20,7 +20,7 @@
</div>
<a href={`/payments`}>
- <div class="opacity-0 w-screen h-screen fixed top-0 left-0 z-50" />
+ <div class="opacity-0 w-screen h-screen fixed top-0 left-0 z-50"></div>
</a>
<div class="flex justify-center">
diff --git a/src/routes/(app)/messages/+page.svelte b/src/routes/(app)/messages/+page.svelte
index 61464770..269a5de3 100644
--- a/src/routes/(app)/messages/+page.svelte
+++ b/src/routes/(app)/messages/+page.svelte
@@ -1,20 +1,21 @@
<script>
+ import { run } from 'svelte/legacy';
+
import { t } from "$lib/translations";
import Avatar from "$comp/Avatar.svelte";
import { event as e, password } from "$lib/store";
import { browser } from "$app/environment";
import { decrypt } from "$lib/nostr";
- export let data;
+ let { data } = $props();
let { messages, notes, invoices, sent, received, subject, user, rates } =
- data;
- $: refresh(data);
+ $state(data);
let refresh = (d) =>
({ messages, notes, invoices, sent, received, subject, user, rates } = d);
let keys = new Set();
- let latest = [];
+ let latest = $state([]);
let ready;
e.subscribe(async (event) => {
@@ -35,7 +36,6 @@
}
});
- $: initialize($password);
let initialize = async (p) => {
let i = 0;
ready = false;
@@ -61,6 +61,12 @@
latest = latest;
ready = true;
};
+ run(() => {
+ refresh(data);
+ });
+ run(() => {
+ initialize($password);
+ });
</script>
<div class="container w-full mx-auto text-lg px-4 max-w-xl space-y-5">
diff --git a/src/routes/(app)/messages/[recipient]/+page.svelte b/src/routes/(app)/messages/[recipient]/+page.svelte
index 9b9f6f47..bc1a6383 100644
--- a/src/routes/(app)/messages/[recipient]/+page.svelte
+++ b/src/routes/(app)/messages/[recipient]/+page.svelte
@@ -1,4 +1,6 @@
<script>
+ import { run, preventDefault } from 'svelte/legacy';
+
import { cubicInOut } from "svelte/easing";
import { browser } from "$app/environment";
import { t } from "$lib/translations";
@@ -13,7 +15,7 @@
import { tick, onMount } from "svelte";
import { getEventHash } from "nostr-tools";
- export let data;
+ let { data } = $props();
function fadeScale(
node,
@@ -36,10 +38,9 @@
};
}
- let { messages, recipient, user } = data;
- let input, pane;
+ let { messages, recipient, user } = $state(data);
+ let input, pane = $state();
- $: initialize($password);
let initialize = async (p) => {
await Promise.all(
messages.map(
@@ -61,7 +62,7 @@
}
});
- let sent, submitting, message;
+ let sent, submitting, message = $state();
let submit = async () => {
submitting = true;
@@ -109,6 +110,9 @@
submit();
}
};
+ run(() => {
+ initialize($password);
+ });
</script>
<div class="container max-w-xl mx-auto px-4 space-y-5">
@@ -116,7 +120,7 @@
type="button"
class="hover:opacity-80"
data-sveltekit-preload-data="false"
- on:click={back}
+ onclick={back}
>
<Icon icon="arrow-left" style="w-10" />
</button>
@@ -162,7 +166,7 @@
<form
method="POST"
class="w-full border rounded-xl outline-none gap-4 flex p-0 pr-2"
- on:submit|preventDefault={submit}
+ onsubmit={preventDefault(submit)}
>
<input type="hidden" name="requester_id" value={user.id} />
<input type="hidden" name="recipient" value={recipient.username} />
@@ -172,8 +176,8 @@
contenteditable
class="grow break-all py-4 outline-none mt-0 pl-4"
bind:innerHTML={message}
- on:keydown={keydown}
- />
+ onkeydown={keydown}
+></div>
<button type="submit" class="my-auto shrink-0">
<Icon icon="send" style="w-8" />
</button>
diff --git a/src/routes/(app)/pay/[username]/[...amount]/+page.svelte b/src/routes/(app)/pay/[username]/[...amount]/+page.svelte
index bf2e877e..4fbd0b64 100644
--- a/src/routes/(app)/pay/[username]/[...amount]/+page.svelte
+++ b/src/routes/(app)/pay/[username]/[...amount]/+page.svelte
@@ -1,4 +1,6 @@
<script>
+ import { run } from "svelte/legacy";
+
import { t } from "$lib/translations";
import { goto } from "$app/navigation";
import { pin } from "$lib/store";
@@ -10,22 +12,19 @@
import { page } from "$app/stores";
import { f, fail, post, s, sat, sats } from "$lib/utils";
- export let data;
- export let form;
+ let { data, form } = $props();
- let { subject, rate, rates, user } = data;
+ let { subject, rate, rates, user } = $state(data);
let currency = subject?.currency || "USD";
- let next;
+ let next = $state();
- let amount = form?.amount || data.amount;
- let a,
- af,
- fiat = !amount,
- hash,
+ let amount = $state(form?.amount || data.amount);
+ let a = $state(),
+ af = $state(0),
+ fiat = $state(!amount),
+ hash = $state(),
amountFiat = 0;
- $: r = rate || rates[subject?.currency];
-
let setAmount = async () => {
amount = a;
amountFiat = parseFloat(af).toFixed(2);
@@ -49,14 +48,20 @@
goto(`/send/invoice/${id}`);
};
- let loading;
+ let loading = $state();
let submit = () => (loading = true);
- $: update(form);
let update = () => {
if (form?.message?.includes("pin")) $pin = undefined;
loading = false;
};
+ let r;
+ run(() => {
+ r = rate || rates[subject?.currency];
+ });
+ run(() => {
+ update(form);
+ });
</script>
{#if form?.message}
@@ -72,10 +77,10 @@
{currency}
bind:fiat
bind:rate={r}
- bind:submit={next}
+ submit={next}
/>
- <form method="POST" use:enhance on:submit={submit}>
+ <form method="POST" use:enhance onsubmit={submit}>
<input name="amount" value={amount} type="hidden" />
<input name="username" value={subject.username} type="hidden" />
<input name="pin" value={$pin} type="hidden" />
@@ -98,8 +103,8 @@
type="button"
bind:this={next}
class="btn btn-accent"
- on:click={setAmount}
- on:keydown={setAmount}
+ onclick={setAmount}
+ onkeydown={setAmount}
>
{$t("payments.next")}</button
>
diff --git a/src/routes/(app)/payment/[id]/+page.svelte b/src/routes/(app)/payment/[id]/+page.svelte
index 150c2bc4..fd5ea95f 100644
--- a/src/routes/(app)/payment/[id]/+page.svelte
+++ b/src/routes/(app)/payment/[id]/+page.svelte
@@ -1,4 +1,6 @@
<script>
+ import { run } from 'svelte/legacy';
+
import { browser } from "$app/environment";
import { onMount, tick } from "svelte";
import { t, loading } from "$lib/translations";
@@ -19,11 +21,10 @@
import { PUBLIC_EXPLORER, PUBLIC_LIQUID_EXPLORER } from "$env/static/public";
import locales from "$lib/locales";
- export let data;
- let { user, payment: p } = data;
+ let { data } = $props();
+ let { user, payment: p } = $state(data);
let locale = locales[user.language];
- $: refresh(data);
let refresh = (d) => {
({ user, payment: p } = d);
({
@@ -65,7 +66,7 @@
ourfee,
fee,
currency,
- } = p;
+ } = $state(p);
let a = Math.abs(amount);
let expl = {
@@ -86,11 +87,11 @@
}
};
- let txid, vout;
+ let txid = $state(), vout = $state();
if (amount > 0) [txid, vout] = ref.split(":");
else txid = hash;
- let direction = "";
+ let direction = $state("");
onMount(() => {
direction = amount > 0 ? $t("payments.from") : $t("payments.to");
@@ -98,6 +99,9 @@
direction =
direction[0].toUpperCase() + direction.substr(1, direction.length);
});
+ run(() => {
+ refresh(data);
+ });
</script>
<div class="container mx-auto max-w-lg px-4 space-y-8 break-all text-2xl">
@@ -222,7 +226,7 @@
</div>
<button
class="flex font-bold hover:opacity-80 mb-auto my-auto"
- on:click={() => copy(txid)}
+ onclick={() => copy(txid)}
>
<Icon icon="copy" style="ml-2 w-12 my-auto" />
</button>
@@ -237,7 +241,7 @@
<div>{path}</div>
<button
class="flex font-bold hover:opacity-80 mb-auto my-auto"
- on:click={() => copy(path)}
+ onclick={() => copy(path)}
>
<Icon icon="copy" style="ml-2 w-12 my-auto" />
</button>
diff --git a/src/routes/(app)/payment/[id]/plain/+page.svelte b/src/routes/(app)/payment/[id]/plain/+page.svelte
index c63a9d7f..7d5c09aa 100644
--- a/src/routes/(app)/payment/[id]/plain/+page.svelte
+++ b/src/routes/(app)/payment/[id]/plain/+page.svelte
@@ -19,7 +19,7 @@
import { format } from "date-fns";
import { PUBLIC_EXPLORER as expl } from "$env/static/public";
- export let data;
+ let { data } = $props();
let { user, payment: p } = data;
let { username } = user;
@@ -84,5 +84,5 @@
</div>
<a href={`/payment/${id}`}>
- <div class="opacity-0 w-screen h-screen fixed top-0 left-0 z-50" />
+ <div class="opacity-0 w-screen h-screen fixed top-0 left-0 z-50"></div>
</a>
diff --git a/src/routes/(app)/payments/[...page]/+page.svelte b/src/routes/(app)/payments/[...page]/+page.svelte
index ba2e4992..2735491c 100644
--- a/src/routes/(app)/payments/[...page]/+page.svelte
+++ b/src/routes/(app)/payments/[...page]/+page.svelte
@@ -1,4 +1,6 @@
<script>
+ import { run } from 'svelte/legacy';
+
import Avatar from "$comp/Avatar.svelte";
import { onMount } from "svelte";
import { format } from "date-fns";
@@ -9,9 +11,9 @@
import { differenceInDays, getUnixTime, sub } from "date-fns";
import { goto, invalidate } from "$app/navigation";
import locales from "$lib/locales";
- export let data;
+ let { data } = $props();
- let { start, end, user, rates, payments } = data;
+ let { start, end, user, rates, payments } = $state(data);
let locale = locales[user.language];
let change = ({ target: { value } }) => goto(value);
@@ -21,7 +23,7 @@
return `/p/${p.id}`;
};
- $: presets = [
+ let presets = $derived([
{
title: $t("payments.day"),
start: sub(new Date(), { days: 1 }),
@@ -42,27 +44,33 @@
start: sub(new Date(), { years: 5 }),
end: null,
},
- ];
+ ]);
- $: selection = start
+ let selection = $derived(start
? presets.findIndex(
(p) => Math.abs(differenceInDays(new Date(start * 1000), p.start)) < 1,
)
- : 0;
+ : 0);
- let p,
- incoming,
- outgoing,
- pages = [];
- $: data &&
- ({ page: p, pages, start, end, incoming, outgoing, payments } = data);
+ let p = $state(),
+ incoming = $state(),
+ outgoing = $state(),
+ pages = $state([]);
+ run(() => {
+ data &&
+ ({ page: p, pages, start, end, incoming, outgoing, payments } = data);
+ });
- $: $page && ($newPayment = false);
- $: $newPayment && invalidate(`/users/${user.username}`);
+ run(() => {
+ $page && ($newPayment = false);
+ });
+ run(() => {
+ $newPayment && invalidate(`/users/${user.username}`);
+ });
- $: path = $page.params.page
+ let path = $derived($page.params.page
? $page.url.pathname.substring(0, $page.url.pathname.lastIndexOf("/"))
- : $page.url.pathname;
+ : $page.url.pathname);
let csv = async () => {
let url = `/payments`;
@@ -128,7 +136,7 @@
}
};
- $: showPage = (i) => {
+ let showPage = $derived((i) => {
const currentPage = parseInt(p);
const maxVisiblePages = 12;
@@ -146,13 +154,13 @@
}
return i >= start && i <= end;
- };
+ });
- $: isEllipsis = (i) => {
+ let isEllipsis = $derived((i) => {
return (
(i === 1 && !showPage(i)) || (i === pages.length - 2 && !showPage(i))
);
- };
+ });
</script>
<div class="space-y-5">
@@ -241,7 +249,7 @@
{:else if p.type === types.ecash}
<img src="/images/cash.png" class="w-12" />
{:else if p.type === types.reconcile}
- <iconify-icon icon="ph:scales-bold" width="32" />
+ <iconify-icon icon="ph:scales-bold" width="32"></iconify-icon>
{:else if p.type === types.bitcoin}
<div class="my-auto">
<img
@@ -288,7 +296,7 @@
<div class="grid grid-cols-3 w-full text-center text-lg">
{#each Object.keys(incoming) as c}
- <span class="text-base text-secondary text-left" />
+ <span class="text-base text-secondary text-left"></span>
<!-- <span class="text-base text-secondary" -->
<!-- >{$t("payments.subtotal")}</span -->
<!-- > -->
@@ -323,8 +331,8 @@
</div>
<div class="flex justify-center">
- <button class="btn !w-auto" on:click={csv}>
- <iconify-icon icon="ph:floppy-disk-bold" width="32" />
+ <button class="btn !w-auto" onclick={csv}>
+ <iconify-icon icon="ph:floppy-disk-bold" width="32"></iconify-icon>
<div class="my-auto">{$t("payments.export")}</div>
</button>
</div>
diff --git a/src/routes/(app)/qr/[text]/+page.svelte b/src/routes/(app)/qr/[text]/+page.svelte
index e1aae854..02a5b718 100644
--- a/src/routes/(app)/qr/[text]/+page.svelte
+++ b/src/routes/(app)/qr/[text]/+page.svelte
@@ -2,7 +2,7 @@
import Icon from "$comp/Icon.svelte";
import Qr from "$comp/Qr.svelte";
import { back, copy } from "$lib/utils";
- export let data;
+ let { data } = $props();
let { src, text } = data;
</script>
@@ -12,9 +12,9 @@
<button
type="button"
class="btn break-all !h-auto flex-nowrap p-4 font-normal leading-normal"
- on:click={() => copy(text)}
+ onclick={() => copy(text)}
>
- <iconify-icon icon="ph:copy-bold" width="32" />
+ <iconify-icon icon="ph:copy-bold" width="32"></iconify-icon>
<div class="my-auto">{text}</div>
</button>
</div>
diff --git a/src/routes/(app)/qr/create/+page.svelte b/src/routes/(app)/qr/create/+page.svelte
index fd99a54b..74316ba9 100644
--- a/src/routes/(app)/qr/create/+page.svelte
+++ b/src/routes/(app)/qr/create/+page.svelte
@@ -1,9 +1,11 @@
<script>
+ import { run, preventDefault } from 'svelte/legacy';
+
import { goto } from "$app/navigation";
import { browser } from "$app/environment";
import { t } from "$lib/translations";
import Icon from "$comp/Icon.svelte";
- let el, text, pasted;
+ let el = $state(), text = $state(), pasted = $state();
let keypress = (e) =>
e.key === "Enter" ? e.preventDefault() || el.click() : (pasted = false);
@@ -15,7 +17,9 @@
let submit = () => goto(`/qr/${encodeURIComponent(text)}`);
- $: if (browser && pasted && text) el.click() && (pasted = false);
+ run(() => {
+ if (browser && pasted && text) el.click() && (pasted = false);
+ });
</script>
<div class="container px-4 max-w-lg mx-auto space-y-5 mt-20">
@@ -23,25 +27,25 @@
Create QR
</h1>
- <form on:submit|preventDefault={submit} class="space-y-2 text-xl">
+ <form onsubmit={preventDefault(submit)} class="space-y-2 text-xl">
<div class="mb-2">
<textarea
use:focus
name="text"
placeholder="Enter some text or a URL to put in a QR"
- on:keypress={keypress}
+ onkeypress={keypress}
class="w-full p-4 border rounded-xl h-32 text-xl"
bind:value={text}
- on:paste={() => (pasted = true)}
+ onpaste={() => (pasted = true)}
autocapitalize="none"
- />
+></textarea>
</div>
<div class="flex gap-2">
<button
type="button"
class="flex border rounded-2xl px-6 py-5 font-bold hover:opacity-80 w-full bg-primary justify-center gap-2"
- on:click={paste}
+ onclick={paste}
>
<Icon icon="paste" style="w-8 my-auto" />
<div class="my-auto">{$t("user.send.paste")}</div>
diff --git a/src/routes/(app)/receive/[...token]/+page.svelte b/src/routes/(app)/receive/[...token]/+page.svelte
index 575c8269..3c081fdc 100644
--- a/src/routes/(app)/receive/[...token]/+page.svelte
+++ b/src/routes/(app)/receive/[...token]/+page.svelte
@@ -1,4 +1,6 @@
<script>
+ import { run } from 'svelte/legacy';
+
import { page } from "$app/stores";
import { fly } from "svelte/transition";
import { enhance } from "$app/forms";
@@ -9,13 +11,12 @@
import Spinner from "$comp/Spinner.svelte";
import { back, fail, focus } from "$lib/utils";
- export let data;
- export let form;
+ let { data = $bindable(), form } = $props();
let { token } = data;
data.subject = data.user;
- let el, text, pasted, w;
+ let el = $state(), text = $state(), pasted = $state(), w = $state();
let keypress = (e) => e.key === "Enter" && (e.preventDefault() || el.click());
@@ -23,7 +24,9 @@
text = await navigator.clipboard.readText();
};
- $: if (browser && pasted && text) el.click() && (pasted = false);
+ run(() => {
+ if (browser && pasted && text) el.click() && (pasted = false);
+ });
</script>
<svelte:window bind:innerWidth={w} />
@@ -49,24 +52,24 @@
use:focus
name="text"
placeholder={$t("payments.voucherText")}
- on:keypress={keypress}
+ onkeypress={keypress}
class="w-full p-4 border rounded-xl h-32 text-xl"
bind:value={text}
- on:paste={() => (pasted = true)}
+ onpaste={() => (pasted = true)}
autocapitalize="none"
- />
+></textarea>
</div>
<div class="flex gap-2">
<a href="/scan" class="contents">
<button type="button" class="btn !w-auto flex-grow">
- <iconify-icon icon="ph:camera-bold" width="32" />
+ <iconify-icon icon="ph:camera-bold" width="32"></iconify-icon>
<div class="my-auto">{$t("user.send.scan")}</div>
</button>
</a>
- <button type="button" class="btn !w-auto flex-grow" on:click={paste}>
- <iconify-icon icon="ph:clipboard-text-bold" width="32" />
+ <button type="button" class="btn !w-auto flex-grow" onclick={paste}>
+ <iconify-icon icon="ph:clipboard-text-bold" width="32"></iconify-icon>
<div class="my-auto">{$t("user.send.paste")}</div>
</button>
</div>
diff --git a/src/routes/(app)/reset/[code]/+page.svelte b/src/routes/(app)/reset/[code]/+page.svelte
index d93e8bdf..144c73a9 100644
--- a/src/routes/(app)/reset/[code]/+page.svelte
+++ b/src/routes/(app)/reset/[code]/+page.svelte
@@ -5,10 +5,10 @@
import { fly } from "svelte/transition";
import { password } from "$lib/store";
- export let form;
+ let { form } = $props();
let email;
let loading;
- let revealPassword;
+ let revealPassword = $state();
</script>
<div class="pt-10">
@@ -56,7 +56,7 @@
{/if}
<button
type="button"
- on:click={() => (revealPassword = !revealPassword)}
+ onclick={() => (revealPassword = !revealPassword)}
class="absolute right-5 top-10"
>
<Icon icon={revealPassword ? "eye" : "eye-off"} />
diff --git a/src/routes/(app)/scan/[email protected] b/src/routes/(app)/scan/[email protected]
index 2dc061a8..14b35465 100644
--- a/src/routes/(app)/scan/[email protected]
+++ b/src/routes/(app)/scan/[email protected]
@@ -1,3 +1,11 @@
+<script lang="ts">
+ interface Props {
+ children?: import('svelte').Snippet;
+ }
+
+ let { children }: Props = $props();
+</script>
+
<main class="min-h-dvh">
- <slot />
+ {@render children?.()}
</main>
diff --git a/src/routes/(app)/scan/+page.svelte b/src/routes/(app)/scan/+page.svelte
index 1acc9b13..edff522e 100644
--- a/src/routes/(app)/scan/+page.svelte
+++ b/src/routes/(app)/scan/+page.svelte
@@ -6,7 +6,7 @@
import { back } from "$lib/utils";
import { goto } from "$app/navigation";
- let scanner, vid, resizing;
+ let scanner, vid = $state(), resizing;
let resize = () => {
if (resizing) clearTimeout(resizing);
@@ -31,19 +31,19 @@
onDestroy(() => scanner?.stop());
</script>
-<svelte:window on:resize={resize} />
+<svelte:window onresize={resize} />
<div class="flex w-full mb-4 p-4">
<div class="mx-auto rounded-3xl">
<video
bind:this={vid}
class="border-4 rounded-3xl border-black max-h-[calc(100vh*0.7)]"
- />
+></video>
</div>
</div>
<div class="flex justify-center">
- <button class="btn !w-auto" on:click={back}>Cancel</button>
+ <button class="btn !w-auto" onclick={back}>Cancel</button>
</div>
<style>
diff --git a/src/routes/(app)/send/+layout.svelte b/src/routes/(app)/send/+layout.svelte
index 9e14fa39..5c6d8f11 100644
--- a/src/routes/(app)/send/+layout.svelte
+++ b/src/routes/(app)/send/+layout.svelte
@@ -3,7 +3,7 @@
import Pin from "$comp/Pin.svelte";
import { pin } from "$lib/store";
- export let data;
+ let { data, children } = $props();
let { user } = data;
let cancel = () => goto(`/${user.username}`);
@@ -13,4 +13,4 @@
<Pin bind:value={$pin} {cancel} />
{/if}
-<slot />
+{@render children?.()}
diff --git a/src/routes/(app)/send/[...text]/+page.svelte b/src/routes/(app)/send/[...text]/+page.svelte
index 2dd4a723..7ec76bc9 100644
--- a/src/routes/(app)/send/[...text]/+page.svelte
+++ b/src/routes/(app)/send/[...text]/+page.svelte
@@ -1,4 +1,6 @@
<script>
+ import { run } from 'svelte/legacy';
+
import { page } from "$app/stores";
import { fly } from "svelte/transition";
import { enhance } from "$app/forms";
@@ -10,13 +12,12 @@
import Spinner from "$comp/Spinner.svelte";
import { back, fail, focus } from "$lib/utils";
- export let data;
- export let form;
+ let { data = $bindable(), form } = $props();
data.subject = data.user;
let { contacts } = data;
- let el, text, pasted, w;
+ let el = $state(), text = $state(), pasted = $state(), w = $state();
let keypress = (e) =>
e.key === "Enter" ? e.preventDefault() || el.click() : (pasted = false);
@@ -27,7 +28,9 @@
pasted = true;
};
- $: if (browser && pasted && text) el.click() && (pasted = false);
+ run(() => {
+ if (browser && pasted && text) el.click() && (pasted = false);
+ });
</script>
<svelte:window bind:innerWidth={w} />
@@ -52,29 +55,29 @@
use:focus
name="text"
placeholder={$t("user.send.placeholder")}
- on:keypress={keypress}
+ onkeypress={keypress}
class="w-full p-4 border rounded-xl h-32 text-xl"
bind:value={text}
- on:paste={() => (pasted = true)}
+ onpaste={() => (pasted = true)}
autocapitalize="none"
- />
+></textarea>
<div class="flex gap-2">
<a href="/scan" class="contents">
<button type="button" class="btn !w-auto flex-grow">
- <iconify-icon icon="ph:camera-bold" width="32" />
+ <iconify-icon icon="ph:camera-bold" width="32"></iconify-icon>
{$t("user.send.scan")}
</button>
</a>
- <button type="button" class="btn !w-auto flex-grow" on:click={paste}>
- <iconify-icon icon="ph:clipboard-text-bold" width="32" />
+ <button type="button" class="btn !w-auto flex-grow" onclick={paste}>
+ <iconify-icon icon="ph:clipboard-text-bold" width="32"></iconify-icon>
{$t("user.send.paste")}
</button>
</div>
<button bind:this={el} type="submit" class="btn btn-accent">
- <iconify-icon icon="ph:paper-plane-right-bold" width="32" />
+ <iconify-icon icon="ph:paper-plane-right-bold" width="32"></iconify-icon>
<div class="my-auto">{$t("user.send.next")}</div>
</button>
diff --git a/src/routes/(app)/send/bitcoin/[address]/+page.svelte b/src/routes/(app)/send/bitcoin/[address]/+page.svelte
index 20fed58a..c271543c 100644
--- a/src/routes/(app)/send/bitcoin/[address]/+page.svelte
+++ b/src/routes/(app)/send/bitcoin/[address]/+page.svelte
@@ -1,4 +1,6 @@
<script>
+ import { run, preventDefault } from 'svelte/legacy';
+
import { t } from "$lib/translations";
import Icon from "$comp/Icon.svelte";
import Numpad from "$comp/Numpad.svelte";
@@ -6,22 +8,24 @@
import { rate } from "$lib/store";
import { fail, s } from "$lib/utils";
- export let data;
+ let { data } = $props();
let { balance, rates, user } = data;
let { address } = $page.params;
let { currency, username } = user;
- let amount = 0;
- let submit, fiat;
+ let amount = $state(0);
+ let submit = $state(), fiat = $state();
- $: update(data);
let update = () => ($rate = data.rates[currency]);
let setMax = () => {
fiat = false;
amount = balance;
};
+ run(() => {
+ update(data);
+ });
</script>
<div class="container px-4 max-w-xl mx-auto space-y-5 text-center">
@@ -35,8 +39,8 @@
<button
type="button"
class="btn !w-auto grow"
- on:click|preventDefault={setMax}
- on:keydown={setMax}>Max ⚡️{s(balance)}</button
+ onclick={preventDefault(setMax)}
+ onkeydown={setMax}>Max ⚡️{s(balance)}</button
>
<form action={`/send/bitcoin/${address}/${amount}`} class="contents">
diff --git a/src/routes/(app)/send/bitcoin/[address]/[amount]/[...feeRate]/+page.svelte b/src/routes/(app)/send/bitcoin/[address]/[amount]/[...feeRate]/+page.svelte
index 15080493..20128d2b 100644
--- a/src/routes/(app)/send/bitcoin/[address]/[amount]/[...feeRate]/+page.svelte
+++ b/src/routes/(app)/send/bitcoin/[address]/[amount]/[...feeRate]/+page.svelte
@@ -1,4 +1,6 @@
<script>
+ import { run } from 'svelte/legacy';
+
import { tick } from "svelte";
import { t } from "$lib/translations";
import { enhance } from "$app/forms";
@@ -28,14 +30,13 @@
import { entropyToMnemonic, mnemonicToSeed } from "@scure/bip39";
import { wordlist } from "@scure/bip39/wordlists/english";
- export let data;
- export let form;
+ let { data, form } = $props();
let { encode, decode } = hexUtil;
- let passwordPrompt;
- let password;
- let cancel = () => (passwordPrompt = false);
- let signed;
+ let passwordPrompt = $state();
+ let password = $state();
+ let cancel = $state(() => (passwordPrompt = false));
+ let signed = $state();
let togglePassword = () => (passwordPrompt = !passwordPrompt);
let handler = ({ cancel }) => {
@@ -90,9 +91,8 @@
rates,
hex,
inputs,
- } = data;
+ } = $state(data);
- $: reload(data);
let reload = () => {
({ amount, address, message, fee, fees, feeRate, ourfee, rates, hex } =
data);
@@ -103,7 +103,7 @@
};
let { balance, currency } = data.user;
- let submitting, submit, showSettings;
+ let submitting = $state(), submit = $state(), showSettings;
let feeNames = {
fastestFee: $t("payments.fastest"),
@@ -113,7 +113,6 @@
let toggleSettings = () => (showSettings = !showSettings);
- $: update(form);
let update = () => {
submitting = false;
if (form?.message?.includes("pin")) $pin = undefined;
@@ -121,6 +120,12 @@
let setFee = () => goto(`/send/bitcoin/${address}/${amount}/${feeRate}`);
let goBack = () => goto(`/send/bitcoin/${address}`);
+ run(() => {
+ reload(data);
+ });
+ run(() => {
+ update(form);
+ });
</script>
<div
@@ -148,7 +153,7 @@
<div class="flex flex-wrap gap-4 justify-center">
<select
bind:value={feeRate}
- on:change={setFee}
+ onchange={setFee}
class="border text-lg bg-white p-4 rounded-2xl text-center my-auto"
>
{#each Object.keys(feeNames) as feeName}
diff --git a/src/routes/(app)/send/ecash/+page.svelte b/src/routes/(app)/send/ecash/+page.svelte
index 3a708f80..88239c1a 100644
--- a/src/routes/(app)/send/ecash/+page.svelte
+++ b/src/routes/(app)/send/ecash/+page.svelte
@@ -1,4 +1,6 @@
<script>
+ import { run, preventDefault } from 'svelte/legacy';
+
import { enhance, applyAction } from "$app/forms";
import { t } from "$lib/translations";
import Icon from "$comp/Icon.svelte";
@@ -9,15 +11,14 @@
import { fail, s } from "$lib/utils";
import handler from "$lib/handler";
- export let data;
+ let { data } = $props();
let { rates, user } = data;
let { balance, currency, username } = user;
- let amount = 0;
- let submit, fiat;
+ let amount = $state(0);
+ let submit = $state(), fiat = $state();
- $: update(data);
let update = () => ($rate = data.rates[currency]);
let setMax = () => {
@@ -25,8 +26,11 @@
amount = balance;
};
- let submitting;
+ let submitting = $state();
let toggle = () => (submitting = !submitting);
+ run(() => {
+ update(data);
+ });
</script>
<div class="container px-4 max-w-xl mx-auto space-y-5 text-center">
@@ -47,9 +51,9 @@
<button
type="button"
class="btn !w-auto grow"
- on:click|preventDefault={setMax}
+ onclick={preventDefault(setMax)}
disabled={submitting}
- on:keydown={setMax}>Max ⚡️{s(balance)}</button
+ onkeydown={setMax}>Max ⚡️{s(balance)}</button
>
<button
diff --git a/src/routes/(app)/send/fund/[name]/[...amount]/+page.svelte b/src/routes/(app)/send/fund/[name]/[...amount]/+page.svelte
index b6a4aa0c..d1c3b204 100644
--- a/src/routes/(app)/send/fund/[name]/[...amount]/+page.svelte
+++ b/src/routes/(app)/send/fund/[name]/[...amount]/+page.svelte
@@ -1,4 +1,6 @@
<script>
+ import { run } from 'svelte/legacy';
+
import { t } from "$lib/translations";
import { enhance } from "$app/forms";
import Icon from "$comp/Icon.svelte";
@@ -8,25 +10,29 @@
import { back } from "$lib/utils";
import { pin } from "$lib/store";
- export let data;
- export let form;
+ let { data, form } = $props();
- let { amount, name } = $page.params;
+ let { amount, name } = $state($page.params);
let { rates } = data;
let { currency } = data.user;
- let loading;
+ let loading = $state();
- $: rate = rates[currency];
let submit = () => (loading = true);
- $: update(form);
let update = () => {
if (form?.message?.includes("pin")) $pin = undefined;
loading = false;
};
+ let rate;
+ run(() => {
+ rate = rates[currency];
+ });
+ run(() => {
+ update(form);
+ });
</script>
-<button class="ml-5 md:ml-20 mt-5 md:mt-10 hover:opacity-80" on:click={back}>
+<button class="ml-5 md:ml-20 mt-5 md:mt-10 hover:opacity-80" onclick={back}>
<Icon icon="arrow-left" style="w-10" />
</button>
@@ -39,7 +45,7 @@
<div class="container px-4 mt-20 max-w-xl mx-auto">
<Numpad bind:amount {currency} bind:rate />
- <form method="POST" use:enhance on:submit={submit}>
+ <form method="POST" use:enhance onsubmit={submit}>
<input name="name" value={name} type="hidden" />
<input name="amount" value={amount} type="hidden" />
<input name="pin" value={$pin} type="hidden" />
diff --git a/src/routes/(app)/send/invoice/[id]/+page.svelte b/src/routes/(app)/send/invoice/[id]/+page.svelte
index 5a9729a2..9f3a008b 100644
--- a/src/routes/(app)/send/invoice/[id]/+page.svelte
+++ b/src/routes/(app)/send/invoice/[id]/+page.svelte
@@ -1,4 +1,6 @@
<script>
+ import { run } from 'svelte/legacy';
+
import handler from "$lib/handler";
import { onDestroy, onMount } from "svelte";
import { t } from "$lib/translations";
@@ -21,34 +23,31 @@
sats,
focus,
} from "$lib/utils";
- export let data;
- export let form;
+ let { data, form } = $props();
- let { invoice, rates, user } = data;
- let { address, hash, payreq, user: recipient, tip } = invoice;
- let { currency } = user;
+ let { invoice, rates, user } = $state(data);
+ let { address, hash, payreq, user: recipient, tip } = $state(invoice);
+ let { currency } = $state(user);
- $: reload(data);
let reload = (data) => {
({ invoice, rates, user } = data);
({ address, hash, payreq, user: recipient, tip } = invoice);
({ currency } = user);
};
- $: rate = invoice.rate * (rates[user.currency] / rates[invoice.currency]);
- let amount = form?.amount || invoice.amount;
- let a,
- af,
+ let amount = $state(form?.amount || invoice.amount);
+ let a = $state(),
+ af = $state(),
amountFiat = amount * (rate / sats),
- fiat = !amount;
+ fiat = $state(!amount);
let setAmount = () => {
amount = a;
amountFiat = af;
};
- let submit, submitting;
+ let submit = $state(), submitting = $state();
let toggle = () => (submitting = !submitting);
let external = async () => {
@@ -67,7 +66,6 @@
});
};
- $: update(form);
let update = () => {
if (form?.message?.includes("pin")) $pin = undefined;
submitting = false;
@@ -91,6 +89,16 @@
// }
// }
// });
+ run(() => {
+ reload(data);
+ });
+ let rate;
+ run(() => {
+ rate = invoice.rate * (rates[user.currency] / rates[invoice.currency]);
+ });
+ run(() => {
+ update(form);
+ });
</script>
{#if form?.message}
@@ -192,13 +200,13 @@
bind:this={submit}
type="button"
class="btn !w-auto"
- on:click={setAmount}
+ onclick={setAmount}
>
{$t("payments.next")}
</button>
{/if}
</div>
- <button type="button" class="btn" on:click={external}
+ <button type="button" class="btn" onclick={external}
>{$t("payments.moreOptions")}</button
>
</form>
diff --git a/src/routes/(app)/send/lightning/[payreq]/+page.svelte b/src/routes/(app)/send/lightning/[payreq]/+page.svelte
index 659b0e51..6b9fe4e2 100644
--- a/src/routes/(app)/send/lightning/[payreq]/+page.svelte
+++ b/src/routes/(app)/send/lightning/[payreq]/+page.svelte
@@ -1,4 +1,6 @@
<script>
+ import { run } from "svelte/legacy";
+
import { t } from "$lib/translations";
import { enhance } from "$app/forms";
import Icon from "$comp/Icon.svelte";
@@ -8,8 +10,7 @@
import { back, fiat, f, s, focus } from "$lib/utils";
import { rate, pin } from "$lib/store";
- export let data;
- export let form;
+ let { data, form } = $props();
let { payreq } = $page.params;
let {
@@ -17,10 +18,9 @@
ourfee,
rates,
user: { currency },
- } = data;
- let a;
+ } = $state(data);
+ let a = $state();
- $: reload(data);
let reload = (data) => {
({
alias,
@@ -31,13 +31,10 @@
if (!$rate) $rate = rates[currency];
};
- $: amount = form?.amount || data.amount;
- $: maxfee = Math.max(5, Math.round(amount * 0.005));
- let showMax;
+ let showMax = $state();
- let loading;
+ let loading = $state();
let submit = () => (loading = true);
- $: update(form);
let update = () => {
if (form?.message?.includes("pin")) $pin = undefined;
loading = false;
@@ -45,6 +42,17 @@
let show;
let toggle = () => (show = !show);
+ run(() => {
+ reload(data);
+ });
+ let amount = $derived(form?.amount || data.amount);
+ let maxfee;
+ run(() => {
+ maxfee = Math.max(5, Math.round(amount * 0.005));
+ });
+ run(() => {
+ update(form);
+ });
</script>
<div class="container px-4 max-w-xl mx-auto text-center space-y-2">
@@ -89,7 +97,7 @@
<form
method="POST"
use:enhance
- on:submit={submit}
+ onsubmit={submit}
action="?/send"
class="space-y-2"
>
@@ -135,7 +143,7 @@
</button>
{#if !(form?.message || showMax)}
- <button type="button" class="btn" on:click={() => (showMax = !showMax)}
+ <button type="button" class="btn" onclick={() => (showMax = !showMax)}
>Advanced settings</button
>
<input name="maxfee" type="hidden" bind:value={maxfee} />
diff --git a/src/routes/(app)/sent/[id]/+page.svelte b/src/routes/(app)/sent/[id]/+page.svelte
index b4f6ab68..615638c7 100644
--- a/src/routes/(app)/sent/[id]/+page.svelte
+++ b/src/routes/(app)/sent/[id]/+page.svelte
@@ -5,8 +5,8 @@
import { toast } from "@zerodevx/svelte-toast";
import { t } from "$lib/translations";
- export let data;
- let { amount, rate, tip, user } = data;
+ let { data } = $props();
+ let { amount, rate, tip, user } = $state(data);
let { currency, username } = user;
amount = Math.abs(amount);
@@ -38,7 +38,7 @@
</div>
<a href={`/${username}`} use:focus>
- <div class="opacity-0 w-screen h-screen fixed top-0 left-0 z-50" />
+ <div class="opacity-0 w-screen h-screen fixed top-0 left-0 z-50"></div>
</a>
<div class="flex justify-center">
diff --git a/src/routes/(app)/settings/[...tab]/+page.svelte b/src/routes/(app)/settings/[...tab]/+page.svelte
index d2da3722..5b9e048d 100644
--- a/src/routes/(app)/settings/[...tab]/+page.svelte
+++ b/src/routes/(app)/settings/[...tab]/+page.svelte
@@ -1,4 +1,6 @@
<script>
+ import { run, preventDefault } from 'svelte/legacy';
+
import { browser } from "$app/environment";
import { onMount, tick } from "svelte";
import { fly } from "svelte/transition";
@@ -22,24 +24,20 @@
import { PUBLIC_COINOS_URL } from "$env/static/public";
- export let data;
- export let form;
+ let { data, form } = $props();
- let submit;
- let formElement;
+ let submit = $state();
+ let formElement = $state();
- let { user, token, rates, tab, cookies, subscriptions } = data;
+ let { user, token, rates, tab, cookies, subscriptions } = $state(data);
let prev;
- $: update(data);
let update = () => {
({ user, token, rates, tab, subscriptions } = data);
prev = { ...user };
};
- $: form?.user && ({ user } = form);
- $: form?.success && throttledSuccess();
let justUpdated;
let throttledSuccess = () => {
@@ -50,12 +48,7 @@
}
};
- $: form?.message && fail(form.message);
- $: if (form?.message?.startsWith("Pin")) {
- fail("Wrong pin, try again");
- $pin = "";
- }
let tabs = [
{ name: "account", key: "ACCOUNT", comp: Account },
@@ -64,13 +57,10 @@
{ name: "shopify", key: "SHOPIFY", comp: Shopify },
];
- $: ({ comp } = tabs.find((t) => t.name === tab));
let { address, id, username } = user;
- let submitting;
+ let submitting = $state();
- $: if (!$loading && $page.url.searchParams.get("verified"))
- success($t("user.settings.verified"));
async function handleSubmit() {
try {
@@ -191,6 +181,31 @@
submitting = false;
}
+ run(() => {
+ update(data);
+ });
+ run(() => {
+ form?.user && ({ user } = form);
+ });
+ run(() => {
+ form?.success && throttledSuccess();
+ });
+ run(() => {
+ form?.message && fail(form.message);
+ });
+ run(() => {
+ if (form?.message?.startsWith("Pin")) {
+ fail("Wrong pin, try again");
+ $pin = "";
+ }
+ });
+ let { comp } = $derived(tabs.find((t) => t.name === tab));
+ run(() => {
+ if (!$loading && $page.url.searchParams.get("verified"))
+ success($t("user.settings.verified"));
+ });
+
+ const SvelteComponent = $derived(comp);
</script>
{#if user.haspin && $pin?.length !== 6}
@@ -200,7 +215,7 @@
<form
method="POST"
class="mb-[154px] settings"
- on:submit|preventDefault={handleSubmit}
+ onsubmit={preventDefault(handleSubmit)}
bind:this={formElement}
>
<input type="hidden" name="pin" value={$pin} />
@@ -229,7 +244,7 @@
</div>
</div>
- <svelte:component this={comp} {user} {rates} {submit} {subscriptions} />
+ <SvelteComponent {user} {rates} {submit} {subscriptions} />
</div>
<div
diff --git a/src/routes/(app)/settings/[...tab]/_account.svelte b/src/routes/(app)/settings/[...tab]/_account.svelte
index 8537322e..54249265 100644
--- a/src/routes/(app)/settings/[...tab]/_account.svelte
+++ b/src/routes/(app)/settings/[...tab]/_account.svelte
@@ -4,11 +4,11 @@
import { t } from "$lib/translations";
import { page } from "$app/stores";
- export let user, rates, submit;
+ let { user = $bindable(), rates, submit } = $props();
let { id } = user;
- let avatarFile, avatarInput, bannerFile, bannerInput;
+ let avatarFile, avatarInput = $state(), bannerFile, bannerInput = $state();
let selectAvatar = () => avatarInput.click();
let selectBanner = () => bannerInput.click();
@@ -18,7 +18,7 @@
percent = Math.round((event.loaded / event.total) * 100);
};
- let tooLarge = {};
+ let tooLarge = $state({});
let handleFile = async ({ target }, type) => {
tooLarge[type] = false;
@@ -47,9 +47,9 @@
if (!user.display) user.display = user.username;
- $: url = `${$page.url.host}/${user.username}`;
- $: full = `${$page.url.protocol}//${url}`;
- $: addr = `${user.username}@${$page.url.host}`;
+ let url = $derived(`${$page.url.host}/${user.username}`);
+ let full = $derived(`${$page.url.protocol}//${url}`);
+ let addr = $derived(`${user.username}@${$page.url.host}`);
</script>
<div>
@@ -83,13 +83,13 @@
icon="ph:check-bold"
class="text-success ml-auto"
width="32"
- />
+></iconify-icon>
{:else if user.email}
<iconify-icon
icon="ph:clock-bold"
class="text-warning ml-auto"
width="32"
- />
+></iconify-icon>
{/if}
</label>
</div>
@@ -101,8 +101,8 @@
{#if $avatar || user.profile}
<div
class="relative rounded-full overflow-hidden text-center w-20 h-20 my-auto hover:opacity-80 cursor-pointer"
- on:click={selectAvatar}
- on:keydown={selectAvatar}
+ onclick={selectAvatar}
+ onkeydown={selectAvatar}
>
<img
src={$avatar?.src || `/api/public/${user.profile}.webp`}
@@ -113,11 +113,11 @@
{:else}
<div
class="rounded-full border-4 border-white p-4 bg-gradient-to-r from-primary to-gradient w-24 my-auto hover:opacity-80 cursor-pointer"
- on:click={selectAvatar}
- on:keydown={selectAvatar}
+ onclick={selectAvatar}
+ onkeydown={selectAvatar}
>
<Icon icon="logo-symbol-white" style="mx-auto" />
- <iconify-icon icon="ph:floppy-disk-bold" width="32" />
+ <iconify-icon icon="ph:floppy-disk-bold" width="32"></iconify-icon>
</div>
{/if}
<div class="ml-2 p-2">
@@ -125,14 +125,14 @@
<button
type="button"
class="btn"
- on:click={selectAvatar}
- on:keydown={selectAvatar}>{$t("user.settings.select")}</button
+ onclick={selectAvatar}
+ onkeydown={selectAvatar}>{$t("user.settings.select")}</button
>
<input
type="file"
class="hidden"
bind:this={avatarInput}
- on:change={(e) => handleFile(e, "profile")}
+ onchange={(e) => handleFile(e, "profile")}
/>
</div>
</div>
@@ -151,30 +151,30 @@
<img
src={$banner ? $banner.src : `/api/public/${user.banner}.webp`}
class="w-full object-cover object-center visible overflow-hidden h-48 mb-4 hover:opacity-80"
- on:click={selectBanner}
- on:keydown={selectBanner}
+ onclick={selectBanner}
+ onkeydown={selectBanner}
alt="Banner"
/>
{:else}
<div
class="bg-gradient-to-r from-primary to-gradient w-full h-48 mb-4 cursor-pointer hover:opacity-80"
- on:click={selectBanner}
- on:keydown={selectBanner}
+ onclick={selectBanner}
+ onkeydown={selectBanner}
alt="Banner"
- />
+></div>
{/if}
<button
type="button"
class="btn !w-auto"
- on:click={selectBanner}
- on:keydown={selectBanner}>{$t("user.settings.select")}</button
+ onclick={selectBanner}
+ onkeydown={selectBanner}>{$t("user.settings.select")}</button
>
<input
type="file"
class="hidden"
bind:this={bannerInput}
- on:change={(e) => handleFile(e, "banner")}
+ onchange={(e) => handleFile(e, "banner")}
/>
{#if tooLarge["banner"]}
@@ -191,5 +191,5 @@
name="address"
bind:value={user.address}
placeholder={$t("user.settings.aboutPlaceholder")}
- />
+></textarea>
</div>
diff --git a/src/routes/(app)/settings/[...tab]/_pos.svelte b/src/routes/(app)/settings/[...tab]/_pos.svelte
index f4a01c09..3f68eebc 100644
--- a/src/routes/(app)/settings/[...tab]/_pos.svelte
+++ b/src/routes/(app)/settings/[...tab]/_pos.svelte
@@ -1,4 +1,6 @@
<script>
+ import { run } from 'svelte/legacy';
+
import { onMount, tick } from "svelte";
import { browser } from "$app/environment";
import Numpad from "$comp/Numpad.svelte";
@@ -9,16 +11,20 @@
import { page } from "$app/stores";
import { PUBLIC_VAPID_PUBKEY } from "$env/static/public";
- export let user, rates, submit, subscriptions;
+ let {
+ user = $bindable(),
+ rates,
+ submit,
+ subscriptions
+ } = $props();
- let { currency } = user;
- let rate = rates[currency];
+ let { currency } = $state(user);
+ let rate = $state(rates[currency]);
let fiats = Object.keys(rates).sort((a, b) => a.localeCompare(b));
- $: user.language = $locale;
let keypress = (e) => e.key === "Enter" && (e.preventDefault() || el.click());
- let editingReserve, editingThreshold, doneReserve, doneThreshold;
+ let editingReserve = $state(), editingThreshold = $state(), doneReserve = $state(), doneThreshold;
let doneEditing = () => {
editingReserve = false;
editingThreshold = false;
@@ -38,9 +44,9 @@
if (!user.threshold) user.threshold = 1000000;
if (!user.reserve) user.reserve = 100000;
- let reserveEl, thresholdEl;
+ let reserveEl = $state(), thresholdEl = $state();
- let push, pm, subscription;
+ let push = $state(), pm, subscription;
onMount(async () => {
if (!browser) return;
@@ -60,8 +66,7 @@
}
});
- let permission;
- $: updateNotifications(push);
+ let permission = $state();
let updateNotifications = async (push) => {
if (!browser || !pm) return (push = false);
@@ -80,6 +85,12 @@
await post("/subscription", { subscription });
}
};
+ run(() => {
+ user.language = $locale;
+ });
+ run(() => {
+ updateNotifications(push);
+ });
</script>
<div>
@@ -154,17 +165,17 @@
<textarea
name="destination"
placeholder={$t("user.settings.destinationPlaceholder")}
- on:keypress={keypress}
+ onkeypress={keypress}
class="w-full p-4 border rounded-xl h-48"
bind:value={user.destination}
- />
+></textarea>
</div>
<div>
<label for="display" class="font-bold mb-1 block"
>{$t("user.settings.threshold")}</label
>
- <button type="button" class="flex w-full" on:click={editThreshold}>
+ <button type="button" class="flex w-full" onclick={editThreshold}>
<div class="p-4 border rounded-2xl rounded-r-none border-r-0 bg-base-200">
⚡️
</div>
@@ -184,7 +195,7 @@
<label for="display" class="font-bold mb-1 block"
>{$t("user.settings.reserve")}</label
>
- <button type="button" class="flex w-full" on:click={editReserve}>
+ <button type="button" class="flex w-full" onclick={editReserve}>
<div class="p-4 border rounded-2xl rounded-r-none border-r-0 bg-base-200">
⚡️
</div>
@@ -220,7 +231,7 @@
<button
bind:this={doneReserve}
type="button"
- on:click={doneEditing}
+ onclick={doneEditing}
class="btn">Ok</button
>
</div>
@@ -247,7 +258,7 @@
<button
bind:this={doneReserve}
type="button"
- on:click={doneEditing}
+ onclick={doneEditing}
class="btn">Ok</button
>
</div>
diff --git a/src/routes/(app)/settings/[...tab]/_security.svelte b/src/routes/(app)/settings/[...tab]/_security.svelte
index d67bda37..8bb8a3fa 100644
--- a/src/routes/(app)/settings/[...tab]/_security.svelte
+++ b/src/routes/(app)/settings/[...tab]/_security.svelte
@@ -1,4 +1,6 @@
<script>
+ import { run } from 'svelte/legacy';
+
import { getMnemonic, getNsec } from "$lib/nostr";
import { tick } from "svelte";
import { t } from "$lib/translations";
@@ -10,26 +12,26 @@
import { invalidate } from "$app/navigation";
import { page } from "$app/stores";
- export let user, rates, submit;
+ let { user = $bindable(), rates, submit } = $props();
- let confirming2fa,
- disabling2fa,
- importing,
+ let confirming2fa = $state(),
+ disabling2fa = $state(),
+ importing = $state(),
locked,
mnemonic,
- newNsec,
- nsec,
+ newNsec = $state(),
+ nsec = $state(),
old,
- otp,
- password,
- pin,
- revealPassword,
+ otp = $state(),
+ password = $state(),
+ pin = $state(),
+ revealPassword = $state(),
revealSeed,
- revealNsec,
- token = "",
- setting2fa,
- settingPin,
- verify;
+ revealNsec = $state(),
+ token = $state(""),
+ setting2fa = $state(),
+ settingPin = $state(),
+ verify = $state();
let toggleImporting = () => {
revealNsec = false;
@@ -56,8 +58,6 @@
}
};
- $: verifying = pin?.length > 5;
- $: verify && checkPin(pin);
let checkPin = async () => {
old = $current;
@@ -88,7 +88,7 @@
return true;
};
- let disablingPin = false;
+ let disablingPin = $state(false);
let togglePin = async () => {
if (user.haspin) {
@@ -129,7 +129,6 @@
disabling2fa = false;
};
- $: enable2fa(token);
let enable2fa = async (twoFa) => {
try {
if (setting2fa && token.length === 6) {
@@ -143,7 +142,6 @@
}
};
- $: disable2fa(token);
let disable2fa = async () => {
try {
if (disabling2fa && token.length === 6) {
@@ -157,6 +155,19 @@
fail("Failed to disable 2FA, try again");
}
};
+ let verifying;
+ run(() => {
+ verifying = pin?.length > 5;
+ });
+ run(() => {
+ verify && checkPin(pin);
+ });
+ run(() => {
+ enable2fa(token);
+ });
+ run(() => {
+ disable2fa(token);
+ });
</script>
<input type="hidden" name="newpin" value={disablingPin ? "delete" : pin} />
@@ -173,14 +184,14 @@
{/if}
<button
type="button"
- on:click={togglePassword}
- on:keydown={togglePassword}
+ onclick={togglePassword}
+ onkeydown={togglePassword}
class="absolute right-5 top-11"
>
<iconify-icon
icon={revealPassword ? "ph:eye-bold" : "ph:eye-slash-bold"}
width="32"
- />
+></iconify-icon>
</button>
</div>
@@ -203,12 +214,12 @@
notify={false}
/>
{:else}
- <button type="button" class="btn" on:click={togglePin}
+ <button type="button" class="btn" onclick={togglePin}
>
<iconify-icon
icon={user.haspin ? "ph:lock-key-open-bold" : "ph:lock-key-bold"}
width="32"
- />
+></iconify-icon>
{user.haspin
? $t("user.settings.disablePIN")
: $t("user.settings.enablePIN")}</button
@@ -232,18 +243,18 @@
<b>{otp.secret}</b>
</div>
- <button type="button" class="btn" on:click={startConfirming2fa}>
- <iconify-icon icon="ph:numpad-bold" width="32" />
+ <button type="button" class="btn" onclick={startConfirming2fa}>
+ <iconify-icon icon="ph:numpad-bold" width="32"></iconify-icon>
<div class="my-auto">Confirm</div>
</button>
{:else if user.twofa}
- <button type="button" class="btn" on:click={startDisabling2fa}>
- <iconify-icon icon="ph:device-mobile-bold" width="32" />
+ <button type="button" class="btn" onclick={startDisabling2fa}>
+ <iconify-icon icon="ph:device-mobile-bold" width="32"></iconify-icon>
<div class="my-auto">{$t("user.settings.twofaDisable")}</div>
</button>
{:else}
- <button type="button" class="btn" on:click={startEnabling2fa}>
- <iconify-icon icon="ph:device-mobile-bold" width="32" />
+ <button type="button" class="btn" onclick={startEnabling2fa}>
+ <iconify-icon icon="ph:device-mobile-bold" width="32"></iconify-icon>
<div class="my-auto">{$t("user.settings.twofaSetup")}</div>
</button>
{/if}
@@ -269,12 +280,12 @@
</p>
<div class="flex gap-2">
- <button type="button" class="btn !w-auto flex-grow" on:click={toggleNsec}>
+ <button type="button" class="btn !w-auto flex-grow" onclick={toggleNsec}>
{#if revealNsec}
- <iconify-icon icon="ph:eye-slash-bold" width="32" />
+ <iconify-icon icon="ph:eye-slash-bold" width="32"></iconify-icon>
{$t("user.settings.hideNsec")}
{:else}
- <iconify-icon icon="ph:warning-bold" width="32" />
+ <iconify-icon icon="ph:warning-bold" width="32"></iconify-icon>
{$t("user.settings.revealNsec")}
{/if}
</button>
@@ -282,9 +293,9 @@
<button
type="button"
class="btn !w-auto flex-grow"
- on:click={toggleImporting}
+ onclick={toggleImporting}
>
- <iconify-icon icon="ph:floppy-disk-bold" width="32" />
+ <iconify-icon icon="ph:floppy-disk-bold" width="32"></iconify-icon>
{$t("user.settings.import")}
</button>
</div>
@@ -298,8 +309,8 @@
{nsec}
</div>
- <button type="button" class="btn" on:click={() => copy(nsec)}>
- <iconify-icon icon="ph:copy-bold" width="32" />
+ <button type="button" class="btn" onclick={() => copy(nsec)}>
+ <iconify-icon icon="ph:copy-bold" width="32"></iconify-icon>
Copy
</button>
{/if}
diff --git a/src/routes/(app)/settings/[...tab]/_shopify.svelte b/src/routes/(app)/settings/[...tab]/_shopify.svelte
index 48fe7718..cc746c49 100644
--- a/src/routes/(app)/settings/[...tab]/_shopify.svelte
+++ b/src/routes/(app)/settings/[...tab]/_shopify.svelte
@@ -3,22 +3,22 @@
import Icon from "$comp/Icon.svelte";
import { page } from "$app/stores";
- export let user;
- $: paymentsUrl =
- user.shopifyStore &&
+ let { user = $bindable() } = $props();
+ let paymentsUrl =
+ $derived(user.shopifyStore &&
"https://admin.shopify.com/store/" +
user.shopifyStore +
- "/settings/payments";
- $: checkoutUrl =
- user.shopifyStore &&
+ "/settings/payments");
+ let checkoutUrl =
+ $derived(user.shopifyStore &&
"https://admin.shopify.com/store/" +
user.shopifyStore +
- "/settings/checkout";
- $: appsUrl =
- user.shopifyStore &&
+ "/settings/checkout");
+ let appsUrl =
+ $derived(user.shopifyStore &&
"https://admin.shopify.com/store/" +
user.shopifyStore +
- "/settings/apps/development";
+ "/settings/apps/development");
let script = `<script src="${$page.url.protocol}//${$page.url.host}/${user.username}/shopify.js"><\/script>`;
</script>
diff --git a/src/routes/(app)/verify/[code]/+page.svelte b/src/routes/(app)/verify/[code]/+page.svelte
index de5212e5..1fe5d898 100644
--- a/src/routes/(app)/verify/[code]/+page.svelte
+++ b/src/routes/(app)/verify/[code]/+page.svelte
@@ -3,7 +3,7 @@
import Icon from "$comp/Icon.svelte";
import { t } from "$lib/translations";
- export let data;
+ let { data } = $props();
let { user, error } = data;
</script>
@@ -27,7 +27,7 @@
</div>
<a href={`/${user.username}`}>
- <div class="opacity-0 w-screen h-screen fixed top-0 left-0 z-50" />
+ <div class="opacity-0 w-screen h-screen fixed top-0 left-0 z-50"></div>
</a>
<div class="flex justify-center">
diff --git a/src/routes/(static)/+layout.svelte b/src/routes/(static)/+layout.svelte
index c9bdc091..44310c97 100644
--- a/src/routes/(static)/+layout.svelte
+++ b/src/routes/(static)/+layout.svelte
@@ -1,13 +1,17 @@
<script>
+ import { run } from 'svelte/legacy';
+
import { SvelteToast } from "@zerodevx/svelte-toast";
import Footer from "$comp/Footer.svelte";
import LandingHeader from "$comp/LandingHeader.svelte";
import { theme as themeStore } from "$lib/store";
- export let data;
- let { theme } = data;
- $: ({ user } = data);
- $: theme = $themeStore;
+ let { data, children } = $props();
+ let { theme } = $state(data);
+ let { user } = $derived(data);
+ run(() => {
+ theme = $themeStore;
+ });
</script>
<SvelteToast options={{ reversed: true, intro: { y: 192 } }} />
@@ -16,6 +20,6 @@
class="container flex px-4 md:px-40 mx-auto min-h-[600px]"
data-theme={theme}
>
- <slot />
+ {@render children?.()}
</main>
<Footer />
diff --git a/src/routes/(static)/docs/+page.svelte b/src/routes/(static)/docs/+page.svelte
index f83ba8c0..9f724484 100644
--- a/src/routes/(static)/docs/+page.svelte
+++ b/src/routes/(static)/docs/+page.svelte
@@ -5,7 +5,7 @@
import Code from "$comp/Code.svelte";
import Icon from "$comp/Icon.svelte";
- export let data;
+ let { data } = $props();
let { user, token } = data;
@@ -40,7 +40,7 @@
<h2 class="text-2xl">API Base URL</h2>
<div class="bg-primary text-primary-content rounded-lg p-4 flex gap-4">
<div>{api}</div>
- <button class="ml-auto my-auto invert opacity-90" on:click={() => copy(api)}
+ <button class="ml-auto my-auto invert opacity-90" onclick={() => copy(api)}
><Icon icon="copy" style="w-10 max-w-none" /></button
>
</div>
@@ -61,7 +61,7 @@
<div class="w-full break-all">{tokenSample}</div>
<button
class="ml-auto my-auto invert opacity-90"
- on:click={() => copy(tokenSample)}
+ onclick={() => copy(tokenSample)}
><Icon icon="copy" style="w-10 max-w-none" /></button
>
</div>
diff --git a/src/routes/(static)/login/+page.svelte b/src/routes/(static)/login/+page.svelte
index f51a24eb..d50e0cdc 100644
--- a/src/routes/(static)/login/+page.svelte
+++ b/src/routes/(static)/login/+page.svelte
@@ -1,4 +1,6 @@
<script>
+ import { run, preventDefault } from 'svelte/legacy';
+
import { onMount } from "svelte";
import { applyAction, deserialize } from "$app/forms";
import { tick } from "svelte";
@@ -23,28 +25,24 @@
if (lang) document.cookie = `lang=${lang} ;`;
});
- export let form;
+ let { form } = $props();
- let token, formElement;
+ let token = $state(), formElement;
let code = [];
let redirect;
$password = undefined;
- $: need2fa = form?.message === "2fa";
let cancel = () => (need2fa = false);
- $: if (form?.message === "2fa" && form.token === token) token = "";
- let username, email, btn;
+ let username = $state(), email, btn = $state();
- $: update(form);
let update = (form) => form && ({ username, password: $password } = form);
- $: token && token?.length === 6 && tick().then(() => btn.click());
- let revealPassword = false;
+ let revealPassword = $state(false);
- let loading;
+ let loading = $state();
async function handleSubmit(e) {
loading = true;
@@ -69,6 +67,19 @@
applyAction(result);
loading = false;
}
+ let need2fa;
+ run(() => {
+ need2fa = form?.message === "2fa";
+ });
+ run(() => {
+ if (form?.message === "2fa" && form.token === token) token = "";
+ });
+ run(() => {
+ update(form);
+ });
+ run(() => {
+ token && token?.length === 6 && tick().then(() => btn.click());
+ });
</script>
{#if need2fa}
@@ -86,7 +97,7 @@
</div>
{/if}
- <form class="space-y-5" on:submit|preventDefault={handleSubmit} method="POST">
+ <form class="space-y-5" onsubmit={preventDefault(handleSubmit)} method="POST">
<input
type="hidden"
name="loginRedirect"
@@ -131,10 +142,10 @@
{/if}
<iconify-icon
class="cursor-pointer ml-auto"
- on:click={() => (revealPassword = !revealPassword)}
+ onclick={() => (revealPassword = !revealPassword)}
icon={revealPassword ? "ph:eye-bold" : "ph:eye-slash-bold"}
width="32"
- />
+></iconify-icon>
</label>
<div class="flex justify-end items-center">
diff --git a/src/routes/(static)/register/+page.svelte b/src/routes/(static)/register/+page.svelte
index fe9a4aa2..c179552c 100644
--- a/src/routes/(static)/register/+page.svelte
+++ b/src/routes/(static)/register/+page.svelte
@@ -1,4 +1,6 @@
<script>
+ import { run, preventDefault } from 'svelte/legacy';
+
import punks from "$lib/punks";
import { upload } from "$lib/upload";
import { afterNavigate, invalidateAll } from "$app/navigation";
@@ -23,12 +25,10 @@
animals,
} from "unique-names-generator";
- export let form;
- export let data;
+ let { form = $bindable(), data } = $props();
- $: data && ($avatar = undefined);
- let username;
- let { index } = data;
+ let username = $state();
+ let { index } = $state(data);
let cleared;
let clear = () => {
@@ -64,24 +64,20 @@
}
});
- let token, formElement;
+ let token = $state(), formElement;
let code = [];
let redirect;
- $: need2fa = form?.message === "2fa";
let cancel = () => (need2fa = false);
- $: if (form?.message === "2fa" && form.token === token) token = "";
- let email, btn;
+ let email, btn = $state();
- $: update(form);
let update = (form) => form && ({ username, password: $password } = form);
- $: token && token?.length === 6 && tick().then(() => btn.click());
- let revealPassword;
+ let revealPassword = $state();
- let loading;
+ let loading = $state();
async function handleSubmit(e) {
loading = true;
@@ -127,8 +123,7 @@
loading = false;
}
- let avatarInput;
- $: src = `/api/public/${punks[index]}.webp`;
+ let avatarInput = $state();
let decr = () => (index = index <= 0 ? 63 : index - 1);
let incr = () => (index = index >= 63 ? 0 : index + 1);
let selectAvatar = () => avatarInput.click();
@@ -149,6 +144,26 @@
reader.readAsDataURL(file);
};
+ run(() => {
+ data && ($avatar = undefined);
+ });
+ let need2fa;
+ run(() => {
+ need2fa = form?.message === "2fa";
+ });
+ run(() => {
+ if (form?.message === "2fa" && form.token === token) token = "";
+ });
+ run(() => {
+ update(form);
+ });
+ run(() => {
+ token && token?.length === 6 && tick().then(() => btn.click());
+ });
+ let src;
+ run(() => {
+ src = `/api/public/${punks[index]}.webp`;
+ });
</script>
{#if need2fa}
@@ -163,17 +178,17 @@
type="file"
class="hidden"
bind:this={avatarInput}
- on:change={(e) => handleFile(e, "profile")}
+ onchange={(e) => handleFile(e, "profile")}
/>
<div class="relative">
<button
class="absolute w-8 h-12 left-12 bg-base-100 rounded top-12"
- on:click={decr}
+ onclick={decr}
>
- <iconify-icon icon="ph:caret-left-bold" width="32" />
+ <iconify-icon icon="ph:caret-left-bold" width="32"></iconify-icon>
</button>
- <div class="block relative w-32 mx-auto" on:click={selectAvatar}>
+ <div class="block relative w-32 mx-auto" onclick={selectAvatar}>
<button
class="w-32 h-32 rounded-full border-4 border-white overflow-hidden flex mx-auto relative"
>
@@ -186,14 +201,14 @@
<button
class="absolute bg-base-100 rounded-full p-2 mx-auto right-0 bottom-0 z-10 w-12"
>
- <iconify-icon icon="ph:upload-simple-bold" width="24" />
+ <iconify-icon icon="ph:upload-simple-bold" width="24"></iconify-icon>
</button>
</div>
<button
class="absolute w-8 h-12 right-12 bg-base-100 rounded top-12"
- on:click={incr}
+ onclick={incr}
>
- <iconify-icon icon="ph:caret-right-bold" width="32" />
+ <iconify-icon icon="ph:caret-right-bold" width="32"></iconify-icon>
</button>
</div>
@@ -203,7 +218,7 @@
</div>
{/if}
- <form class="space-y-5" on:submit|preventDefault={handleSubmit} method="POST">
+ <form class="space-y-5" onsubmit={preventDefault(handleSubmit)} method="POST">
<input
type="hidden"
name="loginRedirect"
@@ -222,17 +237,17 @@
type="text"
required
bind:value={username}
- on:focus={clear}
+ onfocus={clear}
autocapitalize="none"
placeholder={$t("login.username")}
/>
<iconify-icon
class="cursor-pointer"
tabindex="-1"
- on:click={refresh}
+ onclick={refresh}
icon="ph:dice-three-bold"
width="32"
- />
+></iconify-icon>
</label>
<label
@@ -257,17 +272,17 @@
required
bind:value={$password}
autocapitalize="none"
- on:focus={clear}
+ onfocus={clear}
placeholder={$t("login.password")}
/>
{/if}
<iconify-icon
tabindex="-1"
class="cursor-pointer"
- on:click={() => (revealPassword = !revealPassword)}
+ onclick={() => (revealPassword = !revealPassword)}
icon={revealPassword ? "ph:eye-bold" : "ph:eye-slash-bold"}
width="32"
- />
+></iconify-icon>
</label>
<button type="submit" class="btn" disabled={loading} bind:this={btn}>
diff --git a/src/routes/(static)/support/+page.svelte b/src/routes/(static)/support/+page.svelte
index 062f552b..b47c5c1a 100644
--- a/src/routes/(static)/support/+page.svelte
+++ b/src/routes/(static)/support/+page.svelte
@@ -1,4 +1,6 @@
<script>
+ import { run } from 'svelte/legacy';
+
import { browser } from "$app/environment";
import { onDestroy } from "svelte";
import { fail, success, post } from "$lib/utils";
@@ -6,16 +8,18 @@
import Icon from "$comp/Icon.svelte";
import { t } from "$lib/translations";
- export let data;
+ let { data = $bindable() } = $props();
let { user } = data;
- $: if (user) {
- data.subject = { ...user };
- }
+ run(() => {
+ if (user) {
+ data.subject = { ...user };
+ }
+ });
- let email;
- let message;
- let sent;
+ let email = $state();
+ let message = $state();
+ let sent = $state();
let recaptchaSiteKey = "6LfCd8YkAAAAANmVJgzN3SQY3n3fv1RhiS5PgMYM";
let submit = (e) => {
@@ -80,7 +84,7 @@
> and we'll do our best to get back to you in a timely manner.
</p>
- <form on:submit={submit}>
+ <form onsubmit={submit}>
<div class="mb-4">
<label for="account" class="font-semibold"
>{$t("user.support.accountName")}</label
@@ -110,7 +114,7 @@
name="message"
bind:value={message}
required
- />
+></textarea>
</div>
<button
diff --git a/src/routes/+error.svelte b/src/routes/+error.svelte
index faa7d738..c9e65806 100644
--- a/src/routes/+error.svelte
+++ b/src/routes/+error.svelte
@@ -2,7 +2,7 @@
import Icon from "$comp/Icon.svelte";
import { page } from "$app/stores";
- export let data;
+ let { data } = $props();
let { user } = data;
let link = user ? `/${user.username}` : "/";
diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte
index e5aeb206..a2dc3bff 100644
--- a/src/routes/+layout.svelte
+++ b/src/routes/+layout.svelte
@@ -1,4 +1,6 @@
<script>
+ import { run } from 'svelte/legacy';
+
import { browser } from "$app/environment";
import { PUBLIC_DOMAIN } from "$env/static/public";
import "../app.css";
@@ -6,15 +8,17 @@
import { onMount } from "svelte";
import { installPrompt, theme as themeStore } from "$lib/store";
- export let data;
- let { pathname, theme } = data;
+ let { data, children } = $props();
+ let { pathname, theme } = $state(data);
$themeStore = theme;
let host = PUBLIC_DOMAIN.includes("localhost")
? `http://${PUBLIC_DOMAIN}`
: `https://${PUBLIC_DOMAIN}`;
- $: theme = $themeStore
+ run(() => {
+ theme = $themeStore
+ });
onMount(() => {
if (!browser) return;
@@ -48,7 +52,7 @@
{#if !$loading}
<main data-theme={theme}>
- <slot />
+ {@render children?.()}
</main>
{/if}
diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte
index a04d669e..480ea1c4 100644
--- a/src/routes/+page.svelte
+++ b/src/routes/+page.svelte
@@ -1,4 +1,6 @@
<script>
+ import { run } from 'svelte/legacy';
+
import LandingHeader from "$comp/LandingHeader.svelte";
import LandingHero from "$comp/LandingHero.svelte";
import LandingInfoCard from "$comp/LandingInfoCard.svelte";
@@ -11,14 +13,16 @@
import { locale, t } from "$lib/translations";
import { onDestroy, onMount, tick } from "svelte";
- export let data;
- let { faqs, locations, user } = data;
+ let { data } = $props();
+ let { faqs, locations, user } = $state(data);
let update = (data) => ({ faqs, locations, user } = data);
- $: update(data);
+ run(() => {
+ update(data);
+ });
- let howItWorks;
- let faq;
- let about;
+ let howItWorks = $state();
+ let faq = $state();
+ let about = $state();
const howItWorksSteps = [
{ image: "coinos:hand", stepID: "step1" },
@@ -26,7 +30,7 @@
{ image: "coinos:smile", stepID: "step3" },
];
- let loaded;
+ let loaded = $state();
let observer;
@@ -66,8 +70,8 @@
title={$t("landing.info3.title")}
description={$t("landing.info3.description")}
/>
- <div bind:this={howItWorks} />
- <div id="about" />
+ <div bind:this={howItWorks}></div>
+ <div id="about"></div>
</div>
<div>
@@ -79,7 +83,7 @@
<HowItWorksCard image={step.image} stepID={step.stepID} />
{/each}
</div>
- <div bind:this={faq} />
+ <div bind:this={faq}></div>
</div>
<div>
@@ -91,7 +95,7 @@
<FaqCard questionID={f} />
{/each}
</div>
- <div bind:this={about} />
+ <div bind:this={about}></div>
</div>
<About />
diff --git a/src/routes/map/+page.svelte b/src/routes/map/+page.svelte
index 2addca54..3e0fae5a 100644
--- a/src/routes/map/+page.svelte
+++ b/src/routes/map/+page.svelte
@@ -1,7 +1,7 @@
<script>
import Icon from "$comp/Icon.svelte";
import LocationsMap from "$comp/LocationsMap.svelte";
- export let data;
+ let { data } = $props();
let { locations } = data;
</script>