update to svelte 5

This commit is contained in:
Max Nuding 2024-10-29 16:26:07 +01:00
parent d39ccba927
commit 66f09cf5a3
No known key found for this signature in database
9 changed files with 558 additions and 1244 deletions

1668
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -15,8 +15,8 @@
}, },
"devDependencies": { "devDependencies": {
"@sveltejs/adapter-node": "^5.0.0", "@sveltejs/adapter-node": "^5.0.0",
"@sveltejs/kit": "^2.0.0", "@sveltejs/kit": "^2.7.0",
"@sveltejs/vite-plugin-svelte": "^3.0.0", "@sveltejs/vite-plugin-svelte": "^4.0.0",
"@types/node": "^22.6.1", "@types/node": "^22.6.1",
"@types/sqlite3": "^3.0.0", "@types/sqlite3": "^3.0.0",
"@types/ws": "^8.5.0", "@types/ws": "^8.5.0",
@ -25,12 +25,12 @@
"@zerodevx/svelte-toast": "^0.9.3", "@zerodevx/svelte-toast": "^0.9.3",
"eslint": "^9.11.1", "eslint": "^9.11.1",
"eslint-config-prettier": "^9.0.0", "eslint-config-prettier": "^9.0.0",
"eslint-plugin-svelte": "^2.0.0", "eslint-plugin-svelte": "^2.45.1",
"prettier": "^3.0.0", "prettier": "^3.1.0",
"prettier-plugin-svelte": "^3.0.0", "prettier-plugin-svelte": "^3.2.6",
"svelte": "^4.0.0", "svelte": "^5",
"svelte-check": "^4.0.0", "svelte-check": "^4.0.0",
"tslib": "^2.4.1", "tslib": "^2.0.0",
"typescript": "^5.0.0", "typescript": "^5.0.0",
"vite": "^5.0.0" "vite": "^5.0.0"
}, },

View File

@ -1,7 +1,11 @@
<script lang="ts"> <script lang="ts">
import type { Account } from '$lib/mastodon/response'; import type { Account } from '$lib/mastodon/response';
export let account: Account; interface Props {
account: Account;
}
let { account }: Props = $props();
</script> </script>
<a href={account.url} target="_blank">{account.display_name} @{account.acct}</a> <a href={account.url} target="_blank">{account.display_name} @{account.acct}</a>

View File

@ -1,11 +1,13 @@
<script lang="ts"> <script lang="ts">
import type { Account } from '$lib/mastodon/response'; import type { Account } from '$lib/mastodon/response';
export let account: Account; interface Props {
let avatarDescription: string; account: Account;
let sourceSetHtml: string; }
$: avatarDescription = `Avatar for ${account.acct}`;
$: { let { account }: Props = $props();
let avatarDescription: string = $derived(`Avatar for ${account.acct}`);
let sourceSetHtml: string = $derived.by(() => {
// Sort thumbnails by file type. This is important, because the order of the srcset entries matter. // Sort thumbnails by file type. This is important, because the order of the srcset entries matter.
// We need the best format to be first // We need the best format to be first
const formatPriority = new Map<string, number>([ const formatPriority = new Map<string, number>([
@ -33,8 +35,8 @@
const srcset = entry[1].join(', '); const srcset = entry[1].join(', ');
html += `<source srcset="${srcset}" type="${entry[0]}" />`; html += `<source srcset="${srcset}" type="${entry[0]}" />`;
} }
sourceSetHtml = html; return html;
} });
</script> </script>
<picture> <picture>

View File

@ -1,33 +1,34 @@
<script lang="ts"> <script lang="ts">
import { createEventDispatcher } from 'svelte';
import LoadingSpinnerComponent from '$lib/components/LoadingSpinnerComponent.svelte'; import LoadingSpinnerComponent from '$lib/components/LoadingSpinnerComponent.svelte';
export let moreAvailable = false; interface Props {
export let isLoading = false; moreAvailable?: boolean;
let displayText = ''; isLoading?: boolean;
let title = ''; loadOlderPosts: any;
let disabled: boolean;
$: if (isLoading) {
displayText = 'Loading...';
} else if (!moreAvailable) {
displayText = 'You reached the end';
} else {
displayText = 'Load More';
} }
$: disabled = !moreAvailable || isLoading;
$: title = moreAvailable ? 'Load More' : 'There be dragons!';
const dispatch = createEventDispatcher<{ let { moreAvailable = false, isLoading = false, loadOlderPosts }: Props = $props();
loadOlderPosts: string; let displayText = $derived.by(() => {
}>(); if (isLoading) {
return 'Loading...';
} else if (!moreAvailable) {
return 'You reached the end';
}
return 'Load More';
});
let title = $derived(moreAvailable ? 'Load More' : 'There be dragons!');
let disabled: boolean = $derived(!moreAvailable || isLoading);
function loadOlderPosts() { /*const dispatch = createEventDispatcher<{
dispatch('loadOlderPosts'); loadOlderPosts: string;
} }>();
function loadOlderPosts() {
dispatch('loadOlderPosts');
}*/
</script> </script>
<button on:click={loadOlderPosts} {disabled} {title}> <button onclick={() => loadOlderPosts()} {disabled} {title}>
<div class="loading" class:collapsed={!isLoading}> <div class="loading" class:collapsed={!isLoading}>
<LoadingSpinnerComponent size="0.5em" thickness="6px" /> <LoadingSpinnerComponent size="0.5em" thickness="6px" />
</div> </div>

View File

@ -1,9 +1,13 @@
<script lang="ts"> <script lang="ts">
export let size = '64px'; interface Props {
export let thickness = '6px'; size?: string;
thickness?: string;
}
let { size = '64px', thickness = '6px' }: Props = $props();
</script> </script>
<div class="lds-dual-ring" style="--size: {size}; --thickness: {thickness}" /> <div class="lds-dual-ring" style="--size: {size}; --thickness: {thickness}"></div>
<style> <style>
.lds-dual-ring { .lds-dual-ring {

View File

@ -6,15 +6,21 @@
import { secondsSince, relativeTime } from '$lib/relativeTime'; import { secondsSince, relativeTime } from '$lib/relativeTime';
import { onMount } from 'svelte'; import { onMount } from 'svelte';
export let post: Post; interface Props {
let displayRelativeTime = false; post: Post;
const absoluteDate = new Date(post.created_at).toLocaleString();
let dateCreated = absoluteDate;
const timePassed = secondsSince(new Date(post.created_at));
$: if (displayRelativeTime) {
dateCreated = relativeTime($timePassed) ?? absoluteDate;
} }
let { post }: Props = $props();
let displayRelativeTime = $state(false);
const absoluteDate = new Date(post.created_at).toLocaleString();
const timePassed = secondsSince(new Date(post.created_at));
let dateCreated = $derived.by(() => {
if (displayRelativeTime) {
return relativeTime($timePassed) ?? absoluteDate;
}
return absoluteDate;
});
const songs = filterDuplicates(post.songs ?? []); const songs = filterDuplicates(post.songs ?? []);
function filterDuplicates(songs: SongInfo[]): SongInfo[] { function filterDuplicates(songs: SongInfo[]): SongInfo[] {

View File

@ -1,6 +1,11 @@
<script lang="ts"> <script lang="ts">
import FooterComponent from '$lib/components/FooterComponent.svelte'; import FooterComponent from '$lib/components/FooterComponent.svelte';
import { SvelteToast } from '@zerodevx/svelte-toast'; import { SvelteToast } from '@zerodevx/svelte-toast';
interface Props {
children?: import('svelte').Snippet;
}
let { children }: Props = $props();
const options = { const options = {
pausable: true, pausable: true,
@ -8,7 +13,7 @@
}; };
</script> </script>
<slot /> {@render children?.()}
<SvelteToast {options} /> <SvelteToast {options} />
<div class="footer"> <div class="footer">
<FooterComponent /> <FooterComponent />

View File

@ -12,7 +12,11 @@
import { cubicInOut } from 'svelte/easing'; import { cubicInOut } from 'svelte/easing';
import { errorToast } from '$lib/errorToast'; import { errorToast } from '$lib/errorToast';
export let data: PageData; interface Props {
data: PageData;
}
let { data = $bindable() }: Props = $props();
interface FetchOptions { interface FetchOptions {
since?: string; since?: string;
@ -26,8 +30,8 @@
const refreshInterval = parseInt(PUBLIC_REFRESH_INTERVAL); const refreshInterval = parseInt(PUBLIC_REFRESH_INTERVAL);
let interval: ReturnType<typeof setTimeout> | null = null; let interval: ReturnType<typeof setTimeout> | null = null;
let moreOlderPostsAvailable = true; let moreOlderPostsAvailable = $state(true);
let loadingOlderPosts = false; let loadingOlderPosts = $state(false);
// Needed, so that edgeFly() can do its thing: // Needed, so that edgeFly() can do its thing:
// To determine whether a newly loaded post is older than the existing ones, is required to know what the oldest // To determine whether a newly loaded post is older than the existing ones, is required to know what the oldest
@ -152,7 +156,7 @@
</svelte:head> </svelte:head>
<h2>{PUBLIC_MASTODON_INSTANCE_DISPLAY_NAME} music list</h2> <h2>{PUBLIC_MASTODON_INSTANCE_DISPLAY_NAME} music list</h2>
<div class="wrapper"> <div class="wrapper">
<div /> <div></div>
<div class="posts"> <div class="posts">
{#if data.posts.length === 0} {#if data.posts.length === 0}
Sorry, no posts recommending music have been found yet Sorry, no posts recommending music have been found yet
@ -171,12 +175,12 @@
</div> </div>
{/each} {/each}
<LoadMoreComponent <LoadMoreComponent
on:loadOlderPosts={loadOlderPosts} {loadOlderPosts}
moreAvailable={moreOlderPostsAvailable} moreAvailable={moreOlderPostsAvailable}
isLoading={loadingOlderPosts} isLoading={loadingOlderPosts}
/> />
</div> </div>
<div /> <div></div>
</div> </div>
<style> <style>