mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-09 17:36:15 -08:00
Plan thread C1, journey **J1 `launch`**, counter **`renderer.initialBytes`**. Stacked on #1694 → #1693 → #1692; merge in order. `apps/web/src/app/app-date-locales.ts` imported the locale data of all 18 supported languages eagerly, so every user shipped and parsed all of it at startup. Each locale is now a dynamic import keyed by the Angular locale id that `normalizeDateLocale()` derives from the app language (`by` → `be`, `ary` → `ar-MA`, `zhtw` → `zh-Hant`); English needs no data. Ordering is preserved so no template renders a locale whose data has not arrived (Angular throws in that case): - `main.ts` awaits the initial language's data (from `getInitialLanguage()`) before `bootstrapApplication`. - Both `TranslateService.use()` call sites, `AppComponent.initSettings()` and `SettingsFormFacade.applySavedSettings()`, register the data first through the new `AppDateLocaleService`. - A failed load never leaves the locale without data: English formatting is registered under the requested id (eager 1.1 KB `@angular/common/locales/en`), so `DatePipe` renders instead of throwing; the locale is not marked registered, so the next call retries and a success replaces the fallback (review follow-up). - `AppDateLocaleService.use()` orders switches by request, not by completion: a switch whose data arrives after a newer request is dropped, so the language chosen last wins (review follow-up). No kill switch: behavior is identical once the locale resolves, and the only new failure mode (a same-origin chunk failing to load) is shared with every lazy route. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
37 lines
1.8 KiB
TypeScript
37 lines
1.8 KiB
TypeScript
import { bootstrapApplication } from '@angular/platform-browser';
|
|
import { resolveRestoredRendererRoute } from '@iptvnator/shared/interfaces';
|
|
import { registerAppDateLocale } from './app/app-date-locales';
|
|
import { AppComponent } from './app/app.component';
|
|
import { appConfig, getInitialLanguage } from './app/app.config';
|
|
|
|
// 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);
|
|
}
|
|
|
|
// Angular ships only English locale data; the preferred language's data is a
|
|
// lazy chunk. It is awaited before bootstrapping because the first route
|
|
// renders dates with that locale, and a locale without data throws. English
|
|
// (the default) resolves immediately.
|
|
registerAppDateLocale(getInitialLanguage())
|
|
.then(() => 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));
|