Added image loaders

This commit is contained in:
WardPearce
2024-03-08 02:24:19 +13:00
parent f88c51e20d
commit 1076ac2b27
9 changed files with 68 additions and 44 deletions
+33 -7
View File
@@ -1,4 +1,5 @@
<script lang="ts">
import { onMount } from 'svelte';
import type { Video, VideoBase } from './Api/model';
import { truncate } from './misc';
@@ -11,6 +12,24 @@
return `${hours}:${minutes}:${seconds}`;
}
let loading = true;
let loaded = false;
let failed = false;
onMount(() => {
const img = new Image();
img.src = video.videoThumbnails[3].url;
img.onload = () => {
loading = false;
loaded = true;
};
img.onerror = () => {
loading = false;
failed = true;
};
});
</script>
<article class="no-padding transparent">
@@ -18,12 +37,19 @@
class="wave"
style="width: 100%; height: 155px; overflow: hidden;"
href={`/watch/${video.videoId}`}
><img
class="responsive"
style="object-fit: crop;"
src={video.videoThumbnails[3].url}
alt="Thumbnail for video"
/>
>
{#if loading}
<progress class="circle"></progress>
{:else if loaded}
<img
class="responsive"
style="object-fit: crop;"
src={video.videoThumbnails[3].url}
alt="Thumbnail for video"
/>
{:else}
<p>Failed to load image</p>
{/if}
{#if !('liveVideo' in video) || !video.liveVideo}
<div class="absolute right bottom small-margin black white-text small-text">
&nbsp;{videoLength(video.lengthSeconds)}&nbsp;
@@ -40,7 +66,7 @@
<div class="small-padding">
<nav>
<div class="max">
<div class="bold">{truncate(video.title)}</div>
<a href={`/watch/${video.videoId}`}><div class="bold">{truncate(video.title)}</div></a>
<div>
{video.author}{#if !('publishedText' in video)}
&nbsp;{video.viewCountText}{/if}
+4
View File
@@ -1,3 +1,7 @@
export function truncate(value: string, maxLength: number = 50): string {
return value.length > maxLength ? `${value.substring(0, maxLength)}...` : value;
}
export function numberWithCommas(number: number) {
return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
-1
View File
@@ -1 +0,0 @@
export const ssr = false;
-2
View File
@@ -1,7 +1,5 @@
<script lang="ts">
import Logo from '$lib/Logo.svelte';
import 'beercss';
import 'material-dynamic-colors';
const pages = [
{
+3
View File
@@ -0,0 +1,3 @@
import 'beercss/dist/cdn/beer.min.css';
import 'material-dynamic-colors';
+3 -10
View File
@@ -1,22 +1,15 @@
<script lang="ts">
import { getTrending } from '$lib/Api';
import type { Video } from '$lib/Api/model';
import PageLoading from '$lib/PageLoading.svelte';
import Thumbnail from '$lib/Thumbnail.svelte';
import { onMount } from 'svelte';
let trending: Video[];
onMount(async () => {
trending = await getTrending();
});
export let data;
</script>
{#if trending}
{#if data.trending}
<div class="page right active">
<div class="space"></div>
<div class="grid">
{#each trending as video}
{#each data.trending as video}
<div class="s12 m6 l2">
<Thumbnail {video} />
</div>
+5
View File
@@ -0,0 +1,5 @@
import { getTrending } from '$lib/Api/index.js';
export async function load({ params }) {
return { trending: await getTrending() };
}
@@ -1,30 +1,21 @@
<script lang="ts">
import { page } from '$app/stores';
import { getVideo } from '$lib/Api';
import type { VideoPlay } from '$lib/Api/model';
import PageLoading from '$lib/PageLoading.svelte';
import Thumbnail from '$lib/Thumbnail.svelte';
import { onMount } from 'svelte';
import { numberWithCommas } from '$lib/misc.js';
let video: VideoPlay;
onMount(async () => {
video = await getVideo($page.params.slug);
});
export let data;
</script>
{#if video}
<div class="grid large-margin">
<div class="s12 m10 l10">
<h5>{video.title}</h5>
<p style="white-space: pre-line">{video.description}</p>
</div>
<div class="m4 l2">
{#each video.recommendedVideos as recommendedVideo}
<Thumbnail video={recommendedVideo} />
{/each}
</div>
<div class="grid large-margin">
<div class="s12 m10 l10">
<h5>{data.video.title}</h5>
<article>
<p>{numberWithCommas(data.video.viewCount)} views • {data.video.publishedText}</p>
<p style="white-space: pre-line">{data.video.description}</p>
</article>
</div>
{:else}
<PageLoading />
{/if}
<div class="m4 l2">
{#each data.video.recommendedVideos as recommendedVideo}
<Thumbnail video={recommendedVideo} />
{/each}
</div>
</div>
@@ -0,0 +1,5 @@
import { getVideo } from '$lib/Api/index.js';
export async function load({ params }) {
return { video: await getVideo(params.slug) };
};