From 7063eb77bfa680d1513c5f861bc4b2aba515d7c1 Mon Sep 17 00:00:00 2001 From: Sean Morley Date: Fri, 26 Jun 2026 21:34:11 -0400 Subject: [PATCH] Enhance AboutModal and AppVersionDisplay components - Added functionality to copy the app version to clipboard with user feedback via toasts. - Improved layout and styling of the AboutModal for better user experience. - Updated AppVersionDisplay to support different display variants. - Added new translations for the "Copy version" feature in the localization files. --- frontend/src/lib/components/AboutModal.svelte | 427 +++++++++++------- .../shared/AppVersionDisplay.svelte | 14 +- frontend/src/locales/en.json | 1 + 3 files changed, 262 insertions(+), 180 deletions(-) diff --git a/frontend/src/lib/components/AboutModal.svelte b/frontend/src/lib/components/AboutModal.svelte index 84e25cde..b4621771 100644 --- a/frontend/src/lib/components/AboutModal.svelte +++ b/frontend/src/lib/components/AboutModal.svelte @@ -2,13 +2,30 @@ import { createEventDispatcher } from 'svelte'; import { onMount } from 'svelte'; import { t } from 'svelte-i18n'; - import { copyrightYear, versionChangelog } from '$lib/config'; + import { copyrightYear, versionChangelog, appVersion } from '$lib/config'; + import { copyToClipboard } from '$lib/index'; + import { addToast } from '$lib/toasts'; import AppVersionDisplay from '$lib/components/shared/AppVersionDisplay.svelte'; + import CloseIcon from '~icons/mdi/close'; + import AccountIcon from '~icons/mdi/account-circle'; + import TagIcon from '~icons/mdi/tag-outline'; + import InformationIcon from '~icons/mdi/information-outline'; + import ScaleBalanceIcon from '~icons/mdi/scale-balance'; + import GitHubIcon from '~icons/mdi/github'; + import HeartIcon from '~icons/mdi/heart'; + import BookOpenIcon from '~icons/mdi/book-open-page-variant'; + import DiscordIcon from '~icons/mdi/discord'; + import OpenInNewIcon from '~icons/mdi/open-in-new'; + import ContentCopyIcon from '~icons/mdi/content-copy'; + import CheckIcon from '~icons/mdi/check'; + const dispatch = createEventDispatcher(); let modal: HTMLDialogElement; let integrations: Record | null = null; + let versionCopied = false; + let copyResetTimeout: ReturnType | undefined; onMount(async () => { modal = document.getElementById('about_modal') as HTMLDialogElement; @@ -21,6 +38,10 @@ } else { integrations = null; } + + return () => { + if (copyResetTimeout) clearTimeout(copyResetTimeout); + }; }); function close() { @@ -32,215 +53,271 @@ dispatch('close'); } } + + function handleBackdropClick(event: MouseEvent) { + if (event.target === modal) { + close(); + } + } + + async function copyVersion() { + try { + await copyToClipboard(appVersion); + versionCopied = true; + addToast('success', $t('adventures.copied_to_clipboard')); + if (copyResetTimeout) clearTimeout(copyResetTimeout); + copyResetTimeout = setTimeout(() => { + versionCopied = false; + }, 2000); + } catch { + addToast('error', $t('adventures.copy_failed')); + } + } - + + +