added tags to frontend anime item

This commit is contained in:
John O'Keefe 2025-05-14 14:31:43 -04:00
parent 8460d56d55
commit 6db01f7f9f
3 changed files with 879 additions and 801 deletions

View File

@ -2,79 +2,92 @@ export interface AniListCurrentUserWatchList {
data: { data: {
Page: { Page: {
pageInfo: { pageInfo: {
total: number total: number;
perPage: number perPage: number;
currentPage: number currentPage: number;
lastPage: number lastPage: number;
hasNextPage: boolean hasNextPage: boolean;
}, };
mediaList: MediaList[] mediaList: MediaList[];
} };
} };
} }
export interface AniListGetSingleAnime { export interface AniListGetSingleAnime {
data: { data: {
MediaList: MediaList MediaList: MediaList;
} };
} }
export interface MediaList { export interface MediaList {
id: number id: number;
mediaId: number mediaId: number;
userId: number userId: number;
media: { media: {
id: number id: number;
idMal: number idMal: number;
title: { title: {
romaji: string romaji: string;
english?: string english?: string;
native: string native: string;
} };
description: string description: string;
coverImage: { coverImage: {
large: string large: string;
} };
season: string season: string;
seasonYear: number seasonYear: number;
status: string status: string;
episodes?: number episodes?: number;
nextAiringEpisode?: { nextAiringEpisode?: {
airingAt: number airingAt: number;
timeUntilAiring: number timeUntilAiring: number;
episode: number episode: number;
} };
} tags: [
status: string {
id: number;
name: string;
description: string;
rank: number;
isMediaSpoiler: boolean;
isAdult: boolean;
},
];
isAdult: boolean;
};
status: string;
startedAt: { startedAt: {
year: number year: number;
month: number month: number;
day: number day: number;
} };
completedAt: { completedAt: {
year?: number year?: number;
month?: number month?: number;
day?: number day?: number;
} };
notes?: string notes?: string;
progress: number progress: number;
score: number score: number;
repeat: number repeat: number;
user: { user: {
id: number id: number;
name: string name: string;
avatar: { avatar: {
large: string large: string;
medium: string medium: string;
} };
statistics: { statistics: {
anime: { anime: {
count: number count: number;
statuses: [{ statuses: [
status: string {
count: number status: string;
}] count: number;
} },
} ];
} };
};
};
} }

View File

@ -22,7 +22,10 @@
} from "../mal/types/MALTypes"; } from "../mal/types/MALTypes";
import type { SimklAnime } from "../simkl/types/simklTypes"; import type { SimklAnime } from "../simkl/types/simklTypes";
import { writable } from "svelte/store"; import { writable } from "svelte/store";
import type { StatusOption, StatusOptions } from "../helperTypes/StatusTypes"; import type {
StatusOption,
StatusOptions,
} from "../helperTypes/StatusTypes";
import type { AniListUpdateVariables } from "../anilist/types/AniListTypes"; import type { AniListUpdateVariables } from "../anilist/types/AniListTypes";
import { convertDateToAniList } from "../helperFunctions/convertDateToAniList"; import { convertDateToAniList } from "../helperFunctions/convertDateToAniList";
import { import {
@ -38,6 +41,7 @@
import { AddAnimeServiceToTable } from "../helperModules/AddAnimeServiceToTable.svelte"; import { AddAnimeServiceToTable } from "../helperModules/AddAnimeServiceToTable.svelte";
import { CheckIfAniListLoggedInAndLoadWatchList } from "../helperModules/CheckIfAniListLoggedInAndLoadWatchList.svelte"; import { CheckIfAniListLoggedInAndLoadWatchList } from "../helperModules/CheckIfAniListLoggedInAndLoadWatchList.svelte";
import Datepicker from "./Datepicker.svelte"; import Datepicker from "./Datepicker.svelte";
import { Badge } from "flowbite-svelte";
const re = /^([0-9]{4})-([0-9]{2})-([0-9]{2})/; const re = /^([0-9]{4})-([0-9]{2})-([0-9]{2})/;
let isAniListLoggedIn: boolean; let isAniListLoggedIn: boolean;
@ -76,7 +80,8 @@
{ id: 5, aniList: "REPEATING", mal: "rewatching", simkl: "watching" }, { id: 5, aniList: "REPEATING", mal: "rewatching", simkl: "watching" },
]; ];
let startingAnilistStatusOption: StatusOption = statusOptions.filter( let startingAnilistStatusOption: StatusOption = statusOptions.filter(
(option) => currentAniListAnime.data.MediaList.status === option.aniList, (option) =>
currentAniListAnime.data.MediaList.status === option.aniList,
)[0]; )[0];
let startedAtDate: Date | null = convertAniListDateToDate( let startedAtDate: Date | null = convertAniListDateToDate(
currentAniListAnime.data.MediaList.startedAt, currentAniListAnime.data.MediaList.startedAt,
@ -107,11 +112,15 @@
let startDate = ""; let startDate = "";
let finishDate = ""; let finishDate = "";
if (currentMalAnime.my_list_status.start_date !== "") { if (currentMalAnime.my_list_status.start_date !== "") {
const startArray = re.exec(currentMalAnime.my_list_status.start_date); const startArray = re.exec(
currentMalAnime.my_list_status.start_date,
);
startDate = `${startArray[2]}-${startArray[3]}-${startArray[1]}`; startDate = `${startArray[2]}-${startArray[3]}-${startArray[1]}`;
} }
if (currentMalAnime.my_list_status.finish_date !== "") { if (currentMalAnime.my_list_status.finish_date !== "") {
const finishArray = re.exec(currentMalAnime.my_list_status.finish_date); const finishArray = re.exec(
currentMalAnime.my_list_status.finish_date,
);
finishDate = `${finishArray[2]}-${finishArray[3]}-${finishArray[1]}`; finishDate = `${finishArray[2]}-${finishArray[3]}-${finishArray[1]}`;
} }
AddAnimeServiceToTable({ AddAnimeServiceToTable({
@ -188,7 +197,10 @@
submitData[key] = value; submitData[key] = value;
} }
if (isAniListLoggedIn && currentAniListAnime.data.MediaList.mediaId !== 0) { if (
isAniListLoggedIn &&
currentAniListAnime.data.MediaList.mediaId !== 0
) {
let body: AniListUpdateVariables = { let body: AniListUpdateVariables = {
mediaId: currentAniListAnime.data.MediaList.mediaId, mediaId: currentAniListAnime.data.MediaList.mediaId,
progress: submitData.episodes, progress: submitData.episodes,
@ -199,7 +211,8 @@
startedAt: convertDateToAniList(startedAtDate), startedAt: convertDateToAniList(startedAtDate),
completedAt: convertDateToAniList(completedAtDate), completedAt: convertDateToAniList(completedAtDate),
}; };
await AniListUpdateEntry(body).then((value: AniListGetSingleAnime) => { await AniListUpdateEntry(body).then(
(value: AniListGetSingleAnime) => {
/* TODO in future when you inevitably add tags to typescript, until Anilist fixes the api bug /* TODO in future when you inevitably add tags to typescript, until Anilist fixes the api bug
where tags break the SaveMediaListEntry return, you'll want to use this delete line where tags break the SaveMediaListEntry return, you'll want to use this delete line
delete value.data.MediaList.media.tags */ delete value.data.MediaList.media.tags */
@ -223,7 +236,8 @@
repeat: currentAniListAnime.data.MediaList.repeat, repeat: currentAniListAnime.data.MediaList.repeat,
notes: currentAniListAnime.data.MediaList.notes, notes: currentAniListAnime.data.MediaList.notes,
}); });
}); },
);
} }
if (malLoggedIn && currentMalAnime.id !== 0) { if (malLoggedIn && currentMalAnime.id !== 0) {
@ -240,7 +254,8 @@
(malAnimeReturn: MalListStatus) => { (malAnimeReturn: MalListStatus) => {
malAnime.update((value) => { malAnime.update((value) => {
value.my_list_status.status = malAnimeReturn.status; value.my_list_status.status = malAnimeReturn.status;
value.my_list_status.is_rewatching = malAnimeReturn.is_rewatching; value.my_list_status.is_rewatching =
malAnimeReturn.is_rewatching;
value.my_list_status.score = malAnimeReturn.score; value.my_list_status.score = malAnimeReturn.score;
value.my_list_status.num_episodes_watched = value.my_list_status.num_episodes_watched =
malAnimeReturn.num_episodes_watched; malAnimeReturn.num_episodes_watched;
@ -267,12 +282,14 @@
id: `m-${currentMalAnime.id}`, id: `m-${currentMalAnime.id}`,
title: currentMalAnime.title, title: currentMalAnime.title,
service: "MyAnimeList", service: "MyAnimeList",
progress: currentMalAnime.my_list_status.num_episodes_watched, progress:
currentMalAnime.my_list_status.num_episodes_watched,
status: currentMalAnime.my_list_status.status, status: currentMalAnime.my_list_status.status,
startedAt: startDate, startedAt: startDate,
completedAt: finishDate, completedAt: finishDate,
score: currentMalAnime.my_list_status.score, score: currentMalAnime.my_list_status.score,
repeat: currentMalAnime.my_list_status.num_times_rewatched, repeat: currentMalAnime.my_list_status
.num_times_rewatched,
notes: currentMalAnime.my_list_status.comments, notes: currentMalAnime.my_list_status.comments,
}); });
}, },
@ -280,9 +297,13 @@
} }
if (simklLoggedIn && currentSimklAnime.show.ids.simkl !== 0) { if (simklLoggedIn && currentSimklAnime.show.ids.simkl !== 0) {
if (currentSimklAnime.watched_episodes_count !== submitData.episodes) { if (
await SimklSyncEpisodes(currentSimklAnime, submitData.episodes).then( currentSimklAnime.watched_episodes_count !== submitData.episodes
(value: SimklAnime) => { ) {
await SimklSyncEpisodes(
currentSimklAnime,
submitData.episodes,
).then((value: SimklAnime) => {
AddAnimeServiceToTable({ AddAnimeServiceToTable({
id: `s-${value.show.ids.simkl}`, id: `s-${value.show.ids.simkl}`,
title: value.show.title, title: value.show.title,
@ -299,13 +320,14 @@
newValue = value; newValue = value;
return newValue; return newValue;
}); });
}, });
);
} }
if (currentSimklAnime.user_rating !== submitData.rating) { if (currentSimklAnime.user_rating !== submitData.rating) {
await SimklSyncRating(currentSimklAnime, submitData.rating).then( await SimklSyncRating(
(value) => { currentSimklAnime,
submitData.rating,
).then((value) => {
AddAnimeServiceToTable({ AddAnimeServiceToTable({
id: `s-${value.show.ids.simkl}`, id: `s-${value.show.ids.simkl}`,
title: value.show.title, title: value.show.title,
@ -322,13 +344,14 @@
newValue = value; newValue = value;
return newValue; return newValue;
}); });
}, });
);
} }
if (currentSimklAnime.status !== submitData.status.simkl) { if (currentSimklAnime.status !== submitData.status.simkl) {
await SimklSyncStatus(currentSimklAnime, submitData.status.simkl).then( await SimklSyncStatus(
(value) => { currentSimklAnime,
submitData.status.simkl,
).then((value) => {
AddAnimeServiceToTable({ AddAnimeServiceToTable({
id: `s-${value.show.ids.simkl}`, id: `s-${value.show.ids.simkl}`,
title: value.show.title, title: value.show.title,
@ -345,8 +368,7 @@
newValue = value; newValue = value;
return newValue; return newValue;
}); });
}, });
);
} }
} }
@ -357,7 +379,10 @@
const deleteEntries = async () => { const deleteEntries = async () => {
submitting.set(true); submitting.set(true);
if (isAniListLoggedIn && currentAniListAnime.data.MediaList.mediaId !== 0) { if (
isAniListLoggedIn &&
currentAniListAnime.data.MediaList.mediaId !== 0
) {
await AniListDeleteEntry(currentAniListAnime.data.MediaList.id); await AniListDeleteEntry(currentAniListAnime.data.MediaList.id);
AddAnimeServiceToTable({ AddAnimeServiceToTable({
id: `a-${currentAniListAnime.data.MediaList.mediaId}`, id: `a-${currentAniListAnime.data.MediaList.mediaId}`,
@ -417,8 +442,10 @@
currentAniListAnime.data.MediaList.media.nextAiringEpisode.episode !== 0 currentAniListAnime.data.MediaList.media.nextAiringEpisode.episode !== 0
) { ) {
max = max =
currentAniListAnime.data.MediaList.media.nextAiringEpisode.episode - 1; currentAniListAnime.data.MediaList.media.nextAiringEpisode.episode -
1;
} }
console.log(currentAniListAnime.data.MediaList.media);
</script> </script>
<form on:submit|preventDefault={handleSubmit} class="container pt-3 pb-10"> <form on:submit|preventDefault={handleSubmit} class="container pt-3 pb-10">
@ -453,11 +480,17 @@
on:click={() => { on:click={() => {
currentAniListAnime.data.MediaList.progress -= 1; currentAniListAnime.data.MediaList.progress -= 1;
if ( if (
currentAniListAnime.data.MediaList.progress < currentAniListAnime.data.MediaList
currentAniListAnime.data.MediaList.media.episodes .progress <
currentAniListAnime.data.MediaList.media
.episodes
) { ) {
startingAnilistStatusOption = statusOptions[0]; startingAnilistStatusOption =
if (currentAniListAnime.data.MediaList.repeat === 0) statusOptions[0];
if (
currentAniListAnime.data.MediaList
.repeat === 0
)
completedAtDate = null; completedAtDate = null;
} }
}} }}
@ -487,18 +520,22 @@
id="episodes" id="episodes"
class="border border-x-0 p-2.5 h-11 text-center text-sm block w-full placeholder-gray-400 [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none class="border border-x-0 p-2.5 h-11 text-center text-sm block w-full placeholder-gray-400 [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none
{currentAniListAnime.data.MediaList.progress < 0 || {currentAniListAnime.data.MediaList.progress < 0 ||
(currentAniListAnime.data.MediaList.media.episodes > 0 && (currentAniListAnime.data.MediaList.media.episodes >
0 &&
currentAniListAnime.data.MediaList.progress > currentAniListAnime.data.MediaList.progress >
currentAniListAnime.data.MediaList.media.episodes) || currentAniListAnime.data.MediaList.media
(currentAniListAnime.data.MediaList.media.nextAiringEpisode .episodes) ||
.episode > 0 && (currentAniListAnime.data.MediaList.media
.nextAiringEpisode.episode > 0 &&
currentAniListAnime.data.MediaList.progress > currentAniListAnime.data.MediaList.progress >
currentAniListAnime.data.MediaList.media.nextAiringEpisode currentAniListAnime.data.MediaList.media
.episode - .nextAiringEpisode.episode -
1) 1)
? 'border-red-500 border-[2px] text-rose-300 focus:ring-red-500 focus:border-red-500' ? 'border-red-500 border-[2px] text-rose-300 focus:ring-red-500 focus:border-red-500'
: 'bg-gray-700 hover:bg-gray-600 border-gray-600 text-white focus:ring-blue-500 focus:border-blue-500'} w-24" : 'bg-gray-700 hover:bg-gray-600 border-gray-600 text-white focus:ring-blue-500 focus:border-blue-500'} w-24"
bind:value={currentAniListAnime.data.MediaList.progress} bind:value={
currentAniListAnime.data.MediaList.progress
}
required required
/> />
<button <button
@ -508,15 +545,24 @@
on:click={() => { on:click={() => {
currentAniListAnime.data.MediaList.progress += 1; currentAniListAnime.data.MediaList.progress += 1;
if ( if (
currentAniListAnime.data.MediaList.media.episodes === currentAniListAnime.data.MediaList.media
.episodes ===
currentAniListAnime.data.MediaList.progress currentAniListAnime.data.MediaList.progress
) { ) {
startingAnilistStatusOption = statusOptions[2]; startingAnilistStatusOption =
statusOptions[2];
completedAtDate = new Date(); completedAtDate = new Date();
} }
if (currentAniListAnime.data.MediaList.progress - 1 === 0) { if (
startingAnilistStatusOption = statusOptions[0]; currentAniListAnime.data.MediaList
if (startedAtDate === null) startedAtDate = new Date(); .progress -
1 ===
0
) {
startingAnilistStatusOption =
statusOptions[0];
if (startedAtDate === null)
startedAtDate = new Date();
} }
}} }}
class="bg-gray-700 hover:bg-gray-600 border-gray-600 border rounded-e-lg p-3 h-11 focus:ring-gray-700 focus:ring-2 focus:outline-none" class="bg-gray-700 hover:bg-gray-600 border-gray-600 border rounded-e-lg p-3 h-11 focus:ring-gray-700 focus:ring-2 focus:outline-none"
@ -539,15 +585,16 @@
</button> </button>
</div> </div>
<div> <div>
/ {currentAniListAnime.data.MediaList.media.nextAiringEpisode / {currentAniListAnime.data.MediaList.media
.episode !== 0 .nextAiringEpisode.episode !== 0
? currentAniListAnime.data.MediaList.media.nextAiringEpisode ? currentAniListAnime.data.MediaList.media
.episode - 1 .nextAiringEpisode.episode - 1
: currentAniListAnime.data.MediaList.media.episodes} : currentAniListAnime.data.MediaList.media.episodes}
</div> </div>
{#if currentAniListAnime.data.MediaList.media.nextAiringEpisode.episode !== 0} {#if currentAniListAnime.data.MediaList.media.nextAiringEpisode.episode !== 0}
<div> <div>
of {currentAniListAnime.data.MediaList.media.episodes} of {currentAniListAnime.data.MediaList.media
.episodes}
</div> </div>
{/if} {/if}
</div> </div>
@ -619,7 +666,8 @@
name="repeat" name="repeat"
min="0" min="0"
id="repeat" id="repeat"
class="border {currentAniListAnime.data.MediaList.repeat < 0 class="border {currentAniListAnime.data.MediaList
.repeat < 0
? 'border-red-500 border-[2px] text-rose-300 focus:ring-red-500 focus:border-red-500' ? 'border-red-500 border-[2px] text-rose-300 focus:ring-red-500 focus:border-red-500'
: 'border-gray-500 text-white focus:ring-blue-500 focus:border-blue-500'} text-sm rounded-lg block w-24 p-2.5 bg-gray-600 placeholder-gray-400 text-white" : 'border-gray-500 text-white focus:ring-blue-500 focus:border-blue-500'} text-sm rounded-lg block w-24 p-2.5 bg-gray-600 placeholder-gray-400 text-white"
bind:value={currentAniListAnime.data.MediaList.repeat} bind:value={currentAniListAnime.data.MediaList.repeat}
@ -779,8 +827,25 @@
</div> </div>
</div> </div>
<div class="flex m-5">
<div> <div>
<h3 class="text-2xl">Tags</h3>
<div class="mt-2">
{#each currentAniListAnime.data.MediaList.media.tags as tag}
<div>
<Badge large border color="blue" class="m-1 w-40"
>{tag.name}</Badge
>
</div>
{/each}
</div>
</div>
<div class="ml-5">
<h3 class="text-2xl">Summary</h3> <h3 class="text-2xl">Summary</h3>
<p>{@html currentAniListAnime.data.MediaList.media.description}</p> <p class="rounded border border-gray-700 p-2 mt-2">
{@html currentAniListAnime.data.MediaList.media.description}
</p>
</div>
</div> </div>
</form> </form>

View File

@ -12,6 +12,6 @@
}, },
"info": { "info": {
"productName": "AniTrack", "productName": "AniTrack",
"productVersion": "0.1.8" "productVersion": "0.1.9"
} }
} }