aboutsummaryrefslogtreecommitdiffstats
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
parentbe5aa52cea1d57c875cfb22d25c6a866b8de2239 (diff)
downloadcoinos-ui-32fcc461cd43c8907df5e306d520bb671307eab1.tar.gz
coinos-ui-32fcc461cd43c8907df5e306d520bb671307eab1.zip
svelte 5
-rw-r--r--package.json10
-rw-r--r--src/components/About.svelte2
-rw-r--r--src/components/Account.svelte33
-rw-r--r--src/components/AppHeader.svelte22
-rw-r--r--src/components/Avatar.svelte31
-rw-r--r--src/components/Balance.svelte8
-rw-r--r--src/components/Code.svelte4
-rw-r--r--src/components/DarkToggle.svelte4
-rw-r--r--src/components/DeleteItem.svelte10
-rw-r--r--src/components/Event.svelte4
-rw-r--r--src/components/FaqCard.svelte11
-rw-r--r--src/components/Feed.svelte25
-rw-r--r--src/components/Footer.svelte4
-rw-r--r--src/components/HowItWorksCard.svelte5
-rw-r--r--src/components/Icon.svelte3
-rw-r--r--src/components/Image.svelte3
-rw-r--r--src/components/InvoiceActions.svelte24
-rw-r--r--src/components/InvoiceData.svelte8
-rw-r--r--src/components/InvoiceTypes.svelte15
-rw-r--r--src/components/ItemForm.svelte27
-rw-r--r--src/components/Items.svelte53
-rw-r--r--src/components/LandingHeader.svelte50
-rw-r--r--src/components/LandingHero.svelte2
-rw-r--r--src/components/LandingInfoCard.svelte13
-rw-r--r--src/components/Lnurlp.svelte22
-rw-r--r--src/components/Lnurlw.svelte17
-rw-r--r--src/components/LocaleSelector.svelte11
-rw-r--r--src/components/LocationsMap.svelte46
-rw-r--r--src/components/Menu.svelte51
-rw-r--r--src/components/Mnemonic.svelte2
-rw-r--r--src/components/Numpad.svelte55
-rw-r--r--src/components/Password.svelte18
-rw-r--r--src/components/Pin.svelte50
-rw-r--r--src/components/Pinpad.svelte19
-rw-r--r--src/components/Popup.svelte2
-rw-r--r--src/components/Qr.svelte8
-rw-r--r--src/components/SetAmount.svelte32
-rw-r--r--src/components/Slider.svelte17
-rw-r--r--src/components/Toggle.svelte5
-rw-r--r--src/components/WalletPass.svelte14
-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
109 files changed, 1319 insertions, 944 deletions
diff --git a/package.json b/package.json
index f3553ca1..d5086c64 100644
--- a/package.json
+++ b/package.json
@@ -11,7 +11,7 @@
"@scure/bip39": "^1.2.1",
"@scure/btc-signer": "^1.3.2",
"@sveltejs/adapter-node": "^2.0.0",
- "@sveltejs/kit": "^2.5.22",
+ "@sveltejs/kit": "^2.5.27",
"@sveltejs/vite-plugin-svelte": "^4.0.0",
"@tailwindcss/line-clamp": "^0.4.2",
"@types/uuid": "^10.0.0",
@@ -30,8 +30,8 @@
"maplibre-gl": "^3.3.1",
"nostr-tools": "^2.7.2",
"postcss": "^8.4.20",
- "prettier": "3",
- "prettier-plugin-svelte": "3",
+ "prettier": "^3.1.0",
+ "prettier-plugin-svelte": "^3.2.6",
"qr-code-styling": "1.6.0-rc.1",
"qr-scanner": "^1.4.2",
"qrcode-base64": "^1.0.1",
@@ -41,7 +41,7 @@
"svelte-adapter-bun": "^0.5.1",
"svelte-dnd-action": "^0.9.39",
"svelte-outclick": "^3.3.3",
- "svelte-preprocess": "^5.0.3",
+ "svelte-preprocess": "^6.0.0",
"svelte-virtual-scroll-list": "^1.1.0",
"sveltekit-i18n": "^2.2.2",
"tailwind-scrollbar": "^2.1.0",
@@ -50,7 +50,7 @@
"uint8array-extras": "^1.0.0",
"unique-names-generator": "^4.7.1",
"uuid": "^9.0.0",
- "vite": "^5.0.0"
+ "vite": "^5.4.4"
},
"scripts": {
"dev": "vite dev",
diff --git a/src/components/About.svelte b/src/components/About.svelte
index 01ff4c7c..5f87e99a 100644
--- a/src/components/About.svelte
+++ b/src/components/About.svelte
@@ -24,7 +24,7 @@
{ name: "cole", socials: [] },
];
- let locations;
+ let locations = $state();
onMount(async () => {
try {
({ locations } = await fetch("/locations").then((r) => r.json()));
diff --git a/src/components/Account.svelte b/src/components/Account.svelte
index 38c8c418..c378b9a3 100644
--- a/src/components/Account.svelte
+++ b/src/components/Account.svelte
@@ -1,14 +1,19 @@
<script>
+ import { run } from 'svelte/legacy';
+
import { goto } from "$app/navigation";
import Icon from "$comp/Icon.svelte";
import Balance from "$comp/Balance.svelte";
import { t } from "$lib/translations";
- export let user, rate, account, last;
- let { name, seed, balance, id } = account;
- $: type = seed ? "Savings" : "Cash";
+ let {
+ user,
+ rate,
+ account,
+ last
+ } = $props();
+ let { name, seed, balance, id } = $state(account);
- $: refresh(account);
let refresh = (a) => ({ seed, balance, id } = a);
let setAccount = () => (document.cookie = `aid=${id}; path=/; max-age=86400`);
@@ -16,38 +21,42 @@
setAccount();
goto("/payments");
};
+ let type = $derived(seed ? "Savings" : "Cash");
+ run(() => {
+ refresh(account);
+ });
</script>
<div
class="block space-y-2 border-primary py-4 cursor-pointer"
class:border-b-8={!last}
- on:click={go}
+ onclick={go}
>
<div class="flex">
<Balance {balance} {user} {rate} />
- <a href={`/payments`} class="contents" on:click={setAccount}>
+ <a href={`/payments`} class="contents" onclick={setAccount}>
<button class="ml-auto flex gap-1 mb-auto pb-4 pl-4">
- <iconify-icon icon="ph:clock-bold" width="32" />
+ <iconify-icon icon="ph:clock-bold" width="32"></iconify-icon>
</button>
</a>
<a href={`/account/${id}`} class="contents">
<button class="flex gap-1 mb-auto pb-4 pl-4">
- <iconify-icon icon="ph:gear-bold" width="32" />
+ <iconify-icon icon="ph:gear-bold" width="32"></iconify-icon>
</button>
</a>
</div>
<div class="flex justify-center w-full text-xl gap-2">
- <a href={`/invoice`} class="contents" on:click={setAccount}>
+ <a href={`/invoice`} class="contents" onclick={setAccount}>
<button class="btn !w-auto flex-grow">
- <iconify-icon icon="ph:hand-coins-bold" width="32" flip="horizontal" />
+ <iconify-icon icon="ph:hand-coins-bold" width="32" flip="horizontal"></iconify-icon>
<div class="my-auto">{$t("user.dashboard.receive")}</div>
</button>
</a>
- <a href={`/send`} class="contents grow" on:click={setAccount}>
+ <a href={`/send`} class="contents grow" onclick={setAccount}>
<button type="button" class="btn !w-auto flex-grow">
- <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.dashboard.send")}</div>
</button>
</a>
diff --git a/src/components/AppHeader.svelte b/src/components/AppHeader.svelte
index 5a922792..fef2f0f4 100644
--- a/src/components/AppHeader.svelte
+++ b/src/components/AppHeader.svelte
@@ -1,4 +1,6 @@
<script>
+ import { run } from 'svelte/legacy';
+
import { banner, theme, newPayment } from "$lib/store";
import { goto } from "$app/navigation";
import Avatar from "$comp/Avatar.svelte";
@@ -6,19 +8,21 @@
import { loading, t } from "$lib/translations";
import { page } from "$app/stores";
- export let user, subject;
+ let { user, subject = $bindable() } = $props();
- let w;
- $: if (!subject) subject = user;
+ let w = $state();
+ run(() => {
+ if (!subject) subject = user;
+ });
- $: bg =
- $banner?.id && $banner.id === subject.id
+ let bg =
+ $derived($banner?.id && $banner.id === subject.id
? `url(${$banner.src})`
: subject?.banner
? subject.banner.includes(":")
? `url(${subject.banner})`
: `url(/api/public/${subject.banner}.webp)`
- : undefined;
+ : undefined);
const links = [
{
@@ -40,10 +44,10 @@
},
];
- $: opacity = (href) =>
+ let opacity = $derived((href) =>
$page.url.pathname === href
? "opacity-100"
- : "opacity-90 hover:opacity-none";
+ : "opacity-90 hover:opacity-none");
</script>
<svelte:window bind:innerWidth={w} />
@@ -58,7 +62,7 @@
{#each links as { href, icon, flip }}
<a {href} data-sveltekit-preload-code="eager">
<button class="btn-menu {opacity(href)}">
- <iconify-icon {icon} width={w > 640 ? 32 : 24} {flip} />
+ <iconify-icon {icon} width={w > 640 ? 32 : 24} {flip}></iconify-icon>
</button>
</a>
{/each}
diff --git a/src/components/Avatar.svelte b/src/components/Avatar.svelte
index a088c4ee..3007c3e7 100644
--- a/src/components/Avatar.svelte
+++ b/src/components/Avatar.svelte
@@ -1,20 +1,29 @@
-<script>
+<script lang="ts">
+ import { run } from 'svelte/legacy';
+
import { avatar, banner } from "$lib/store";
import Icon from "$comp/Icon.svelte";
import { punk } from "$lib/utils";
- export let user;
- export let size = 32;
- export let disabled = false;
+ interface Props {
+ user: any;
+ size?: number;
+ disabled?: boolean;
+ }
+
+ let { user, size = 32, disabled = false }: Props = $props();
- $: s = size.toString();
- $: link = user?.anon ? `/${user.pubkey}` : `/${user.username}`;
+ let s = $derived(size.toString());
+ let link = $derived(user?.anon ? `/${user.pubkey}` : `/${user.username}`);
let base = "/api/public";
- $: profile = user?.profile ? `${base}/${user.profile}.webp` : user?.picture;
- $: fallback = `${base}/punks/` + punk(user.pubkey || user.id || "aa");
- $: tmp = $avatar?.id && $avatar.id === user.id && $avatar.src;
- $: src = tmp || profile || fallback;
+ let profile = $derived(user?.profile ? `${base}/${user.profile}.webp` : user?.picture);
+ let fallback = $derived(`${base}/punks/` + punk(user.pubkey || user.id || "aa"));
+ let tmp = $derived($avatar?.id && $avatar.id === user.id && $avatar.src);
+ let src;
+ run(() => {
+ src = tmp || profile || fallback;
+ });
let handle = () => (src = fallback);
</script>
@@ -27,7 +36,7 @@
{src}
class="w-full h-full object-cover object-center overflow-hidden"
alt={user.username}
- on:error={handle}
+ onerror={handle}
/>
</div>
</a>
diff --git a/src/components/Balance.svelte b/src/components/Balance.svelte
index 0cc27068..91463f7e 100644
--- a/src/components/Balance.svelte
+++ b/src/components/Balance.svelte
@@ -1,12 +1,14 @@
<script>
+ import { preventDefault } from 'svelte/legacy';
+
import Icon from "$comp/Icon.svelte";
import Pin from "$comp/Pin.svelte";
import { f, s, sat, sats } from "$lib/utils";
import { pin } from "$lib/store";
import { t } from "$lib/translations";
- let show;
- export let user, rate, balance;
+ let show = $state();
+ let { user, rate, balance } = $props();
</script>
{#if show && user.haspin && $pin?.length !== 6}
@@ -16,7 +18,7 @@
<div>
{#if user.haspin && !$pin}
<button
- on:click|preventDefault={() => (show = true)}
+ onclick={preventDefault(() => (show = true))}
class="flex gap-2 text-xl"
>
<Icon icon="eye-off" style="w-8 my-auto" />
diff --git a/src/components/Code.svelte b/src/components/Code.svelte
index 7ec046a6..00ef38a8 100644
--- a/src/components/Code.svelte
+++ b/src/components/Code.svelte
@@ -2,7 +2,7 @@
import { copyNoNewlines as copy } from "$lib/utils";
import Icon from "$comp/Icon.svelte";
import samples from "$lib/samples";
- export let sample;
+ let { sample } = $props();
</script>
<div
@@ -13,7 +13,7 @@
</div>
<button
class="ml-auto my-auto invert opacity-90"
- on:click={() => copy(samples[sample])}
+ onclick={() => copy(samples[sample])}
><Icon icon="copy" style="w-10 max-w-none" /></button
>
</div>
diff --git a/src/components/DarkToggle.svelte b/src/components/DarkToggle.svelte
index 5ddc80a1..be1fe858 100644
--- a/src/components/DarkToggle.svelte
+++ b/src/components/DarkToggle.svelte
@@ -9,12 +9,12 @@
<button
class="flex justify-center items-center hover:opacity-80 gap-2 font-bold"
- on:click={dark}
+ onclick={dark}
>
<iconify-icon
icon={$theme === "dark" ? "ph:sun-bold" : "ph:moon-stars-bold"}
width="30"
- />
+></iconify-icon>
{$t(`nav.${$theme === "dark" ? "light" : "dark"}`)}
</button>
diff --git a/src/components/DeleteItem.svelte b/src/components/DeleteItem.svelte
index 8f7f97ca..d45f09e6 100644
--- a/src/components/DeleteItem.svelte
+++ b/src/components/DeleteItem.svelte
@@ -1,9 +1,11 @@
<script>
+ import { preventDefault } from 'svelte/legacy';
+
import Icon from "$comp/Icon.svelte";
import { fail, post } from "$lib/utils";
import { invalidate } from "$app/navigation";
- export let item;
+ let { item = $bindable() } = $props();
let cancel = () => (item = null);
@@ -25,13 +27,13 @@
class="relative top-1/3 mx-auto p-5 border w-96 shadow-lg rounded-md bg-white space-y-5"
>
<h1 class="text-center text-2xl font-semibold">Delete item</h1>
- <form on:submit|preventDefault={submit}>
+ <form onsubmit={preventDefault(submit)}>
<div class="w-full flex">
<button
type="button"
class="border-2 border-black rounded-xl font-semibold mx-auto py-3 w-40 hover:opacity-80 mx-auto"
- on:click={cancel}
- on:keydown={cancel}
+ onclick={cancel}
+ onkeydown={cancel}
>
<div class="my-auto">No</div>
</button>
diff --git a/src/components/Event.svelte b/src/components/Event.svelte
index 640b9e68..78fdd230 100644
--- a/src/components/Event.svelte
+++ b/src/components/Event.svelte
@@ -1,7 +1,7 @@
<script>
import Avatar from "$comp/Avatar.svelte";
import Icon from "$comp/Icon.svelte";
- export let event;
+ let { event } = $props();
let { id, user, seen, content } = event;
@@ -22,7 +22,7 @@
: "now";
};
- let w;
+ let w = $state();
</script>
<svelte:window bind:innerWidth={w} />
diff --git a/src/components/FaqCard.svelte b/src/components/FaqCard.svelte
index ae1ad077..a2d13bc8 100644
--- a/src/components/FaqCard.svelte
+++ b/src/components/FaqCard.svelte
@@ -1,10 +1,15 @@
-<script>
+<script lang="ts">
import { t } from "$lib/translations";
// this ID will be used to get the strings from the locale
// question is at faq.[questionID].question
- // answer is at faq.[questionID].answer
- export let questionID;
+
+ interface Props {
+ // answer is at faq.[questionID].answer
+ questionID: any;
+ }
+
+ let { questionID }: Props = $props();
</script>
<div class="mx-auto w-full md:w-2/3 lg:w-[700px] space-y-5">
diff --git a/src/components/Feed.svelte b/src/components/Feed.svelte
index 5dc2b21a..593c2289 100644
--- a/src/components/Feed.svelte
+++ b/src/components/Feed.svelte
@@ -1,4 +1,6 @@
<script>
+ import { preventDefault } from 'svelte/legacy';
+
import { t } from "$lib/translations";
import { onMount } from "svelte";
import Event from "$comp/Event.svelte";
@@ -7,10 +9,9 @@
import { fail } from "$lib/utils";
import { sign, send } from "$lib/nostr";
- export let events;
- export let user = undefined;
+ let { events = $bindable(), user = undefined } = $props();
- let message;
+ let message = $state();
let submit = async () => {
try {
@@ -38,14 +39,14 @@
}
};
- $: sorted = Object.values(events)
+ let sorted = $derived(Object.values(events)
.filter((ev) => ev?.pubkey && ev?.kind === 1)
- .sort((a, b) => b.seen - a.seen);
+ .sort((a, b) => b.seen - a.seen));
</script>
{#if user}
<form
- on:submit|preventDefault={submit}
+ onsubmit={preventDefault(submit)}
class="flex justify-center gap-4 max-w-2xl mx-auto"
>
<div class="grow">
@@ -68,14 +69,16 @@
<VirtualScroll
data={sorted}
key="id"
- let:data
+
pageMode={true}
estimateSize={200}
>
- <a href={`/${data.user.pubkey}/event/${data.id}`}>
- <Event event={data} />
- </a>
- </VirtualScroll>
+ {#snippet children({ data })}
+ <a href={`/${data.user.pubkey}/event/${data.id}`}>
+ <Event event={data} />
+ </a>
+ {/snippet}
+ </VirtualScroll>
{:else}
<div class="flex w-full">
<div class="mx-auto text-secondary">{$t("user.noNotes")}</div>
diff --git a/src/components/Footer.svelte b/src/components/Footer.svelte
index 1fac31e9..3af5f6a3 100644
--- a/src/components/Footer.svelte
+++ b/src/components/Footer.svelte
@@ -24,7 +24,7 @@
<div class="space-y-5">
<div class="text-center w-full">
<a href="/">
- <iconify-icon icon="coinos:logo" width="224" />
+ <iconify-icon icon="coinos:logo" width="224"></iconify-icon>
</a>
</div>
<div class="flex gap-2 justify-center sm:hidden">
@@ -73,5 +73,5 @@
</ul>
</div>
- <iconify-icon icon="coinos:shield" class="flex justify-center" width="96" />
+ <iconify-icon icon="coinos:shield" class="flex justify-center" width="96"></iconify-icon>
</footer>
diff --git a/src/components/HowItWorksCard.svelte b/src/components/HowItWorksCard.svelte
index a8fe63fd..2b8967ae 100644
--- a/src/components/HowItWorksCard.svelte
+++ b/src/components/HowItWorksCard.svelte
@@ -1,12 +1,11 @@
<script>
import Icon from "./Icon.svelte";
import { t } from "$lib/translations";
- export let image;
- export let stepID;
+ let { image, stepID } = $props();
</script>
<div class="space-y-5">
- <iconify-icon icon={image} class="mx-auto" width="128" />
+ <iconify-icon icon={image} class="mx-auto" width="128"></iconify-icon>
<p class="text-2xl font-medium">{$t("howItWorks." + stepID + ".header")}</p>
<p class="text-secondary text-xl font-medium w-full md:w-2/3 mx-auto">
{$t("howItWorks." + stepID + ".description")}
diff --git a/src/components/Icon.svelte b/src/components/Icon.svelte
index 0b47f726..6d55bf94 100644
--- a/src/components/Icon.svelte
+++ b/src/components/Icon.svelte
@@ -1,6 +1,5 @@
<script>
- export let icon;
- export let style = undefined;
+ let { icon, style = undefined } = $props();
</script>
<img src="/icons/{icon}.svg" alt={icon} class={style} />
diff --git a/src/components/Image.svelte b/src/components/Image.svelte
index 4f8b39bb..4bc90571 100644
--- a/src/components/Image.svelte
+++ b/src/components/Image.svelte
@@ -1,6 +1,5 @@
<script>
- export let image;
- export let style;
+ let { image, style } = $props();
</script>
<img src="/images/{image}.webp" alt={image} class={style} />
diff --git a/src/components/InvoiceActions.svelte b/src/components/InvoiceActions.svelte
index 7f1607e0..0b5dca55 100644
--- a/src/components/InvoiceActions.svelte
+++ b/src/components/InvoiceActions.svelte
@@ -1,33 +1,35 @@
<script>
- export let user,
+ let {
+ user,
invoice,
copy,
t,
link,
type,
types,
- showQr,
+ showQr = $bindable(),
txt,
- toggleAmount;
+ toggleAmount
+ } = $props();
</script>
<div class="text-secondary space-y-2 text-xl pt-2">
- <button type="button" class="btn" on:click={() => copy(txt)}>
- <iconify-icon icon="ph:copy-bold" width="32" />
+ <button type="button" class="btn" onclick={() => copy(txt)}>
+ <iconify-icon icon="ph:copy-bold" width="32"></iconify-icon>
<div class="my-auto">
{t("payments.copy")}
</div>
</button>
{#if user?.id === invoice?.user?.id}
- <button class="btn" on:click={toggleAmount}>
- <iconify-icon icon="ph:pencil-simple-bold" width="32" />
+ <button class="btn" onclick={toggleAmount}>
+ <iconify-icon icon="ph:pencil-simple-bold" width="32"></iconify-icon>
<div class="my-auto">{t("payments.setAmount")}</div>
</button>
{:else}
<a href={link} class="block">
<button class="btn">
- <iconify-icon icon="ph:wallet-bold" width="32" />
+ <iconify-icon icon="ph:wallet-bold" width="32"></iconify-icon>
<div class="my-auto">{t("payments.openLink")}</div>
</button>
</a>
@@ -35,11 +37,11 @@
{#if txt.startsWith("ln")}
<div class="w-full flex justify-center gap-2 flex-wrap">
- <button class="btn" on:click={() => (showQr = !showQr)}>
+ <button class="btn" onclick={() => (showQr = !showQr)}>
{#if showQr}
- <iconify-icon icon="ph:text-align-center-bold" width="32" />
+ <iconify-icon icon="ph:text-align-center-bold" width="32"></iconify-icon>
{:else}
- <iconify-icon icon="ph:qr-code-bold" width="32" />
+ <iconify-icon icon="ph:qr-code-bold" width="32"></iconify-icon>
{/if}
<div class="my-auto">
{showQr ? t("payments.showText") : t("payments.showQr")}
diff --git a/src/components/InvoiceData.svelte b/src/components/InvoiceData.svelte
index 7723eb56..da1ea5d9 100644
--- a/src/components/InvoiceData.svelte
+++ b/src/components/InvoiceData.svelte
@@ -1,16 +1,18 @@
<script>
import { btc, f, sat, s, sats } from "$lib/utils";
- export let showQr,
+ let {
+ showQr,
src,
link,
- qr,
+ qr = $bindable(),
txt,
invoice,
amount,
amountFiat,
currency,
tip,
- rate;
+ rate
+ } = $props();
</script>
{#if showQr}
diff --git a/src/components/InvoiceTypes.svelte b/src/components/InvoiceTypes.svelte
index 354f0a49..cdd01aac 100644
--- a/src/components/InvoiceTypes.svelte
+++ b/src/components/InvoiceTypes.svelte
@@ -1,5 +1,12 @@
<script>
- export let aid, user, type, types, t, setType;
+ let {
+ aid,
+ user,
+ type,
+ types,
+ t,
+ setType
+ } = $props();
</script>
{#if aid === user?.id}
@@ -8,7 +15,7 @@
class="btn flex-nowrap"
class:bg-base-300={type === types.bitcoin}
class:text-secondary={type === types.bitcoin}
- on:click={() => setType(types.bitcoin)}
+ onclick={() => setType(types.bitcoin)}
>
<img src="/images/bitcoin.svg" class="w-8" alt="Bitcoin" />
<div class="my-auto text-lg">Bitcoin</div>
@@ -18,7 +25,7 @@
class="btn flex-nowrap"
class:bg-base-300={type === types.liquid}
class:text-secondary={type === types.liquid}
- on:click={() => setType(types.liquid)}
+ onclick={() => setType(types.liquid)}
>
<img src="/images/liquid.svg" class="w-8" alt="Liquid" />
<div class="my-auto text-lg">Liquid</div>
@@ -28,7 +35,7 @@
class="btn flex-nowrap"
class:bg-base-300={type === types.lightning}
class:text-secondary={type === types.lightning}
- on:click={() => setType(types.lightning)}
+ onclick={() => setType(types.lightning)}
>
<div class="bg-base-100 rounded-full w-8 h-8 text-center flex">
<div class="m-auto">⚡️</div>
diff --git a/src/components/ItemForm.svelte b/src/components/ItemForm.svelte
index 7e0f58d8..d3ea88c0 100644
--- a/src/components/ItemForm.svelte
+++ b/src/components/ItemForm.svelte
@@ -1,15 +1,16 @@
<script>
+ import { preventDefault } from 'svelte/legacy';
+
import { t } from "$lib/translations";
import { upload } from "$lib/upload";
import { fail } from "$lib/utils";
import { applyAction, deserialize } from "$app/forms";
import Spinner from "$comp/Spinner.svelte";
- export let item;
- export let user;
+ let { item = $bindable(), user } = $props();
- let fileInput, formElement, file, submitting, progress;
+ let fileInput = $state(), formElement = $state(), file, submitting = $state(), progress;
let select = () => fileInput.click();
- let src;
+ let src = $state();
let tooLarge = {};
let handleFile = async ({ target }, type) => {
@@ -67,7 +68,7 @@
<form
method="POST"
class="space-y-5"
- on:submit|preventDefault={handleSubmit}
+ onsubmit={preventDefault(handleSubmit)}
bind:this={formElement}
>
<input type="hidden" name="id" bind:value={item.id} />
@@ -104,24 +105,24 @@
{src}
alt={item.name}
class="object-cover w-full h-full"
- on:click={select}
- on:keydown={select}
+ onclick={select}
+ onkeydown={select}
/>
{:else if item.image}
<img
src={`/api/public/${item.image}.webp`}
alt={item.name}
class="object-cover w-full h-full"
- on:click={select}
- on:keydown={select}
+ onclick={select}
+ onkeydown={select}
/>
{:else}
<div
class="bg-gradient-to-r from-primary to-gradient mb-4 cursor-pointer hover:opacity-80 w-full h-full"
- on:click={select}
- on:keydown={select}
+ onclick={select}
+ onkeydown={select}
alt="Banner"
- />
+></div>
{/if}
</div>
</div>
@@ -130,7 +131,7 @@
type="file"
class="hidden"
bind:this={fileInput}
- on:change={(e) => handleFile(e, "item")}
+ onchange={(e) => handleFile(e, "item")}
/>
</div>
diff --git a/src/components/Items.svelte b/src/components/Items.svelte
index db5dedc1..a7b4fe1a 100644
--- a/src/components/Items.svelte
+++ b/src/components/Items.svelte
@@ -1,4 +1,6 @@
<script>
+ import { run, stopPropagation } from 'svelte/legacy';
+
import { t } from "$lib/translations";
import { btc, f, sat, post } from "$lib/utils";
import { browser } from "$app/environment";
@@ -15,15 +17,22 @@
import DeleteItem from "$comp/DeleteItem.svelte";
import Icon from "$comp/Icon.svelte";
- export let subject, user, items, rate, currency, total;
+ let {
+ subject,
+ user,
+ items = $bindable(),
+ rate,
+ currency,
+ total
+ } = $props();
let flipDurationMs = 200;
let dropTargetStyle = {};
let dragDisabled =
- subject?.id !== user?.id || (browser && window.innerWidth < 768);
+ $state(subject?.id !== user?.id || (browser && window.innerWidth < 768));
- let deleting;
+ let deleting = $state();
let del = (item) => {
deleting = item;
};
@@ -62,10 +71,6 @@
dragDisabled = false;
}
- $: if (total > 0 && browser) {
- let payButton = document.querySelector("#payButton");
- if (payButton) payButton.addEventListener("click", checkout);
- }
let checkout = async () => {
let invoice = {
@@ -92,9 +97,15 @@
let reset = () =>
(dragDisabled =
user?.username !== subject?.username || window.innerWidth < 768);
+ run(() => {
+ if (total > 0 && browser) {
+ let payButton = document.querySelector("#payButton");
+ if (payButton) payButton.addEventListener("click", checkout);
+ }
+ });
</script>
-<svelte:window on:resize={reset} />
+<svelte:window onresize={reset} />
{#if deleting}
<DeleteItem bind:item={deleting} />
@@ -106,21 +117,21 @@
<div
class="grid sm:grid-cols-2 gap-4 pb-20"
use:dndzone={{ items, flipDurationMs, dropTargetStyle, dragDisabled }}
- on:consider={handleConsider}
- on:finalize={handleFinalize}
+ onconsider={handleConsider}
+ onfinalize={handleFinalize}
>
{#each items as i (i.id)}
<button
type="button"
class="w-full text-center cursor-pointer hover:opacity-80 mb-auto"
- on:click={() => i.quantity++}
+ onclick={() => i.quantity++}
>
<div class="relative w-full h-64 overflow-hidden rounded-xl">
{#if i[SHADOW_ITEM_MARKER_PROPERTY_NAME]}
<div
in:fade={{ duration: 200, easing: cubicIn }}
class="custom-shadow-item"
- />
+></div>
{:else if i.image}
<img
src={`/api/public/${i.image}.webp`}
@@ -131,7 +142,7 @@
<div
class="bg-gradient-to-r from-primary to-gradient mb-4 cursor-pointer hover:opacity-80 w-full h-full"
alt="Banner"
- />
+></div>
{/if}
{#if user?.username === subject.username}
<div class="flex gap-2 justify-center absolute top-2 right-2">
@@ -144,16 +155,16 @@
</a>
<button
class="bg-black rounded-full w-12 h-12 bg-opacity-40 hover:bg-opacity-100"
- on:click|stopPropagation={() => del(i)}
+ onclick={stopPropagation(() => del(i))}
>
<Icon icon="trash" style="w-8 mx-auto invert" />
</button>
<div
- on:click|stopPropagation={() => {}}
+ onclick={stopPropagation(() => {})}
class="sm:hidden"
- on:mousedown={startDrag}
- on:touchstart={startDrag}
- on:keydown={handleKeyDown}
+ onmousedown={startDrag}
+ ontouchstart={startDrag}
+ onkeydown={handleKeyDown}
>
<a href={`/items/${i.id}`}>
<button
@@ -183,7 +194,7 @@
{#if i.quantity}
<button
type="button"
- on:click|stopPropagation={() => i.quantity > 0 && i.quantity--}
+ onclick={stopPropagation(() => i.quantity > 0 && i.quantity--)}
>
<Icon icon="minus" style="w-10 min-w-10" />
</button>
@@ -194,7 +205,7 @@
{#if i.quantity}
<button
type="button"
- on:click|stopPropagation={() => i.quantity++}
+ onclick={stopPropagation(() => i.quantity++)}
>
<Icon icon="plus" style="w-10 min-w-10" />
</button>
@@ -213,7 +224,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/components/LandingHeader.svelte b/src/components/LandingHeader.svelte
index 7a4c5d18..c20c80a0 100644
--- a/src/components/LandingHeader.svelte
+++ b/src/components/LandingHeader.svelte
@@ -7,13 +7,15 @@
import DarkToggle from "$comp/DarkToggle.svelte";
import LocaleSelector from "$comp/LocaleSelector.svelte";
- export let howItWorks;
- export let faq;
- export let about;
- export let user;
+ let {
+ howItWorks,
+ faq,
+ about,
+ user
+ } = $props();
- let showMobileMenu = false;
- let header;
+ let showMobileMenu = $state(false);
+ let header = $state();
const mobileMenuButtonClick = (section) => {
showMobileMenu = false;
scroll(section);
@@ -26,45 +28,45 @@
>
<nav class="block lg:flex justify-between items-center">
<div class="flex justify-start lg:justify-center items-center lg:space-x-5">
- <a href="/" on:click={() => scroll(header)}>
- <iconify-icon icon="coinos:logo" width="224" />
+ <a href="/" onclick={() => scroll(header)}>
+ <iconify-icon icon="coinos:logo" width="224"></iconify-icon>
</a>
</div>
<!-- desktop nav -->
<div class="hidden space-x-5 lg:flex justify-center items-center font-bold">
{#if $page.url.pathname === "/"}
- <button class="hover:opacity-80" on:click={() => scroll(howItWorks)}
+ <button class="hover:opacity-80" onclick={() => scroll(howItWorks)}
>{$t("howItWorks.header")}</button
>
- <button class="hover:opacity-80" on:click={() => scroll(faq)}
+ <button class="hover:opacity-80" onclick={() => scroll(faq)}
>{$t("faq.header")}</button
>
- <button class="hover:opacity-80" on:click={() => scroll(about)}
+ <button class="hover:opacity-80" onclick={() => scroll(about)}
>{$t("about.header")}</button
>
{/if}
{#if user}
<button
class="btn !w-auto !rounded-full"
- on:click={() => goto(`/${user.username}`)}
+ onclick={() => goto(`/${user.username}`)}
>Home
</button>
<button
class="btn !w-auto !rounded-full"
- on:click={() => goto("/logout")}
+ onclick={() => goto("/logout")}
>
{$t("nav.signOut")}
</button>
{:else}
<button
class="btn btn-accent !w-auto !rounded-full"
- on:click={() => goto("/register")}
+ onclick={() => goto("/register")}
>{$t("nav.register")}
</button>
<button
class="btn !w-auto !rounded-full"
- on:click={() => goto("/login")}
+ onclick={() => goto("/login")}
>
{$t("nav.signIn")}
</button>
@@ -73,12 +75,12 @@
<button
class="block lg:hidden absolute top-[34.5px] right-10 z"
- on:click={() => (showMobileMenu = !showMobileMenu)}
+ onclick={() => (showMobileMenu = !showMobileMenu)}
>
<iconify-icon
icon={!showMobileMenu ? "ph:list-bold" : "ph:x-bold"}
width="32"
- />
+></iconify-icon>
</button>
<div
@@ -89,31 +91,31 @@
<div class="space-y-5 mt-24 font-bold text-xl">
<LocaleSelector />
<DarkToggle />
- <button on:click={() => mobileMenuButtonClick(howItWorks)} class="block"
+ <button onclick={() => mobileMenuButtonClick(howItWorks)} class="block"
>{$t("howItWorks.header")}</button
>
- <button on:click={() => mobileMenuButtonClick(faq)} class="block"
+ <button onclick={() => mobileMenuButtonClick(faq)} class="block"
>{$t("faq.header")}</button
>
- <button on:click={() => mobileMenuButtonClick(about)} class="block"
+ <button onclick={() => mobileMenuButtonClick(about)} class="block"
>{$t("about.header")}</button
>
{#if !user}
- <button class="btn btn-accent" on:click={() => goto("/register")}
+ <button class="btn btn-accent" onclick={() => goto("/register")}
>{$t("nav.register")}
</button>
- <button class="btn" on:click={() => goto("/login")}>
+ <button class="btn" onclick={() => goto("/login")}>
{$t("nav.signIn")}
</button>
{:else}
<button
class="border rounded-full px-6 py-2 font-bold block"
- on:click={() => goto(`/${user.username}`)}
+ onclick={() => goto(`/${user.username}`)}
>{$t("nav.account")}
</button>
<button
class="bg-primary text-white border rounded-full px-6 py-2 font-bold block"
- on:click={() => goto("/logout")}
+ onclick={() => goto("/logout")}
>
{$t("nav.signOut")}
</button>
diff --git a/src/components/LandingHero.svelte b/src/components/LandingHero.svelte
index 8d47283e..d3f71390 100644
--- a/src/components/LandingHero.svelte
+++ b/src/components/LandingHero.svelte
@@ -17,7 +17,7 @@
<iconify-icon
icon="coinos:rays"
class="absolute -top-16 left-5 md:left-8 lg:left-14 2xl:left-24"
- />
+></iconify-icon>
</span>
{$t("landing.header_after_icon")}
</h1>
diff --git a/src/components/LandingInfoCard.svelte b/src/components/LandingInfoCard.svelte
index fadcb6c0..63951e86 100644
--- a/src/components/LandingInfoCard.svelte
+++ b/src/components/LandingInfoCard.svelte
@@ -1,10 +1,13 @@
<script>
import Image from "./Image.svelte";
- export let image;
- export let title;
- export let description = undefined;
- export let order = undefined;
+ let {
+ image,
+ title,
+ description = undefined,
+ order = undefined,
+ children
+ } = $props();
</script>
<div class="block lg:flex justify-center lg:space-x-20 items-center">
@@ -25,7 +28,7 @@
{#if description}
{description}
{:else}
- <slot />
+ {@render children?.()}
{/if}
</p>
</div>
diff --git a/src/components/Lnurlp.svelte b/src/components/Lnurlp.svelte
index 0268e363..74be0571 100644
--- a/src/components/Lnurlp.svelte
+++ b/src/components/Lnurlp.svelte
@@ -1,19 +1,29 @@
<script>
+ import { run } from 'svelte/legacy';
+
import { t } from "$lib/translations";
import { enhance } from "$app/forms";
import Numpad from "$comp/Numpad.svelte";
import Spinner from "$comp/Spinner.svelte";
import { pin } from "$lib/store";
- export let data, form, send, comment;
+ let {
+ data,
+ form,
+ send = $bindable(),
+ comment = $bindable()
+ } = $props();
let { currency } = data.user;
let { minSendable, maxSendable, commentAllowed, callback, metadata, rates } =
data;
- $: rate = rates[currency];
+ let rate;
+ run(() => {
+ rate = rates[currency];
+ });
- let amount = Math.round(minSendable / 1000),
- loading;
+ let amount = $state(Math.round(minSendable / 1000)),
+ loading = $state();
let submit = () => (loading = true);
</script>
@@ -39,7 +49,7 @@
<Numpad bind:amount bind:rate {currency} bind:submit={send} />
- <form action="?/pay" method="POST" use:enhance on:submit={submit}>
+ <form action="?/pay" method="POST" use:enhance onsubmit={submit}>
<input name="amount" value={amount} type="hidden" />
<input name="minSendable" value={minSendable} type="hidden" />
<input name="maxSendable" value={maxSendable} type="hidden" />
@@ -53,7 +63,7 @@
class="w-full p-4 border rounded-xl h-32 text-xl"
bind:value={comment}
autocapitalize="none"
- />
+></textarea>
{/if}
<div class="flex w-full">
diff --git a/src/components/Lnurlw.svelte b/src/components/Lnurlw.svelte
index d0fbf3b4..50aa1488 100644
--- a/src/components/Lnurlw.svelte
+++ b/src/components/Lnurlw.svelte
@@ -1,4 +1,6 @@
<script>
+ import { run } from 'svelte/legacy';
+
import { sats, f, s } from "$lib/utils";
import { t } from "$lib/translations";
import { enhance } from "$app/forms";
@@ -6,7 +8,7 @@
import Spinner from "$comp/Spinner.svelte";
import { pin } from "$lib/store";
- export let data, form;
+ let { data, form } = $props();
let { currency, username } = data.user;
let {
@@ -17,13 +19,16 @@
callback,
rates,
} = data;
- $: rate = rates[currency];
+ let rate;
+ run(() => {
+ rate = rates[currency];
+ });
- let amount = Math.round(minWithdrawable / 1000),
- loading;
+ let amount = $state(Math.round(minWithdrawable / 1000)),
+ loading = $state();
let submit = () => (loading = true);
- $: amountFiat = parseFloat(((amount * rate) / sats).toFixed(2));
+ let amountFiat = $derived(parseFloat(((amount * rate) / sats).toFixed(2)));
</script>
<div class="container px-4 mt-20 max-w-xl mx-auto">
@@ -56,7 +61,7 @@
<Numpad bind:amount {currency} bind:rate />
{/if}
- <form action="?/withdraw" method="POST" use:enhance on:submit={submit}>
+ <form action="?/withdraw" method="POST" use:enhance onsubmit={submit}>
<input name="amount" value={amount} type="hidden" />
<input name="username" value={username} type="hidden" />
<input name="currency" value={currency} type="hidden" />
diff --git a/src/components/LocaleSelector.svelte b/src/components/LocaleSelector.svelte
index d837a534..cb057dbd 100644
--- a/src/components/LocaleSelector.svelte
+++ b/src/components/LocaleSelector.svelte
@@ -1,8 +1,13 @@
<script>
+ import { run } from 'svelte/legacy';
+
import { t, locale, locales } from "$lib/translations";
- export let style;
+ let { style } = $props();
- $: l = $locale;
+ let l;
+ run(() => {
+ l = $locale;
+ });
const handleChange = ({ currentTarget }) => {
const { value } = currentTarget;
@@ -11,7 +16,7 @@
};
</script>
-<select name="language" bind:value={l} on:change={handleChange}>
+<select name="language" bind:value={l} onchange={handleChange}>
{#each $locales as locale}
<option value={locale}>{$t(`lang.${locale}`)}</option>
{/each}
diff --git a/src/components/LocationsMap.svelte b/src/components/LocationsMap.svelte
index c01d8b75..b04b8e98 100644
--- a/src/components/LocationsMap.svelte
+++ b/src/components/LocationsMap.svelte
@@ -1,5 +1,5 @@
<script>
- import { tick, onMount, onDestroy } from "svelte";
+ import { tick, onMount, onDestroy, mount } from "svelte";
import { browser } from "$app/environment";
import Icon from "$comp/Icon.svelte";
import Popup from "$comp/Popup.svelte";
@@ -7,15 +7,15 @@
import "maplibre-gl/dist/maplibre-gl.css";
- export let locations;
+ let { locations } = $props();
let map;
- let mapContainer, mapWrapper;
+ let mapContainer = $state(), mapWrapper = $state();
let markers = [];
- let search;
+ let search = $state();
let clearSearch = (e) => (search = "");
let currentIndex = -1;
- let timeout;
+ let timeout = $state();
let full = () => {
if (!document.fullscreenElement) {
@@ -49,11 +49,6 @@
}
};
- $: list = search
- ? markers.filter((m) =>
- m.tags.name.toLowerCase().includes(search.toLowerCase()),
- )
- : inview;
let scroll = () => {
const el = document.querySelector(".selected");
@@ -65,7 +60,7 @@
});
};
- let selected;
+ let selected = $state();
function select(m) {
selected = m;
stopFlying();
@@ -109,7 +104,7 @@
};
let toggleList = () => (showList = !showList);
- let showList;
+ let showList = $state();
let currentPopup;
function startFlying() {
@@ -155,7 +150,7 @@
map.off("moveend");
}
- let inview = [];
+ let inview = $state([]);
let updateLabelVisibility = debounce(() => {
inview = [];
@@ -201,10 +196,10 @@
let popupContainer = document.createElement("div");
- new Popup({
- target: popupContainer,
- props: { tags },
- });
+ mount(Popup, {
+ target: popupContainer,
+ props: { tags },
+ });
let marker = new maplibre.Marker({ color: "#F7931A", scale: 0.65 })
.setLngLat([lon, lat])
@@ -252,6 +247,11 @@
});
onDestroy(() => map && map.remove());
+ let list = $derived(search
+ ? markers.filter((m) =>
+ m.tags.name.toLowerCase().includes(search.toLowerCase()),
+ )
+ : inview);
</script>
<div class="w-screen h-dvh flex" id="map" bind:this={mapWrapper}>
@@ -259,11 +259,11 @@
id="map-container"
class="mx-auto h-full w-full z-0"
bind:this={mapContainer}
- />
+></div>
<div class="absolute flex top-2 left-2 gap-2">
<button
class="rounded-full border-2 border-black bg-base-100 w-10 h-10"
- on:click={back}
+ onclick={back}
>
<Icon icon="arrow-left" style="w-4 m-auto" />
</button>
@@ -277,7 +277,7 @@
<input bind:value={search} class="w-full" />
<div class="flex gap-1 absolute right-6 top-3">
{#if search}
- <button on:click={clearSearch}>
+ <button onclick={clearSearch}>
<Icon icon="close" style="w-8" />
</button>
{:else}
@@ -288,7 +288,7 @@
{#each list as marker, i}
<button
- on:click={() => select(marker)}
+ onclick={() => select(marker)}
class:font-bold={selected === marker}
class:selected={selected === marker}
class="block whitespace-nowrap text-ellipsis text-left w-full overflow-hidden"
@@ -301,13 +301,13 @@
<div class="absolute flex top-2 right-2 gap-2">
<button
class="rounded-full border-2 border-black bg-white w-10 h-10"
- on:click={toggleList}
+ onclick={toggleList}
>
<Icon icon="list" style="w-4 m-auto" />
</button>
<button
class="rounded-full border-2 border-black bg-white w-10 h-10"
- on:click={toggle}
+ onclick={toggle}
>
{#if timeout}
<Icon icon="pause" style="w-4 m-auto" />
diff --git a/src/components/Menu.svelte b/src/components/Menu.svelte
index 3ce6d9ce..de21bbbc 100644
--- a/src/components/Menu.svelte
+++ b/src/components/Menu.svelte
@@ -1,26 +1,35 @@
<script>
+ import { run } from 'svelte/legacy';
+
import { theme } from "$lib/store";
import DarkToggle from "$comp/DarkToggle.svelte";
import OutClick from "svelte-outclick";
- export let t, user, w, opacity;
+ let {
+ t,
+ user,
+ w,
+ opacity
+ } = $props();
let dark = () => ($theme = $theme === "dark" ? "light" : "dark");
- let showMenu = false;
+ let showMenu = $state(false);
- let menuButtons;
- $: if (user)
- menuButtons = [
- { key: "nav.settings", icon: "ph:gear-bold", href: `/settings` },
- { key: "nav.support", icon: "ph:lifebuoy-bold", href: `/support` },
- { key: "nav.map", icon: "ph:map-trifold-bold", href: `/map` },
- {
- key: "nav.merch",
- icon: "ph:storefront-bold",
- href: `https://coinosmerch.com`,
- },
- { key: "nav.dark", icon: "ph:moon-stars-bold", href: `/dark` },
- { key: "nav.signOut", icon: "ph:sign-out-bold", href: `/logout` },
- ];
+ let menuButtons = $state();
+ run(() => {
+ if (user)
+ menuButtons = [
+ { key: "nav.settings", icon: "ph:gear-bold", href: `/settings` },
+ { key: "nav.support", icon: "ph:lifebuoy-bold", href: `/support` },
+ { key: "nav.map", icon: "ph:map-trifold-bold", href: `/map` },
+ {
+ key: "nav.merch",
+ icon: "ph:storefront-bold",
+ href: `https://coinosmerch.com`,
+ },
+ { key: "nav.dark", icon: "ph:moon-stars-bold", href: `/dark` },
+ { key: "nav.signOut", icon: "ph:sign-out-bold", href: `/logout` },
+ ];
+ });
let hideMenu = () => (showMenu = false);
let toggleMenu = () => (showMenu = !showMenu);
@@ -28,8 +37,8 @@
<div>
<OutClick on:outclick={hideMenu}>
- <button class="btn-menu {opacity('/support')}" on:click={toggleMenu}
- ><iconify-icon icon="ph:list-bold" width={w > 640 ? 32 : 24} />
+ <button class="btn-menu {opacity('/support')}" onclick={toggleMenu}
+ ><iconify-icon icon="ph:list-bold" width={w > 640 ? 32 : 24}></iconify-icon>
</button>
<div
@@ -47,12 +56,12 @@
{href}
data-sveltekit-preload-code="eager"
data-sveltekit-preload-data="false"
- on:click={hideMenu}
+ onclick={hideMenu}
>
<button
class="flex justify-center items-center font-semibold hover:opacity-80 gap-2"
>
- <iconify-icon {icon} width="32" />
+ <iconify-icon {icon} width="32"></iconify-icon>
{t(key)}
</button>
</a>
@@ -61,7 +70,7 @@
{/each}
</ul>
<hr class="my-4" />
- <a href="/?stay=true"><iconify-icon icon="coinos:logo" width="160" /></a>
+ <a href="/?stay=true"><iconify-icon icon="coinos:logo" width="160"></iconify-icon></a>
</div>
</OutClick>
</div>
diff --git a/src/components/Mnemonic.svelte b/src/components/Mnemonic.svelte
index 41e81d9a..93035230 100644
--- a/src/components/Mnemonic.svelte
+++ b/src/components/Mnemonic.svelte
@@ -1,5 +1,5 @@
<script>
- export let mnemonic;
+ let { mnemonic } = $props();
</script>
<div class="flex w-full border p-4 rounded-2xl h-full">
diff --git a/src/components/Numpad.svelte b/src/components/Numpad.svelte
index 07d1ef4c..03c7c48f 100644
--- a/src/components/Numpad.svelte
+++ b/src/components/Numpad.svelte
@@ -1,21 +1,33 @@
-<script>
+<script lang="ts">
+ import { run, preventDefault, stopPropagation } from "svelte/legacy";
+
import Left from "$comp/Left.svelte";
import Icon from "$comp/Icon.svelte";
import { f, s, focus, warning, sat, sats } from "$lib/utils";
import { t } from "$lib/translations";
- export let amount,
- currency,
- element,
- fiat = !amount,
- rate,
- submit = undefined;
+ interface Props {
+ amount: any;
+ currency: any;
+ element: any;
+ fiat?: any;
+ rate: any;
+ submit?: any;
+ amountFiat?: number;
+ }
- export let amountFiat = 0;
+ let {
+ amount = $bindable(),
+ currency,
+ element = $bindable(),
+ fiat = $bindable(!amount),
+ rate = $bindable(),
+ submit = undefined,
+ amountFiat = $bindable(0),
+ }: Props = $props();
let arrow = "<";
- $: update(amount, amountFiat);
let update = (a, f) => {
if (fiat) {
amount = Math.round(f / (rate / sats));
@@ -102,8 +114,6 @@
}
};
- $: html = fiat ? amountFiat : s(amount);
-
let prev = "";
let input = (e) => {
@@ -193,6 +203,13 @@
}
fiat = !fiat;
};
+ run(() => {
+ update(amount, amountFiat);
+ });
+ let html;
+ run(() => {
+ html = fiat ? amountFiat : s(amount);
+ });
</script>
<div class="flex justify-center items-center">
@@ -208,17 +225,17 @@
use:focus
contenteditable
bind:innerHTML={html}
- on:focus={select}
- on:blur={blur}
- on:input={input}
- on:keydown={keydown}
+ onfocus={select}
+ onblur={blur}
+ oninput={input}
+ onkeydown={keydown}
class="outline-none my-auto"
bind:this={element}
- />
+ ></div>
</div>
<div
class="flex items-center justify-center text-2xl cursor-pointer"
- on:click|preventDefault|stopPropagation={swap}
+ onclick={stopPropagation(preventDefault(swap))}
>
{fiat ? "⚡️" + s(amount) : f(amountFiat, currency)}
</div>
@@ -230,7 +247,7 @@
<button
type="button"
class="btn"
- on:click|preventDefault|stopPropagation={() => handleInput(value)}
+ onclick={stopPropagation(preventDefault(() => handleInput(value)))}
>
<Left />
</button>
@@ -238,7 +255,7 @@
<button
type="button"
class="btn"
- on:click|preventDefault|stopPropagation={() => handleInput(value)}
+ onclick={stopPropagation(preventDefault(() => handleInput(value)))}
>{value}</button
>
{/if}
diff --git a/src/components/Password.svelte b/src/components/Password.svelte
index cb57eec5..ac2a9a44 100644
--- a/src/components/Password.svelte
+++ b/src/components/Password.svelte
@@ -1,13 +1,15 @@
<script>
+ import { preventDefault } from 'svelte/legacy';
+
import Icon from "$comp/Icon.svelte";
import { focus, fail, post } from "$lib/utils";
import { password as pw, passwordPrompt } from "$lib/store";
- export let user;
+ let { user } = $props();
- let password;
+ let password = $state();
let { username } = user;
- let revealPassword = false;
+ let revealPassword = $state(false);
let cancel = () => ($passwordPrompt = false);
@@ -31,7 +33,7 @@
<h1 class="text-center text-2xl font-semibold">
Please enter your password
</h1>
- <form on:submit|preventDefault={submit}>
+ <form onsubmit={preventDefault(submit)}>
<div class="relative mb-5">
{#if revealPassword}
<input
@@ -54,21 +56,21 @@
{/if}
<button
type="button"
- on:click={() => (revealPassword = !revealPassword)}
+ onclick={() => (revealPassword = !revealPassword)}
class="absolute right-5 top-6"
>
<iconify-icon
icon={revealPassword ? "ph:eye-bold" : "ph:eye-slash-bold"}
width="32"
- />
+></iconify-icon>
</button>
</div>
<div class="w-full flex">
<button
type="button"
class="border-2 border-black rounded-xl font-semibold mx-auto py-3 w-40 hover:opacity-80 mx-auto"
- on:click={cancel}
- on:keydown={cancel}
+ onclick={cancel}
+ onkeydown={cancel}
>
<div class="my-auto">Cancel</div>
</button>
diff --git a/src/components/Pin.svelte b/src/components/Pin.svelte
index fb17c612..da53577e 100644
--- a/src/components/Pin.svelte
+++ b/src/components/Pin.svelte
@@ -1,28 +1,36 @@
-<script>
+<script lang="ts">
+ import { run, createBubbler, preventDefault } from "svelte/legacy";
+
+ const bubble = createBubbler();
import { t } from "$lib/translations";
import { post, success, fail, focus, setCookie } from "$lib/utils";
import Pinpad from "$comp/Pinpad.svelte";
import { pin } from "$lib/store";
import { onMount } from "svelte";
- export let value = "";
- export let title = $t("user.settings.verifyPIN");
- export let cancel = () => (p = "");
- export let notify = true;
+ interface Props {
+ value?: string;
+ title?: any;
+ cancel?: any;
+ notify?: boolean;
+ }
- let p = "";
+ let {
+ value = $bindable(""),
+ title = $t("user.settings.verifyPIN"),
+ cancel = () => (p = ""),
+ notify = true,
+ }: Props = $props();
- $: update(value);
- let update = (value) => (p = value);
+ let p = $state("");
- $: p.toString().length > 5 && (value = p.toString());
+ let update = (value) => (p = value);
- let loaded;
+ let loaded = $state();
onMount(() => setTimeout(() => (loaded = true), 500));
- let locktime = 30 * 60;
+ let locktime = $state(30 * 60);
- $: loaded && checkPin(p);
let checkPin = async (p) => {
if (p?.length !== 6) return;
let result;
@@ -41,12 +49,21 @@
value = "";
}
};
+ run(() => {
+ p.toString().length > 5 && (value = p.toString());
+ });
+ run(() => {
+ update(value);
+ });
+ run(() => {
+ loaded && checkPin(p);
+ });
</script>
{#if loaded}
<div
class="fixed bg-base-100 bg-opacity-90 inset-0 h-full w-full z-50 cursor-default"
- on:click|preventDefault
+ onclick={preventDefault(bubble("click"))}
>
<div
class="mx-auto p-5 border shadow-lg rounded-md bg-base-100 space-y-5 max-w-lg"
@@ -58,10 +75,7 @@
<label for="locktime" class="font-bold"
>{$t("user.settings.rememberFor")}</label
>
- <select
- name="locktime"
- bind:value={locktime}
- >
+ <select name="locktime" bind:value={locktime}>
<option value={30}>30 {$t("user.settings.seconds")}</option>
<option value={5 * 60}>5 {$t("user.settings.minutes")}</option>
<option value={10 * 60}>10 {$t("user.settings.minutes")}</option>
@@ -72,7 +86,7 @@
</div>
<div class="w-full flex">
- <button class="btn" on:click|preventDefault={cancel}>
+ <button class="btn" onclick={preventDefault(cancel)}>
<div class="my-auto">Cancel</div>
</button>
</div>
diff --git a/src/components/Pinpad.svelte b/src/components/Pinpad.svelte
index d61dd2a0..93f31d08 100644
--- a/src/components/Pinpad.svelte
+++ b/src/components/Pinpad.svelte
@@ -1,11 +1,12 @@
<script>
+ import { preventDefault, stopPropagation } from 'svelte/legacy';
+
import Left from "$comp/Left.svelte";
import Icon from "$comp/Icon.svelte";
import { focus, post, warning } from "$lib/utils";
import { t } from "$lib/translations";
- export let v;
- export let cancel;
+ let { v = $bindable(), cancel } = $props();
let arrow = "<";
let loading = false;
@@ -33,7 +34,7 @@
}
};
- let hide = true;
+ let hide = $state(true);
</script>
<label
@@ -41,7 +42,7 @@
>
{#if hide}
<input
- on:keydown={validate}
+ onkeydown={validate}
use:focus
bind:value={v}
type="password"
@@ -50,7 +51,7 @@
/>
{:else}
<input
- on:keydown={validate}
+ onkeydown={validate}
use:focus
bind:value={v}
class="clean text-center !text-5xl !w-96 block"
@@ -61,9 +62,9 @@
<iconify-icon
icon={hide ? "ph:eye-slash-bold" : "ph:eye-bold"}
width="32"
- on:click|stopPropagation|preventDefault={() => (hide = !hide)}
+ onclick={stopPropagation(preventDefault(() => (hide = !hide)))}
class="cursor-pointer"
- />
+></iconify-icon>
</label>
<div class="grid grid-cols-3 gap-2 w-[300px] mx-auto grayscale">
@@ -72,7 +73,7 @@
<button
type="button"
class="btn"
- on:click|stopPropagation|preventDefault={() => handleInput(value)}
+ onclick={stopPropagation(preventDefault(() => handleInput(value)))}
>
<Left />
</button>
@@ -80,7 +81,7 @@
<button
type="button"
class="btn"
- on:click|stopPropagation|preventDefault={() => handleInput(value)}
+ onclick={stopPropagation(preventDefault(() => handleInput(value)))}
>{value}</button
>
{/if}
diff --git a/src/components/Popup.svelte b/src/components/Popup.svelte
index df96215f..661b2bed 100644
--- a/src/components/Popup.svelte
+++ b/src/components/Popup.svelte
@@ -1,7 +1,7 @@
<script>
import { page } from "$app/stores";
import Avatar from "$comp/Avatar.svelte";
- export let tags;
+ let { tags } = $props();
let addr = (tags) => {
let {
diff --git a/src/components/Qr.svelte b/src/components/Qr.svelte
index e98497c4..c8d33e23 100644
--- a/src/components/Qr.svelte
+++ b/src/components/Qr.svelte
@@ -1,14 +1,14 @@
<script>
import screenfull from "screenfull";
- export let src;
- let qr;
+ let { src } = $props();
+ let qr = $state();
</script>
<div
class="w-80 mx-auto cursor-pointer"
bind:this={qr}
- on:click={() => screenfull.toggle(qr)}
- on:keydown={() => screenfull.toggle(qr)}
+ onclick={() => screenfull.toggle(qr)}
+ onkeydown={() => screenfull.toggle(qr)}
>
<img {src} class="mx-auto" alt="QR Code" />
</div>
diff --git a/src/components/SetAmount.svelte b/src/components/SetAmount.svelte
index 506762da..332c2eca 100644
--- a/src/components/SetAmount.svelte
+++ b/src/components/SetAmount.svelte
@@ -1,17 +1,21 @@
<script>
+ import { preventDefault, stopPropagation } from "svelte/legacy";
+
import Numpad from "$comp/Numpad.svelte";
import Toggle from "$comp/Toggle.svelte";
- export let currency,
- rate,
- fiat,
- submit,
+ let {
+ currency = $bindable(),
+ fiat = $bindable(),
+ rate = $bindable(),
+ submit = $bindable(),
settingAmount,
setAmount,
- newAmount,
+ newAmount = $bindable(),
toggleAmount,
t,
- amountPrompt;
+ amountPrompt = $bindable(),
+ } = $props();
</script>
{#if settingAmount}
@@ -21,19 +25,13 @@
<div
class="relative mx-auto p-12 max-w-xl shadow-lg rounded-md bg-base-100 space-y-5"
>
- <form on:submit|preventDefault={setAmount} class="space-y-5">
- <Numpad
- bind:amount={newAmount}
- bind:currency
- bind:rate
- bind:fiat
- bind:submit
- />
+ <form onsubmit={preventDefault(setAmount)} class="space-y-5">
+ <Numpad bind:amount={newAmount} bind:fiat {currency} {rate} {submit} />
<div class="w-full flex flex-wrap gap-2">
<button
bind:this={submit}
type="submit"
- on:click|preventDefault|stopPropagation={setAmount}
+ onclick={stopPropagation(preventDefault(setAmount))}
class="btn btn-accent"
>
<div class="my-auto">{t("payments.ok")}</div>
@@ -41,8 +39,8 @@
<button
type="button"
class="btn"
- on:click|preventDefault|stopPropagation={toggleAmount}
- on:keydown|preventDefault|stopPropagation={toggleAmount}
+ onclick={stopPropagation(preventDefault(toggleAmount))}
+ onkeydown={stopPropagation(preventDefault(toggleAmount))}
>
<div class="my-auto">{t("payments.cancel")}</div>
</button>
diff --git a/src/components/Slider.svelte b/src/components/Slider.svelte
index b82b6bf9..137c28b4 100644
--- a/src/components/Slider.svelte
+++ b/src/components/Slider.svelte
@@ -1,8 +1,17 @@
-<script>
- export let value,
+<script lang="ts">
+ interface Props {
+ value: any;
+ handle: any;
+ min?: number;
+ max?: number;
+ }
+
+ let {
+ value = $bindable(),
handle,
min = 0,
- max = 100;
+ max = 100
+ }: Props = $props();
</script>
<input
@@ -13,7 +22,7 @@
bind:value
class="px-0 py-0 my-5"
style="--bgPercent: {((value - min) * 100) / (max - min)}%;"
- on:input={handle}
+ oninput={handle}
/>
<style>
diff --git a/src/components/Toggle.svelte b/src/components/Toggle.svelte
index 2f92837d..0bc319ab 100644
--- a/src/components/Toggle.svelte
+++ b/src/components/Toggle.svelte
@@ -1,6 +1,5 @@
<script>
- export let id;
- export let value;
+ let { id, value = $bindable() } = $props();
</script>
<label for={id} class="inline-flex relative items-center mr-5 cursor-pointer">
@@ -13,5 +12,5 @@
/>
<div
class="w-11 h-6 bg-gray-200 rounded-full peer dark:bg-gray-700 peer-focus:ring-4 peer-focus:ring-gray-300 dark:peer-focus:ring-gray-800 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-0.5 after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-green-500"
- />
+></div>
</label>
diff --git a/src/components/WalletPass.svelte b/src/components/WalletPass.svelte
index 75c94f34..57cf69c3 100644
--- a/src/components/WalletPass.svelte
+++ b/src/components/WalletPass.svelte
@@ -1,9 +1,11 @@
<script>
+ import { preventDefault } from 'svelte/legacy';
+
import { focus } from "$lib/utils";
import { t } from "$lib/translations";
import Icon from "$comp/Icon.svelte";
- export let cancel, password, submit;
- let revealPassword;
+ let { cancel, password = $bindable(), submit } = $props();
+ let revealPassword = $state();
</script>
<div
@@ -15,7 +17,7 @@
<h1 class="text-center text-2xl font-semibold">
{$t("payments.enterWalletPass")}
</h1>
- <form on:submit|preventDefault={submit}>
+ <form onsubmit={preventDefault(submit)}>
<div class="relative mb-5">
{#if revealPassword}
<input
@@ -38,7 +40,7 @@
{/if}
<button
type="button"
- on:click={() => (revealPassword = !revealPassword)}
+ onclick={() => (revealPassword = !revealPassword)}
class="absolute right-5 top-1/2"
>
<Icon icon={revealPassword ? "eye" : "eye-off"} />
@@ -48,8 +50,8 @@
<button
type="button"
class="border rounded-2xl font-semibold mx-auto py-5 px-6 hover:opacity-80 mx-auto grow"
- on:click={cancel}
- on:keydown={cancel}
+ onclick={cancel}
+ onkeydown={cancel}
>
<div class="my-auto">Cancel</div>
</button>
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>