Lazy-loading images on dashboard

This commit is contained in:
Mawoka
2022-12-14 19:22:32 +01:00
parent 6ec2970846
commit 47ec493fa6
2 changed files with 50 additions and 6 deletions
+20 -6
View File
@@ -14,6 +14,7 @@
import { getLocalization } from '$lib/i18n'; import { getLocalization } from '$lib/i18n';
import StartGamePopup from './start_game.svelte'; import StartGamePopup from './start_game.svelte';
import { onMount } from 'svelte'; import { onMount } from 'svelte';
import viewport from './useViewportAction.js';
let copy_toast_open = false; let copy_toast_open = false;
let start_game = null; let start_game = null;
@@ -29,6 +30,8 @@
}); });
window.location.reload(); window.location.reload();
}; };
let visibleImages = Array.from(Array(quizzes.length), () => []);
const close_start_game_if_esc_is_pressed = (key: KeyboardEvent) => { const close_start_game_if_esc_is_pressed = (key: KeyboardEvent) => {
if (key.code === 'Escape') { if (key.code === 'Escape') {
start_game = null; start_game = null;
@@ -46,6 +49,7 @@
document.body.addEventListener('keydown', close_start_game_if_esc_is_pressed); document.body.addEventListener('keydown', close_start_game_if_esc_is_pressed);
}); });
$: console.log(quizzes, 'quizzes_here'); $: console.log(quizzes, 'quizzes_here');
$: console.log(visibleImages, 'visible images');
</script> </script>
{#if copy_toast_open} {#if copy_toast_open}
@@ -140,6 +144,7 @@
class="max-h-full max-w-full block" class="max-h-full max-w-full block"
src={quiz.cover_image} src={quiz.cover_image}
alt="Not provided" alt="Not provided"
loading="lazy"
/> />
</div> </div>
</div> </div>
@@ -265,7 +270,7 @@
</p> </p>
</div> </div>
</SwiperSlide> </SwiperSlide>
{#each quiz.questions as question} {#each quiz.questions as question, q}
<SwiperSlide> <SwiperSlide>
<div class="h-full"> <div class="h-full">
<h5 class="text-center text-2xl"> <h5 class="text-center text-2xl">
@@ -273,14 +278,23 @@
</h5> </h5>
{#if question.image} {#if question.image}
<div <div
use:viewport
on:enterViewport={() => {
visibleImages[i][q] = true;
}}
on:exitViewport={() => {
visibleImages[i][q] = false;
}}
class="flex justify-center align-middle items-center" class="flex justify-center align-middle items-center"
> >
<div class="h-[30vh] m-auto w-auto"> <div class="h-[30vh] m-auto w-auto">
<img {#if visibleImages?.[i]?.[q]}
class="max-h-full max-w-full block" <img
src={question.image} class="max-h-full max-w-full block"
alt="Not provided" src={question.image}
/> alt="Not provided"
/>
{/if}
</div> </div>
</div> </div>
{/if} {/if}
@@ -0,0 +1,30 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
// Stolen from https://svelte.dev/repl/c6a402704224403f96a3db56c2f48dfc?version=3.55.0
let intersectionObserver;
function ensureIntersectionObserver() {
if (intersectionObserver) return;
intersectionObserver = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
const eventName = entry.isIntersecting ? 'enterViewport' : 'exitViewport';
entry.target.dispatchEvent(new CustomEvent(eventName));
});
});
}
export default function viewport(element) {
ensureIntersectionObserver();
intersectionObserver.observe(element);
return {
destroy() {
intersectionObserver.unobserve(element);
}
};
}