mirror of
https://github.com/pocket-id/pocket-id.git
synced 2026-04-13 10:06:36 +00:00
fix: prevent flickering if no background image is set on login page
This commit is contained in:
@@ -1,7 +1,5 @@
|
|||||||
<script module lang="ts">
|
<script module lang="ts">
|
||||||
// Persist the last failing background image URL across route remounts so
|
let backgroundImageExists = $state<boolean | undefined>(undefined);
|
||||||
// login pages without a background do not briefly retry the image and stutter.
|
|
||||||
let persistedMissingBackgroundImageUrl: string | undefined;
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
@@ -11,8 +9,9 @@
|
|||||||
import appConfigStore from '$lib/stores/application-configuration-store';
|
import appConfigStore from '$lib/stores/application-configuration-store';
|
||||||
import { cachedBackgroundImage } from '$lib/utils/cached-image-util';
|
import { cachedBackgroundImage } from '$lib/utils/cached-image-util';
|
||||||
import { cn } from '$lib/utils/style';
|
import { cn } from '$lib/utils/style';
|
||||||
import { type Snippet } from 'svelte';
|
import { onMount, type Snippet } from 'svelte';
|
||||||
import { MediaQuery } from 'svelte/reactivity';
|
import { MediaQuery } from 'svelte/reactivity';
|
||||||
|
import { fade } from 'svelte/transition';
|
||||||
import * as Card from './ui/card';
|
import * as Card from './ui/card';
|
||||||
|
|
||||||
let {
|
let {
|
||||||
@@ -23,32 +22,21 @@
|
|||||||
showAlternativeSignInMethodButton?: boolean;
|
showAlternativeSignInMethodButton?: boolean;
|
||||||
} = $props();
|
} = $props();
|
||||||
|
|
||||||
let missingBackgroundImageUrl = $state<string | undefined>(persistedMissingBackgroundImageUrl);
|
|
||||||
let loadedBackgroundImageUrl = $state<string | undefined>();
|
|
||||||
let isInitialLoad = $state(false);
|
let isInitialLoad = $state(false);
|
||||||
let backgroundImageUrl = $derived(cachedBackgroundImage.getUrl());
|
let animate = $derived(isInitialLoad && !$appConfigStore.disableAnimations);
|
||||||
let imageError = $derived(missingBackgroundImageUrl === backgroundImageUrl);
|
|
||||||
let imageLoaded = $derived(loadedBackgroundImageUrl === backgroundImageUrl);
|
onMount(async () => {
|
||||||
let animate = $derived(isInitialLoad && imageLoaded && !$appConfigStore.disableAnimations);
|
fetch(cachedBackgroundImage.getUrl(), {
|
||||||
|
method: 'HEAD'
|
||||||
|
})
|
||||||
|
.then(async (res) => (backgroundImageExists = res.ok))
|
||||||
|
.catch(() => (backgroundImageExists = false));
|
||||||
|
});
|
||||||
|
|
||||||
afterNavigate((e) => {
|
afterNavigate((e) => {
|
||||||
isInitialLoad = !e?.from?.url;
|
isInitialLoad = !e?.from?.url;
|
||||||
});
|
});
|
||||||
|
|
||||||
function onBackgroundImageLoad() {
|
|
||||||
loadedBackgroundImageUrl = backgroundImageUrl;
|
|
||||||
if (persistedMissingBackgroundImageUrl === backgroundImageUrl) {
|
|
||||||
persistedMissingBackgroundImageUrl = undefined;
|
|
||||||
missingBackgroundImageUrl = undefined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function onBackgroundImageError() {
|
|
||||||
loadedBackgroundImageUrl = undefined;
|
|
||||||
persistedMissingBackgroundImageUrl = backgroundImageUrl;
|
|
||||||
missingBackgroundImageUrl = backgroundImageUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
const isDesktop = new MediaQuery('min-width: 1024px');
|
const isDesktop = new MediaQuery('min-width: 1024px');
|
||||||
let alternativeSignInButton = $state({
|
let alternativeSignInButton = $state({
|
||||||
href: '/login/alternative',
|
href: '/login/alternative',
|
||||||
@@ -70,11 +58,14 @@
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if isDesktop.current}
|
{#if backgroundImageExists === undefined}
|
||||||
<div class="h-screen items-center overflow-hidden text-center flex justify-center">
|
<div class="bg-background h-screen"></div>
|
||||||
|
{:else if isDesktop.current}
|
||||||
|
<div in:fade={{ duration: 150 }} class="h-screen items-center overflow-hidden text-center">
|
||||||
<div
|
<div
|
||||||
class="flex h-full w-[650px] 2xl:w-[800px] p-16 {cn(
|
class="relative z-10 flex h-full p-16 {cn(
|
||||||
showAlternativeSignInMethodButton && 'pb-0'
|
showAlternativeSignInMethodButton && 'pb-0',
|
||||||
|
backgroundImageExists && 'w-[650px] 2xl:w-[800px]'
|
||||||
)}"
|
)}"
|
||||||
>
|
>
|
||||||
<div class="flex h-full w-full flex-col overflow-hidden">
|
<div class="flex h-full w-full flex-col overflow-hidden">
|
||||||
@@ -94,15 +85,17 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if !imageError}
|
{#if backgroundImageExists}
|
||||||
<!-- Background image -->
|
<!-- Background image -->
|
||||||
<div class="m-6 flex h-[calc(100vh-3rem)] overflow-hidden rounded-[40px]">
|
<div
|
||||||
|
class="absolute top-0 right-0 left-500px bottom-0 z-0 overflow-hidden rounded-[40px] m-6"
|
||||||
|
>
|
||||||
<img
|
<img
|
||||||
src={backgroundImageUrl}
|
src={cachedBackgroundImage.getUrl()}
|
||||||
class="h-full object-cover {cn(animate && 'animate-bg-zoom')}"
|
class="{cn(
|
||||||
|
animate && 'animate-bg-zoom'
|
||||||
|
)} h-screen object-cover w-[calc(100vw-650px)] 2xl:w-[calc(100vw-800px)]"
|
||||||
alt={m.login_background()}
|
alt={m.login_background()}
|
||||||
onload={onBackgroundImageLoad}
|
|
||||||
onerror={onBackgroundImageError}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
@@ -112,9 +105,14 @@
|
|||||||
class="flex h-screen items-center justify-center bg-cover bg-center text-center"
|
class="flex h-screen items-center justify-center bg-cover bg-center text-center"
|
||||||
style="background-image: url({cachedBackgroundImage.getUrl()});"
|
style="background-image: url({cachedBackgroundImage.getUrl()});"
|
||||||
>
|
>
|
||||||
<Card.Root class="mx-3 w-full max-w-md">
|
<Card.Root
|
||||||
|
class={{
|
||||||
|
'mx-3 w-full max-w-md': true,
|
||||||
|
'bg-transparent border-0': !backgroundImageExists
|
||||||
|
}}
|
||||||
|
>
|
||||||
<Card.CardContent
|
<Card.CardContent
|
||||||
class="px-4 py-10 sm:p-10 {showAlternativeSignInMethodButton ? 'pb-3 sm:pb-3' : ''}"
|
class="px-4 py-10 sm:p-10 {showAlternativeSignInMethodButton ? 'pb-3 sm:pb-3' : ''} "
|
||||||
>
|
>
|
||||||
{@render children()}
|
{@render children()}
|
||||||
{#if showAlternativeSignInMethodButton}
|
{#if showAlternativeSignInMethodButton}
|
||||||
|
|||||||
Reference in New Issue
Block a user