aboutsummaryrefslogtreecommitdiff
path: root/src/lib/List/Anime/CleanAnimeList.svelte
blob: 3da3556e0d8a51bbde8be10a868d03e0263ab5fd (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
<script lang="ts">
	/* eslint svelte/no-at-html-tags: "off" */

	import settings from '../../../stores/settings';
	import type { Media } from '$lib/AniList/media';
	import { cleanCache, updateMedia } from '$lib/Media/Anime/cache';
	import { totalEpisodes } from '$lib/Media/Anime/episodes';
	import { airingTime } from '$lib/Media/Anime/airing';
	import type { AniListAuthorisation, UserIdentity } from '$lib/AniList/identity';
	import ListTitle from '../ListTitle.svelte';
	import MediaTitle from '../MediaTitleDisplay.svelte';
	import { outboundLink } from '$lib/Media/links';
	import { onDestroy } from 'svelte';

	export let media: Media[];
	export let title: string;
	export let animeLists: Promise<Media[]>;
	export let user: AniListAuthorisation;
	export let identity: UserIdentity;
	export let endTime: number;
	export let lastUpdatedMedia: number;
	export let completed = false;
	export let previousAnimeList: Media[];
	export let pendingUpdate: number | null;

	const keyCacher = setInterval(
		() => (media = media),
		(() => {
			const airingAt = media.find((m) => m.nextAiringEpisode?.airingAt)?.nextAiringEpisode
				?.airingAt;
			const untilAiring = airingAt
				? Math.round((airingAt - Date.now() / 1000) * 100) / 100
				: undefined;

			if (untilAiring && untilAiring < 3600) return 10000;

			return 300000;
		})()
	);

	onDestroy(() => clearInterval(keyCacher));
</script>

<ListTitle time={endTime / 1000} count={media.length} custom={title} />

{#if media.length === 0}
	<ul>
		<li>
			No anime to display. <a href={'#'} on:click={() => (animeLists = cleanCache(user, identity))}>
				Force refresh
			</a>
		</li>
	</ul>
{/if}

<ul>
	{#each media as anime}
		{@const progress = (anime.mediaListEntry || { progress: 0 }).progress}

		{#if title.includes('Upcoming Episodes') || progress !== (anime.nextAiringEpisode?.episode || 9999) - 1}
			<li class="entry">
				<span class="content">
					<a href={outboundLink(anime, 'anime', $settings.displayOutboundLinksTo)} target="_blank">
						<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' || !$settings.displayCountdownRightAligned}
						<span style="opacity: 50%;">|</span>
					{/if}
					{#await fetch(`/api/subsplease?tz=${Intl.DateTimeFormat().resolvedOptions().timeZone}`).then( (r) => r.json() )}
						<span
							style={`opacity: 50%; ${
								$settings.displayCountdownRightAligned ? 'float: right;' : ''
							}`}
						>
							...
						</span>
					{:then subsPlease}
						{#if title !== 'Upcoming Episodes'}
							<!-- {anime.mediaListEntry?.progress || 0}{@html totalEpisodes(anime)} -->
							{pendingUpdate === anime.id ? progress + 1 : progress}{@html totalEpisodes(anime)}
							<a
								href={'#'}
								style={pendingUpdate === anime.id ? 'pointer-events: none; opacity: 50%;' : ''}
								on:click={() => {
									if (pendingUpdate !== anime.id) {
										lastUpdatedMedia = anime.id;
										pendingUpdate = anime.id;

										updateMedia(anime.id, anime.mediaListEntry?.progress, () => {
											const mediaListEntry = media.find((m) => m.id === anime.id)?.mediaListEntry;

											if (mediaListEntry) mediaListEntry.progress = progress + 1;

											previousAnimeList = media;
											animeLists = cleanCache(user, identity);
											pendingUpdate = null;
										});
									}
								}}>+</a
							>
							{#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, true)}
							</span>
						{/if}
					{/await}
				</span>
			</li>
		{/if}
	{/each}
</ul>

<style>
	.entry::after {
		content: '';
		display: table;
		clear: both;
	}

	.countdown {
		white-space: nowrap;
		float: right;
	}
</style>