Regenerated bindings with wails3 generate bindings (1 service, 29 methods, 25 models) into frontend/bindings/AniTrack as TypeScript; output verified byte-deterministic across regens, so it is committed like wailsjs was.
- 10 Svelte files: wailsjs/go/main/App imports -> import {App} from bindings/AniTrack with App.* call prefixes. No logic or markup changes.
- WebsiteLink.svelte: BrowserOpenURL -> Browser.OpenURL from @wailsio/runtime.
- AvatarMenu.svelte: runtime.Quit -> Application.Quit from @wailsio/runtime.
- package.json: add @wailsio/runtime pinned to 3.0.0-beta.20 (exact, matching the Go framework); lockfile updated, all deps still max in-range, majors deferred.
- Production vite build passes with the new bindings.
233 lines
7.3 KiB
Svelte
233 lines
7.3 KiB
Svelte
<script lang="ts" context="module">
|
|
import {App} from "../../bindings/AniTrack";
|
|
import type {
|
|
AniListCurrentUserWatchList,
|
|
AniListGetSingleAnime,
|
|
} from "../anilist/types/AniListCurrentUserWatchListType.js";
|
|
import { writable } from "svelte/store";
|
|
import type {
|
|
SimklAnime,
|
|
SimklUser,
|
|
SimklWatchList,
|
|
} from "../simkl/types/simklTypes";
|
|
import {
|
|
type AniListUser,
|
|
MediaListSort,
|
|
} from "../anilist/types/AniListTypes";
|
|
import type {
|
|
MALAnime,
|
|
MALWatchlist,
|
|
MyAnimeListUser,
|
|
} from "../mal/types/MALTypes";
|
|
import type { TableItems } from "../helperTypes/TableTypes";
|
|
import { AniListGetSingleAnimeDefaultData } from "../helperDefaults/AniListGetSingleAnime";
|
|
|
|
export let aniListAnime = writable(AniListGetSingleAnimeDefaultData);
|
|
export let title = writable("");
|
|
export let aniListLoggedIn = writable(false);
|
|
export let simklLoggedIn = writable(false);
|
|
export let malLoggedIn = writable(false);
|
|
export const serviceLoggingIn = writable([] as string[]);
|
|
export let simklWatchList = writable({} as SimklWatchList);
|
|
export let aniListPrimary = writable(true);
|
|
export let simklPrimary = writable(false);
|
|
export let malPrimary = writable(false);
|
|
export let simklUser = writable({} as SimklUser);
|
|
export let aniListUser = writable({} as AniListUser);
|
|
export let malUser = writable({} as MyAnimeListUser);
|
|
export let aniListWatchlist = writable({} as AniListCurrentUserWatchList);
|
|
export let malWatchList = writable({} as MALWatchlist);
|
|
export let malAnime = writable({} as MALAnime);
|
|
export let simklAnime = writable({} as SimklAnime);
|
|
export let loading = writable(false);
|
|
export let tableItems = writable([] as TableItems);
|
|
export let watchlistNeedsRefresh = writable(false);
|
|
export let aniListSort = writable(MediaListSort.UpdatedTimeDesc);
|
|
|
|
export let watchListPage = writable(1);
|
|
export let animePerPage = writable(20);
|
|
|
|
let isAniListPrimary: boolean;
|
|
let page: number;
|
|
let perPage: number;
|
|
let sort: string;
|
|
let aniWatchlist: AniListCurrentUserWatchList;
|
|
let currentAniListAnime: AniListGetSingleAnime;
|
|
|
|
let isMalLoggedIn: boolean;
|
|
let isSimklLoggedIn: boolean;
|
|
|
|
aniListPrimary.subscribe((value) => (isAniListPrimary = value));
|
|
watchListPage.subscribe((value) => (page = value));
|
|
animePerPage.subscribe((value) => (perPage = value));
|
|
aniListWatchlist.subscribe((value) => (aniWatchlist = value));
|
|
malLoggedIn.subscribe((value) => (isMalLoggedIn = value));
|
|
simklLoggedIn.subscribe((value) => (isSimklLoggedIn = value));
|
|
aniListAnime.subscribe((value) => (currentAniListAnime = value));
|
|
aniListSort.subscribe((value) => (sort = value));
|
|
|
|
export interface ApiError {
|
|
service: string;
|
|
message: string;
|
|
statusCode?: string;
|
|
canRetry: boolean;
|
|
}
|
|
export const apiError = writable<ApiError | null>(null);
|
|
export const isApiDown = writable(false);
|
|
export function setApiError(
|
|
service: string,
|
|
message: string,
|
|
statusCode?: string,
|
|
canRetry: boolean = true,
|
|
) {
|
|
apiError.set({
|
|
service,
|
|
message,
|
|
statusCode,
|
|
canRetry,
|
|
});
|
|
isApiDown.set(true);
|
|
}
|
|
export function clearApiError() {
|
|
apiError.set(null);
|
|
isApiDown.set(false);
|
|
}
|
|
|
|
export async function GetAnimeSingleItem(
|
|
aniId: number,
|
|
login: boolean,
|
|
): Promise<""> {
|
|
await App.GetAniListItem(aniId, login).then((aniListResult) => {
|
|
let finalResult: AniListGetSingleAnime;
|
|
finalResult = aniListResult;
|
|
if (login === false) {
|
|
finalResult.data.MediaList.status = "";
|
|
finalResult.data.MediaList.score = 0;
|
|
finalResult.data.MediaList.progress = 0;
|
|
finalResult.data.MediaList.notes = "";
|
|
finalResult.data.MediaList.repeat = 0;
|
|
finalResult.data.MediaList.startedAt.day = 0;
|
|
finalResult.data.MediaList.startedAt.month = 0;
|
|
finalResult.data.MediaList.startedAt.year = 0;
|
|
finalResult.data.MediaList.completedAt.day = 0;
|
|
finalResult.data.MediaList.completedAt.month = 0;
|
|
finalResult.data.MediaList.completedAt.year = 0;
|
|
}
|
|
aniListAnime.set(finalResult);
|
|
title.set(
|
|
currentAniListAnime.data.MediaList.media.title.english === ""
|
|
? currentAniListAnime.data.MediaList.media.title.romaji
|
|
: currentAniListAnime.data.MediaList.media.title.english,
|
|
);
|
|
});
|
|
if (isMalLoggedIn) {
|
|
await App.GetMyAnimeListAnime(
|
|
currentAniListAnime.data.MediaList.media.idMal,
|
|
).then((malResult) => {
|
|
malAnime.set(malResult);
|
|
});
|
|
}
|
|
if (isSimklLoggedIn) {
|
|
await App.SimklSearch(currentAniListAnime.data.MediaList).then(
|
|
(value: SimklAnime) => {
|
|
simklAnime.set(value);
|
|
},
|
|
);
|
|
}
|
|
return "";
|
|
}
|
|
|
|
export function setServiceLoggingIn(service: string, isLoggingIn: boolean): void {
|
|
serviceLoggingIn.update((services) => {
|
|
if (isLoggingIn) {
|
|
return services.includes(service) ? services : [...services, service];
|
|
}
|
|
return services.filter((s) => s !== service);
|
|
});
|
|
}
|
|
|
|
export function isServiceLoggingIn(service: string): boolean {
|
|
let loggingIn = false;
|
|
serviceLoggingIn.subscribe((services) => {
|
|
loggingIn = services.includes(service);
|
|
})();
|
|
return loggingIn;
|
|
}
|
|
|
|
export function loginToSimkl(): void {
|
|
setServiceLoggingIn("simkl", true);
|
|
App.GetSimklLoggedInUser()
|
|
.then((user) => {
|
|
if (Object.keys(user).length === 0) {
|
|
simklLoggedIn.set(false);
|
|
} else {
|
|
simklUser.set(user);
|
|
App.SimklGetUserWatchlist().then((result) => {
|
|
simklWatchList.set(result);
|
|
simklLoggedIn.set(true);
|
|
});
|
|
}
|
|
})
|
|
.finally(() => setServiceLoggingIn("simkl", false));
|
|
}
|
|
|
|
export function loginToAniList(): void {
|
|
setServiceLoggingIn("anilist", true);
|
|
App.GetAniListLoggedInUser()
|
|
.then((result) => {
|
|
aniListUser.set(result);
|
|
if (isAniListPrimary) {
|
|
App.GetAniListUserWatchingList(page, perPage, sort).then((result) => {
|
|
aniListWatchlist.set(result);
|
|
aniListLoggedIn.set(true);
|
|
});
|
|
} else {
|
|
aniListLoggedIn.set(true);
|
|
}
|
|
})
|
|
.finally(() => setServiceLoggingIn("anilist", false));
|
|
}
|
|
|
|
export function loginToMAL(): void {
|
|
setServiceLoggingIn("mal", true);
|
|
App.GetMyAnimeListLoggedInUser()
|
|
.then((result) => {
|
|
if (!result.name) {
|
|
malUser.set({} as MyAnimeListUser);
|
|
malLoggedIn.set(false);
|
|
return;
|
|
}
|
|
malUser.set(result);
|
|
malLoggedIn.set(true);
|
|
})
|
|
.finally(() => setServiceLoggingIn("mal", false));
|
|
}
|
|
|
|
export function logoutOfAniList(): void {
|
|
App.LogoutAniList().then((result) => {
|
|
console.log(result);
|
|
if (Object.keys(aniWatchlist).length !== 0) {
|
|
aniListWatchlist.set({} as AniListCurrentUserWatchList);
|
|
}
|
|
aniListUser.set({} as AniListUser);
|
|
aniListLoggedIn.set(false);
|
|
});
|
|
}
|
|
|
|
export function logoutOfMAL(): void {
|
|
App.LogoutMyAnimeList().then((result) => {
|
|
console.log(result);
|
|
malUser.set({} as MyAnimeListUser);
|
|
malLoggedIn.set(false);
|
|
});
|
|
}
|
|
|
|
export function logoutOfSimkl(): void {
|
|
App.LogoutSimkl().then((result) => {
|
|
console.log(result);
|
|
simklUser.set({} as SimklUser);
|
|
simklLoggedIn.set(false);
|
|
});
|
|
}
|
|
</script>
|