From 139ecd81469c8f1427f09c2e1256ee72f911771f Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Mon, 15 Sep 2025 10:10:47 -0400 Subject: [PATCH] Add typing for browser.js --- .../constants/subtitleStylingOption.ts | 10 +++-- .../features/playback/utils/subtitleStyles.ts | 14 ++---- src/elements/emby-scroller/Scroller.tsx | 1 - src/scripts/browser.d.ts | 45 +++++++++++++++++++ 4 files changed, 56 insertions(+), 14 deletions(-) create mode 100644 src/scripts/browser.d.ts diff --git a/src/apps/stable/features/playback/constants/subtitleStylingOption.ts b/src/apps/stable/features/playback/constants/subtitleStylingOption.ts index 12ac60f6e..bf524ae16 100644 --- a/src/apps/stable/features/playback/constants/subtitleStylingOption.ts +++ b/src/apps/stable/features/playback/constants/subtitleStylingOption.ts @@ -1,9 +1,13 @@ /** - * Options specifying if the player's native styling of subtitles should be used, Jellyfin's custom styling, or allow - * Jellyfin to choose automatically based on known browser support. + * Options specifying if the player's native subtitle (cue) element should be used, a custom element (div), or allow + * Jellyfin to choose automatically based on known browser support. Some browsers do not properly apply CSS styling to + * the native subtitle element. */ export const SubtitleStylingOption = { Auto: 'Auto', Custom: 'Custom', Native: 'Native' -}; +} as const; + +// eslint-disable-next-line @typescript-eslint/no-redeclare +export type SubtitleStylingOption = typeof SubtitleStylingOption[keyof typeof SubtitleStylingOption]; diff --git a/src/apps/stable/features/playback/utils/subtitleStyles.ts b/src/apps/stable/features/playback/utils/subtitleStyles.ts index f583e01b2..3dbfe78c0 100644 --- a/src/apps/stable/features/playback/utils/subtitleStyles.ts +++ b/src/apps/stable/features/playback/utils/subtitleStyles.ts @@ -1,19 +1,13 @@ import { SubtitleStylingOption } from 'apps/stable/features/playback/constants/subtitleStylingOption'; -import _browser from 'scripts/browser'; +import browser from 'scripts/browser'; import type { UserSettings } from 'scripts/settings/userSettings'; -// TODO: These type overrides should be removed when browser and userSettings are properly typed -type Browser = typeof _browser & { - edge?: boolean; - firefox?: boolean; -}; - +// TODO: This type override should be removed when userSettings are properly typed interface SubtitleAppearanceSettings { - subtitleStyling: keyof typeof SubtitleStylingOption + subtitleStyling: SubtitleStylingOption } export function useCustomSubtitles(userSettings: UserSettings) { - const browser = _browser as Browser; const subtitleAppearance = userSettings.getSubtitleAppearanceSettings() as SubtitleAppearanceSettings; switch (subtitleAppearance.subtitleStyling) { case SubtitleStylingOption.Native: @@ -28,7 +22,7 @@ export function useCustomSubtitles(userSettings: UserSettings) { } // Tizen 5 doesn't support displaying secondary subtitles - if (browser.tizenVersion >= 5 || browser.web0s) { + if ((browser.tizenVersion && browser.tizenVersion >= 5) || browser.web0s) { return true; } diff --git a/src/elements/emby-scroller/Scroller.tsx b/src/elements/emby-scroller/Scroller.tsx index baf054010..3aa70e6ad 100644 --- a/src/elements/emby-scroller/Scroller.tsx +++ b/src/elements/emby-scroller/Scroller.tsx @@ -178,7 +178,6 @@ const Scroller: FC> = ({ allowNativeScroll: !enableScrollButtons, forceHideScrollbars: enableScrollButtons, // In edge, with the native scroll, the content jumps around when hovering over the buttons - // @ts-expect-error browser doesn't explicitly declare browser.edge, so fails type checking requireAnimation: enableScrollButtons && browser.edge }; diff --git a/src/scripts/browser.d.ts b/src/scripts/browser.d.ts new file mode 100644 index 000000000..0f8a5dfaf --- /dev/null +++ b/src/scripts/browser.d.ts @@ -0,0 +1,45 @@ +export default browser; +/** + * Browser detection utility. + */ +declare namespace browser { + import version = version; + export { version }; + import versionMajor = versionMajor; + export { versionMajor }; + export let edge: boolean; + export let edgeChromium: boolean; + export let firefox: boolean; + export let safari: boolean; + export let osx: boolean; + export let ipad: boolean; + export let ps4: boolean; + export let tv: boolean; + export let mobile: boolean; + export let xboxOne: boolean; + export let animate: boolean; + export let hisense: boolean; + export let tizen: boolean; + export let vidaa: boolean; + export let web0s: boolean; + export let edgeUwp: boolean; + export let web0sVersion: number | undefined; + export let tizenVersion: number | undefined; + export let orsay: boolean; + export let operaTv: boolean; + export let slow: boolean; + export let touch: boolean; + export let keyboard: boolean; + export { supportsCssAnimation }; + export let iOS: boolean; + export let iOSVersion: number | undefined; +} + +declare namespace matched { + export { browser }; + export { version }; + export let platform: string; + export { versionMajor }; +} + +declare function supportsCssAnimation(allowPrefix: any): any;