From 94d54f65bf5145aecceb1924460e8166bc515fff Mon Sep 17 00:00:00 2001 From: StroepWafel Date: Mon, 6 Apr 2026 14:48:03 +0930 Subject: [PATCH] feat: Unified portaled sign-in overlay Updated the sign-in overlay to be unified across the site, improving UX --- .../components/SignInToFavoriteModal.svelte | 56 ++++----- .../components/store/CloudHeader.svelte | 81 +------------ .../components/store/CloudLoginForm.svelte | 111 ++++++++++++++++++ .../components/store/ThemeCard.svelte | 25 ++-- .../components/store/ThemeGrid.svelte | 8 +- .../components/store/ThemeModal.svelte | 16 +-- src/interface/pages/store.svelte | 8 ++ src/seqta/ui/SettingsResizer.ts | 9 +- 8 files changed, 174 insertions(+), 140 deletions(-) create mode 100644 src/interface/components/store/CloudLoginForm.svelte diff --git a/src/interface/components/SignInToFavoriteModal.svelte b/src/interface/components/SignInToFavoriteModal.svelte index 24f21e1b..2f5f178f 100644 --- a/src/interface/components/SignInToFavoriteModal.svelte +++ b/src/interface/components/SignInToFavoriteModal.svelte @@ -1,29 +1,32 @@
{ if (e.target === e.currentTarget) onClose(); }} @@ -37,7 +40,7 @@
e.stopPropagation()} onkeydown={(e) => e.stopPropagation()} > @@ -45,32 +48,19 @@ Sign in to favorite themes -

- Sign in in the Theme Store to save favorites across devices, or create an account to get started. +

+ Sign in to the Theme Store to save favorites across devices, or create an account to get started.

-
+ + +
- - Create account - -
diff --git a/src/interface/components/store/CloudHeader.svelte b/src/interface/components/store/CloudHeader.svelte index 61775987..421b8dfd 100644 --- a/src/interface/components/store/CloudHeader.svelte +++ b/src/interface/components/store/CloudHeader.svelte @@ -1,11 +1,8 @@ + +{#if introText} +

+ {introText} +

+{/if} +
{ + e.preventDefault(); + handleLogin(); + }} +> + e.currentTarget.removeAttribute("readonly")} + class={inputClass} + /> + e.currentTarget.removeAttribute("readonly")} + class={inputClass} + /> + {#if error} +

{error}

+ {/if} + + + Create account + +
diff --git a/src/interface/components/store/ThemeCard.svelte b/src/interface/components/store/ThemeCard.svelte index 7b28a504..97dad4a3 100644 --- a/src/interface/components/store/ThemeCard.svelte +++ b/src/interface/components/store/ThemeCard.svelte @@ -2,16 +2,14 @@ import type { Theme } from '@/interface/types/Theme' import { fade } from 'svelte/transition'; import { onMount } from 'svelte'; - import SignInToFavoriteModal from '@/interface/components/SignInToFavoriteModal.svelte'; - - let { theme, onClick, toggleFavorite, isLoggedIn } = $props<{ + let { theme, onClick, toggleFavorite, isLoggedIn, onRequestSignIn } = $props<{ theme: Theme; onClick: () => void; toggleFavorite: (theme: Theme) => void; isLoggedIn: boolean; + onRequestSignIn?: () => void; }>(); let menuOpen = $state(false); - let showSignInModal = $state(false); let menuRef: HTMLDivElement; onMount(() => { @@ -34,14 +32,23 @@ if (isLoggedIn) { toggleFavorite(theme); } else { - showSignInModal = true; + onRequestSignIn?.(); } menuOpen = false; } -
-
+
+
- -{#if showSignInModal} - (showSignInModal = false)} /> -{/if} diff --git a/src/interface/components/store/ThemeGrid.svelte b/src/interface/components/store/ThemeGrid.svelte index b3523f67..c27f9b74 100644 --- a/src/interface/components/store/ThemeGrid.svelte +++ b/src/interface/components/store/ThemeGrid.svelte @@ -2,12 +2,13 @@ import type { Theme } from '@/interface/types/Theme' import ThemeCard from './ThemeCard.svelte'; - let { themes, searchTerm, setDisplayTheme, toggleFavorite, isLoggedIn } = $props<{ + let { themes, searchTerm, setDisplayTheme, toggleFavorite, isLoggedIn, onRequestSignIn } = $props<{ themes: Theme[]; searchTerm: string; setDisplayTheme: (theme: Theme) => void; toggleFavorite: (theme: Theme) => void; isLoggedIn: boolean; + onRequestSignIn?: () => void; }>(); let filteredThemes = $derived(themes.filter((theme: Theme) => @@ -23,12 +24,13 @@ onClick={() => setDisplayTheme(theme)} {toggleFavorite} {isLoggedIn} + {onRequestSignIn} /> {/each} {#if filteredThemes.length !== 0} - -
+ +
{'\uecb3'}
Got a Theme Idea? diff --git a/src/interface/components/store/ThemeModal.svelte b/src/interface/components/store/ThemeModal.svelte index cb340221..8a56a6ae 100644 --- a/src/interface/components/store/ThemeModal.svelte +++ b/src/interface/components/store/ThemeModal.svelte @@ -2,9 +2,7 @@ import type { Theme } from '@/interface/types/Theme' import { fade } from 'svelte/transition'; import { animate } from 'motion'; - import SignInToFavoriteModal from '@/interface/components/SignInToFavoriteModal.svelte'; - - let { theme, currentThemes, setDisplayTheme, onInstall, onRemove, allThemes, displayTheme, toggleFavorite, isLoggedIn } = $props<{ + let { theme, currentThemes, setDisplayTheme, onInstall, onRemove, allThemes, displayTheme, toggleFavorite, isLoggedIn, onRequestSignIn } = $props<{ theme: Theme | null; currentThemes: string[]; setDisplayTheme: (theme: Theme | null) => void; @@ -14,16 +12,16 @@ displayTheme: Theme | null; toggleFavorite?: (theme: Theme) => void; isLoggedIn?: boolean; + onRequestSignIn?: () => void; }>(); let installing = $state(false); - let showSignInModal = $state(false); let modalElement: HTMLElement; function handleFavoriteClick() { if (isLoggedIn && toggleFavorite && theme) { toggleFavorite(theme); } else { - showSignInModal = true; + onRequestSignIn?.(); } } @@ -159,8 +157,8 @@
{#each getRelatedThemes() as relatedTheme (relatedTheme.id)} -
- -{#if showSignInModal} - (showSignInModal = false)} /> -{/if} diff --git a/src/interface/pages/store.svelte b/src/interface/pages/store.svelte index 67de3f78..ce0da22f 100644 --- a/src/interface/pages/store.svelte +++ b/src/interface/pages/store.svelte @@ -16,6 +16,7 @@ import { loadBackground } from '@/seqta/ui/ImageBackgrounds' import Backgrounds from '../components/store/Backgrounds.svelte' import { cloudAuth } from '@/seqta/utils/CloudAuth' + import SignInToFavoriteModal from '../components/SignInToFavoriteModal.svelte' const themeManager = ThemeManager.getInstance(); let cloudLoggedIn = $state(cloudAuth.state.isLoggedIn); @@ -34,6 +35,7 @@ let error = $state(null); let selectedBackground = $state(null); + let showSignInOverlay = $state(false); const fetchCurrentThemes = async () => { const themes = await themeManager.getAvailableThemes(); @@ -169,6 +171,7 @@ {setDisplayTheme} {toggleFavorite} isLoggedIn={cloudLoggedIn} + onRequestSignIn={() => (showSignInOverlay = true)} /> {#if displayTheme} @@ -180,6 +183,7 @@ {setDisplayTheme} {toggleFavorite} isLoggedIn={cloudLoggedIn} + onRequestSignIn={() => (showSignInOverlay = true)} onInstall={async () => { if (displayTheme) { await themeManager.downloadTheme(displayTheme); @@ -204,4 +208,8 @@ {/if}
+ + {#if showSignInOverlay} + (showSignInOverlay = false)} /> + {/if}
\ No newline at end of file diff --git a/src/seqta/ui/SettingsResizer.ts b/src/seqta/ui/SettingsResizer.ts index af768855..85de86e1 100644 --- a/src/seqta/ui/SettingsResizer.ts +++ b/src/seqta/ui/SettingsResizer.ts @@ -18,12 +18,9 @@ export class SettingsResizer { if (!iframePopup) return; const viewportHeight = window.innerHeight; - const idealHeight = viewportHeight - 80 - 15; // -80px for the top of the popup + const rawIdeal = viewportHeight - 80 - 15; // room below top chrome + const idealHeight = Math.min(Math.max(rawIdeal, 280), 600); - if (idealHeight > 600) { - iframePopup.style.height = "600px"; - } else { - iframePopup.style.height = `${idealHeight}px`; - } + iframePopup.style.height = `${idealHeight}px`; } }