diff options
| author | Fuwn <[email protected]> | 2024-01-16 02:21:25 -0800 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2024-01-16 02:21:25 -0800 |
| commit | 2f7c8ce0bbc7ecc13f6670e4575678a2ff0d7432 (patch) | |
| tree | b149b36fa8567694ae4cc706f8302cfa0d00c912 /src/lib | |
| parent | fix(sequelspy): move hover cover to title (diff) | |
| download | due.moe-2f7c8ce0bbc7ecc13f6670e4575678a2ff0d7432.tar.xz due.moe-2f7c8ce0bbc7ecc13f6670e4575678a2ff0d7432.zip | |
feat(anime): thumbnail mode
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/List/Anime/CleanAnimeList.svelte | 235 | ||||
| -rw-r--r-- | src/lib/List/mediaTitle.ts | 14 | ||||
| -rw-r--r-- | src/lib/Media/Anime/Airing/time.ts | 9 | ||||
| -rw-r--r-- | src/lib/Settings/Categories/Display.svelte | 1 |
4 files changed, 181 insertions, 78 deletions
diff --git a/src/lib/List/Anime/CleanAnimeList.svelte b/src/lib/List/Anime/CleanAnimeList.svelte index 32f4b6f4..6daba5f3 100644 --- a/src/lib/List/Anime/CleanAnimeList.svelte +++ b/src/lib/List/Anime/CleanAnimeList.svelte @@ -19,6 +19,8 @@ onMouseMove, type HoverCoverResponse } from '$lib/Media/Cover/hoverCover'; + import { mediaTitle } from '../mediaTitle'; + import tooltip from '$lib/Tooltip/tooltip'; export let media: Media[]; export let title: string; @@ -64,95 +66,178 @@ </ul> {/if} -<ul> - {#each media as anime} - {@const progress = (anime.mediaListEntry || { progress: 0 }).progress} +{#if $settings.displayThumbnailMode} + <div id="covers"> + {#each media as anime} + {@const progress = (anime.mediaListEntry || { progress: 0 }).progress} - {#if title.includes('Upcoming Episodes') || title.includes('Not Yet Released') || progress !== (anime.nextAiringEpisode?.episode || 9999) - 1} - <li class="entry"> - <span class="content"> + {#if title.includes('Upcoming Episodes') || title.includes('Not Yet Released') || progress !== (anime.nextAiringEpisode?.episode || 9999) - 1} + <div class="cover-card"> <a href={outboundLink(anime, 'anime', $settings.displayOutboundLinksTo)} target="_blank" - on:mouseenter={() => { - const response = onMouseEnter(anime); - - hoverCoverState.hovering = response.hovering; - hoverCoverState.item = response.item; - hoverCoverState.media = response.media; - }} - on:mouseleave={() => { - const response = onMouseLeave(); - - hoverCoverState.hovering = response.hovering; - hoverCoverState.item = response.item; - hoverCoverState.media = response.media; - }} - on:mousemove={(e) => { - const response = onMouseMove(e, 300); - - hoverCoverState.style = response.style; - }} + title={mediaTitle(anime)} + use:tooltip > - <span - style={lastUpdatedMedia === anime.id && anime.episodes !== progress - ? 'color: lightcoral' - : ''} - > - <MediaTitle title={anime.title} /> - </span> + <img class="cover" src={anime.coverImage.extraLarge} alt="Cover" /> </a> - {#if $settings.displaySocialButton} - [<a href={`https://anilist.co/anime/${anime.id}/social`} target="_blank">S</a>] - {/if} - {#if title !== 'Upcoming Episodes' || title.includes('Not Yet Released') || !$settings.displayCountdownRightAligned} - <span style="opacity: 50%;">|</span> - {/if} - {#if title !== 'Upcoming Episodes' || title.includes('Not Yet Released')} - <!-- {anime.mediaListEntry?.progress || 0}{@html totalEpisodes(anime)} --> - {pendingUpdate === anime.id ? progress + 1 : progress}{@html totalEpisodes(anime)} - <button - class="button-square button-action" - style={pendingUpdate === anime.id ? 'pointer-events: none; opacity: 50%;' : ''} - on:click={() => { - if (pendingUpdate !== anime.id) { - lastUpdatedMedia = anime.id; - pendingUpdate = anime.id; - - incrementMediaProgress(anime.id, anime.mediaListEntry?.progress, user, () => { - const mediaListEntry = media.find((m) => m.id === anime.id)?.mediaListEntry; - - if (mediaListEntry) mediaListEntry.progress = progress + 1; - - previousAnimeList = media; - animeLists = cleanCache(user, identity); - pendingUpdate = null; - }); - } - }}>+</button + + <div class="cover-title"> + {#if title !== 'Upcoming Episodes' || title.includes('Not Yet Released')} + {pendingUpdate === anime.id ? progress + 1 : progress}{@html totalEpisodes(anime)} + <button + class="button-square button-action" + style={pendingUpdate === anime.id ? 'pointer-events: none; opacity: 50%;' : ''} + on:click={() => { + if (pendingUpdate !== anime.id) { + lastUpdatedMedia = anime.id; + pendingUpdate = anime.id; + + incrementMediaProgress(anime.id, anime.mediaListEntry?.progress, user, () => { + const mediaListEntry = media.find((m) => m.id === anime.id)?.mediaListEntry; + + if (mediaListEntry) mediaListEntry.progress = progress + 1; + + previousAnimeList = media; + animeLists = cleanCache(user, identity); + pendingUpdate = null; + }); + } + }}>+</button + > + {#if !completed} + [{anime.nextAiringEpisode?.episode === -1 + ? '?' + : (anime.nextAiringEpisode?.episode || 1) - 1}] + <br /> + {@html airingTime(anime, subsPlease)} + {/if} + {:else} + {@html airingTime(anime, subsPlease, true)} + {/if} + </div> + </div> + {/if} + {/each} + </div> +{:else} + <ul> + {#each media as anime} + {@const progress = (anime.mediaListEntry || { progress: 0 }).progress} + + {#if title.includes('Upcoming Episodes') || title.includes('Not Yet Released') || progress !== (anime.nextAiringEpisode?.episode || 9999) - 1} + <li class="entry"> + <span class="content"> + <a + href={outboundLink(anime, 'anime', $settings.displayOutboundLinksTo)} + target="_blank" + on:mouseenter={() => { + const response = onMouseEnter(anime); + + hoverCoverState.hovering = response.hovering; + hoverCoverState.item = response.item; + hoverCoverState.media = response.media; + }} + on:mouseleave={() => { + const response = onMouseLeave(); + + hoverCoverState.hovering = response.hovering; + hoverCoverState.item = response.item; + hoverCoverState.media = response.media; + }} + on:mousemove={(e) => { + const response = onMouseMove(e, 300); + + hoverCoverState.style = response.style; + }} > - {#if !completed} - [{anime.nextAiringEpisode?.episode === -1 - ? '?' - : (anime.nextAiringEpisode?.episode || 1) - 1}] + <span + style={lastUpdatedMedia === anime.id && anime.episodes !== progress + ? 'color: lightcoral' + : ''} + > + <MediaTitle title={anime.title} /> + </span> + </a> + {#if $settings.displaySocialButton} + [<a href={`https://anilist.co/anime/${anime.id}/social`} target="_blank">S</a>] + {/if} + {#if title !== 'Upcoming Episodes' || title.includes('Not Yet Released') || !$settings.displayCountdownRightAligned} + <span style="opacity: 50%;">|</span> + {/if} + {#if title !== 'Upcoming Episodes' || title.includes('Not Yet Released')} + <!-- {anime.mediaListEntry?.progress || 0}{@html totalEpisodes(anime)} --> + {pendingUpdate === anime.id ? progress + 1 : progress}{@html totalEpisodes(anime)} + <button + class="button-square button-action" + style={pendingUpdate === anime.id ? 'pointer-events: none; opacity: 50%;' : ''} + on:click={() => { + if (pendingUpdate !== anime.id) { + lastUpdatedMedia = anime.id; + pendingUpdate = anime.id; + + incrementMediaProgress(anime.id, anime.mediaListEntry?.progress, user, () => { + const mediaListEntry = media.find((m) => m.id === anime.id)?.mediaListEntry; + + if (mediaListEntry) mediaListEntry.progress = progress + 1; + + previousAnimeList = media; + animeLists = cleanCache(user, identity); + pendingUpdate = null; + }); + } + }}>+</button + > + {#if !completed} + [{anime.nextAiringEpisode?.episode === -1 + ? '?' + : (anime.nextAiringEpisode?.episode || 1) - 1}] + <span class:countdown={$settings.displayCountdownRightAligned}> + {@html airingTime(anime, subsPlease)} + </span> + {/if} + {:else} <span class:countdown={$settings.displayCountdownRightAligned}> - {@html airingTime(anime, subsPlease)} + {@html airingTime(anime, subsPlease, true)} </span> {/if} - {:else} - <span class:countdown={$settings.displayCountdownRightAligned}> - {@html airingTime(anime, subsPlease, true)} - </span> - {/if} - </span> - </li> - {/if} - {/each} -</ul> + </span> + </li> + {/if} + {/each} + </ul> +{/if} <HoverCover options={hoverCoverState} width={300} /> <style> + #covers { + display: grid; + justify-content: center; + gap: 0.5rem; + row-gap: 1rem; + margin-top: 0.5rem; + grid-template-columns: repeat(auto-fill, minmax(116.609px, 1fr)); + } + + .cover { + background-size: cover; + background-position: center; + border-radius: 8px; + } + + .cover-title { + text-align: center; + margin: 0.25rem; + } + + .cover-card { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + } + .entry::after { content: ''; display: table; diff --git a/src/lib/List/mediaTitle.ts b/src/lib/List/mediaTitle.ts new file mode 100644 index 00000000..83344a7b --- /dev/null +++ b/src/lib/List/mediaTitle.ts @@ -0,0 +1,14 @@ +import type { Media } from '$lib/AniList/media'; +import settings from '$stores/settings'; +import { get } from 'svelte/store'; + +export const mediaTitle = (media: Media) => { + switch (get(settings).displayTitleFormat) { + case 'native': + return media.title.native || media.title.romaji || media.title.english; + case 'romaji': + return media.title.romaji || media.title.english || media.title.native; + case 'english': + return media.title.english || media.title.romaji || media.title.native; + } +}; diff --git a/src/lib/Media/Anime/Airing/time.ts b/src/lib/Media/Anime/Airing/time.ts index bcad803f..0f24ccc4 100644 --- a/src/lib/Media/Anime/Airing/time.ts +++ b/src/lib/Media/Anime/Airing/time.ts @@ -4,6 +4,7 @@ import type { SubsPlease } from '$lib/Media/Anime/Airing/Subtitled/subsPlease'; import settings from '$stores/settings'; import { injectAiringTime } from './Subtitled/match'; import { totalEpisodes } from '../episodes'; +import { get } from 'svelte/store'; export const airingTime = ( originalAnime: Media, @@ -70,13 +71,15 @@ export const airingTime = ( hours ? `${hours.toFixed(3)} hours` : '' }" style="opacity: ${opacity}%;">${anime.nextAiringEpisode?.episode}${totalEpisodes( anime - )} in ${timeFrame} <span style="opacity: 50%">${few ? `(${time})` : ''}</span></span>`; + )} in ${timeFrame} <span style="opacity: 50%">${ + few && get(settings).displayThumbnailMode ? '<br>' : '' + }${few ? `(${time})` : ''}</span></span>`; else return `<span title="${ hours ? `${hours.toFixed(3)} hours` : '' }" style="opacity: ${opacity}%;">${anime.nextAiringEpisode?.episode} in ${ - few ? '<b>' : '' - }${timeFrame}${few ? '</b>' : ''} ${few ? `(${time})` : ''}</span>`; + few && get(settings).displayThumbnailMode ? '<br>' : '' + }${few ? '<b>' : ''}${timeFrame}${few ? '</b>' : ''} ${few ? `(${time})` : ''}</span>`; } return ''; diff --git a/src/lib/Settings/Categories/Display.svelte b/src/lib/Settings/Categories/Display.svelte index 78fd514f..55661787 100644 --- a/src/lib/Settings/Categories/Display.svelte +++ b/src/lib/Settings/Categories/Display.svelte @@ -96,6 +96,7 @@ setting="displayHoverCover" text="Show media cover when hovering on supported media titles" /> +<SettingCheckboxToggle setting="displayThumbnailMode" text="Show anime lists with thumbnails" /> <SettingCheckboxToggle setting="displaySocialButton" text="Show social tab shortcut for media" /> <select bind:value={$settings.displayTitleFormat}> <option value="english">English</option> |