fix(frontend): Svelte 5 mount API and route-driven refresh
- loader action used new Component() plus $destroy, both removed in Svelte 5 (component_api_invalid_new crashed every refresh click before the reload ran); rewritten on mount/unmount with a real action destroy for the leaked subscription - homecoming refresh moves off the legacy $: block, which never tracked the runes-backed router.location, onto the sanctioned onRouteLoaded callback with identical guard semantics; unused router import dropped so the check stays warning-free
This commit is contained in:
+22
-14
@@ -21,7 +21,6 @@
|
||||
import { CheckIfMALLoggedInAndSetUser } from "./helperModules/CheckIfMyAnimeListLoggedIn.svelte";
|
||||
import { CheckIfSimklLoggedInAndSetUser } from "./helperModules/CheckIsSimklLoggedIn.svelte";
|
||||
import {App} from "../bindings/AniTrack";
|
||||
import { router } from "svelte-spa-router";
|
||||
import ErrorModal from "./helperComponents/ErrorModal.svelte";
|
||||
|
||||
onMount(async () => {
|
||||
@@ -39,26 +38,35 @@
|
||||
!isSimklLoggedIn && (await CheckIfSimklLoggedInAndSetUser());
|
||||
});
|
||||
|
||||
$: if (router.location === "/" && $watchlistNeedsRefresh) {
|
||||
(async () => {
|
||||
if ($aniListLoggedIn && $aniListPrimary) {
|
||||
await CheckIfAniListLoggedInAndLoadWatchList();
|
||||
}
|
||||
if ($malLoggedIn && $malPrimary) {
|
||||
await App.GetMyAnimeList(1000).then((w) => malWatchList.set(w));
|
||||
}
|
||||
if ($simklLoggedIn && $simklPrimary) {
|
||||
await App.SimklGetUserWatchlist().then((w) => simklWatchList.set(w));
|
||||
}
|
||||
import { get } from "svelte/store";
|
||||
|
||||
watchlistNeedsRefresh.set(false);
|
||||
})();
|
||||
// Reloads all watchlists when returning home with the refresh flag set
|
||||
// (e.g. after saving changes on a detail page). Driven by the router's
|
||||
// onRouteLoaded callback: the old `$: ... router.location ...` reactive
|
||||
// statement did not reliably re-fire on navigation under Svelte 5,
|
||||
// so homecoming refreshes silently never ran.
|
||||
async function refreshHomeWatchlists(location: string): Promise<void> {
|
||||
if (location !== "/" || !get(watchlistNeedsRefresh)) return;
|
||||
if (get(aniListLoggedIn) && get(aniListPrimary)) {
|
||||
await CheckIfAniListLoggedInAndLoadWatchList();
|
||||
}
|
||||
if (get(malLoggedIn) && get(malPrimary)) {
|
||||
await App.GetMyAnimeList(1000).then((w) => malWatchList.set(w));
|
||||
}
|
||||
if (get(simklLoggedIn) && get(simklPrimary)) {
|
||||
await App.SimklGetUserWatchlist().then((w) => simklWatchList.set(w));
|
||||
}
|
||||
|
||||
watchlistNeedsRefresh.set(false);
|
||||
}
|
||||
</script>
|
||||
|
||||
<Header />
|
||||
<ErrorModal />
|
||||
<Router
|
||||
onRouteLoaded={(detail) => {
|
||||
void refreshHomeWatchlists(detail.location);
|
||||
}}
|
||||
routes={{
|
||||
"/": Home,
|
||||
"/anime/:id": wrap({
|
||||
|
||||
@@ -1,18 +1,29 @@
|
||||
import { mount, unmount } from 'svelte';
|
||||
import Spinner from '../helperComponents/Spinner.svelte';
|
||||
|
||||
export default (node: any, loading: any) => {
|
||||
let Spin: any
|
||||
loading.subscribe((loading: any) => {
|
||||
if(loading){
|
||||
Spin = new Spinner({
|
||||
let app: any;
|
||||
const unsubscribe = loading.subscribe((isLoading: any) => {
|
||||
if (isLoading && !app) {
|
||||
app = mount(Spinner, {
|
||||
target: node,
|
||||
intro: true
|
||||
})
|
||||
} else {
|
||||
if(Spin){
|
||||
Spin?.$destroy?.()
|
||||
Spin = undefined;
|
||||
});
|
||||
} else if (!isLoading && app) {
|
||||
const current = app;
|
||||
app = undefined;
|
||||
// Teardown must never break the caller.
|
||||
void unmount(current).catch(() => {});
|
||||
}
|
||||
});
|
||||
return {
|
||||
destroy() {
|
||||
unsubscribe();
|
||||
if (app) {
|
||||
const current = app;
|
||||
app = undefined;
|
||||
void unmount(current).catch(() => {});
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user