summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorWolfgang Müller2024-07-13 17:29:33 +0200
committerWolfgang Müller2024-07-22 14:08:40 +0200
commitd297c6310a6a4db8dd7cc3efe6ff59620deadcc0 (patch)
treeb47256337a095cef9df5b6ed9f9dfa5885eab79e
parentf530348de4aa5db05eff44c801af6251200372cf (diff)
downloadhircine-d297c6310a6a4db8dd7cc3efe6ff59620deadcc0.tar.gz
frontend/reader: Show loading indicators
Sometimes images may not load fast enough, resulting in the app being seemingly stuck displaying the same sets of images. Use a timeout to detect when images take too long to load and show a spinner instead.
-rw-r--r--frontend/.eslintrc.cjs3
-rw-r--r--frontend/src/lib/reader/Reader.svelte2
-rw-r--r--frontend/src/lib/reader/ReaderPage.svelte35
3 files changed, 35 insertions, 5 deletions
diff --git a/frontend/.eslintrc.cjs b/frontend/.eslintrc.cjs
index c204ebe..352fa79 100644
--- a/frontend/.eslintrc.cjs
+++ b/frontend/.eslintrc.cjs
@@ -34,7 +34,8 @@ module.exports = {
'@typescript-eslint/no-unsafe-assignment': 'off',
'@typescript-eslint/no-unsafe-call': 'off',
'@typescript-eslint/no-unsafe-enum-comparison': 'off',
- '@typescript-eslint/no-unsafe-member-access': 'off'
+ '@typescript-eslint/no-unsafe-member-access': 'off',
+ 'no-undef': 'off'
}
},
{
diff --git a/frontend/src/lib/reader/Reader.svelte b/frontend/src/lib/reader/Reader.svelte
index 0b1450a..a8f9440 100644
--- a/frontend/src/lib/reader/Reader.svelte
+++ b/frontend/src/lib/reader/Reader.svelte
@@ -24,7 +24,7 @@
</aside>
{/if}
<main class="relative flex grow">
- <div class="absolute flex w-full p-1 text-lg [&>*:last-child]:ml-auto">
+ <div class="absolute z-10 flex w-full p-1 text-lg [&>*:last-child]:ml-auto">
{#if $$slots.sidebar}
<ReaderMenuButton />
{/if}
diff --git a/frontend/src/lib/reader/ReaderPage.svelte b/frontend/src/lib/reader/ReaderPage.svelte
index fb3e780..c86414d 100644
--- a/frontend/src/lib/reader/ReaderPage.svelte
+++ b/frontend/src/lib/reader/ReaderPage.svelte
@@ -1,19 +1,48 @@
<script lang="ts">
import type { PageFragment } from '$gql/graphql';
+ import Spinner from '$lib/components/Spinner.svelte';
import { src } from '$lib/Utils';
+ import { onDestroy } from 'svelte';
export let page: PageFragment;
+
+ let loading = false;
+ let loadingTimeout: NodeJS.Timeout;
+ let lastId = -1;
+
+ $: page.id, updateLoadingState();
+
+ function updateLoadingState() {
+ if (page.id === lastId) return;
+ lastId = page.id;
+
+ loadingTimeout = setTimeout(() => (loading = true), 150);
+ }
+
+ function finishLoading() {
+ clearTimeout(loadingTimeout);
+ loading = false;
+ }
+
+ onDestroy(() => clearTimeout(loadingTimeout));
</script>
<!-- svelte-ignore a11y-click-events-have-key-events -->
<!-- svelte-ignore a11y-no-static-element-interactions -->
-<div class="flex grow" on:click>
+<div class="relative flex grow" on:click>
+ <div class="absolute right-0 top-0 z-0 h-full w-full">
+ {#if loading}
+ <Spinner />
+ {/if}
+ </div>
<img
- class="h-auto w-auto object-contain"
+ class="h-auto w-auto object-contain transition-opacity duration-200"
+ class:opacity-0={loading}
width={page.image.width}
height={page.image.height}
src={src(page.image, 'full')}
- alt={page.path}
+ alt=""
+ on:load={finishLoading}
/>
</div>