diff options
| author | Fuwn <[email protected]> | 2024-10-09 00:41:20 -0700 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2024-10-09 00:41:43 -0700 |
| commit | 998b63a35256ac985a5a2714dd1ca451af4dfd8a (patch) | |
| tree | 50796121a9d5ab0330fdc5d7e098bda2860d9726 /src/lib/Tools/Birthdays.svelte | |
| parent | feat(graphql): add badgeCount field (diff) | |
| download | due.moe-998b63a35256ac985a5a2714dd1ca451af4dfd8a.tar.xz due.moe-998b63a35256ac985a5a2714dd1ca451af4dfd8a.zip | |
chore(prettier): use spaces instead of tabs
Diffstat (limited to 'src/lib/Tools/Birthdays.svelte')
| -rw-r--r-- | src/lib/Tools/Birthdays.svelte | 310 |
1 files changed, 155 insertions, 155 deletions
diff --git a/src/lib/Tools/Birthdays.svelte b/src/lib/Tools/Birthdays.svelte index 15e2d2fb..97ff40d8 100644 --- a/src/lib/Tools/Birthdays.svelte +++ b/src/lib/Tools/Birthdays.svelte @@ -1,166 +1,166 @@ <script lang="ts"> - import { browser } from '$app/environment'; - import { page } from '$app/stores'; - import { ACDBBirthdays, type ACDBBirthday } from '$lib/Data/Birthday/secondary'; - import { aniSearchBirthdays, type aniSearchBirthday } from '$lib/Data/Birthday/primary'; - import Error from '$lib/Error/RateLimited.svelte'; - import { onMount } from 'svelte'; - import { clearAllParameters, parseOrDefault } from '../Utility/parameters'; - import Skeleton from '$lib/Loading/Skeleton.svelte'; - import Message from '$lib/Loading/Message.svelte'; - import tooltip from '$lib/Tooltip/tooltip'; - - interface Birthday { - name: string; - image: string; - origin?: 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()); - let anisearchBirthdays: Promise<aniSearchBirthday[]>; - let acdbBirthdays: Promise<ACDBBirthday[]>; - - $: { - 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) anisearchBirthdays = aniSearchBirthdays(month, day); - - acdbBirthdays = ACDBBirthdays(month, day); - - 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'])); - - const normaliseName = (name: string): string => name.toLowerCase().split(' ').sort().join(' '); - - const fixName = (name: string): string => { - const split = name.split(' '); - const last = split[split.length - 1]; - - if (last === last.toUpperCase()) { - split[split.length - 1] = last[0] + last.slice(1).toLowerCase(); - return split.join(' '); - } - - const bracketIndex = name.indexOf('['); - - if (bracketIndex !== -1) return name.slice(0, bracketIndex).trim(); - - return name; - }; - - const combineBirthdaySources = ( - acdb: ACDBBirthday[], - aniSearch: aniSearchBirthday[] - ): Birthday[] => { - const nameMap = new Map<string, Birthday>(); - - for (const entry of aniSearch.map((entry) => ({ - ...entry, - normalisedName: normaliseName(fixName(entry.name)) - }))) { - if (!nameMap.has(entry.normalisedName)) - nameMap.set(entry.normalisedName, { - name: fixName(entry.name), - image: entry.image - }); - } - - for (const entry of acdb) { - const normalisedName = normaliseName(fixName(entry.name)); - - if (!nameMap.has(normalisedName)) - nameMap.set(normalisedName, { - name: entry.name, - image: entry.character_image, - origin: entry.origin - }); - } - - return Array.from(nameMap.values()); - }; + import { browser } from '$app/environment'; + import { page } from '$app/stores'; + import { ACDBBirthdays, type ACDBBirthday } from '$lib/Data/Birthday/secondary'; + import { aniSearchBirthdays, type aniSearchBirthday } from '$lib/Data/Birthday/primary'; + import Error from '$lib/Error/RateLimited.svelte'; + import { onMount } from 'svelte'; + import { clearAllParameters, parseOrDefault } from '../Utility/parameters'; + import Skeleton from '$lib/Loading/Skeleton.svelte'; + import Message from '$lib/Loading/Message.svelte'; + import tooltip from '$lib/Tooltip/tooltip'; + + interface Birthday { + name: string; + image: string; + origin?: 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()); + let anisearchBirthdays: Promise<aniSearchBirthday[]>; + let acdbBirthdays: Promise<ACDBBirthday[]>; + + $: { + 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) anisearchBirthdays = aniSearchBirthdays(month, day); + + acdbBirthdays = ACDBBirthdays(month, day); + + 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'])); + + const normaliseName = (name: string): string => name.toLowerCase().split(' ').sort().join(' '); + + const fixName = (name: string): string => { + const split = name.split(' '); + const last = split[split.length - 1]; + + if (last === last.toUpperCase()) { + split[split.length - 1] = last[0] + last.slice(1).toLowerCase(); + return split.join(' '); + } + + const bracketIndex = name.indexOf('['); + + if (bracketIndex !== -1) return name.slice(0, bracketIndex).trim(); + + return name; + }; + + const combineBirthdaySources = ( + acdb: ACDBBirthday[], + aniSearch: aniSearchBirthday[] + ): Birthday[] => { + const nameMap = new Map<string, Birthday>(); + + for (const entry of aniSearch.map((entry) => ({ + ...entry, + normalisedName: normaliseName(fixName(entry.name)) + }))) { + if (!nameMap.has(entry.normalisedName)) + nameMap.set(entry.normalisedName, { + name: fixName(entry.name), + image: entry.image + }); + } + + for (const entry of acdb) { + const normalisedName = normaliseName(fixName(entry.name)); + + if (!nameMap.has(normalisedName)) + nameMap.set(normalisedName, { + name: entry.name, + image: entry.character_image, + origin: entry.origin + }); + } + + return Array.from(nameMap.values()); + }; </script> {#await acdbBirthdays} - <Message message="Loading birthday set one ..." /> + <Message message="Loading birthday set one ..." /> - <Skeleton grid={true} count={100} width="150px" height="170px" /> + <Skeleton grid={true} count={100} width="150px" height="170px" /> {:then acdbBirthdays} - {#await anisearchBirthdays} - <Message message="Loading birthday set two ..." /> - - <Skeleton grid={true} count={100} width="150px" height="170px" /> - {:then anisearch} - {@const birthdays = combineBirthdaySources(acdbBirthdays, anisearch)} - - <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> - - <div class="characters"> - {#each birthdays as birthday} - <div class="card card-small"> - <a - href={`https://anilist.co/search/characters?search=${encodeURIComponent( - birthday.name - ).replace(/%20/g, '+')}`} - target="_blank" - title={birthday.origin} - use:tooltip - data-tooltip-disable={birthday.origin === undefined} - > - {birthday.name} - <img src={birthday.image} alt="Character (Large)" class="character-image" /> - </a> - </div> - {/each} - </div> - {:catch} - <Error type="Character" card /> - {/await} + {#await anisearchBirthdays} + <Message message="Loading birthday set two ..." /> + + <Skeleton grid={true} count={100} width="150px" height="170px" /> + {:then anisearch} + {@const birthdays = combineBirthdaySources(acdbBirthdays, anisearch)} + + <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> + + <div class="characters"> + {#each birthdays as birthday} + <div class="card card-small"> + <a + href={`https://anilist.co/search/characters?search=${encodeURIComponent( + birthday.name + ).replace(/%20/g, '+')}`} + target="_blank" + title={birthday.origin} + use:tooltip + data-tooltip-disable={birthday.origin === undefined} + > + {birthday.name} + <img src={birthday.image} alt="Character (Large)" class="character-image" /> + </a> + </div> + {/each} + </div> + {:catch} + <Error type="Character" card /> + {/await} {:catch} - <Error type="Character" card /> + <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); - } - } + .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> |