diff options
| author | Fuwn <[email protected]> | 2025-02-14 01:56:58 -0800 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2025-02-14 01:56:58 -0800 |
| commit | dcf1f40557d4c42671406b329e55bfed7ea50c1c (patch) | |
| tree | c45fff0fc5b2cfa5197e799472e58632f091f0a2 /src | |
| parent | feat(notifications): initial notification update on first visit (diff) | |
| download | due.moe-dcf1f40557d4c42671406b329e55bfed7ea50c1c.tar.xz due.moe-dcf1f40557d4c42671406b329e55bfed7ea50c1c.zip | |
feat(Tools): Use generic birthdays tool template, adds NIJISANJI birthdays tool
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/Tools/BirthdaysTemplate.svelte | 115 | ||||
| -rw-r--r-- | src/lib/Tools/HololiveBirthdays.svelte | 95 | ||||
| -rw-r--r-- | src/lib/Tools/tools.ts | 6 | ||||
| -rw-r--r-- | src/routes/tools/[tool]/+page.svelte | 10 |
4 files changed, 129 insertions, 97 deletions
diff --git a/src/lib/Tools/BirthdaysTemplate.svelte b/src/lib/Tools/BirthdaysTemplate.svelte new file mode 100644 index 00000000..4e2f0755 --- /dev/null +++ b/src/lib/Tools/BirthdaysTemplate.svelte @@ -0,0 +1,115 @@ +<script lang="ts"> + import { browser } from '$app/environment'; + import { page } from '$app/stores'; + import { onMount } from 'svelte'; + import { clearAllParameters, parseOrDefault } from '../Utility/parameters'; + import Message from '$lib/Loading/Message.svelte'; + import locale from '$stores/locale'; + import Error from '$lib/Error/RateLimited.svelte'; + import Skeleton from '$lib/Loading/Skeleton.svelte'; + + export let remoteURL: string; + + const urlParameters = browser ? new URLSearchParams(window.location.search) : null; + let date = new Date(); + let month = parseOrDefault(urlParameters, 'month', date.getMonth() + 1); + let day = parseOrDefault(urlParameters, 'day', date.getDate()); + const remoteBirthdays = fetch(remoteURL); + + $: { + month = Math.min(month, 12); + month = Math.max(month, 1); + day = Math.min(day, new Date(new Date().getFullYear(), month, 0).getDate()); + day = Math.max(day, 1); + + if (browser) { + $page.url.searchParams.set('month', month.toString()); + $page.url.searchParams.set('day', day.toString()); + clearAllParameters(['month', 'day']); + history.replaceState(null, '', `?${$page.url.searchParams.toString()}`); + } + } + + onMount(() => clearAllParameters(['month', 'day'])); +</script> + +{#await remoteBirthdays} + <Message message="Loading birthdays ... 33%" /> + + <Skeleton grid={true} count={100} width="150px" height="170px" /> +{:then birthdaysResponse} + {#await birthdaysResponse.json()} + <Message message="Loading birthdays ... 66%" /> + + <Skeleton grid={true} count={100} width="150px" height="170px" /> + {:then birthdays} + {@const todaysBirthdays = birthdays.filter( + (birthday) => birthday.month === month && birthday.day === day + )} + + <p> + <select bind:value={month}> + {#each Array.from({ length: 12 }, (_, i) => i + 1) as month} + <option value={month}> + {new Date(0, month - 1).toLocaleString('default', { month: 'long' })} + </option> + {/each} + </select> + + <select bind:value={day}> + {#each Array.from({ length: new Date(new Date().getFullYear(), month, 0).getDate() }, (_, i) => i + 1) as day} + <option value={day}>{day}</option> + {/each} + </select> + </p> + + {#if todaysBirthdays.length === 0} + <Message + message={`No birthdays for ${$locale().dayFormatter( + new Date(new Date().getFullYear(), month - 1, day) + )}.`} + fullscreen={false} + loader="ripple" + /> + {:else} + <div class="characters"> + {#each todaysBirthdays as birthday} + <div class="card card-small"> + <a + href={`https://anilist.co/search/characters?search=${encodeURIComponent( + birthday.name + ).replace(/%20/g, '+')}`} + target="_blank" + > + {birthday.name} + <img src={birthday.pictureURL} alt="Character" class="character-image" /> + </a> + </div> + {/each} + </div> + {/if} + {:catch} + <Error type="Character" card /> + {/await} +{:catch} + <Error type="Character" card /> +{/await} + +<style lang="scss"> + .characters { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr)); + gap: 1rem; + grid-row-gap: 1rem; + align-items: start; + + img { + width: 100%; + height: auto; + object-fit: cover; + border-radius: 8px; + margin-top: 0.5rem; + box-shadow: 0 4px 30px var(--base01); + } + } +</style> diff --git a/src/lib/Tools/HololiveBirthdays.svelte b/src/lib/Tools/HololiveBirthdays.svelte deleted file mode 100644 index 68a591de..00000000 --- a/src/lib/Tools/HololiveBirthdays.svelte +++ /dev/null @@ -1,95 +0,0 @@ -<script lang="ts"> - import { browser } from '$app/environment'; - import { page } from '$app/stores'; - import { onMount } from 'svelte'; - import { clearAllParameters, parseOrDefault } from '../Utility/parameters'; - import Message from '$lib/Loading/Message.svelte'; - import locale from '$stores/locale'; - import birthdays from '$lib/Data/Static/hololiveBirthdays.json'; - - const urlParameters = browser ? new URLSearchParams(window.location.search) : null; - let date = new Date(); - let month = parseOrDefault(urlParameters, 'month', date.getMonth() + 1); - let day = parseOrDefault(urlParameters, 'day', date.getDate()); - - $: todaysBirthdays = birthdays.filter( - (birthday) => birthday.month === month && birthday.day === day - ); - - $: { - month = Math.min(month, 12); - month = Math.max(month, 1); - day = Math.min(day, new Date(new Date().getFullYear(), month, 0).getDate()); - day = Math.max(day, 1); - - if (browser) { - $page.url.searchParams.set('month', month.toString()); - $page.url.searchParams.set('day', day.toString()); - clearAllParameters(['month', 'day']); - history.replaceState(null, '', `?${$page.url.searchParams.toString()}`); - } - } - - onMount(() => clearAllParameters(['month', 'day'])); -</script> - -<p> - <select bind:value={month}> - {#each Array.from({ length: 12 }, (_, i) => i + 1) as month} - <option value={month}> - {new Date(0, month - 1).toLocaleString('default', { month: 'long' })} - </option> - {/each} - </select> - - <select bind:value={day}> - {#each Array.from({ length: new Date(new Date().getFullYear(), month, 0).getDate() }, (_, i) => i + 1) as day} - <option value={day}>{day}</option> - {/each} - </select> -</p> - -{#if todaysBirthdays.length === 0} - <Message - message={`No birthdays for ${$locale().dayFormatter( - new Date(new Date().getFullYear(), month - 1, day) - )}.`} - fullscreen={false} - loader="ripple" - /> -{:else} - <div class="characters"> - {#each todaysBirthdays as birthday} - <div class="card card-small"> - <a - href={`https://anilist.co/search/characters?search=${encodeURIComponent( - birthday.name - ).replace(/%20/g, '+')}`} - target="_blank" - > - {birthday.name} - <img src={birthday.image} alt="Character" class="character-image" /> - </a> - </div> - {/each} - </div> -{/if} - -<style lang="scss"> - .characters { - display: grid; - grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr)); - gap: 1rem; - grid-row-gap: 1rem; - align-items: start; - - img { - width: 100%; - height: auto; - object-fit: cover; - border-radius: 8px; - margin-top: 0.5rem; - box-shadow: 0 4px 30px var(--base01); - } - } -</style> diff --git a/src/lib/Tools/tools.ts b/src/lib/Tools/tools.ts index 988d7826..52b08564 100644 --- a/src/lib/Tools/tools.ts +++ b/src/lib/Tools/tools.ts @@ -57,6 +57,12 @@ export const tools: { 'Find and display the birthdays of all hololive talents for today, or any other day of the year', id: 'hololive_birthdays' }, + nijisanji_birthdays: { + name: () => 'NIJISANJI Birthdays', + description: () => + 'Find and display the birthdays of all NIJISANJI talents for today, or any other day of the year', + id: 'nijisanji_birthdays' + }, hayai: { name: () => '早い', description: () => 'Read light novels at 1.5x speed!', diff --git a/src/routes/tools/[tool]/+page.svelte b/src/routes/tools/[tool]/+page.svelte index c811cf2a..043b47fb 100644 --- a/src/routes/tools/[tool]/+page.svelte +++ b/src/routes/tools/[tool]/+page.svelte @@ -17,9 +17,9 @@ import Likes from '$lib/Tools/Likes.svelte'; import root from '$lib/Utility/root.js'; import Popup from '$lib/Layout/Popup.svelte'; - import HololiveBirthdays from '$lib/Tools/HololiveBirthdays.svelte'; import SequelCatcher from '$lib/Tools/SequelCatcher/Tool.svelte'; import Tracker from '$lib/Tools/Tracker/Tool.svelte'; + import BirthdaysTemplate from '$lib/Tools/BirthdaysTemplate.svelte'; export let data; @@ -78,7 +78,13 @@ {:else if tool === 'hayai'} <Hayai /> {:else if tool === 'hololive_birthdays'} - <HololiveBirthdays /> + <BirthdaysTemplate + remoteURL="https://raw.githubusercontent.com/Fuwn/hololist-to-json-and-ical/refs/heads/main/data/latest_hololive.json" + /> + {:else if tool === 'nijisanji_birthdays'} + <BirthdaysTemplate + remoteURL="https://raw.githubusercontent.com/Fuwn/hololist-to-json-and-ical/refs/heads/main/data/latest_nijisanji.json" + /> {:else if tool === 'sequel_catcher'} <SequelCatcher user={data.user} /> {:else if tool === 'tracker'} |