mirror of
https://github.com/maxdorninger/MediaManager.git
synced 2026-04-20 07:54:19 +02:00
make counters animated with animejs
This commit is contained in:
11
web/package-lock.json
generated
11
web/package-lock.json
generated
@@ -8,6 +8,7 @@
|
||||
"name": "web",
|
||||
"version": "0.0.1",
|
||||
"dependencies": {
|
||||
"animejs": "^4.2.2",
|
||||
"lucide-svelte": "^0.544.0",
|
||||
"openapi-fetch": "^0.14.0",
|
||||
"uuid": "^11.1.0"
|
||||
@@ -2777,6 +2778,16 @@
|
||||
"url": "https://github.com/sponsors/epoberezkin"
|
||||
}
|
||||
},
|
||||
"node_modules/animejs": {
|
||||
"version": "4.2.2",
|
||||
"resolved": "https://registry.npmjs.org/animejs/-/animejs-4.2.2.tgz",
|
||||
"integrity": "sha512-Ys3RuvLdAeI14fsdKCQy7ytu4057QX6Bb7m4jwmfd6iKmUmLquTwk1ut0e4NtRQgCeq/s2Lv5+oMBjz6c7ZuIg==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/juliangarnier"
|
||||
}
|
||||
},
|
||||
"node_modules/ansi-colors": {
|
||||
"version": "4.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz",
|
||||
|
||||
@@ -70,6 +70,7 @@
|
||||
"zod": "^3.25.76"
|
||||
},
|
||||
"dependencies": {
|
||||
"animejs": "^4.2.2",
|
||||
"lucide-svelte": "^0.544.0",
|
||||
"openapi-fetch": "^0.14.0",
|
||||
"uuid": "^11.1.0"
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import client from '$lib/api';
|
||||
import { isSemver, semverIsGreater } from '$lib/utils.ts';
|
||||
import { env } from '$env/dynamic/public';
|
||||
import { resolve } from '$app/paths';
|
||||
import { animate } from 'animejs';
|
||||
|
||||
let moviesCount: string | null = $state(null);
|
||||
let episodeCount: string | null = $state(null);
|
||||
@@ -14,18 +14,55 @@
|
||||
let releaseUrl: string | null = $state(null);
|
||||
let newestVersion: string | null = $state(null);
|
||||
|
||||
// Elements to animate
|
||||
let showEl: HTMLSpanElement;
|
||||
let episodeEl: HTMLSpanElement;
|
||||
let moviesEl: HTMLSpanElement;
|
||||
let torrentEl: HTMLSpanElement;
|
||||
|
||||
function animateCounter(el: HTMLElement | undefined, target: number, pad = 3) {
|
||||
if (!el) return;
|
||||
|
||||
const obj = { value: 0 };
|
||||
|
||||
animate(obj, {
|
||||
value: target,
|
||||
duration: 2000,
|
||||
easing: 'easeInOutSine',
|
||||
onUpdate: () => {
|
||||
el.textContent = Math.floor(obj.value).toString().padStart(pad, '0');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onMount(async () => {
|
||||
let tvShows = await client.GET('/api/v1/tv/shows');
|
||||
if (!tvShows.error) showCount = tvShows.data.length.toString().padStart(3, '0');
|
||||
if (!tvShows.error) {
|
||||
const target = tvShows.data.length;
|
||||
showCount = target.toString().padStart(3, '0');
|
||||
animateCounter(showEl, target, 3);
|
||||
}
|
||||
|
||||
let episodes = await client.GET('/api/v1/tv/episodes/count');
|
||||
if (!episodes.error) episodeCount = episodes.data.toString().padStart(3, '0');
|
||||
if (!episodes.error) {
|
||||
const target = Number(episodes.data);
|
||||
episodeCount = target.toString().padStart(3, '0');
|
||||
animateCounter(episodeEl, target, 3);
|
||||
}
|
||||
|
||||
let movies = await client.GET('/api/v1/movies');
|
||||
if (!movies.error) moviesCount = movies.data.length.toString().padStart(3, '0');
|
||||
if (!movies.error) {
|
||||
const target = movies.data.length;
|
||||
moviesCount = target.toString().padStart(3, '0');
|
||||
animateCounter(moviesEl, target, 3);
|
||||
}
|
||||
|
||||
let torrents = await client.GET('/api/v1/torrent');
|
||||
if (!torrents.error) torrentCount = torrents.data.length.toString().padStart(3, '0');
|
||||
if (!torrents.error) {
|
||||
const target = torrents.data.length;
|
||||
torrentCount = target.toString().padStart(3, '0');
|
||||
animateCounter(torrentEl, target, 3);
|
||||
}
|
||||
|
||||
let releases = await fetch('https://api.github.com/repos/maxdorninger/mediamanager/releases');
|
||||
if (releases.ok) {
|
||||
@@ -38,25 +75,32 @@
|
||||
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<div class="flex-auto">
|
||||
<Card title="TV Shows" footer="Total count of downloaded episodes">{showCount ?? 'Error'}</Card>
|
||||
<Card title="TV Shows" footer="Total count of downloaded episodes">
|
||||
<span bind:this={showEl}>{showCount ?? 'Error'}</span>
|
||||
</Card>
|
||||
</div>
|
||||
<div class="flex-auto">
|
||||
<Card title="Episodes" footer="Total count of downloaded episodes"
|
||||
>{episodeCount ?? 'Error'}</Card
|
||||
>
|
||||
<Card title="Episodes" footer="Total count of downloaded episodes">
|
||||
<span bind:this={episodeEl}>{episodeCount ?? 'Error'}</span>
|
||||
</Card>
|
||||
</div>
|
||||
<div class="flex-auto">
|
||||
<Card title="Movies" footer="Total count of movies">{moviesCount ?? 'Error'}</Card>
|
||||
<Card title="Movies" footer="Total count of movies">
|
||||
<span bind:this={moviesEl}>{moviesCount ?? 'Error'}</span>
|
||||
</Card>
|
||||
</div>
|
||||
<div class="flex-auto">
|
||||
<Card title="Torrents" footer="Total count of torrents/NZBs">{torrentCount ?? 'Error'}</Card>
|
||||
<Card title="Torrents" footer="Total count of torrents/NZBs">
|
||||
<span bind:this={torrentEl}>{torrentCount ?? 'Error'}</span>
|
||||
</Card>
|
||||
</div>
|
||||
<div class="flex-auto">
|
||||
{#if semverIsGreater(newestVersion ?? '', installedVersion ?? '') || !isSemver(installedVersion ?? '')}
|
||||
<Card title="New version available!" footer="A new version of MediaManager is available!">
|
||||
<a
|
||||
rel="external"
|
||||
target="_blank"
|
||||
href={resolve(releaseUrl ?? 'https://github.com/maxdorninger/MediaManager/releases')}
|
||||
href={releaseUrl ?? 'https://github.com/maxdorninger/MediaManager/releases'}
|
||||
class="underline"
|
||||
>
|
||||
{installedVersion} → v{newestVersion}
|
||||
|
||||
Reference in New Issue
Block a user