mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-09 01:16: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>
38 lines
2.7 KiB
Markdown
38 lines
2.7 KiB
Markdown
# Date Handling
|
|
|
|
## Rules
|
|
|
|
- Use native `Date`, ISO strings, and epoch timestamps as the stored/runtime values.
|
|
- Use `date-fns` for parsing, arithmetic, and normalization logic.
|
|
- Use Angular `DatePipe` in templates when the value is already a `Date`, ISO string, or epoch timestamp.
|
|
- Use cached `Intl.DateTimeFormat` helpers in TypeScript-only formatting paths where Angular pipes are not available.
|
|
- Do not add new `moment` usage. The app no longer depends on it.
|
|
|
|
## Locale Strategy
|
|
|
|
- Date display should follow the user-selected app language from `TranslateService`.
|
|
- When a template renders localized month or weekday names, pass the normalized app locale explicitly to `DatePipe`.
|
|
- Angular locale data is loaded lazily per language by `registerAppDateLocale()` in [apps/web/src/app/app-date-locales.ts](/apps/web/src/app/app-date-locales.ts): `main.ts` awaits the initial language's data before bootstrapping, and every `TranslateService.use()` call site registers the data first (through `AppDateLocaleService`), because the switch re-renders dates with the new locale and a locale without data throws. English needs no data. `AppDateLocaleService.use()` applies only the language requested last when switches overlap, and a locale whose chunk fails to load falls back to English formatting under that locale id until a later call loads it.
|
|
- App language aliases are normalized in [libs/ui/pipes/src/lib/date-format.util.ts](/libs/ui/pipes/src/lib/date-format.util.ts):
|
|
- `ary` -> `ar-MA`
|
|
- `by` -> `be`
|
|
- `zhtw` -> `zh-Hant`
|
|
|
|
## Parsing Boundaries
|
|
|
|
- Normalize provider-specific or legacy date strings to ISO as early as possible.
|
|
- Keep optional epoch fields such as `startTimestamp` and `stopTimestamp` when the provider already supplies them.
|
|
- Avoid new non-standard `Date.parse(...)` usage for provider formats; prefer explicit `date-fns` parsing when the input is not ISO.
|
|
- Xtream `added` / `last_modified` values are provider-supplied epoch fields.
|
|
Normalize them through `toXtreamRecentlyAddedTimestamp()` /
|
|
`toXtreamRecentlyAddedEpochSeconds()` from `@iptvnator/shared/interfaces`
|
|
before ranking or storing recently-added content. Values more than 24 hours
|
|
in the future are treated as invalid so provider placeholders such as
|
|
`2030-01-01` cannot permanently pin the top of recently-added rails.
|
|
Recently-added ranking uses `added` before `last_modified` for live/VOD
|
|
content and `last_modified` before `added` for series. The VOD/live fallback
|
|
is intentional for providers that omit `added` but still expose a valid
|
|
`last_modified` epoch. Legacy cached millisecond epochs in `content.added`
|
|
are migrated to epoch seconds during database startup so indexed dashboard
|
|
queries can continue to compare and sort text timestamps directly.
|