From 359e168acea940ef51b609f7517b20f6fc654919 Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Mon, 16 Oct 2023 01:38:22 -0400 Subject: [PATCH 1/2] Use icon url from client capabilities --- src/components/cardbuilder/cardBuilder.js | 2 +- .../homesections/sections/libraryButtons.ts | 2 +- src/controllers/dashboard/dashboard.js | 2 +- src/controllers/dashboard/devices/devices.js | 2 +- src/controllers/dashboard/library.js | 2 +- src/scripts/libraryMenu.js | 2 +- .../imagehelper.js => utils/image.ts} | 19 +++++++++++-------- 7 files changed, 17 insertions(+), 14 deletions(-) rename src/{scripts/imagehelper.js => utils/image.ts} (80%) diff --git a/src/components/cardbuilder/cardBuilder.js b/src/components/cardbuilder/cardBuilder.js index 6d33700ca0..c1c7460062 100644 --- a/src/components/cardbuilder/cardBuilder.js +++ b/src/components/cardbuilder/cardBuilder.js @@ -11,8 +11,8 @@ import browser from 'scripts/browser'; import datetime from 'scripts/datetime'; import dom from 'scripts/dom'; import globalize from 'scripts/globalize'; -import imageHelper from 'scripts/imagehelper'; import { getBackdropShape, getPortraitShape, getSquareShape } from 'utils/card'; +import imageHelper from 'utils/image'; import { randomInt } from 'utils/number'; import focusManager from '../focusManager'; diff --git a/src/components/homesections/sections/libraryButtons.ts b/src/components/homesections/sections/libraryButtons.ts index 06656c343a..fc5c481663 100644 --- a/src/components/homesections/sections/libraryButtons.ts +++ b/src/components/homesections/sections/libraryButtons.ts @@ -4,7 +4,7 @@ import escapeHtml from 'escape-html'; import imageLoader from 'components/images/imageLoader'; import { appRouter } from 'components/router/appRouter'; import globalize from 'scripts/globalize'; -import imageHelper from 'scripts/imagehelper'; +import imageHelper from 'utils/image'; function getLibraryButtonsHtml(items: BaseItemDto[]) { let html = ''; diff --git a/src/controllers/dashboard/dashboard.js b/src/controllers/dashboard/dashboard.js index bae3880f28..30f37764b2 100644 --- a/src/controllers/dashboard/dashboard.js +++ b/src/controllers/dashboard/dashboard.js @@ -12,7 +12,7 @@ import playMethodHelper from '../../components/playback/playmethodhelper'; import cardBuilder from '../../components/cardbuilder/cardBuilder'; import imageLoader from '../../components/images/imageLoader'; import ActivityLog from '../../components/activitylog'; -import imageHelper from '../../scripts/imagehelper'; +import imageHelper from '../../utils/image'; import indicators from '../../components/indicators/indicators'; import '../../components/listview/listview.scss'; import '../../elements/emby-button/emby-button'; diff --git a/src/controllers/dashboard/devices/devices.js b/src/controllers/dashboard/devices/devices.js index c62571a1bc..33ca6bfb00 100644 --- a/src/controllers/dashboard/devices/devices.js +++ b/src/controllers/dashboard/devices/devices.js @@ -3,7 +3,7 @@ import cardBuilder from '../../../components/cardbuilder/cardBuilder'; import loading from '../../../components/loading/loading'; import dom from '../../../scripts/dom'; import globalize from '../../../scripts/globalize'; -import imageHelper from '../../../scripts/imagehelper'; +import imageHelper from '../../../utils/image'; import { formatDistanceToNow } from 'date-fns'; import { getLocaleWithSuffix } from '../../../utils/dateFnsLocale.ts'; import '../../../elements/emby-button/emby-button'; diff --git a/src/controllers/dashboard/library.js b/src/controllers/dashboard/library.js index 62d9329969..987169ecd3 100644 --- a/src/controllers/dashboard/library.js +++ b/src/controllers/dashboard/library.js @@ -5,7 +5,7 @@ import loading from '../../components/loading/loading'; import libraryMenu from '../../scripts/libraryMenu'; import globalize from '../../scripts/globalize'; import dom from '../../scripts/dom'; -import imageHelper from '../../scripts/imagehelper'; +import imageHelper from '../../utils/image'; import '../../components/cardbuilder/card.scss'; import '../../elements/emby-itemrefreshindicator/emby-itemrefreshindicator'; import Dashboard, { pageClassOn, pageIdOn } from '../../utils/dashboard'; diff --git a/src/scripts/libraryMenu.js b/src/scripts/libraryMenu.js index f90ece9d79..ce105dbecd 100644 --- a/src/scripts/libraryMenu.js +++ b/src/scripts/libraryMenu.js @@ -12,7 +12,7 @@ import { pluginManager } from '../components/pluginManager'; import groupSelectionMenu from '../plugins/syncPlay/ui/groupSelectionMenu'; import browser from './browser'; import globalize from './globalize'; -import imageHelper from './imagehelper'; +import imageHelper from '../utils/image'; import { getMenuLinks } from '../scripts/settings/webSettings'; import Dashboard, { pageClassOn } from '../utils/dashboard'; import ServerConnections from '../components/ServerConnections'; diff --git a/src/scripts/imagehelper.js b/src/utils/image.ts similarity index 80% rename from src/scripts/imagehelper.js rename to src/utils/image.ts index 052c68111e..5534204227 100644 --- a/src/scripts/imagehelper.js +++ b/src/utils/image.ts @@ -1,7 +1,10 @@ +import type { DeviceInfo } from '@jellyfin/sdk/lib/generated-client/models/device-info'; +import type { SessionInfo } from '@jellyfin/sdk/lib/generated-client/models/session-info'; + const BASE_DEVICE_IMAGE_URL = 'assets/img/devices/'; // audit note: this module is expected to return safe text for use in HTML -function getWebDeviceIcon(browser) { +function getWebDeviceIcon(browser: string | null | undefined) { switch (browser) { case 'Opera': case 'Opera TV': @@ -31,8 +34,8 @@ function getWebDeviceIcon(browser) { } } -export function getDeviceIcon(device) { - switch (device.AppName || device.Client) { +export function getDeviceIcon(info: DeviceInfo | SessionInfo) { + switch ((info as DeviceInfo).AppName || (info as SessionInfo).Client) { case 'Samsung Smart TV': return BASE_DEVICE_IMAGE_URL + 'samsung.svg'; case 'Xbox One': @@ -58,13 +61,13 @@ export function getDeviceIcon(device) { case 'Finamp': return BASE_DEVICE_IMAGE_URL + 'finamp.svg'; case 'Jellyfin Web': - return getWebDeviceIcon(device.Name || device.DeviceName); + return getWebDeviceIcon((info as DeviceInfo).Name || (info as SessionInfo).DeviceName); default: - return BASE_DEVICE_IMAGE_URL + 'other.svg'; + return info.Capabilities?.IconUrl || BASE_DEVICE_IMAGE_URL + 'other.svg'; } } -export function getLibraryIcon(library) { +export function getLibraryIcon(library: string | null | undefined) { switch (library) { case 'movies': return 'video_library'; @@ -94,6 +97,6 @@ export function getLibraryIcon(library) { } export default { - getDeviceIcon: getDeviceIcon, - getLibraryIcon: getLibraryIcon + getDeviceIcon, + getLibraryIcon }; From abb0c7d2ca4cc315c2b3e4e1a012d31696d73263 Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Mon, 16 Oct 2023 12:09:56 -0400 Subject: [PATCH 2/2] Ensure IconUrl from capabilities is a valid url --- src/utils/image.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/utils/image.ts b/src/utils/image.ts index 5534204227..7420fad41c 100644 --- a/src/utils/image.ts +++ b/src/utils/image.ts @@ -63,7 +63,14 @@ export function getDeviceIcon(info: DeviceInfo | SessionInfo) { case 'Jellyfin Web': return getWebDeviceIcon((info as DeviceInfo).Name || (info as SessionInfo).DeviceName); default: - return info.Capabilities?.IconUrl || BASE_DEVICE_IMAGE_URL + 'other.svg'; + if (info.Capabilities?.IconUrl) { + try { + return new URL(info.Capabilities.IconUrl).toString(); + } catch (err) { + console.error('[getDeviceIcon] device capabilities has invalid IconUrl', info, err); + } + } + return BASE_DEVICE_IMAGE_URL + 'other.svg'; } }