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:
+15
-7
@@ -21,7 +21,6 @@
|
|||||||
import { CheckIfMALLoggedInAndSetUser } from "./helperModules/CheckIfMyAnimeListLoggedIn.svelte";
|
import { CheckIfMALLoggedInAndSetUser } from "./helperModules/CheckIfMyAnimeListLoggedIn.svelte";
|
||||||
import { CheckIfSimklLoggedInAndSetUser } from "./helperModules/CheckIsSimklLoggedIn.svelte";
|
import { CheckIfSimklLoggedInAndSetUser } from "./helperModules/CheckIsSimklLoggedIn.svelte";
|
||||||
import {App} from "../bindings/AniTrack";
|
import {App} from "../bindings/AniTrack";
|
||||||
import { router } from "svelte-spa-router";
|
|
||||||
import ErrorModal from "./helperComponents/ErrorModal.svelte";
|
import ErrorModal from "./helperComponents/ErrorModal.svelte";
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
@@ -39,26 +38,35 @@
|
|||||||
!isSimklLoggedIn && (await CheckIfSimklLoggedInAndSetUser());
|
!isSimklLoggedIn && (await CheckIfSimklLoggedInAndSetUser());
|
||||||
});
|
});
|
||||||
|
|
||||||
$: if (router.location === "/" && $watchlistNeedsRefresh) {
|
import { get } from "svelte/store";
|
||||||
(async () => {
|
|
||||||
if ($aniListLoggedIn && $aniListPrimary) {
|
// 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();
|
await CheckIfAniListLoggedInAndLoadWatchList();
|
||||||
}
|
}
|
||||||
if ($malLoggedIn && $malPrimary) {
|
if (get(malLoggedIn) && get(malPrimary)) {
|
||||||
await App.GetMyAnimeList(1000).then((w) => malWatchList.set(w));
|
await App.GetMyAnimeList(1000).then((w) => malWatchList.set(w));
|
||||||
}
|
}
|
||||||
if ($simklLoggedIn && $simklPrimary) {
|
if (get(simklLoggedIn) && get(simklPrimary)) {
|
||||||
await App.SimklGetUserWatchlist().then((w) => simklWatchList.set(w));
|
await App.SimklGetUserWatchlist().then((w) => simklWatchList.set(w));
|
||||||
}
|
}
|
||||||
|
|
||||||
watchlistNeedsRefresh.set(false);
|
watchlistNeedsRefresh.set(false);
|
||||||
})();
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Header />
|
<Header />
|
||||||
<ErrorModal />
|
<ErrorModal />
|
||||||
<Router
|
<Router
|
||||||
|
onRouteLoaded={(detail) => {
|
||||||
|
void refreshHomeWatchlists(detail.location);
|
||||||
|
}}
|
||||||
routes={{
|
routes={{
|
||||||
"/": Home,
|
"/": Home,
|
||||||
"/anime/:id": wrap({
|
"/anime/:id": wrap({
|
||||||
|
|||||||
@@ -1,18 +1,29 @@
|
|||||||
|
import { mount, unmount } from 'svelte';
|
||||||
import Spinner from '../helperComponents/Spinner.svelte';
|
import Spinner from '../helperComponents/Spinner.svelte';
|
||||||
|
|
||||||
export default (node: any, loading: any) => {
|
export default (node: any, loading: any) => {
|
||||||
let Spin: any
|
let app: any;
|
||||||
loading.subscribe((loading: any) => {
|
const unsubscribe = loading.subscribe((isLoading: any) => {
|
||||||
if(loading){
|
if (isLoading && !app) {
|
||||||
Spin = new Spinner({
|
app = mount(Spinner, {
|
||||||
target: node,
|
target: node,
|
||||||
intro: true
|
intro: true
|
||||||
})
|
});
|
||||||
} else {
|
} else if (!isLoading && app) {
|
||||||
if(Spin){
|
const current = app;
|
||||||
Spin?.$destroy?.()
|
app = undefined;
|
||||||
Spin = 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