aboutsummaryrefslogtreecommitdiff
path: root/src/lib/Tools
diff options
context:
space:
mode:
authorFuwn <[email protected]>2024-07-07 21:55:32 -0700
committerFuwn <[email protected]>2024-07-07 21:55:32 -0700
commit3c85251b260d7abbb1b3f48f2621be9b4e45124c (patch)
tree654ba8280d2c7105049527a00e9c2fde121d15fa /src/lib/Tools
parentfeat(attributions): add a few (diff)
downloaddue.moe-3c85251b260d7abbb1b3f48f2621be9b4e45124c.tar.xz
due.moe-3c85251b260d7abbb1b3f48f2621be9b4e45124c.zip
feat(tools): sequel catcher
Diffstat (limited to 'src/lib/Tools')
-rw-r--r--src/lib/Tools/SequelCatcher.svelte112
-rw-r--r--src/lib/Tools/tools.ts6
2 files changed, 118 insertions, 0 deletions
diff --git a/src/lib/Tools/SequelCatcher.svelte b/src/lib/Tools/SequelCatcher.svelte
new file mode 100644
index 00000000..df6c0d3a
--- /dev/null
+++ b/src/lib/Tools/SequelCatcher.svelte
@@ -0,0 +1,112 @@
+<script lang="ts">
+ import { type AniListAuthorisation } from '$lib/Data/AniList/identity';
+ import userIdentity from '$stores/identity';
+ import { filterRelations, type Media, mediaListCollection, Type } from '$lib/Data/AniList/media';
+ import LogInRestricted from '$lib/Error/LogInRestricted.svelte';
+ import LinkedTooltip from '$lib/Tooltip/LinkedTooltip.svelte';
+ import anime from '$stores/anime';
+
+ import identity from '$stores/identity';
+ import { onMount } from 'svelte';
+ import lastPruneTimes from '$stores/lastPruneTimes';
+ import MediaTitleDisplay from '$lib/List/MediaTitleDisplay.svelte';
+ import { outboundLink } from '$lib/Media/links';
+ import settings from '$stores/settings';
+ import Message from '$lib/Loading/Message.svelte';
+ import Skeleton from '$lib/Loading/Skeleton.svelte';
+
+ export let user: AniListAuthorisation;
+
+ let mediaList: Promise<Media[]>;
+
+ onMount(async () => {
+ if (user === undefined || $identity.id === -2) return;
+
+ mediaList = mediaListCollection(
+ user,
+ $userIdentity,
+ Type.Anime,
+ $anime,
+ $lastPruneTimes.anime,
+ {
+ forcePrune: true,
+ includeCompleted: true,
+ all: true,
+ includeRelations: true
+ }
+ );
+ });
+</script>
+
+{#if user === undefined || $identity.id === -2}
+ <LogInRestricted />
+{:else}
+ <div class="card">
+ {#await mediaList}
+ <Message message="Cross-checking media ..." />
+
+ <Skeleton
+ card={false}
+ count={8}
+ pad={false}
+ height={'0.9rem'}
+ width={'100%'}
+ list
+ grid={false}
+ />
+ {:then mediaListUnchecked}
+ {#if mediaListUnchecked}
+ {@const mediaList = mediaListUnchecked.filter(
+ (media) => media.mediaListEntry?.status === 'COMPLETED'
+ )}
+
+ <ul>
+ {#each filterRelations(mediaList) as { media, unwatchedRelations }}
+ <a href={outboundLink(media, 'anime', $settings.displayOutboundLinksTo)}>
+ <MediaTitleDisplay title={media.title} />
+ </a>
+
+ <ul>
+ {#each unwatchedRelations as relation}
+ <li>
+ <a href={outboundLink(relation.node, 'anime', $settings.displayOutboundLinksTo)}>
+ <MediaTitleDisplay title={relation.node.title} />
+ </a>
+ </li>
+ {/each}
+ </ul>
+ {/each}
+ </ul>
+ {:else}
+ <Message message="Cross-checking media ..." />
+
+ <Skeleton
+ card={false}
+ count={8}
+ pad={false}
+ height={'0.9rem'}
+ width={'100%'}
+ list
+ grid={false}
+ />
+ {/if}
+ {:catch}
+ <Message message="" loader="ripple" slot withReload fullscreen>Error fetching media.</Message>
+ {/await}
+
+ <p />
+
+ <blockquote style="margin: 0 0 0 1.5rem;">
+ Thanks to <a href="https://anilist.co/user/sevengirl/">@sevengirl</a> and
+ <a href="https://anilist.co/user/esthereae/">@esthereae</a> for the idea!
+ </blockquote>
+ </div>
+{/if}
+
+<style>
+ .hint-toggle {
+ box-shadow: rgba(0, 0, 11, 0.2) 0px 7px 29px 0px, 0 0 0 5px var(--base02);
+ float: right;
+ border-radius: 8px;
+ }
+</style>
diff --git a/src/lib/Tools/tools.ts b/src/lib/Tools/tools.ts
index 3feaf9e0..2593ea49 100644
--- a/src/lib/Tools/tools.ts
+++ b/src/lib/Tools/tools.ts
@@ -83,5 +83,11 @@ export const tools: {
name: () => 'Anime Girls Holding Programming Books',
id: 'girls',
description: () => 'Find anime girls holding programming books by language'
+ },
+ sequel_catcher: {
+ name: () => 'Sequel Catcher',
+ description: () =>
+ 'Check if any completed anime on your lists have sequels you have not yet seen',
+ id: 'sequel_catcher'
}
};