feat: add animated logo as default logo

This commit is contained in:
Elias Schneider
2026-08-08 20:50:37 +02:00
parent 987d1a8b59
commit 0c9a03e519
16 changed files with 367 additions and 87 deletions
@@ -36,8 +36,8 @@
}
async function updateImages(
logoLight: File | undefined,
logoDark: File | undefined,
logoLight: File | null | undefined,
logoDark: File | null | undefined,
logoEmail: File | undefined,
defaultProfilePicture: File | null | undefined,
backgroundImage: File | null | undefined,
@@ -45,13 +45,19 @@
) {
const faviconPromise = favicon ? appConfigService.updateFavicon(favicon) : Promise.resolve();
const lightLogoPromise = logoLight
? appConfigService.updateLogo(logoLight, true)
: Promise.resolve();
const lightLogoPromise =
logoLight === null
? appConfigService.deleteLogo(true)
: logoLight
? appConfigService.updateLogo(logoLight, true)
: Promise.resolve();
const darkLogoPromise = logoDark
? appConfigService.updateLogo(logoDark, false)
: Promise.resolve();
const darkLogoPromise =
logoDark === null
? appConfigService.deleteLogo(false)
: logoDark
? appConfigService.updateLogo(logoDark, false)
: Promise.resolve();
const emailLogoPromise = logoEmail
? appConfigService.updateEmailLogo(logoEmail)
@@ -2,8 +2,10 @@
import FileInput from '$lib/components/form/file-input.svelte';
import { Button } from '$lib/components/ui/button';
import * as Field from '$lib/components/ui/field';
import { m } from '$lib/paraglide/messages';
import { cn } from '$lib/utils/style';
import { LucideImageOff, LucideUpload, LucideX } from '@lucide/svelte';
import type { Snippet } from 'svelte';
import type { HTMLAttributes } from 'svelte/elements';
let {
@@ -12,6 +14,7 @@
label,
image = $bindable(),
imageURL,
fallback,
accept = 'image/png, image/jpeg, image/svg+xml, image/gif, image/webp, image/avif, image/heic',
forceColorScheme,
isResetable = false,
@@ -23,6 +26,7 @@
label: string;
image: File | null | undefined;
imageURL: string;
fallback?: Snippet;
forceColorScheme?: 'light' | 'dark';
accept?: string;
isResetable?: boolean;
@@ -70,7 +74,11 @@
imageClass
)}
>
<LucideImageOff class="text-muted-foreground" />
{#if fallback}
{@render fallback()}
{:else}
<LucideImageOff class="text-muted-foreground" />
{/if}
</div>
{:else}
<img
@@ -97,6 +105,7 @@
{#if isResetable && isImageSet}
<Button
size="icon"
aria-label={`${m.reset_to_default()} ${label}`}
onclick={(e) => {
e.stopPropagation();
onReset();
@@ -1,4 +1,5 @@
<script lang="ts">
import Logo from '$lib/components/logo.svelte';
import Button from '$lib/components/ui/button/button.svelte';
import { m } from '$lib/paraglide/messages';
import {
@@ -13,8 +14,8 @@
callback
}: {
callback: (
logoLight: File | undefined,
logoDark: File | undefined,
logoLight: File | null | undefined,
logoDark: File | null | undefined,
logoEmail: File | undefined,
defaultProfilePicture: File | null | undefined,
backgroundImage: File | null | undefined,
@@ -22,8 +23,8 @@
) => void;
} = $props();
let logoLight = $state<File | undefined>();
let logoDark = $state<File | undefined>();
let logoLight = $state<File | null | undefined>();
let logoDark = $state<File | null | undefined>();
let logoEmail = $state<File | undefined>();
let defaultProfilePicture = $state<File | null | undefined>();
let backgroundImage = $state<File | null | undefined>();
@@ -31,8 +32,18 @@
let defaultProfilePictureSet = $state(true);
let backgroundImageSet = $state(true);
let logoLightSet = $state(true);
let logoDarkSet = $state(true);
</script>
{#snippet lightLogoFallback()}
<Logo defaultOnly colorScheme="light" class="size-full" />
{/snippet}
{#snippet darkLogoFallback()}
<Logo defaultOnly colorScheme="dark" class="size-full" />
{/snippet}
<div class="flex flex-col gap-8">
<ApplicationImage
id="favicon"
@@ -48,7 +59,10 @@
label={m.light_mode_logo()}
bind:image={logoLight}
imageURL={cachedApplicationLogo.getUrl(true)}
fallback={lightLogoFallback}
forceColorScheme="light"
isResetable
bind:isImageSet={logoLightSet}
/>
<ApplicationImage
id="logo-dark"
@@ -56,7 +70,10 @@
label={m.dark_mode_logo()}
bind:image={logoDark}
imageURL={cachedApplicationLogo.getUrl(false)}
fallback={darkLogoFallback}
forceColorScheme="dark"
isResetable
bind:isImageSet={logoDarkSet}
/>
<ApplicationImage
id="logo-email"