Files
iptvnator/apps/web/src/app/settings/settings-options.ts
T
4grayandClaude Fable 5.1 6f7973a9fb feat(updater): nightly builds and a stable/nightly update channel (#1608)
* feat(updater): nightly builds and a stable/nightly update channel

Every master push publishes its artifacts as a prerelease of
4gray/iptvnator-nightly instead of the rolling test-master draft, with a
version of <next patch>-nightly.<commit date>.<run number> applied in
every build job. Settings → About gains an Update channel switch;
AppUpdateService re-points electron-updater per check (feed repository,
allowPrerelease, channel name, allowDowngrade reset) and reads release
notes from the repository the requested version belongs to. Channel
switches are forward-only: a nightly build stays until a newer stable
release exists.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* fix(updater): compute the nightly version once and keep re-runs safe

Review follow-ups: the nightly version is resolved by a leading job and
handed to every build job, and the patch is bumped only when the base
tag already exists so the release-cut window stays below the imminent
release. A re-run never deletes a published nightly; only a draft left
by a failed run is replaced. Typed update-status literals in the
remaining specs carry the new channel fields.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* test(packaging): expect the nightly-version prerequisite in the build workflow graph

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-15 17:49:22 +02:00

229 lines
5.8 KiB
TypeScript

import {
CoverSize,
EpgViewMode,
StartupBehavior,
Theme,
VideoPlayer,
} from '@iptvnator/shared/interfaces';
import {
CoverSizeOption,
EpgViewModeOption,
SettingsPlayerOption,
SettingsSection,
StartupBehaviorOption,
StartupWindowModeOption,
ThemeOption,
UpdateChannelOption,
} from './settings.models';
export const SETTINGS_THEME_OPTIONS: ThemeOption[] = [
{
value: Theme.LightTheme,
icon: 'light_mode',
labelKey: 'THEMES.LIGHT_THEME',
},
{
value: Theme.DarkTheme,
icon: 'dark_mode',
labelKey: 'THEMES.DARK_THEME',
},
{
value: Theme.SystemTheme,
icon: 'desktop_windows',
labelKey: 'THEMES.SYSTEM_THEME',
},
];
export const SETTINGS_COVER_SIZE_OPTIONS: CoverSizeOption[] = [
{
value: 'small' satisfies CoverSize,
icon: 'view_module',
labelKey: 'SETTINGS.COVER_SIZE_SMALL',
},
{
value: 'medium' satisfies CoverSize,
icon: 'view_comfy',
labelKey: 'SETTINGS.COVER_SIZE_MEDIUM',
},
{
value: 'large' satisfies CoverSize,
icon: 'view_quilt',
labelKey: 'SETTINGS.COVER_SIZE_LARGE',
},
];
export const SETTINGS_EPG_VIEW_MODE_OPTIONS: EpgViewModeOption[] = [
{
value: 'timeline' satisfies EpgViewMode,
icon: 'view_timeline',
labelKey: 'SETTINGS.EPG_VIEW_MODE_TIMELINE',
},
{
value: 'list' satisfies EpgViewMode,
icon: 'view_list',
labelKey: 'SETTINGS.EPG_VIEW_MODE_LIST',
},
];
export const SETTINGS_STARTUP_BEHAVIOR_OPTIONS: StartupBehaviorOption[] = [
{
value: StartupBehavior.FirstView,
labelKey: 'SETTINGS.STARTUP_BEHAVIOR_FIRST_VIEW',
},
{
value: StartupBehavior.RestoreLastView,
labelKey: 'SETTINGS.STARTUP_BEHAVIOR_RESTORE_LAST_VIEW',
},
];
export const SETTINGS_STARTUP_WINDOW_MODE_OPTIONS: StartupWindowModeOption[] = [
{
value: 'normal',
labelKey: 'SETTINGS.STARTUP_WINDOW_MODE_NORMAL',
},
{
value: 'maximized',
labelKey: 'SETTINGS.STARTUP_WINDOW_MODE_MAXIMIZED',
},
{
value: 'fullscreen',
labelKey: 'SETTINGS.STARTUP_WINDOW_MODE_FULLSCREEN',
},
];
export const SETTINGS_UPDATE_CHANNEL_OPTIONS: UpdateChannelOption[] = [
{
value: 'stable',
labelKey: 'SETTINGS.APP_UPDATE_CHANNEL_STABLE',
},
{
value: 'nightly',
labelKey: 'SETTINGS.APP_UPDATE_CHANNEL_NIGHTLY',
},
];
export const SETTINGS_OS_PLAYER_OPTIONS: SettingsPlayerOption[] = [
{
id: VideoPlayer.MPV,
labelKey: 'SETTINGS.PLAYER_MPV',
},
{
id: VideoPlayer.VLC,
labelKey: 'SETTINGS.PLAYER_VLC',
},
];
export const SETTINGS_EMBEDDED_PLAYER_OPTIONS: SettingsPlayerOption[] = [
{
id: VideoPlayer.Html5Player,
labelKey: 'SETTINGS.PLAYER_HTML5',
},
{
id: VideoPlayer.VideoJs,
labelKey: 'SETTINGS.PLAYER_VIDEOJS',
},
{
id: VideoPlayer.ArtPlayer,
labelKey: 'SETTINGS.PLAYER_ARTPLAYER',
},
];
export interface SettingsPlayerAvailability {
supportsEmbeddedMpv: boolean;
supportsManagedExternalPlayers: boolean;
}
/**
* Built-in web players are always offered; the OS-backed ones only show up
* when the current runtime can actually launch them.
*/
export function buildSettingsPlayerOptions({
supportsEmbeddedMpv,
supportsManagedExternalPlayers,
}: SettingsPlayerAvailability): SettingsPlayerOption[] {
return [
...SETTINGS_EMBEDDED_PLAYER_OPTIONS,
...(supportsEmbeddedMpv
? [
{
id: VideoPlayer.EmbeddedMpv,
labelKey: 'SETTINGS.PLAYER_EMBEDDED_MPV',
},
]
: []),
...(supportsManagedExternalPlayers ? SETTINGS_OS_PLAYER_OPTIONS : []),
];
}
export interface SettingsSectionVisibility {
supportsEpg: boolean;
supportsRemoteControl: boolean;
}
export function buildSettingsSectionNavItems({
supportsEpg,
supportsRemoteControl,
}: SettingsSectionVisibility): SettingsSection[] {
return [
{
id: 'general',
label: 'SETTINGS.NAV_GENERAL',
icon: 'tune',
visible: true,
},
{
id: 'playback',
label: 'SETTINGS.NAV_PLAYBACK',
icon: 'play_circle',
visible: true,
},
{
id: 'epg',
label: 'SETTINGS.NAV_EPG',
icon: 'calendar_month',
visible: supportsEpg,
},
{
id: 'dashboard',
label: 'SETTINGS.NAV_DASHBOARD',
icon: 'dashboard',
visible: true,
},
{
// Must match the section's HTML id (`remote-control`) so the
// settings-section-scroll directive can resolve the anchor.
// Was previously '@iptvnator/ui/remote-control' (the NX lib
// name), which meant clicking the nav item silently no-op'd
// because document.getElementById of that string returned null.
id: 'remote-control',
label: 'SETTINGS.NAV_REMOTE',
icon: 'smartphone',
visible: supportsRemoteControl,
},
{
id: 'tmdb',
label: 'SETTINGS.NAV_TMDB',
icon: 'movie',
visible: true,
},
{
id: 'backup',
label: 'SETTINGS.NAV_BACKUP',
icon: 'backup',
visible: true,
},
{
id: 'reset',
label: 'SETTINGS.NAV_RESET',
icon: 'delete_sweep',
visible: true,
},
{
id: 'about',
label: 'SETTINGS.NAV_ABOUT',
icon: 'info',
visible: true,
},
];
}