Files
iptvnator/apps/web/src/main.ts
T
4grayandClaude Fable 5.1 6f987d79d8 fix(shell): reload the packaged renderer back onto its in-app route (#1622)
The packaged renderer is index.html over file:// with path routing, so
after in-app navigation the document URL names a path with no file behind
it. A main-process reload (macOS View > Reload, DevTools) failed with
ERR_FILE_NOT_FOUND and stranded the window on Chromium's error page; a
renderer-initiated reload (the settings unsaved-changes guard's confirmed
location.reload()) was cancelled by the will-navigate trust check and
silently did nothing.

Both legs now re-load the packaged index with the route in a restoreRoute
query parameter, which main.ts restores with history.replaceState before
Angular bootstraps. The did-fail-load recovery is deferred to the error
page's dom-ready: a load issued from inside the failure event yields a
document that never receives animation frames and never paints.

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-19 08:43:43 +02:00

34 lines
1.4 KiB
TypeScript

import { bootstrapApplication } from '@angular/platform-browser';
import { resolveRestoredRendererRoute } from '@iptvnator/shared/interfaces';
import { registerAppDateLocales } from './app/app-date-locales';
import { AppComponent } from './app/app.component';
import { appConfig } from './app/app.config';
registerAppDateLocales();
// A reloaded packaged renderer arrives on index.html with the route it was
// on carried in the query string (the Electron main process recovers the
// file:// reload that way). Put that route back before the router reads the
// URL for its initial navigation.
const restoredHref = resolveRestoredRendererRoute(
window.location.href,
document.baseURI
);
if (restoredHref !== null) {
window.history.replaceState(window.history.state, '', restoredHref);
}
bootstrapApplication(AppComponent, appConfig)
.then(() => {
// Splash is rendered eagerly by index.html so the user sees something
// immediately instead of a blank Material-grey background. Once Angular
// is bootstrapped, AppComponent has rendered and we can drop the
// splash. requestAnimationFrame ensures the swap happens after the
// first AppComponent paint, avoiding a flash of empty background
// between splash removal and Angular's first frame.
requestAnimationFrame(() => {
document.getElementById('initial-splash')?.remove();
});
})
.catch((err) => console.error(err));