1
0
Fork 0
mirror of https://github.com/jellyfin/jellyfin-web synced 2025-03-30 19:56:21 +00:00

Added new setting for using episode images with NextUp/Resume instead of parent images

This commit is contained in:
Ömer Erdinç Yağmurlu 2021-07-10 11:23:31 +02:00
parent f5cf6879f9
commit 59e3427f50
8 changed files with 84 additions and 44 deletions

View file

@ -45,6 +45,7 @@
- [Camc314](https://github.com/camc314) - [Camc314](https://github.com/camc314)
- [danieladov](https://github.com/danieladov) - [danieladov](https://github.com/danieladov)
- [Stephane Senart](https://github.com/ssenart) - [Stephane Senart](https://github.com/ssenart)
- [Ömer Erdinç Yağmurlu](https://github.com/omeryagmurlu)
# Emby Contributors # Emby Contributors

View file

@ -122,6 +122,7 @@ import template from './displaySettings.template.html';
context.querySelector('#chkBlurhash').checked = userSettings.enableBlurhash(); context.querySelector('#chkBlurhash').checked = userSettings.enableBlurhash();
context.querySelector('#chkBackdrops').checked = userSettings.enableBackdrops(); context.querySelector('#chkBackdrops').checked = userSettings.enableBackdrops();
context.querySelector('#chkDetailsBanner').checked = userSettings.detailsBanner(); context.querySelector('#chkDetailsBanner').checked = userSettings.detailsBanner();
context.querySelector('#chkUseEpisodeImagesInNextUp').checked = userSettings.useEpisodeImagesInNextUpAndResume();
context.querySelector('#selectLanguage').value = userSettings.language() || ''; context.querySelector('#selectLanguage').value = userSettings.language() || '';
context.querySelector('.selectDateTimeLocale').value = userSettings.dateTimeLocale() || ''; context.querySelector('.selectDateTimeLocale').value = userSettings.dateTimeLocale() || '';
@ -156,6 +157,7 @@ import template from './displaySettings.template.html';
userSettingsInstance.enableBlurhash(context.querySelector('#chkBlurhash').checked); userSettingsInstance.enableBlurhash(context.querySelector('#chkBlurhash').checked);
userSettingsInstance.enableBackdrops(context.querySelector('#chkBackdrops').checked); userSettingsInstance.enableBackdrops(context.querySelector('#chkBackdrops').checked);
userSettingsInstance.detailsBanner(context.querySelector('#chkDetailsBanner').checked); userSettingsInstance.detailsBanner(context.querySelector('#chkDetailsBanner').checked);
userSettingsInstance.useEpisodeImagesInNextUpAndResume(context.querySelector('#chkUseEpisodeImagesInNextUp').checked);
if (user.Id === apiClient.getCurrentUserId()) { if (user.Id === apiClient.getCurrentUserId()) {
skinManager.setTheme(userSettingsInstance.theme()); skinManager.setTheme(userSettingsInstance.theme());

View file

@ -225,6 +225,14 @@
<div class="fieldDescription checkboxFieldDescription">${DisplayMissingEpisodesWithinSeasonsHelp}</div> <div class="fieldDescription checkboxFieldDescription">${DisplayMissingEpisodesWithinSeasonsHelp}</div>
</div> </div>
<div class="checkboxContainer checkboxContainer-withDescription fldUseEpisodeImagesInNextUp">
<label>
<input type="checkbox" is="emby-checkbox" id="chkUseEpisodeImagesInNextUp" />
<span>${UseEpisodeImagesInNextUp}</span>
</label>
<div class="fieldDescription checkboxFieldDescription">${UseEpisodeImagesInNextUpHelp}</div>
</div>
<button is="emby-button" type="submit" class="raised button-submit block btnSave hide"> <button is="emby-button" type="submit" class="raised button-submit block btnSave hide">
<span>${Save}</span> <span>${Save}</span>
</button> </button>

View file

@ -144,17 +144,17 @@ import ServerConnections from '../ServerConnections';
} else if (section === 'librarybuttons') { } else if (section === 'librarybuttons') {
loadlibraryButtons(elem, apiClient, user, userSettings, userViews); loadlibraryButtons(elem, apiClient, user, userSettings, userViews);
} else if (section === 'resume') { } else if (section === 'resume') {
return loadResume(elem, apiClient, 'HeaderContinueWatching', 'Video'); return loadResume(elem, apiClient, 'HeaderContinueWatching', 'Video', userSettings);
} else if (section === 'resumeaudio') { } else if (section === 'resumeaudio') {
return loadResume(elem, apiClient, 'HeaderContinueListening', 'Audio'); return loadResume(elem, apiClient, 'HeaderContinueListening', 'Audio', userSettings);
} else if (section === 'activerecordings') { } else if (section === 'activerecordings') {
loadLatestLiveTvRecordings(elem, true, apiClient); loadLatestLiveTvRecordings(elem, true, apiClient);
} else if (section === 'nextup') { } else if (section === 'nextup') {
loadNextUp(elem, apiClient); loadNextUp(elem, apiClient, userSettings);
} else if (section === 'onnow' || section === 'livetv') { } else if (section === 'onnow' || section === 'livetv') {
return loadOnNow(elem, apiClient, user); return loadOnNow(elem, apiClient, user);
} else if (section === 'resumebook') { } else if (section === 'resumebook') {
return loadResume(elem, apiClient, 'HeaderContinueReading', 'Book'); return loadResume(elem, apiClient, 'HeaderContinueReading', 'Book', userSettings);
} else { } else {
elem.innerHTML = ''; elem.innerHTML = '';
return Promise.resolve(); return Promise.resolve();
@ -374,7 +374,7 @@ import ServerConnections from '../ServerConnections';
'Video': 'videoplayback,markplayed' 'Video': 'videoplayback,markplayed'
}; };
function loadResume(elem, apiClient, headerText, mediaType) { function loadResume(elem, apiClient, headerText, mediaType, userSettings) {
let html = ''; let html = '';
const dataMonitor = dataMonitorHints[mediaType] || 'markplayed'; const dataMonitor = dataMonitorHints[mediaType] || 'markplayed';
@ -397,7 +397,7 @@ import ServerConnections from '../ServerConnections';
const itemsContainer = elem.querySelector('.itemsContainer'); const itemsContainer = elem.querySelector('.itemsContainer');
itemsContainer.fetchData = getItemsToResumeFn(mediaType, apiClient.serverId()); itemsContainer.fetchData = getItemsToResumeFn(mediaType, apiClient.serverId());
itemsContainer.getItemsHtml = getItemsToResumeHtml; itemsContainer.getItemsHtml = getItemsToResumeHtmlFn(userSettings.useEpisodeImagesInNextUpAndResume());
itemsContainer.parentContainer = elem; itemsContainer.parentContainer = elem;
} }
@ -428,25 +428,28 @@ import ServerConnections from '../ServerConnections';
}; };
} }
function getItemsToResumeHtml(items) { function getItemsToResumeHtmlFn(useEpisodeImages) {
const cardLayout = false; return function (items) {
return cardBuilder.getCardsHtml({ const cardLayout = false;
items: items, return cardBuilder.getCardsHtml({
preferThumb: true, items: items,
defaultShape: getThumbShape(), preferThumb: true,
overlayText: false, inheritThumb: !useEpisodeImages,
showTitle: true, defaultShape: getThumbShape(),
showParentTitle: true, overlayText: false,
lazy: true, showTitle: true,
showDetailsMenu: true, showParentTitle: true,
overlayPlayButton: true, lazy: true,
context: 'home', showDetailsMenu: true,
centerText: !cardLayout, overlayPlayButton: true,
allowBottomPadding: false, context: 'home',
cardLayout: cardLayout, centerText: !cardLayout,
showYear: true, allowBottomPadding: false,
lines: 2 cardLayout: cardLayout,
}); showYear: true,
lines: 2
});
}
} }
function getOnNowFetchFn(serverId) { function getOnNowFetchFn(serverId) {
@ -607,25 +610,28 @@ import ServerConnections from '../ServerConnections';
}; };
} }
function getNextUpItemsHtml(items) { function getNextUpItemsHtmlFn(useEpisodeImages) {
const cardLayout = false; return function (items) {
return cardBuilder.getCardsHtml({ const cardLayout = false;
items: items, return cardBuilder.getCardsHtml({
preferThumb: true, items: items,
shape: getThumbShape(), preferThumb: true,
overlayText: false, inheritThumb: !useEpisodeImages,
showTitle: true, shape: getThumbShape(),
showParentTitle: true, overlayText: false,
lazy: true, showTitle: true,
overlayPlayButton: true, showParentTitle: true,
context: 'home', lazy: true,
centerText: !cardLayout, overlayPlayButton: true,
allowBottomPadding: !enableScrollX(), context: 'home',
cardLayout: cardLayout centerText: !cardLayout,
}); allowBottomPadding: !enableScrollX(),
cardLayout: cardLayout
});
};
} }
function loadNextUp(elem, apiClient) { function loadNextUp(elem, apiClient, userSettings) {
let html = ''; let html = '';
html += '<div class="sectionTitleContainer sectionTitleContainer-cards padded-left">'; html += '<div class="sectionTitleContainer sectionTitleContainer-cards padded-left">';
@ -660,7 +666,7 @@ import ServerConnections from '../ServerConnections';
const itemsContainer = elem.querySelector('.itemsContainer'); const itemsContainer = elem.querySelector('.itemsContainer');
itemsContainer.fetchData = getNextUpFetchFn(apiClient.serverId()); itemsContainer.fetchData = getNextUpFetchFn(apiClient.serverId());
itemsContainer.getItemsHtml = getNextUpItemsHtml; itemsContainer.getItemsHtml = getNextUpItemsHtmlFn(userSettings.useEpisodeImagesInNextUpAndResume());
itemsContainer.parentContainer = elem; itemsContainer.parentContainer = elem;
} }

View file

@ -1115,7 +1115,11 @@ class ItemsView {
let imageType = userSettings.get(basekey + '-imageType'); let imageType = userSettings.get(basekey + '-imageType');
if (!imageType && params.type === 'nextup') { if (!imageType && params.type === 'nextup') {
imageType = 'thumb'; if (userSettings.useEpisodeImagesInNextUpAndResume()) {
imageType = 'primary';
} else {
imageType = 'thumb';
}
} }
return { return {

View file

@ -119,6 +119,7 @@ import autoFocuser from '../../components/autoFocuser';
cardBuilder.buildCards(result.Items, { cardBuilder.buildCards(result.Items, {
itemsContainer: container, itemsContainer: container,
preferThumb: true, preferThumb: true,
inheritThumb: !userSettings.useEpisodeImagesInNextUpAndResume(),
shape: getThumbShape(), shape: getThumbShape(),
scalable: true, scalable: true,
overlayPlayButton: true, overlayPlayButton: true,
@ -197,6 +198,7 @@ import autoFocuser from '../../components/autoFocuser';
parentContainer: section, parentContainer: section,
itemsContainer: container, itemsContainer: container,
preferThumb: true, preferThumb: true,
inheritThumb: !userSettings.useEpisodeImagesInNextUpAndResume(),
shape: 'backdrop', shape: 'backdrop',
scalable: true, scalable: true,
showTitle: true, showTitle: true,

View file

@ -253,6 +253,20 @@ export class UserSettings {
return val !== 'false'; 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. * Get or set language.
* @param {string|undefined} val - 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 enableBlurhash = currentSettings.enableBlurhash.bind(currentSettings);
export const enableBackdrops = currentSettings.enableBackdrops.bind(currentSettings); export const enableBackdrops = currentSettings.enableBackdrops.bind(currentSettings);
export const detailsBanner = currentSettings.detailsBanner.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 language = currentSettings.language.bind(currentSettings);
export const dateTimeLocale = currentSettings.dateTimeLocale.bind(currentSettings); export const dateTimeLocale = currentSettings.dateTimeLocale.bind(currentSettings);
export const chromecastVersion = currentSettings.chromecastVersion.bind(currentSettings); export const chromecastVersion = currentSettings.chromecastVersion.bind(currentSettings);

View file

@ -1426,6 +1426,8 @@
"Upload": "Upload", "Upload": "Upload",
"UseDoubleRateDeinterlacing": "Double the frame rate when deinterlacing", "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.", "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.", "UserAgentHelp": "Supply a custom user-agent HTTP header.",
"UserProfilesIntro": "Jellyfin includes support for user profiles with granular display settings, play state, and parental controls.", "UserProfilesIntro": "Jellyfin includes support for user profiles with granular display settings, play state, and parental controls.",
"ValueAlbumCount": "{0} albums", "ValueAlbumCount": "{0} albums",