mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-14 05:06:16 -08:00
162 lines
5.6 KiB
TypeScript
162 lines
5.6 KiB
TypeScript
import {
|
|
HttpClient,
|
|
provideHttpClient,
|
|
withInterceptorsFromDi,
|
|
} from '@angular/common/http';
|
|
import {
|
|
ApplicationConfig,
|
|
inject,
|
|
importProvidersFrom,
|
|
provideZoneChangeDetection,
|
|
} from '@angular/core';
|
|
import { MAT_FORM_FIELD_DEFAULT_OPTIONS } from '@angular/material/form-field';
|
|
import { provideAnimations } from '@angular/platform-browser/animations';
|
|
import { provideRouter, withComponentInputBinding } from '@angular/router';
|
|
import { provideServiceWorker } from '@angular/service-worker';
|
|
import { provideEffects } from '@ngrx/effects';
|
|
import { provideRouterStore, routerReducer } from '@ngrx/router-store';
|
|
import { provideStore } from '@ngrx/store';
|
|
import { provideStoreDevtools } from '@ngrx/store-devtools';
|
|
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
|
|
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
|
|
import { PlaylistEffects, playlistReducer } from '@iptvnator/m3u-state';
|
|
import { NgxIndexedDBModule } from 'ngx-indexed-db';
|
|
import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader';
|
|
import {
|
|
PORTAL_EXTERNAL_PLAYBACK,
|
|
PORTAL_PLAYER,
|
|
} from '@iptvnator/portal/shared/util';
|
|
import { PLAYLIST_PLAYER_ACTIONS } from '@iptvnator/playlist/shared/util';
|
|
import { provideXtreamDataSource } from '@iptvnator/portal/xtream/data-access';
|
|
import { DataService } from '@iptvnator/services';
|
|
import { dbConfig } from '@iptvnator/shared/interfaces';
|
|
import { AppConfig } from '../environments/environment';
|
|
import { routes } from './app.routes';
|
|
import { ElectronService } from './services/electron.service';
|
|
import { ExternalPlaybackService } from './services/external-playback.service';
|
|
import { PlayerService } from './services/player.service';
|
|
import {
|
|
AppPortalNavigationActionsService,
|
|
providePortalNavigationActions,
|
|
} from './services/portal-navigation-actions.service';
|
|
import { providePortalPlaybackPositions } from './services/portal-playback-positions.service';
|
|
import { PwaService } from './services/pwa.service';
|
|
import { shouldEnableServiceWorker } from './services/runtime-config';
|
|
import { provideWorkspaceShellActions } from './services/workspace-shell-actions.service';
|
|
|
|
// AoT requires an exported function for factories
|
|
export function HttpLoaderFactory(http: HttpClient): TranslateHttpLoader {
|
|
return new TranslateHttpLoader(http, './assets/i18n/', '.json');
|
|
}
|
|
|
|
/**
|
|
* Synchronously read the user's preferred language from localStorage so the
|
|
* very first render uses the right locale instead of flashing English first
|
|
* and re-rendering once the IDB-backed settings finish loading.
|
|
*
|
|
* The hint is written by AppComponent.initSettings() whenever the saved
|
|
* settings resolve, so first-ever boots fall back to English (no hint
|
|
* present yet) and every subsequent boot uses the saved language.
|
|
*/
|
|
const SUPPORTED_LANGS = new Set([
|
|
'ar',
|
|
'ary',
|
|
'by',
|
|
'de',
|
|
'el',
|
|
'en',
|
|
'es',
|
|
'fr',
|
|
'it',
|
|
'ja',
|
|
'ko',
|
|
'nl',
|
|
'pl',
|
|
'pt',
|
|
'ru',
|
|
'tr',
|
|
'zh',
|
|
'zhtw',
|
|
]);
|
|
export const PREFERRED_LANGUAGE_STORAGE_KEY = 'iptvnator:preferred-language';
|
|
export function getInitialLanguage(): string {
|
|
try {
|
|
const saved = localStorage.getItem(PREFERRED_LANGUAGE_STORAGE_KEY);
|
|
if (saved && SUPPORTED_LANGS.has(saved)) {
|
|
return saved;
|
|
}
|
|
} catch {
|
|
// localStorage may throw in privacy modes; fall through to default.
|
|
}
|
|
return 'en';
|
|
}
|
|
|
|
/**
|
|
* Conditionally provides the necessary service based on the current environment
|
|
*/
|
|
export function DataFactory() {
|
|
if (window.electron) {
|
|
return inject(ElectronService);
|
|
}
|
|
return inject(PwaService);
|
|
}
|
|
|
|
export const appConfig: ApplicationConfig = {
|
|
providers: [
|
|
provideZoneChangeDetection({ eventCoalescing: true }),
|
|
provideRouter(routes, withComponentInputBinding()),
|
|
provideAnimations(),
|
|
provideHttpClient(withInterceptorsFromDi()),
|
|
provideStore({
|
|
router: routerReducer,
|
|
playlistState: playlistReducer,
|
|
}),
|
|
provideEffects([PlaylistEffects]),
|
|
provideRouterStore(),
|
|
...(AppConfig.production ? [] : [provideStoreDevtools({ maxAge: 25 })]),
|
|
provideServiceWorker('ngsw-worker.js', {
|
|
enabled: shouldEnableServiceWorker(),
|
|
registrationStrategy: 'registerWhenStable:30000',
|
|
}),
|
|
importProvidersFrom(
|
|
NgxIndexedDBModule.forRoot(dbConfig),
|
|
NgxSkeletonLoaderModule.forRoot({
|
|
animation: 'pulse',
|
|
loadingText: 'This item is actually loading...',
|
|
}),
|
|
TranslateModule.forRoot({
|
|
defaultLanguage: getInitialLanguage(),
|
|
loader: {
|
|
provide: TranslateLoader,
|
|
useFactory: HttpLoaderFactory,
|
|
deps: [HttpClient],
|
|
},
|
|
})
|
|
),
|
|
{
|
|
provide: DataService,
|
|
useFactory: DataFactory,
|
|
},
|
|
{
|
|
provide: PORTAL_PLAYER,
|
|
useExisting: PlayerService,
|
|
},
|
|
{
|
|
provide: PORTAL_EXTERNAL_PLAYBACK,
|
|
useExisting: ExternalPlaybackService,
|
|
},
|
|
...providePortalPlaybackPositions(),
|
|
...providePortalNavigationActions(),
|
|
{
|
|
provide: PLAYLIST_PLAYER_ACTIONS,
|
|
useExisting: AppPortalNavigationActionsService,
|
|
},
|
|
...provideWorkspaceShellActions(),
|
|
...provideXtreamDataSource(),
|
|
{
|
|
provide: MAT_FORM_FIELD_DEFAULT_OPTIONS,
|
|
useValue: { appearance: 'outline', subscriptSizing: 'dynamic' },
|
|
},
|
|
],
|
|
};
|