refactor(app): use runtime capabilities for shell gates

This commit is contained in:
4gray committed 2026-05-22 13:08:00 +03:00
1 parent 33df53f266
commit b51cbcae15
2 files changed
+36 -7

No files matched your search

+27 -1
View File
@@ -8,7 +8,7 @@ import { EpgService } from '@iptvnator/epg/data-access';
import { WORKSPACE_SHELL_ACTIONS } from '@iptvnator/workspace/shell/util';
import { MockProvider } from 'ng-mocks';
import { EMPTY, of } from 'rxjs';
import { DataService } from '@iptvnator/services';
import { DataService, RuntimeCapabilitiesService } from '@iptvnator/services';
import {
Language,
Settings,
@@ -64,9 +64,16 @@ describe('AppComponent', () => {
let snackBar: MatSnackBar;
let store: MockStore;
let translateService: TranslateService;
let runtimeCapabilities: Partial<RuntimeCapabilitiesService>;
const originalElectron = window.electron;
beforeEach(waitForAsync(() => {
runtimeCapabilities = {
isElectron: true,
isMacOS: false,
supportsEpg: true,
};
TestBed.configureTestingModule({
imports: [AppComponent],
providers: [
@@ -83,6 +90,10 @@ describe('AppComponent', () => {
provide: SettingsService,
useClass: MockSettingsService,
},
{
provide: RuntimeCapabilitiesService,
useValue: runtimeCapabilities as RuntimeCapabilitiesService,
},
MockProvider(EpgService, {
fetchEpg: jest.fn(),
}),
@@ -212,4 +223,19 @@ describe('AppComponent', () => {
expect(epgService.fetchEpg).toHaveBeenCalledWith(settings.epgUrl);
expect(snackBar.open).not.toHaveBeenCalled();
});
it('does not fetch EPG settings when runtime does not support EPG', async () => {
const settings: Settings = {
...DEFAULT_SETTINGS,
epgUrl: ['https://example.com/epg.xml'],
};
Object.assign(runtimeCapabilities, { supportsEpg: false });
settingsService.getValueFromLocalStorage.mockReturnValue(of(settings));
component.initSettings();
await fixture.whenStable();
expect(window.electron?.checkEpgFreshness).not.toHaveBeenCalled();
expect(epgService.fetchEpg).not.toHaveBeenCalled();
});
});
+9 -6
View File
@@ -9,7 +9,11 @@ import { WORKSPACE_SHELL_ACTIONS } from '@iptvnator/workspace/shell/util';
import { EpgProgressPanelComponent } from '@iptvnator/ui/epg/progress-panel';
import { PlaylistActions, selectAllPlaylistsMeta } from '@iptvnator/m3u-state';
import { filter, take } from 'rxjs';
import { DataService, SettingsStore } from '@iptvnator/services';
import {
DataService,
RuntimeCapabilitiesService,
SettingsStore,
} from '@iptvnator/services';
import {
AUTO_UPDATE_PLAYLISTS,
Language,
@@ -30,9 +34,7 @@ const debugAppComponent = createDevLogger('AppComponent');
})
export class AppComponent implements OnInit {
@HostBinding('class.macos-platform') get isMacOS() {
return (
window.electron && navigator.platform.toLowerCase().includes('mac')
);
return this.runtime.isMacOS;
}
private actions$ = inject(Actions);
private dataService = inject(DataService);
@@ -43,6 +45,7 @@ export class AppComponent implements OnInit {
private translate = inject(TranslateService);
private settingsService = inject(SettingsService);
private settingsStore = inject(SettingsStore);
private runtime = inject(RuntimeCapabilitiesService);
private readonly workspaceShellActions = inject(WORKSPACE_SHELL_ACTIONS);
/** Default language as fallback */
@@ -75,7 +78,7 @@ export class AppComponent implements OnInit {
document.documentElement.dataset.coverSize = size;
});
if (window.electron) {
if (this.runtime.isElectron) {
document.addEventListener('keydown', (event) => {
if (event.ctrlKey || event.metaKey) {
if (event.key === 'f') {
@@ -128,7 +131,7 @@ export class AppComponent implements OnInit {
// Fetch EPG if URLs are configured (only fetch stale data)
if (
window.electron &&
this.runtime.supportsEpg &&
settings.epgUrl?.length > 0 &&
settings.epgUrl?.some((u) => u !== '')
) {