Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Svelte 5 #291

Merged
merged 9 commits into from
Jan 9, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
888 changes: 169 additions & 719 deletions frontend/package-lock.json

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"@eslint/js": "^9.12.0",
"@sveltejs/adapter-static": "^3.0.6",
"@sveltejs/kit": "^2.7.2",
"@sveltejs/vite-plugin-svelte": "^3.1.2",
"@sveltejs/vite-plugin-svelte": "^4.0.0",
"@types/dompurify": "^3.0.5",
"@types/eslint": "^9.6.1",
"@typescript-eslint/eslint-plugin": "^8.8.1",
Expand All @@ -33,8 +33,8 @@
"stylelint": "^16.10.0",
"stylelint-config-html": "^1.1.0",
"stylelint-config-standard": "^36.0.1",
"svelte": "^4.2.19",
"svelte-check": "^4.1.0",
"svelte": "^5.0.0",
"svelte-check": "^4.0.5",
"tslib": "^2.8.0",
"typescript": "^5.6.3",
"vite": "^5.4.11",
Expand Down
18 changes: 12 additions & 6 deletions frontend/src/lib/components/dashboard/AdminDashboard.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@
import UserTab from './UserTab.svelte';
import ServerTab from './ServerTab.svelte';

export let dialog: HTMLDialogElement;
let selectedTab = 0;
interface Props {
dialog: HTMLDialogElement;
}

let { dialog = $bindable() }: Props = $props();
let selectedTab = $state(0);
let tabs = [
{ name: 'User Management', id: 0, component: UserTab },
{ name: 'Group Management', id: 1, component: GroupTab },
Expand All @@ -16,20 +20,22 @@
const target = e.target as HTMLElement;
selectedTab = Number(target.parentElement!.id);
}

const SvelteComponent = $derived(tabs[selectedTab].component);
</script>

<dialog bind:this={dialog} class="container">
<ul class="tab-menu">
<li>
<svg
on:click={() => {
onclick={() => {
dialog.close();
}}
xmlns="http://www.w3.org/2000/svg"
height="1.5rem"
viewBox="0 -960 960 960"
width="1.5rem"
on:keydown={() => {
onkeydown={() => {
dialog.close();
}}
role="none"
Expand All @@ -42,11 +48,11 @@
</li>
{#each tabs as tab}
<li class={selectedTab == tab.id ? 'selected-tab' : ''} id={tab.id.toString()}>
<button on:click={tabSelectHandler}>{tab.name}</button>
<button onclick={tabSelectHandler}>{tab.name}</button>
</li>
{/each}
</ul>
<svelte:component this={tabs[selectedTab].component} />
<SvelteComponent />
</dialog>

<style>
Expand Down
22 changes: 11 additions & 11 deletions frontend/src/lib/components/dashboard/GroupTab.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@
import { addPermissionToGroup, deleteGroup, removePermissionFromGroup } from '$lib/groups';
import { type GroupListEntry } from '$lib/groups';

let groups: GroupListEntry[] = [];
let selectedGroup = 1;
let groups: GroupListEntry[] = $state([]);
let selectedGroup = $state(1);

let showNewGroupInput = false;
let newGroupInput: HTMLInputElement;
let showNewGroupInput = $state(false);
let newGroupInput: HTMLInputElement = $state();

function userSelectHandler(e: MouseEvent) {
const target = e.target as HTMLElement;
Expand Down Expand Up @@ -56,15 +56,15 @@
<!-- Prevent people from modifying the permissions on the admin group -->
{#if group.name !== 'Admin'}
<li class={selectedGroup == index ? 'selected-group' : ''} id={index.toString()}>
<button on:click={userSelectHandler}>
<button onclick={userSelectHandler}>
<!-- TODO: trashcan on right, label on center -->
<span>{group.name}</span>
<svg
on:click={async () => {
onclick={async () => {
await deleteGroup(group);
groups = groups.filter((g) => g.name !== group.name);
}}
on:keydown={async () => {
onkeydown={async () => {
await deleteGroup(group);
groups = groups.filter((g) => g.name !== group.name);
}}
Expand All @@ -87,10 +87,10 @@
<li>
<input
bind:this={newGroupInput}
on:blur={() => {
onblur={() => {
showNewGroupInput = false;
}}
on:keydown={async (e) => {
onkeydown={async (e) => {
if (e.key === 'Enter') {
// TODO: migrate to a createGroup function
const newGroup = await (
Expand Down Expand Up @@ -119,7 +119,7 @@
<!-- The "new group" button -->
<li>
<button
on:click={async () => {
onclick={async () => {
showNewGroupInput = true;
await tick();
newGroupInput.focus();
Expand All @@ -135,7 +135,7 @@
<li>
<label for={permission} class="checkbox-label">
<input
on:change={checkboxToggleHandler}
onchange={checkboxToggleHandler}
id={permission}
type="checkbox"
name={permission}
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/lib/components/dashboard/ServerTab.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<!-- Admin Dashboard -->
<div>
<button
on:click={async () => {
onclick={async () => {
const tid = addToast({
message: `Cloning fresh repository, this may take a while...`,
type: ToastType.Info,
Expand Down
12 changes: 6 additions & 6 deletions frontend/src/lib/components/dashboard/UserTab.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import { onMount } from 'svelte';

// const allGroups = [{'Admin', 'Group 1', 'Group 2', 'Group 3'];
let allGroups: Group[] = [
let allGroups: Group[] = $state([
{
id: 1,
name: 'Admin'
Expand All @@ -15,9 +15,9 @@
id: 2,
name: 'Mock group 2'
}
];
let users: User[] = [];
let selectedUser = 0;
]);
let users: User[] = $state([]);
let selectedUser = $state(0);
function userSelectHandler(e: MouseEvent) {
const target = e.target as HTMLElement;
selectedUser = Number(target.parentElement!.id);
Expand Down Expand Up @@ -73,7 +73,7 @@
<li class="header"><u>Users</u></li>
{#each users.entries() as [index, user]}
<li class={selectedUser == index ? 'selected-user' : ''} id={index.toString()}>
<button on:click={userSelectHandler}>
<button onclick={userSelectHandler}>
<!-- <svg
xmlns="http://www.w3.org/2000/svg"
height="24px"
Expand All @@ -97,7 +97,7 @@
<li>
<label for={group.name} class="checkbox-label">
<input
on:change={checkboxToggleHandler}
onchange={checkboxToggleHandler}
id={group.name}
type="checkbox"
name={group.name}
Expand Down
69 changes: 37 additions & 32 deletions frontend/src/lib/components/editors/AssetEditor.svelte
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
<script lang="ts">
import { run } from 'svelte/legacy';

import type { INode } from '$lib/types';
import { apiAddress, assetTree } from '$lib/main';
import { addToast, ToastType } from '$lib/toast';
Expand All @@ -7,17 +9,13 @@
import ConfirmationDialogue from '../elements/ConfirmationDialogue.svelte';
import LoadingIcon from '../elements/LoadingIcon.svelte';

export let assetFolderPath = '';
let uploadedFiles: FileList;

// Whenever the list of uploaded files changes, call the handler
$: {
// This shouldn't be an issue when we switch to svelte 5, so ignoring it for now
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
uploadedFiles;
fileUploadHandler();
interface Props {
assetFolderPath?: string;
}

let { assetFolderPath = $bindable('') }: Props = $props();
let uploadedFiles: FileList = $state();

async function fileUploadHandler() {
if (uploadedFiles && uploadedFiles.length > 0) {
loadingIconVisible = true;
Expand Down Expand Up @@ -52,11 +50,11 @@
* When an image is being displayed in "full screen mode", this is the path of that
* image. Otherwise, it's an empty string.
*/
let fullScreenImagePath = '';
let fullScreenImage: HTMLImageElement;
let width = 0;
let height = 0;
let fullScreenHttpInfo: Response | undefined;
let fullScreenImagePath = $state('');
let fullScreenImage: HTMLImageElement = $state();
let width = $state(0);
let height = $state(0);
let fullScreenHttpInfo: Response | undefined = $state();
// So basically, Svelte doesn't understand updates the browser makes to an image object,
// so it doesn't react to changes. This is fixed by manually starting a polling cycle
// that updates the image resolution when the image has finished loading
Expand All @@ -68,21 +66,11 @@
setTimeout(cb, 50);
}
}
$: {
if (fullScreenImagePath !== '') {
fetch(`${apiAddress}/api/asset/${fullScreenImagePath}`).then(async (r) => {
fullScreenHttpInfo = r;
const objectUrl = URL.createObjectURL(await r.blob());
fullScreenImage.src = objectUrl;
});
}
cb();
}

let tree: INode = {
let tree: INode = $state({
name: 'loading',
children: []
};
});

assetTree.subscribe(async (t) => {
fullScreenImagePath = '';
Expand All @@ -96,8 +84,25 @@
tree = t;
});

let deletionConfirmationVisible = false;
let loadingIconVisible = false;
let deletionConfirmationVisible = $state(false);
let loadingIconVisible = $state(false);
// Whenever the list of uploaded files changes, call the handler
run(() => {
// This shouldn't be an issue when we switch to svelte 5, so ignoring it for now
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
uploadedFiles;
fileUploadHandler();
});
run(() => {
if (fullScreenImagePath !== '') {
fetch(`${apiAddress}/api/asset/${fullScreenImagePath}`).then(async (r) => {
fullScreenHttpInfo = r;
const objectUrl = URL.createObjectURL(await r.blob());
fullScreenImage.src = objectUrl;
});
}
cb();
});
</script>

{#if loadingIconVisible}
Expand All @@ -108,10 +113,10 @@
<div
class="fullscreen-backdrop"
transition:blur={{ duration: 100 }}
on:click={() => {
onclick={() => {
fullScreenImagePath = '';
}}
on:keydown={() => {
onkeydown={() => {
fullScreenImagePath = '';
}}
role="none"
Expand Down Expand Up @@ -148,7 +153,7 @@
</p>
{/if}
<button
on:click={() => {
onclick={() => {
deletionConfirmationVisible = true;
}}
class="delete-button"
Expand Down Expand Up @@ -209,7 +214,7 @@
<div class="asset-catalogue">
{#each tree.children.find((n) => n.name === assetFolderPath)?.children ?? [] as asset}
<button
on:click={() => {
onclick={() => {
fullScreenImagePath = `${assetFolderPath}/${asset.name}`;
}}
class="asset"
Expand Down
Loading
Loading