From 59e3427f504882b854a7dcb3f465e23288c6ed43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Erdin=C3=A7=20Ya=C4=9Fmurlu?= Date: Sat, 10 Jul 2021 11:23:31 +0200 Subject: [PATCH 1/2] Added new setting for using episode images with NextUp/Resume instead of parent images --- CONTRIBUTORS.md | 1 + .../displaySettings/displaySettings.js | 2 + .../displaySettings.template.html | 8 ++ src/components/homesections/homesections.js | 92 ++++++++++--------- src/controllers/list.js | 6 +- src/controllers/shows/tvrecommended.js | 2 + src/scripts/settings/userSettings.js | 15 +++ src/strings/en-us.json | 2 + 8 files changed, 84 insertions(+), 44 deletions(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 229a2acbd..4667efb31 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -45,6 +45,7 @@ - [Camc314](https://github.com/camc314) - [danieladov](https://github.com/danieladov) - [Stephane Senart](https://github.com/ssenart) + - [Ömer Erdinç Yağmurlu](https://github.com/omeryagmurlu) # Emby Contributors diff --git a/src/components/displaySettings/displaySettings.js b/src/components/displaySettings/displaySettings.js index 261c25a89..92e071003 100644 --- a/src/components/displaySettings/displaySettings.js +++ b/src/components/displaySettings/displaySettings.js @@ -122,6 +122,7 @@ import template from './displaySettings.template.html'; context.querySelector('#chkBlurhash').checked = userSettings.enableBlurhash(); context.querySelector('#chkBackdrops').checked = userSettings.enableBackdrops(); context.querySelector('#chkDetailsBanner').checked = userSettings.detailsBanner(); + context.querySelector('#chkUseEpisodeImagesInNextUp').checked = userSettings.useEpisodeImagesInNextUpAndResume(); context.querySelector('#selectLanguage').value = userSettings.language() || ''; context.querySelector('.selectDateTimeLocale').value = userSettings.dateTimeLocale() || ''; @@ -156,6 +157,7 @@ import template from './displaySettings.template.html'; userSettingsInstance.enableBlurhash(context.querySelector('#chkBlurhash').checked); userSettingsInstance.enableBackdrops(context.querySelector('#chkBackdrops').checked); userSettingsInstance.detailsBanner(context.querySelector('#chkDetailsBanner').checked); + userSettingsInstance.useEpisodeImagesInNextUpAndResume(context.querySelector('#chkUseEpisodeImagesInNextUp').checked); if (user.Id === apiClient.getCurrentUserId()) { skinManager.setTheme(userSettingsInstance.theme()); diff --git a/src/components/displaySettings/displaySettings.template.html b/src/components/displaySettings/displaySettings.template.html index f79155b7f..35880b90a 100644 --- a/src/components/displaySettings/displaySettings.template.html +++ b/src/components/displaySettings/displaySettings.template.html @@ -225,6 +225,14 @@
${DisplayMissingEpisodesWithinSeasonsHelp}
+
+ +
${UseEpisodeImagesInNextUpHelp}
+
+ diff --git a/src/components/homesections/homesections.js b/src/components/homesections/homesections.js index 0f8b7dc55..b0d29bed1 100644 --- a/src/components/homesections/homesections.js +++ b/src/components/homesections/homesections.js @@ -144,17 +144,17 @@ import ServerConnections from '../ServerConnections'; } else if (section === 'librarybuttons') { loadlibraryButtons(elem, apiClient, user, userSettings, userViews); } else if (section === 'resume') { - return loadResume(elem, apiClient, 'HeaderContinueWatching', 'Video'); + return loadResume(elem, apiClient, 'HeaderContinueWatching', 'Video', userSettings); } else if (section === 'resumeaudio') { - return loadResume(elem, apiClient, 'HeaderContinueListening', 'Audio'); + return loadResume(elem, apiClient, 'HeaderContinueListening', 'Audio', userSettings); } else if (section === 'activerecordings') { loadLatestLiveTvRecordings(elem, true, apiClient); } else if (section === 'nextup') { - loadNextUp(elem, apiClient); + loadNextUp(elem, apiClient, userSettings); } else if (section === 'onnow' || section === 'livetv') { return loadOnNow(elem, apiClient, user); } else if (section === 'resumebook') { - return loadResume(elem, apiClient, 'HeaderContinueReading', 'Book'); + return loadResume(elem, apiClient, 'HeaderContinueReading', 'Book', userSettings); } else { elem.innerHTML = ''; return Promise.resolve(); @@ -374,7 +374,7 @@ import ServerConnections from '../ServerConnections'; 'Video': 'videoplayback,markplayed' }; - function loadResume(elem, apiClient, headerText, mediaType) { + function loadResume(elem, apiClient, headerText, mediaType, userSettings) { let html = ''; const dataMonitor = dataMonitorHints[mediaType] || 'markplayed'; @@ -397,7 +397,7 @@ import ServerConnections from '../ServerConnections'; const itemsContainer = elem.querySelector('.itemsContainer'); itemsContainer.fetchData = getItemsToResumeFn(mediaType, apiClient.serverId()); - itemsContainer.getItemsHtml = getItemsToResumeHtml; + itemsContainer.getItemsHtml = getItemsToResumeHtmlFn(userSettings.useEpisodeImagesInNextUpAndResume()); itemsContainer.parentContainer = elem; } @@ -428,25 +428,28 @@ import ServerConnections from '../ServerConnections'; }; } - function getItemsToResumeHtml(items) { - const cardLayout = false; - return cardBuilder.getCardsHtml({ - items: items, - preferThumb: true, - defaultShape: getThumbShape(), - overlayText: false, - showTitle: true, - showParentTitle: true, - lazy: true, - showDetailsMenu: true, - overlayPlayButton: true, - context: 'home', - centerText: !cardLayout, - allowBottomPadding: false, - cardLayout: cardLayout, - showYear: true, - lines: 2 - }); + function getItemsToResumeHtmlFn(useEpisodeImages) { + return function (items) { + const cardLayout = false; + return cardBuilder.getCardsHtml({ + items: items, + preferThumb: true, + inheritThumb: !useEpisodeImages, + defaultShape: getThumbShape(), + overlayText: false, + showTitle: true, + showParentTitle: true, + lazy: true, + showDetailsMenu: true, + overlayPlayButton: true, + context: 'home', + centerText: !cardLayout, + allowBottomPadding: false, + cardLayout: cardLayout, + showYear: true, + lines: 2 + }); + } } function getOnNowFetchFn(serverId) { @@ -607,25 +610,28 @@ import ServerConnections from '../ServerConnections'; }; } - function getNextUpItemsHtml(items) { - const cardLayout = false; - return cardBuilder.getCardsHtml({ - items: items, - preferThumb: true, - shape: getThumbShape(), - overlayText: false, - showTitle: true, - showParentTitle: true, - lazy: true, - overlayPlayButton: true, - context: 'home', - centerText: !cardLayout, - allowBottomPadding: !enableScrollX(), - cardLayout: cardLayout - }); + function getNextUpItemsHtmlFn(useEpisodeImages) { + return function (items) { + const cardLayout = false; + return cardBuilder.getCardsHtml({ + items: items, + preferThumb: true, + inheritThumb: !useEpisodeImages, + shape: getThumbShape(), + overlayText: false, + showTitle: true, + showParentTitle: true, + lazy: true, + overlayPlayButton: true, + context: 'home', + centerText: !cardLayout, + allowBottomPadding: !enableScrollX(), + cardLayout: cardLayout + }); + }; } - function loadNextUp(elem, apiClient) { + function loadNextUp(elem, apiClient, userSettings) { let html = ''; html += '
'; @@ -660,7 +666,7 @@ import ServerConnections from '../ServerConnections'; const itemsContainer = elem.querySelector('.itemsContainer'); itemsContainer.fetchData = getNextUpFetchFn(apiClient.serverId()); - itemsContainer.getItemsHtml = getNextUpItemsHtml; + itemsContainer.getItemsHtml = getNextUpItemsHtmlFn(userSettings.useEpisodeImagesInNextUpAndResume()); itemsContainer.parentContainer = elem; } diff --git a/src/controllers/list.js b/src/controllers/list.js index d055f9e74..b50b5f91f 100644 --- a/src/controllers/list.js +++ b/src/controllers/list.js @@ -1115,7 +1115,11 @@ class ItemsView { let imageType = userSettings.get(basekey + '-imageType'); if (!imageType && params.type === 'nextup') { - imageType = 'thumb'; + if (userSettings.useEpisodeImagesInNextUpAndResume()) { + imageType = 'primary'; + } else { + imageType = 'thumb'; + } } return { diff --git a/src/controllers/shows/tvrecommended.js b/src/controllers/shows/tvrecommended.js index 82baff8eb..1f523df7b 100644 --- a/src/controllers/shows/tvrecommended.js +++ b/src/controllers/shows/tvrecommended.js @@ -119,6 +119,7 @@ import autoFocuser from '../../components/autoFocuser'; cardBuilder.buildCards(result.Items, { itemsContainer: container, preferThumb: true, + inheritThumb: !userSettings.useEpisodeImagesInNextUpAndResume(), shape: getThumbShape(), scalable: true, overlayPlayButton: true, @@ -197,6 +198,7 @@ import autoFocuser from '../../components/autoFocuser'; parentContainer: section, itemsContainer: container, preferThumb: true, + inheritThumb: !userSettings.useEpisodeImagesInNextUpAndResume(), shape: 'backdrop', scalable: true, showTitle: true, diff --git a/src/scripts/settings/userSettings.js b/src/scripts/settings/userSettings.js index a548f0cef..96b2d5e7c 100644 --- a/src/scripts/settings/userSettings.js +++ b/src/scripts/settings/userSettings.js @@ -253,6 +253,20 @@ export class UserSettings { return val !== 'false'; } + /** + * Get or set 'Use Episode Images in Next Up and Continue Watching' state. + * @param {string|boolean|undefined} val - Flag to enable 'Use Episode Images in Next Up and Continue Watching' or undefined. + * @return {boolean} 'Use Episode Images in Next Up' state. + */ + useEpisodeImagesInNextUpAndResume(val) { + if (val !== undefined) { + return this.set('useEpisodeImagesInNextUpAndResume', val.toString(), true); + } + + val = this.get('useEpisodeImagesInNextUpAndResume', true); + return val === 'true'; + } + /** * Get or set language. * @param {string|undefined} val - Language. @@ -494,6 +508,7 @@ export const enableFastFadein = currentSettings.enableFastFadein.bind(currentSet export const enableBlurhash = currentSettings.enableBlurhash.bind(currentSettings); export const enableBackdrops = currentSettings.enableBackdrops.bind(currentSettings); export const detailsBanner = currentSettings.detailsBanner.bind(currentSettings); +export const useEpisodeImagesInNextUpAndResume = currentSettings.useEpisodeImagesInNextUpAndResume.bind(currentSettings); export const language = currentSettings.language.bind(currentSettings); export const dateTimeLocale = currentSettings.dateTimeLocale.bind(currentSettings); export const chromecastVersion = currentSettings.chromecastVersion.bind(currentSettings); diff --git a/src/strings/en-us.json b/src/strings/en-us.json index 9e4132e58..e99165a69 100644 --- a/src/strings/en-us.json +++ b/src/strings/en-us.json @@ -1426,6 +1426,8 @@ "Upload": "Upload", "UseDoubleRateDeinterlacing": "Double the frame rate when deinterlacing", "UseDoubleRateDeinterlacingHelp": "This setting uses the field rate when deinterlacing, often referred to as bob deinterlacing, which doubles the frame rate of the video to provide full motion like what you would see when viewing interlaced video on a TV.", + "UseEpisodeImagesInNextUp": "Use episode images in Next Up and Continue Watching sections", + "UseEpisodeImagesInNextUpHelp": "Next Up and Continue Watching sections will use episode images as thumbnails instead of the primary thumbnail of the show.", "UserAgentHelp": "Supply a custom user-agent HTTP header.", "UserProfilesIntro": "Jellyfin includes support for user profiles with granular display settings, play state, and parental controls.", "ValueAlbumCount": "{0} albums", From 0171790619701a3babec87af0169dccb6b520f3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Erdin=C3=A7=20Ya=C4=9Fmurlu?= Date: Tue, 13 Jul 2021 09:59:14 +0200 Subject: [PATCH 2/2] fix linting problem --- src/components/homesections/homesections.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/homesections/homesections.js b/src/components/homesections/homesections.js index b0d29bed1..ea10d3e4c 100644 --- a/src/components/homesections/homesections.js +++ b/src/components/homesections/homesections.js @@ -449,7 +449,7 @@ import ServerConnections from '../ServerConnections'; showYear: true, lines: 2 }); - } + }; } function getOnNowFetchFn(serverId) {