Skip to content

Commit

Permalink
feat(web/extension/ui): update to use svelte 5 runes
Browse files Browse the repository at this point in the history
Signed-off-by: Jordan Shatford <[email protected]>
  • Loading branch information
jordanshatford committed Nov 8, 2024
1 parent 8877793 commit 676c32e
Show file tree
Hide file tree
Showing 46 changed files with 475 additions and 263 deletions.
12 changes: 6 additions & 6 deletions apps/extension/src/entrypoints/options/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
}
];
let activePage = tabs[0].key;
let activePage = $state(tabs[0].key);
const formatGroups = [
{
Expand Down Expand Up @@ -60,15 +60,15 @@
helpText="The format of file you want for the download."
bind:value={$settings.format}
groups={formatGroups}
on:change={() => toast.success('Updated', 'Format settings updated successfully.')}
onchange={() => toast.success('Updated', 'Format settings updated successfully.')}
/>
<Select
id="quality"
label="Quality:"
helpText="The preferred quality for the download."
bind:value={$settings.quality}
options={toSelectOptions(DownloadQuality)}
on:change={() => toast.success('Updated', 'Quality settings updated successfully.')}
onchange={() => toast.success('Updated', 'Quality settings updated successfully.')}
/>
</div>
{:else if activePage === 'embed'}
Expand All @@ -83,23 +83,23 @@
label="Metadata:"
helpText="Embed extracted information from the video into the download."
bind:checked={$settings.embed_metadata}
on:change={() =>
onchange={() =>
toast.success('Updated', 'Metadata embedding settings updated successfully.')}
/>
<Toggle
id="thumbnail"
label="Thumbnail:"
helpText="Attempt to embed thumbnail. Depending on other settings, this may not always work."
bind:checked={$settings.embed_thumbnail}
on:change={() =>
onchange={() =>
toast.success('Updated', 'Thumbnail embedding settings updated successfully.')}
/>
<Toggle
id="subtitles"
label="Subtitles:"
helpText="Attempt to embed subtitles. Depending on other settings, this may not always work."
bind:checked={$settings.embed_subtitles}
on:change={() =>
onchange={() =>
toast.success('Updated', 'Subtitle embedding settings updated successfully.')}
/>
</div>
Expand Down
4 changes: 3 additions & 1 deletion apps/extension/src/entrypoints/options/main.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import '~/assets/tailwind.css';

import { mount } from 'svelte';

import App from './App.svelte';

const app = new App({
const app = mount(App, {
target: document.getElementById('app')!
});

Expand Down
6 changes: 4 additions & 2 deletions apps/extension/src/entrypoints/popup/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import PopupMain from '~/lib/components/PopupMain.svelte';
</script>

<PopupLayout let:ctx>
<PopupMain {ctx} />
<PopupLayout>
{#snippet children({ ctx })}
<PopupMain {ctx} />
{/snippet}
</PopupLayout>
4 changes: 3 additions & 1 deletion apps/extension/src/entrypoints/popup/main.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import '~/assets/tailwind.css';

import { mount } from 'svelte';

import App from './App.svelte';

const app = new App({
const app = mount(App, {
target: document.getElementById('app')!
});

Expand Down
29 changes: 17 additions & 12 deletions apps/extension/src/lib/components/DownloadActions.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@
import { createContextStore } from '~/lib/stores/context';
export let store: ReturnType<typeof createContextStore>;
export let download: Download;
interface Props {
store: ReturnType<typeof createContextStore>;
download: Download;
}
let { store, download }: Props = $props();
let isWaitingForBlob = false;
let isWaitingForBlob = $state(false);
async function getDownloadFile() {
isWaitingForBlob = true;
Expand All @@ -22,27 +26,28 @@
src={DownloadIcon}
loading={isWaitingForBlob}
disabled={download.status.state !== 'DONE'}
on:click={async () => await getDownloadFile()}
onclick={async () => await getDownloadFile()}
/>
<ActionIcon
title="Retry Download"
src={ArrowPathIcon}
disabled={download.status.state !== 'ERROR'}
on:click={async () => await store.restart(download.video.id)}
onclick={async () => await store.restart(download.video.id)}
/>
<Confirm
variant="error"
title="Delete download?"
description="Are you sure you want to delete this download? Deleting is permanent."
cancelText="Cancel"
confirmText="Delete"
let:confirm={onConfirm}
>
<ActionIcon
title="Delete Download"
src={TrashIcon}
disabled={!['DONE', 'ERROR'].includes(download.status.state)}
on:click={() => onConfirm(() => store.remove(download.video.id))}
/>
{#snippet children({ confirm: onConfirm })}
<ActionIcon
title="Delete Download"
src={TrashIcon}
disabled={!['DONE', 'ERROR'].includes(download.status.state)}
onclick={() => onConfirm(() => store.remove(download.video.id))}
/>
{/snippet}
</Confirm>
</ButtonGroup>
12 changes: 10 additions & 2 deletions apps/extension/src/lib/components/PageLayout.svelte
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
<script lang="ts">
import type { Snippet } from 'svelte';
import { ExternalLinkIcon, Footer, IconButton, initializeTheme, Toasts } from '@yd/ui';
import config from '~/lib/config';
import { openWebsite } from '~/lib/website';
interface Props {
children?: Snippet;
}
let { children }: Props = $props();
// Ensure theme is set based on user preferences.
initializeTheme();
</script>
Expand All @@ -18,12 +26,12 @@
<IconButton
title="Go to site"
src={ExternalLinkIcon}
on:click={openWebsite}
onclick={openWebsite}
class="h-6 w-6"
/>
</div>
</div>
<slot />
{@render children?.()}
</div>
</main>
</div>
Expand Down
6 changes: 5 additions & 1 deletion apps/extension/src/lib/components/PopupError.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
<script lang="ts">
export let message: string = 'Unexpected error!';
interface Props {
message?: string;
}
let { message = 'Unexpected error!' }: Props = $props();
</script>

<div class="flex h-full flex-col items-center justify-center space-y-2 text-center">
Expand Down
15 changes: 12 additions & 3 deletions apps/extension/src/lib/components/PopupLayout.svelte
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
<script lang="ts">
import type { Snippet } from 'svelte';
import { ExternalLinkIcon, GearIcon, IconButton, initializeTheme } from '@yd/ui';
import type { Ctx } from '~/lib/context-service';
import PopupError from '~/lib/components/PopupError.svelte';
import PopupLoader from '~/lib/components/PopupLoader.svelte';
import { getContextService } from '~/lib/context-service';
import { openWebsite } from '~/lib/website';
interface Props {
children?: Snippet<[{ ctx: Ctx }]>;
}
let { children }: Props = $props();
// Ensure theme is set based on user preferences.
initializeTheme();
Expand All @@ -27,10 +36,10 @@
<IconButton
title="Go to site"
src={ExternalLinkIcon}
on:click={openWebsite}
onclick={openWebsite}
class="h-5 w-5"
/>
<IconButton title="Options" src={GearIcon} on:click={openOptionsPage} class="h-5 w-5" />
<IconButton title="Options" src={GearIcon} onclick={openOptionsPage} class="h-5 w-5" />
</div>
</div>
<!-- Remaining content -->
Expand All @@ -40,7 +49,7 @@
{#await context.get()}
<PopupLoader />
{:then ctx}
<slot {ctx} />
{@render children?.({ ctx })}
{:catch error}
<PopupError message={error.message} />
{/await}
Expand Down
6 changes: 5 additions & 1 deletion apps/extension/src/lib/components/PopupLoader.svelte
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
<script lang="ts">
import { Icon, LoaderIcon } from '@yd/ui';
export let message: string = 'Loading...';
interface Props {
message?: string;
}
let { message = 'Loading...' }: Props = $props();
</script>

<div class="flex h-full flex-col items-center justify-center space-y-2">
Expand Down
10 changes: 7 additions & 3 deletions apps/extension/src/lib/components/PopupMain.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@
import StatusBadge from '~/lib/components/StatusBadge.svelte';
import { createContextStore } from '~/lib/stores/context';
export let ctx: Ctx;
interface Props {
ctx: Ctx;
}
let { ctx }: Props = $props();
const store = createContextStore(ctx);
Expand Down Expand Up @@ -40,7 +44,7 @@
</div>
{#if !$store.currentDownload}
<IconButton
on:click={async () => await store.download()}
onclick={async () => await store.download()}
src={PlusIcon}
class="h-8 w-8 p-1 text-black hover:text-brand-600 dark:text-white dark:hover:text-brand-600"
/>
Expand All @@ -66,7 +70,7 @@
<StatusBadge status={$store.currentDownload.status} />
{/if}
{:else}
<Button disabled={$store.video === undefined} on:click={async () => await store.download()}>
<Button disabled={$store.video === undefined} onclick={async () => await store.download()}>
Download
</Button>
{/if}
Expand Down
6 changes: 5 additions & 1 deletion apps/extension/src/lib/components/StateIcon.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@
import type { IconSource } from '@yd/ui';
import { CheckCircleIcon, ExclamationCircleIcon, Icon, LoaderIcon } from '@yd/ui';
export let state: DownloadState;
interface Props {
state: DownloadState;
}
let { state }: Props = $props();
const lookup: Record<DownloadState, { icon: IconSource; class: string }> = {
WAITING: {
Expand Down
14 changes: 10 additions & 4 deletions apps/extension/src/lib/components/StatusBadge.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@
import type { BadgeVariants } from '@yd/ui';
import { Badge, ProgressBar } from '@yd/ui';
export let status: DownloadStatus;
interface Props {
status: DownloadStatus;
}
let { status }: Props = $props();
const postProcessorLookup: Record<string, string> = {
extractaudio: 'EXTRACTING AUDIO',
Expand Down Expand Up @@ -35,9 +39,11 @@
}
};
$: text = status.postprocessor
? (postProcessorLookup[status.postprocessor?.toLowerCase()] ?? status.state)
: status.state;
let text = $derived(
status.postprocessor
? (postProcessorLookup[status.postprocessor?.toLowerCase()] ?? status.state)
: status.state
);
</script>

{#key status.state}
Expand Down
27 changes: 16 additions & 11 deletions apps/web/src/lib/components/DownloadActions.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@
import type { Download } from '@yd/client';
import { ActionIcon, ArrowPathIcon, ButtonGroup, Confirm, DownloadIcon, TrashIcon } from '@yd/ui';
export let download: Download;
interface Props {
download: Download;
}
let { download }: Props = $props();
let isWaitingForBlob = false;
let isWaitingForBlob = $state(false);
async function getDownloadFile() {
isWaitingForBlob = true;
Expand All @@ -21,27 +25,28 @@
src={DownloadIcon}
loading={isWaitingForBlob}
disabled={download.status.state !== 'DONE'}
on:click={async () => await getDownloadFile()}
onclick={async () => await getDownloadFile()}
/>
<ActionIcon
title="Retry Download"
src={ArrowPathIcon}
disabled={download.status.state !== 'ERROR'}
on:click={async () => await downloads.restart(download.video.id)}
onclick={async () => await downloads.restart(download.video.id)}
/>
<Confirm
variant="error"
title="Delete download?"
description="Are you sure you want to delete this download? Deleting is permanent."
cancelText="Cancel"
confirmText="Delete"
let:confirm={onConfirm}
>
<ActionIcon
title="Delete Download"
src={TrashIcon}
disabled={!['DONE', 'ERROR'].includes(download.status.state)}
on:click={() => onConfirm(() => downloads.remove(download.video.id))}
/>
{#snippet children({ confirm: onConfirm })}
<ActionIcon
title="Delete Download"
src={TrashIcon}
disabled={!['DONE', 'ERROR'].includes(download.status.state)}
onclick={() => onConfirm(() => downloads.remove(download.video.id))}
/>
{/snippet}
</Confirm>
</ButtonGroup>
10 changes: 7 additions & 3 deletions apps/web/src/lib/components/NotFound.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@
import { Button } from '@yd/ui';
export let title: string = '404';
export let subtitle: string = '';
export let description: string = "We can't find that page.";
interface Props {
title?: string;
subtitle?: string;
description?: string;
}
let { title = '404', subtitle = '', description = "We can't find that page." }: Props = $props();
</script>

<div class="-mt-16 grid h-screen place-content-center px-4">
Expand Down
Loading

0 comments on commit 676c32e

Please sign in to comment.