diff --git a/src/App.svelte b/src/App.svelte index aa755b043..513c9b4a9 100644 --- a/src/App.svelte +++ b/src/App.svelte @@ -59,7 +59,7 @@ } }); - $: document.documentElement.setAttribute("data-theme", $theme); + $effect(() => document.documentElement.setAttribute("data-theme", $theme)); {#if $activeRouteStore.resource === "booting"} diff --git a/src/components/Avatar.svelte b/src/components/Avatar.svelte index 7819ff642..e866252a4 100644 --- a/src/components/Avatar.svelte +++ b/src/components/Avatar.svelte @@ -1,7 +1,11 @@ - +
import type { Snippet } from "svelte"; - export let children: Snippet; - export let variant: "primary" | "secondary" | "ghost"; - export let onclick: (() => void) | undefined = undefined; + interface Props { + children: Snippet; + variant: "primary" | "secondary" | "ghost"; + onclick?: () => void; + disabled?: boolean; + active?: boolean; + flatLeft?: boolean; + flatRight?: boolean; + } - export let disabled: boolean = false; - export let active: boolean = false; + const { + children, + variant, + onclick = undefined, + disabled = false, + active = false, + flatLeft = false, + flatRight = false, + }: Props = $props(); - export let flatLeft: boolean = false; - export let flatRight: boolean = false; - - $: style = + const style = $derived( `--button-color-1: var(--color-fill-${variant});` + - `--button-color-2: var(--color-fill-${variant}-hover);` + - `--button-color-3: var(--color-fill-${variant}-shade);` + - // The ghost colors are called --color-fill-counter and --color-fill-counter-emphasized. - `--button-color-4: var(--color-fill${variant === "ghost" ? "" : `-${variant}`}-counter)`; + `--button-color-2: var(--color-fill-${variant}-hover);` + + `--button-color-3: var(--color-fill-${variant}-shade);` + + // The ghost colors are called --color-fill-counter and --color-fill-counter-emphasized. + `--button-color-4: var(--color-fill${variant === "ghost" ? "" : `-${variant}`}-counter)`, + ); - +
| undefined = undefined; - export let caption = "commented"; - export let timestamp: number; - export let lastEdit: Edit | undefined = undefined; - export let disallowEmptyBody: boolean = false; + interface Props { + actions?: Snippet; + id?: string; + rid: string; + author: Author; + body: string; + reactions?: Reaction[]; + embeds?: Map; + caption?: string; + timestamp: number; + lastEdit?: Edit; + disallowEmptyBody?: boolean; + editComment?: (body: string, embeds: Embed[]) => Promise; + reactOnComment?: (authors: Author[], reaction: string) => Promise; + } - export let editComment: - | ((body: string, embeds: Embed[]) => Promise) - | undefined = undefined; - export let reactOnComment: - | ((authors: Author[], reaction: string) => Promise) - | undefined = undefined; + /* eslint-disable prefer-const */ + let { + actions, + id, + rid, + author, + body = $bindable(), + reactions, + embeds, + caption = "commented", + timestamp, + lastEdit, + disallowEmptyBody = false, + editComment, + reactOnComment, + }: Props = $props(); + /* eslint-enable prefer-const */ - let state: "read" | "edit" | "submit" = "read"; + let state: "read" | "edit" | "submit" = $state("read"); async function toggleEdit() { if (state === "read") { @@ -136,7 +151,7 @@ popoverPositionRight="0" popoverPositionBottom="1.5rem" {reactions} - on:select={async ({ detail: { authors, emoji } }) => { + select={async ({ authors, emoji }) => { try { await reactOnComment(authors, emoji); } finally { @@ -169,7 +184,7 @@ submitInProgress={state === "submit"} submitCaption="Save" placeholder="Leave a comment" - on:submit={async ({ detail: { comment, embeds } }) => { + submit={async ({ comment, embeds }) => { state = "submit"; try { await editComment(comment, Array.from(embeds.values())); @@ -177,7 +192,7 @@ state = "read"; } }} - on:close={async () => { + close={async () => { body = body; await tick(); state = "read"; @@ -199,7 +214,7 @@ popoverPositionLeft="0" popoverPositionBottom="1.5rem" {reactions} - on:select={async ({ detail: { authors, emoji } }) => { + select={async ({ authors, emoji }) => { try { await reactOnComment(authors, emoji); } finally { diff --git a/src/components/CommentToggleInput.svelte b/src/components/CommentToggleInput.svelte index 027355060..b32b217ce 100644 --- a/src/components/CommentToggleInput.svelte +++ b/src/components/CommentToggleInput.svelte @@ -4,17 +4,33 @@ import ExtendedTextarea from "@app/components/ExtendedTextarea.svelte"; import Border from "./Border.svelte"; - export let rid: string; - export let placeholder: string | undefined = undefined; - export let focus: boolean = false; - export let submit: (comment: string, embeds: Embed[]) => Promise; - export let onclose: (() => void) | undefined = undefined; - export let onexpand: (() => void) | undefined = undefined; - export let disallowEmptyBody: boolean = false; + interface Props { + rid: string; + placeholder?: string; + focus?: boolean; + submit: (comment: string, embeds: Embed[]) => Promise; + onclose?: () => void; + onexpand?: () => void; + disallowEmptyBody?: boolean; + } - let state: "collapsed" | "expanded" | "submit"; + /* eslint-disable prefer-const */ + let { + rid, + placeholder, + focus = false, + submit, + onclose, + onexpand, + disallowEmptyBody = false, + }: Props = $props(); + /* eslint-enable prefer-const */ - $: state = onclose !== undefined ? "expanded" : "collapsed"; + let state: "collapsed" | "expanded" | "submit" | undefined = $state(); + + $effect(() => { + state = onclose !== undefined ? "expanded" : "collapsed"; + }); - +
+ {onclick}> {@render children()}
diff --git a/src/components/ExtendedTextarea.svelte b/src/components/ExtendedTextarea.svelte index ff5e65797..d63d13b53 100644 --- a/src/components/ExtendedTextarea.svelte +++ b/src/components/ExtendedTextarea.svelte @@ -2,8 +2,6 @@ import type { ComponentProps } from "svelte"; import type { Embed } from "@bindings/cob/thread/Embed"; - import { createEventDispatcher } from "svelte"; - import * as utils from "@app/lib/utils"; import Button from "./Button.svelte"; @@ -12,39 +10,58 @@ import Textarea from "./Textarea.svelte"; import OutlineButton from "./OutlineButton.svelte"; - export let rid: string; - export let placeholder: string = "Leave your comment"; - export let submitCaption: string = "Comment"; - export let focus: boolean = false; - export let inline: boolean = false; - export let body: string = ""; - export let embeds: Map = new Map(); - export let submitInProgress: boolean = false; - export let disallowEmptyBody: boolean = false; - export let isValid: () => boolean = () => { - return true; - }; - export let stylePadding: string | undefined = undefined; - export let borderVariant: ComponentProps diff --git a/src/components/Thread.svelte b/src/components/Thread.svelte index 71c208896..8d25b6ae8 100644 --- a/src/components/Thread.svelte +++ b/src/components/Thread.svelte @@ -13,25 +13,38 @@ import ExtendedTextarea from "./ExtendedTextarea.svelte"; import Icon from "@app/components/Icon.svelte"; - export let thread: { - root: Comment; - replies: Comment[]; - }; - export let rid: string; - export let canEditComment: (author: string) => true | undefined; - export let editComment: - | ((commentId: string, body: string, embeds: Embed[]) => Promise) - | undefined; - export let createReply: - | ((commentId: string, comment: string, embeds: Embed[]) => Promise) - | undefined; - export let reactOnComment: - | (( - commentId: string, - authors: Author[], - reaction: string, - ) => Promise) - | undefined; + interface Props { + thread: { + root: Comment; + replies: Comment[]; + }; + rid: string; + canEditComment: (author: string) => true | undefined; + editComment?: ( + commentId: string, + body: string, + embeds: Embed[], + ) => Promise; + createReply?: ( + commentId: string, + comment: string, + embeds: Embed[], + ) => Promise; + reactOnComment?: ( + commentId: string, + authors: Author[], + reaction: string, + ) => Promise; + } + + const { + thread, + rid, + canEditComment, + editComment, + createReply, + reactOnComment, + }: Props = $props(); async function toggleReply() { showReplyForm = !showReplyForm; @@ -46,16 +59,16 @@ }); } - let showReplyForm = false; - let submitInProgress = false; + let showReplyForm = $state(false); + let submitInProgress = $state(false); - $: root = thread.root; - $: replies = thread.replies; - - $: style = + const root = $derived(thread.root); + const replies = $derived(thread.replies); + const style = $derived( replies.length > 0 ? "--local-clip-path: var(--2px-top-corner-fill)" - : "--local-clip-path: var(--2px-corner-fill)"; + : "--local-clip-path: var(--2px-corner-fill)", + );