diff --git a/frontend/src/helperComponents/Anime.svelte b/frontend/src/helperComponents/Anime.svelte index edb85e6..f5fa5f8 100644 --- a/frontend/src/helperComponents/Anime.svelte +++ b/frontend/src/helperComponents/Anime.svelte @@ -7,112 +7,140 @@ simklAnime, simklLoggedIn, } from "../helperModules/GlobalVariablesAndHelperFunctions.svelte"; - import {push} from "svelte-spa-router"; - import {Button} from "flowbite-svelte"; - import type {AniListGetSingleAnime} from "../anilist/types/AniListCurrentUserWatchListType"; + import { push } from "svelte-spa-router"; + import { Button } from "flowbite-svelte"; + import type { AniListGetSingleAnime } from "../anilist/types/AniListCurrentUserWatchListType"; import Rating from "./Rating.svelte"; import convertAniListDateToString from "../helperFunctions/convertAniListDateToString"; import AnimeTable from "./AnimeTable.svelte"; - import type {MALAnime, MalListStatus, MALUploadStatus} from "../mal/types/MALTypes"; - import type {SimklAnime} from "../simkl/types/simklTypes"; - import {writable} from "svelte/store"; - import type {StatusOption, StatusOptions} from "../helperTypes/StatusTypes"; - import type {AniListUpdateVariables} from "../anilist/types/AniListTypes"; + import type { + MALAnime, + MalListStatus, + MALUploadStatus, + } from "../mal/types/MALTypes"; + import type { SimklAnime } from "../simkl/types/simklTypes"; + import { writable } from "svelte/store"; + import type { + StatusOption, + StatusOptions, + } from "../helperTypes/StatusTypes"; + import type { AniListUpdateVariables } from "../anilist/types/AniListTypes"; import convertDateStringToAniList from "../helperFunctions/convertDateStringToAniList"; import { AniListDeleteEntry, - AniListUpdateEntry, DeleteMyAnimeListEntry, + AniListUpdateEntry, + DeleteMyAnimeListEntry, MyAnimeListUpdate, SimklSyncEpisodes, - SimklSyncRating, SimklSyncRemove, - SimklSyncStatus + SimklSyncRating, + SimklSyncRemove, + SimklSyncStatus, } from "../../wailsjs/go/main/App"; - import {AddAnimeServiceToTable} from "../helperModules/AddAnimeServiceToTable.svelte"; - import {CheckIfAniListLoggedInAndLoadWatchList} from "../helperModules/CheckIfAniListLoggedInAndLoadWatchList.svelte"; + import { AddAnimeServiceToTable } from "../helperModules/AddAnimeServiceToTable.svelte"; + import { CheckIfAniListLoggedInAndLoadWatchList } from "../helperModules/CheckIfAniListLoggedInAndLoadWatchList.svelte"; - let isAniListLoggedIn: boolean - let isMalLoggedIn: boolean - let isSimklLoggedIn: boolean - let currentAniListAnime: AniListGetSingleAnime - let currentMalAnime: MALAnime - let currentSimklAnime: SimklAnime - let submitting = writable(false) - let isSubmitting: boolean - let submitSuccess = writable(false) + let isAniListLoggedIn: boolean; + let isMalLoggedIn: boolean; + let isSimklLoggedIn: boolean; + let currentAniListAnime: AniListGetSingleAnime; + let currentMalAnime: MALAnime; + let currentSimklAnime: SimklAnime; + let submitting = writable(false); + let isSubmitting: boolean; + let submitSuccess = writable(false); - aniListLoggedIn.subscribe((value) => isAniListLoggedIn = value) - malLoggedIn.subscribe((value) => isMalLoggedIn = value) - simklLoggedIn.subscribe((value) => isSimklLoggedIn = value) - aniListAnime.subscribe((value) => currentAniListAnime = value) - malAnime.subscribe((value) => currentMalAnime = value) - simklAnime.subscribe((value) => currentSimklAnime = value) - submitting.subscribe((value) => isSubmitting = value) + aniListLoggedIn.subscribe((value) => (isAniListLoggedIn = value)); + malLoggedIn.subscribe((value) => (isMalLoggedIn = value)); + simklLoggedIn.subscribe((value) => (isSimklLoggedIn = value)); + aniListAnime.subscribe((value) => (currentAniListAnime = value)); + malAnime.subscribe((value) => (currentMalAnime = value)); + simklAnime.subscribe((value) => (currentSimklAnime = value)); + submitting.subscribe((value) => (isSubmitting = value)); - const title = currentAniListAnime.data.MediaList.media.title.english !== "" ? - currentAniListAnime.data.MediaList.media.title.english : - currentAniListAnime.data.MediaList.media.title.romaji + const title = + currentAniListAnime.data.MediaList.media.title.english !== "" + ? currentAniListAnime.data.MediaList.media.title.english + : currentAniListAnime.data.MediaList.media.title.romaji; const statusOptions: StatusOptions = [ - {id: 0, aniList: "CURRENT", mal: "watching", simkl: "watching"}, - {id: 1, aniList: "PLANNING", mal: "plan_to_watch", simkl: "plantowatch"}, - {id: 2, aniList: "COMPLETED", mal: "completed", simkl: "completed"}, - {id: 3, aniList: "DROPPED", mal: "dropped", simkl: "dropped"}, - {id: 4, aniList: "PAUSED", mal: "on_hold", simkl: "hold"}, - {id: 5, aniList: "REPEATING", mal: "rewatching", simkl: "watching"} - ] - let startingAnilistStatusOption: StatusOption = statusOptions.filter(option => currentAniListAnime.data.MediaList.status === option.aniList)[0] - const startedAtDate = convertAniListDateToString(currentAniListAnime.data.MediaList.startedAt) - const completedAtDate = convertAniListDateToString(currentAniListAnime.data.MediaList.completedAt) + { id: 0, aniList: "CURRENT", mal: "watching", simkl: "watching" }, + { + id: 1, + aniList: "PLANNING", + mal: "plan_to_watch", + simkl: "plantowatch", + }, + { id: 2, aniList: "COMPLETED", mal: "completed", simkl: "completed" }, + { id: 3, aniList: "DROPPED", mal: "dropped", simkl: "dropped" }, + { id: 4, aniList: "PAUSED", mal: "on_hold", simkl: "hold" }, + { id: 5, aniList: "REPEATING", mal: "rewatching", simkl: "watching" }, + ]; + let startingAnilistStatusOption: StatusOption = statusOptions.filter( + (option) => + currentAniListAnime.data.MediaList.status === option.aniList, + )[0]; + const startedAtDate = convertAniListDateToString( + currentAniListAnime.data.MediaList.startedAt, + ); + const completedAtDate = convertAniListDateToString( + currentAniListAnime.data.MediaList.completedAt, + ); - if (isAniListLoggedIn) AddAnimeServiceToTable({ - id: currentAniListAnime.data.MediaList.mediaId, - title, - service: "AniList", - progress: currentAniListAnime.data.MediaList.progress, - status: currentAniListAnime.data.MediaList.status, - startedAt: convertAniListDateToString(currentAniListAnime.data.MediaList.startedAt), - completedAt: convertAniListDateToString(currentAniListAnime.data.MediaList.completedAt), - score: currentAniListAnime.data.MediaList.score, - repeat: currentAniListAnime.data.MediaList.repeat, - notes: currentAniListAnime.data.MediaList.notes - }) + if (isAniListLoggedIn) + AddAnimeServiceToTable({ + id: currentAniListAnime.data.MediaList.mediaId, + title, + service: "AniList", + progress: currentAniListAnime.data.MediaList.progress, + status: currentAniListAnime.data.MediaList.status, + startedAt: convertAniListDateToString( + currentAniListAnime.data.MediaList.startedAt, + ), + completedAt: convertAniListDateToString( + currentAniListAnime.data.MediaList.completedAt, + ), + score: currentAniListAnime.data.MediaList.score, + repeat: currentAniListAnime.data.MediaList.repeat, + notes: currentAniListAnime.data.MediaList.notes, + }); + if (isMalLoggedIn) + AddAnimeServiceToTable({ + id: currentMalAnime.id, + title: currentMalAnime.title, + service: "MyAnimeList", + progress: currentMalAnime.my_list_status.num_episodes_watched, + status: currentMalAnime.my_list_status.status, + startedAt: currentMalAnime.my_list_status.start_date, + completedAt: currentMalAnime.my_list_status.finish_date, + score: currentMalAnime.my_list_status.score, + repeat: currentMalAnime.my_list_status.num_times_rewatched, + notes: currentMalAnime.my_list_status.comments, + }); - if (isMalLoggedIn) AddAnimeServiceToTable({ - id: currentMalAnime.id, - title: currentMalAnime.title, - service: "MyAnimeList", - progress: currentMalAnime.my_list_status.num_episodes_watched, - status: currentMalAnime.my_list_status.status, - startedAt: currentMalAnime.my_list_status.start_date, - completedAt: currentMalAnime.my_list_status.finish_date, - score: currentMalAnime.my_list_status.score, - repeat: currentMalAnime.my_list_status.num_times_rewatched, - notes: currentMalAnime.my_list_status.comments - }) - - if (isSimklLoggedIn && Object.keys(currentSimklAnime).length > 0) AddAnimeServiceToTable({ - id: currentSimklAnime.show.ids.simkl, - title: currentSimklAnime.show.title, - service: "Simkl", - progress: currentSimklAnime.watched_episodes_count, - status: currentSimklAnime.status, - startedAt: "", - completedAt: "", - score: currentSimklAnime.user_rating, - repeat: 0, - notes: "" - }) + if (isSimklLoggedIn && Object.keys(currentSimklAnime).length > 0) + AddAnimeServiceToTable({ + id: currentSimklAnime.show.ids.simkl, + title: currentSimklAnime.show.title, + service: "Simkl", + progress: currentSimklAnime.watched_episodes_count, + status: currentSimklAnime.status, + startedAt: "", + completedAt: "", + score: currentSimklAnime.user_rating, + repeat: 0, + notes: "", + }); const handleSubmit = async (e: any) => { - submitting.set(true) + submitting.set(true); let submitData: { - rating: number, - episodes: number, - status: StatusOption, - startedAt: string, - completedAt: string, - repeat: number, - notes: string, + rating: number; + episodes: number; + status: StatusOption; + startedAt: string; + completedAt: string; + repeat: number; + notes: string; } = { rating: 0, episodes: 0, @@ -126,30 +154,33 @@ completedAt: "", repeat: 0, notes: "", - } - const formData = new FormData(e.target) + }; + const formData = new FormData(e.target); for (let field of formData) { - const [key, value] = field + const [key, value] = field; if (key === "rating") { - submitData.rating = (Number(value) * 2) - continue + submitData.rating = Number(value) * 2; + continue; } if (key === "episodes") { - submitData.episodes = Number(value) - continue + submitData.episodes = Number(value); + continue; } if (key === "repeat") { - submitData.repeat = Number(value) - continue + submitData.repeat = Number(value); + continue; } if (key === "status") { - submitData.status = startingAnilistStatusOption - continue + submitData.status = startingAnilistStatusOption; + continue; } - submitData[key] = value + submitData[key] = value; } - if (isAniListLoggedIn && currentAniListAnime.data.MediaList.mediaId !== 0) { + if ( + isAniListLoggedIn && + currentAniListAnime.data.MediaList.mediaId !== 0 + ) { let body: AniListUpdateVariables = { mediaId: currentAniListAnime.data.MediaList.mediaId, progress: submitData.episodes, @@ -158,29 +189,35 @@ repeat: submitData.repeat, notes: submitData.notes, startedAt: convertDateStringToAniList(submitData.startedAt), - completedAt: convertDateStringToAniList(submitData.completedAt) - } - await AniListUpdateEntry(body).then((value: AniListGetSingleAnime) => { - // 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 - // delete value.data.MediaList.media.tags - aniListAnime.update(newValue => { - newValue = value - return newValue - }) - AddAnimeServiceToTable({ - id: currentAniListAnime.data.MediaList.mediaId, - title, - service: "AniList", - progress: currentAniListAnime.data.MediaList.progress, - status: currentAniListAnime.data.MediaList.status, - startedAt: convertAniListDateToString(currentAniListAnime.data.MediaList.startedAt), - completedAt: convertAniListDateToString(currentAniListAnime.data.MediaList.completedAt), - score: currentAniListAnime.data.MediaList.score, - repeat: currentAniListAnime.data.MediaList.repeat, - notes: currentAniListAnime.data.MediaList.notes, - }) - }) + completedAt: convertDateStringToAniList(submitData.completedAt), + }; + await AniListUpdateEntry(body).then( + (value: AniListGetSingleAnime) => { + // 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 + // delete value.data.MediaList.media.tags + aniListAnime.update((newValue) => { + newValue = value; + return newValue; + }); + AddAnimeServiceToTable({ + id: currentAniListAnime.data.MediaList.mediaId, + title, + service: "AniList", + progress: currentAniListAnime.data.MediaList.progress, + status: currentAniListAnime.data.MediaList.status, + startedAt: convertAniListDateToString( + currentAniListAnime.data.MediaList.startedAt, + ), + completedAt: convertAniListDateToString( + currentAniListAnime.data.MediaList.completedAt, + ), + score: currentAniListAnime.data.MediaList.score, + repeat: currentAniListAnime.data.MediaList.repeat, + notes: currentAniListAnime.data.MediaList.notes, + }); + }, + ); } if (malLoggedIn && currentMalAnime.id !== 0) { @@ -190,37 +227,49 @@ score: submitData.rating, num_watched_episodes: submitData.episodes, num_times_rewatched: submitData.repeat, - comments: submitData.notes - } + comments: submitData.notes, + }; - await MyAnimeListUpdate(currentMalAnime, body).then((malAnimeReturn: MalListStatus) => { - malAnime.update(value => { - value.my_list_status.status = malAnimeReturn.status - value.my_list_status.is_rewatching = malAnimeReturn.is_rewatching - value.my_list_status.score = malAnimeReturn.score - value.my_list_status.num_episodes_watched = malAnimeReturn.num_episodes_watched - value.my_list_status.num_times_rewatched = malAnimeReturn.num_times_rewatched - value.my_list_status.comments = malAnimeReturn.comments - return value - }) - AddAnimeServiceToTable({ - id: currentMalAnime.id, - title: currentMalAnime.title, - service: "MyAnimeList", - progress: currentMalAnime.my_list_status.num_episodes_watched, - status: currentMalAnime.my_list_status.status, - startedAt: currentMalAnime.my_list_status.start_date, - completedAt: currentMalAnime.my_list_status.finish_date, - score: currentMalAnime.my_list_status.score, - repeat: currentMalAnime.my_list_status.num_times_rewatched, - notes: currentMalAnime.my_list_status.comments, - }) - }) + await MyAnimeListUpdate(currentMalAnime, body).then( + (malAnimeReturn: MalListStatus) => { + malAnime.update((value) => { + value.my_list_status.status = malAnimeReturn.status; + value.my_list_status.is_rewatching = + malAnimeReturn.is_rewatching; + value.my_list_status.score = malAnimeReturn.score; + value.my_list_status.num_episodes_watched = + malAnimeReturn.num_episodes_watched; + value.my_list_status.num_times_rewatched = + malAnimeReturn.num_times_rewatched; + value.my_list_status.comments = malAnimeReturn.comments; + return value; + }); + AddAnimeServiceToTable({ + id: currentMalAnime.id, + title: currentMalAnime.title, + service: "MyAnimeList", + progress: + currentMalAnime.my_list_status.num_episodes_watched, + status: currentMalAnime.my_list_status.status, + startedAt: currentMalAnime.my_list_status.start_date, + completedAt: currentMalAnime.my_list_status.finish_date, + score: currentMalAnime.my_list_status.score, + repeat: currentMalAnime.my_list_status + .num_times_rewatched, + notes: currentMalAnime.my_list_status.comments, + }); + }, + ); } if (simklLoggedIn && currentSimklAnime.show.ids.simkl !== 0) { - if (currentSimklAnime.watched_episodes_count !== submitData.episodes) { - await SimklSyncEpisodes(currentSimklAnime, submitData.episodes).then((value: SimklAnime) => { + if ( + currentSimklAnime.watched_episodes_count !== submitData.episodes + ) { + await SimklSyncEpisodes( + currentSimklAnime, + submitData.episodes, + ).then((value: SimklAnime) => { AddAnimeServiceToTable({ id: value.show.ids.simkl, title: value.show.title, @@ -231,17 +280,20 @@ completedAt: "", score: value.user_rating, repeat: 0, - notes: "" - }) - simklAnime.update(newValue => { - newValue = value - return newValue - }) - }) + notes: "", + }); + simklAnime.update((newValue) => { + newValue = value; + return newValue; + }); + }); } if (currentSimklAnime.user_rating !== submitData.rating) { - await SimklSyncRating(currentSimklAnime, submitData.rating).then(value => { + await SimklSyncRating( + currentSimklAnime, + submitData.rating, + ).then((value) => { AddAnimeServiceToTable({ id: value.show.ids.simkl, title: value.show.title, @@ -252,17 +304,20 @@ completedAt: "", score: value.user_rating, repeat: 0, - notes: "" - }) - simklAnime.update(newValue => { - newValue = value - return newValue - }) - }) + notes: "", + }); + simklAnime.update((newValue) => { + newValue = value; + return newValue; + }); + }); } if (currentSimklAnime.status !== submitData.status.simkl) { - await SimklSyncStatus(currentSimklAnime, submitData.status.simkl).then(value => { + await SimklSyncStatus( + currentSimklAnime, + submitData.status.simkl, + ).then((value) => { AddAnimeServiceToTable({ id: value.show.ids.simkl, title: value.show.title, @@ -273,25 +328,28 @@ completedAt: "", score: value.user_rating, repeat: 0, - notes: "" - }) - simklAnime.update(newValue => { - newValue = value - return newValue - }) - }) + notes: "", + }); + simklAnime.update((newValue) => { + newValue = value; + return newValue; + }); + }); } } - submitting.set(false) - submitSuccess.set(true) - setTimeout(() => submitSuccess.set(false), 2000) - } + submitting.set(false); + submitSuccess.set(true); + setTimeout(() => submitSuccess.set(false), 2000); + }; const deleteEntries = async () => { - submitting.set(true) - if (isAniListLoggedIn && currentAniListAnime.data.MediaList.mediaId !== 0) { - await AniListDeleteEntry(currentAniListAnime.data.MediaList.id) + submitting.set(true); + if ( + isAniListLoggedIn && + currentAniListAnime.data.MediaList.mediaId !== 0 + ) { + await AniListDeleteEntry(currentAniListAnime.data.MediaList.id); AddAnimeServiceToTable({ id: currentAniListAnime.data.MediaList.mediaId, title, @@ -303,10 +361,10 @@ score: 0, repeat: 0, notes: "", - }) + }); } if (malLoggedIn && currentMalAnime.id !== 0) { - await DeleteMyAnimeListEntry(currentMalAnime.id) + await DeleteMyAnimeListEntry(currentMalAnime.id); AddAnimeServiceToTable({ id: currentMalAnime.id, title: currentMalAnime.title, @@ -318,10 +376,10 @@ score: 0, repeat: 0, notes: "", - }) + }); } if (simklLoggedIn && currentSimklAnime.show.ids.simkl !== 0) { - await SimklSyncRemove(currentSimklAnime) + await SimklSyncRemove(currentSimklAnime); AddAnimeServiceToTable({ id: currentSimklAnime.show.ids.simkl, title: currentSimklAnime.show.title, @@ -333,52 +391,68 @@ score: 0, repeat: 0, notes: "", - }) + }); } - submitting.set(false) - submitSuccess.set(true) - setTimeout(() => submitSuccess.set(false), 2000) - } + submitting.set(false); + submitSuccess.set(true); + setTimeout(() => submitSuccess.set(false), 2000); + }; -
+
- {title} Cover Image - + {title} Cover Image +
-
-
+
+
- + -
of {currentAniListAnime.data.MediaList.media.episodes}
+ type="number" + name="episodes" + min="0" + max={currentAniListAnime.data.MediaList.media.episodes} + id="episodes" + class="border {currentAniListAnime.data.MediaList + .progress < 0 || + currentAniListAnime.data.MediaList.progress > + currentAniListAnime.data.MediaList.media.episodes + ? '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" + bind:value={currentAniListAnime.data.MediaList.progress} + required + /> +
+ of {currentAniListAnime.data.MediaList.media.episodes} +
-
- - {#each statusOptions as option} @@ -386,150 +460,218 @@
-
- +
- - +
-
-
+
+ id="startedAt" + type="date" + name="startedAt" + class="border text-sm rounded-lg + focus:ring-blue-500 focus:border-blue-500 block w-full ps-10 p-2.5 bg-gray-700 border-gray-600 + placeholder-gray-400 text-white" + value={startedAtDate} + placeholder="Date Started" + />
- - +
-
-
+
+ id="completedAt" + type="date" + name="completedAt" + class="border text-sm rounded-lg + block w-full ps-10 p-2.5 bg-gray-700 border-gray-600 + placeholder-gray-400 text-white focus:ring-blue-500 focus:border-blue-500" + value={completedAtDate} + placeholder="Date Completed" + />
- + + type="number" + name="repeat" + min="0" + id="repeat" + class="border {currentAniListAnime.data.MediaList + .repeat < 0 + ? '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" + bind:value={currentAniListAnime.data.MediaList.repeat} + required + />
-
+
- - + +
-
-

AniList

+
+

+ AniList +

- + -
-
-
-
-
-

- Summary -

+

Summary

{@html currentAniListAnime.data.MediaList.media.description}

- \ No newline at end of file + + diff --git a/frontend/src/helperComponents/AnimeTable.svelte b/frontend/src/helperComponents/AnimeTable.svelte index 6cb756c..272593c 100644 --- a/frontend/src/helperComponents/AnimeTable.svelte +++ b/frontend/src/helperComponents/AnimeTable.svelte @@ -1,109 +1,106 @@
- - {#each $headerRows as headerRow (headerRow.id)} - - - {#each headerRow.cells as cell (cell.id)} - - + {#each headerRow.cells as cell (cell.id)} + + - - {/each} - - - {/each} + > +
+ + {#if props.sort.order === "asc"} + ⬇️ + {:else if props.sort.order === "desc"} + ⬆️ + {/if} +
+ + + {/each} + + + {/each} {#each $rows as row (row.id)} - + {#each row.cells as cell (cell.id)} {/each} diff --git a/frontend/src/helperComponents/AvatarMenu.svelte b/frontend/src/helperComponents/AvatarMenu.svelte index 0725efb..b3de7d9 100644 --- a/frontend/src/helperComponents/AvatarMenu.svelte +++ b/frontend/src/helperComponents/AvatarMenu.svelte @@ -1,76 +1,99 @@
- + diff --git a/frontend/src/helperComponents/Pagination.svelte b/frontend/src/helperComponents/Pagination.svelte index 8ec82f3..72b0946 100644 --- a/frontend/src/helperComponents/Pagination.svelte +++ b/frontend/src/helperComponents/Pagination.svelte @@ -50,14 +50,14 @@ {#if page === 1}
  • {:else}
  • @@ -66,26 +66,26 @@ {#if i + 1 === page}
  • + class="flex items-center justify-center px-4 h-10 leading-tight border bg-gray-100 border-gray-700 bg-gray-700 text-white">{i + 1}
  • {:else}
  • + class="flex items-center justify-center px-4 h-10 leading-tight border dark border-gray-700 text-gray-400 hover:bg-gray-700 hover:text-white">{i + 1}
  • {/if} {/each} {#if page === aniListWatchListLoaded.data.Page.pageInfo.lastPage}
  • {:else}
  • @@ -96,7 +96,7 @@
    Page #
    + {#each $headerRows as headerRow (headerRow.id)} + +
    -
    - - {#if props.sort.order === 'asc'} - ⬇️ - {:else if props.sort.order === 'desc'} - ⬆️ - {/if} -
    -
    - +