mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-12 12:06:16 -08:00
feat(web): enable runtime PWA configuration
This commit is contained in:
1 parent
f0af34edef
commit
eafc95bef0
9 files changed
+110
-37
No files matched your search
@@ -40,6 +40,7 @@ import {
|
||||
} 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
|
||||
@@ -113,7 +114,7 @@ export const appConfig: ApplicationConfig = {
|
||||
provideRouterStore(),
|
||||
...(AppConfig.production ? [] : [provideStoreDevtools({ maxAge: 25 })]),
|
||||
provideServiceWorker('ngsw-worker.js', {
|
||||
enabled: AppConfig.production && !!window.electron,
|
||||
enabled: shouldEnableServiceWorker(),
|
||||
registrationStrategy: 'registerWhenStable:30000',
|
||||
}),
|
||||
importProvidersFrom(
|
||||
|
||||
@@ -25,6 +25,7 @@ import {
|
||||
logPortalDebugEvent,
|
||||
logPortalDebugRequest,
|
||||
} from '@iptvnator/portal/shared/util';
|
||||
import { getRuntimeBackendUrl } from './runtime-config';
|
||||
|
||||
interface PwaXtreamResponse {
|
||||
readonly payload?: unknown;
|
||||
@@ -69,7 +70,7 @@ export class PwaService extends DataService {
|
||||
]);
|
||||
|
||||
/** Proxy URL to avoid CORS issues */
|
||||
corsProxyUrl = AppConfig.BACKEND_URL;
|
||||
corsProxyUrl = getRuntimeBackendUrl();
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
import { resolveBackendUrl, shouldEnableServiceWorker } from './runtime-config';
|
||||
|
||||
describe('runtime config helpers', () => {
|
||||
it('uses runtime BACKEND_URL when provided', () => {
|
||||
expect(
|
||||
resolveBackendUrl(
|
||||
{ BACKEND_URL: ' http://self-hosted.local/api ' },
|
||||
'https://fallback.example'
|
||||
)
|
||||
).toBe('http://self-hosted.local/api');
|
||||
});
|
||||
|
||||
it('falls back to the build-time backend URL when runtime config is missing or blank', () => {
|
||||
expect(resolveBackendUrl(undefined, 'https://fallback.example')).toBe(
|
||||
'https://fallback.example'
|
||||
);
|
||||
expect(resolveBackendUrl({}, 'https://fallback.example')).toBe(
|
||||
'https://fallback.example'
|
||||
);
|
||||
expect(
|
||||
resolveBackendUrl(
|
||||
{ BACKEND_URL: ' ' },
|
||||
'https://fallback.example'
|
||||
)
|
||||
).toBe('https://fallback.example');
|
||||
});
|
||||
|
||||
it('enables service worker only for production builds with browser support', () => {
|
||||
expect(
|
||||
shouldEnableServiceWorker(true, {
|
||||
serviceWorker: {},
|
||||
} as Navigator)
|
||||
).toBe(true);
|
||||
expect(
|
||||
shouldEnableServiceWorker(false, { serviceWorker: {} } as Navigator)
|
||||
).toBe(false);
|
||||
expect(shouldEnableServiceWorker(true, {} as Navigator)).toBe(false);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,27 @@
|
||||
import { AppConfig } from '../../environments/environment';
|
||||
|
||||
export interface IptvnatorRuntimeConfig {
|
||||
readonly BACKEND_URL?: string;
|
||||
}
|
||||
|
||||
export function resolveBackendUrl(
|
||||
runtimeConfig: IptvnatorRuntimeConfig | undefined,
|
||||
fallbackUrl: string
|
||||
): string {
|
||||
const runtimeUrl = runtimeConfig?.BACKEND_URL?.trim();
|
||||
return runtimeUrl || fallbackUrl;
|
||||
}
|
||||
|
||||
export function getRuntimeBackendUrl(): string {
|
||||
return resolveBackendUrl(
|
||||
globalThis.window?.__IPTVNATOR_CONFIG__,
|
||||
AppConfig.BACKEND_URL
|
||||
);
|
||||
}
|
||||
|
||||
export function shouldEnableServiceWorker(
|
||||
production = AppConfig.production,
|
||||
navigatorRef: Navigator | undefined = globalThis.navigator
|
||||
): boolean {
|
||||
return production && !!navigatorRef && 'serviceWorker' in navigatorRef;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
window.__IPTVNATOR_CONFIG__ = window.__IPTVNATOR_CONFIG__ || {};
|
||||
@@ -20,6 +20,7 @@
|
||||
<link rel="manifest" href="manifest.webmanifest" />
|
||||
<link rel="apple-touch-icon" href="assets/icons/apple-touch-icon.png" />
|
||||
<link rel="icon" type="image/x-icon" href="assets/icons/favicon.ico" />
|
||||
<script src="assets/app-config.js"></script>
|
||||
<style>
|
||||
/* Inline splash — paints immediately while the JS bundle and the
|
||||
styles.css (~300KB) are still downloading and Angular is
|
||||
@@ -68,11 +69,7 @@
|
||||
</style>
|
||||
</head>
|
||||
<body class="mat-app-background">
|
||||
<div
|
||||
id="initial-splash"
|
||||
role="status"
|
||||
aria-label="Loading IPTVnator"
|
||||
>
|
||||
<div id="initial-splash" role="status" aria-label="Loading IPTVnator">
|
||||
<span class="splash-mark">IPTVnator</span>
|
||||
<span class="splash-spinner" aria-hidden="true"></span>
|
||||
</div>
|
||||
|
||||
Reference in new issue
Block a user