web/changelogs: display skeleton when changelog is loading

This commit is contained in:
dumbmoron
2024-07-21 09:42:48 +00:00
parent f530624467
commit 0cea58922d
5 changed files with 228 additions and 15 deletions

View File

@ -1,9 +1,13 @@
<script lang="ts">
import Skeleton from "$components/misc/Skeleton.svelte";
export let version: string;
export let title: string;
export let date: string | undefined;
export let banner: { file: string; alt: string } | undefined;
let bannerLoaded = false;
const formatDate = (dateString: string) => {
const date = new Date(dateString);
@ -34,8 +38,15 @@
<img
src={`/update-banners/${banner.file}`}
alt={banner.alt}
class:loading={!bannerLoaded}
on:load={() => bannerLoaded = true}
class="changelog-banner"
/>
<Skeleton
class="big changelog-banner"
hidden={bannerLoaded}
/>
{/if}
<div class="contents">
<slot></slot>
@ -90,7 +101,7 @@
-webkit-user-select: text
}
.changelog-banner {
:global(.changelog-banner) {
display: block;
object-fit: cover;
max-height: 320pt;
@ -101,6 +112,10 @@
border-radius: var(--padding);
}
:global(.changelog-banner.loading) {
display: none;
}
.changelog-content {
display: flex;
flex-direction: column;

View File

@ -0,0 +1,128 @@
<script lang="ts">
import Skeleton from "$components/misc/Skeleton.svelte";
export let version: string;
</script>
<main>
<div id="changelog-header">
<div class="changelog-info">
<div class="changelog-version">{ version }</div>
<div class="changelog-date">
<Skeleton
width="8em"
height="16px"
/>
</div>
</div>
<h1 class="changelog-title">
<Skeleton
width="28em"
height="27.59px"
/>
</h1>
</div>
<div class="changelog-content">
<Skeleton
class="big changelog-banner"
width="100%"
/>
<div class="contents">
{#each {length: 3 + Math.random() * 5} as _}
<p>
<Skeleton
width="100%"
height={(Math.random() * 84 + 16) + 'px'}
/>
</p>
{/each}
</div>
</div>
</main>
<style>
main {
overflow-x: hidden;
}
#changelog-header {
display: flex;
flex-direction: column;
align-items: start;
gap: calc(var(--padding) / 2);
padding-bottom: 1em; /* match default <p> padding */
}
.changelog-info {
display: flex;
flex-direction: row;
align-items: center;
gap: 14px;
}
.changelog-version {
padding: 3px 8px;
border-radius: 6px;
background-color: var(--secondary);
color: var(--primary);
font-size: 18px;
font-weight: 500;
}
.changelog-date {
font-size: 13px;
font-weight: 500;
color: var(--gray);
}
.changelog-title {
padding: 0;
line-height: 1.2;
font-size: 23px;
user-select: text;
-webkit-user-select: text
}
:global(#banner-skeleton) {
display: block;
max-height: 320pt;
min-height: 210pt;
width: 100%;
aspect-ratio: 16/9;
border-radius: var(--padding);
}
.changelog-content {
display: flex;
flex-direction: column;
align-items: center;
}
.contents {
width: 100%;
}
.contents,
.contents :global(*) {
line-height: 1.7;
font-size: 14.5px;
font-weight: 410;
font-family: "Noto Sans Mono Variable", "Noto Sans Mono", monospace;
user-select: text;
-webkit-user-select: text;
}
:global(ul) {
padding-inline-start: 30px;
}
:global(li) {
padding-left: 3px;
}
@media screen and (max-width: 535px) {
.contents,
.contents :global(*) {
font-size: 14px;
}
}
</style>

View File

@ -0,0 +1,64 @@
<script lang="ts">
export let width: string | undefined = undefined;
export let height: string | undefined = undefined;
export let hidden: boolean | undefined = undefined;
let _class = '';
export { _class as class };
$: style = [
width && `width: ${width}`,
height && `height: ${height}`,
hidden && `display: none`
].filter(a => a).join(';');
</script>
<div
class="skeleton {_class}"
{style}
{...$$restProps}
></div>
<style>
.skeleton {
border-radius: var(--border-radius);
background-color: var(--button);
background-image: var(--skeleton-gradient);
background-size: 200px 100%;
background-repeat: no-repeat;
display: inline-flex;
justify-content: center;
align-items: center;
animation: skeleton 1.2s ease-in-out infinite;
line-height: 1;
font-size: 1em;
text-align: center;
}
:global([data-theme=light]) .skeleton {
background-color: var(--button-hover);
}
.skeleton.big {
background-size: 700px 100%;
animation: skeleton-big 1.2s ease-in-out infinite;
}
@keyframes skeleton {
0% {
background-position: -200px 0;
}
100% {
background-position: calc(200px + 100%) 0;
}
}
@keyframes skeleton-big {
0% {
background-position: -700px 0;
}
100% {
background-position: calc(700px + 100%) 0;
}
}
</style>