mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
Merge branch 'master' into enable-airplay-audioplayer
This commit is contained in:
commit
04c61af4dc
55 changed files with 1149 additions and 494 deletions
|
@ -90,8 +90,10 @@ function loadForm(context, user, userSettings) {
|
|||
|
||||
if (appHost.supports('screensaver')) {
|
||||
context.querySelector('.selectScreensaverContainer').classList.remove('hide');
|
||||
context.querySelector('.txtBackdropScreensaverIntervalContainer').classList.remove('hide');
|
||||
} else {
|
||||
context.querySelector('.selectScreensaverContainer').classList.add('hide');
|
||||
context.querySelector('.txtBackdropScreensaverIntervalContainer').classList.add('hide');
|
||||
}
|
||||
|
||||
if (datetime.supportsLocalization()) {
|
||||
|
@ -105,6 +107,8 @@ function loadForm(context, user, userSettings) {
|
|||
|
||||
loadScreensavers(context, userSettings);
|
||||
|
||||
context.querySelector('#txtBackdropScreensaverInterval').value = userSettings.backdropScreensaverInterval();
|
||||
|
||||
context.querySelector('.chkDisplayMissingEpisodes').checked = user.Configuration.DisplayMissingEpisodes || false;
|
||||
|
||||
context.querySelector('#chkThemeSong').checked = userSettings.enableThemeSongs();
|
||||
|
@ -147,6 +151,7 @@ function saveUser(context, user, userSettingsInstance, apiClient) {
|
|||
userSettingsInstance.theme(context.querySelector('#selectTheme').value);
|
||||
userSettingsInstance.dashboardTheme(context.querySelector('#selectDashboardTheme').value);
|
||||
userSettingsInstance.screensaver(context.querySelector('.selectScreensaver').value);
|
||||
userSettingsInstance.backdropScreensaverInterval(context.querySelector('#txtBackdropScreensaverInterval').value);
|
||||
|
||||
userSettingsInstance.libraryPageSize(context.querySelector('#txtLibraryPageSize').value);
|
||||
|
||||
|
|
|
@ -203,6 +203,11 @@
|
|||
<select is="emby-select" class="selectScreensaver" label="${LabelScreensaver}"></select>
|
||||
</div>
|
||||
|
||||
<div class="inputContainer hide txtBackdropScreensaverIntervalContainer inputContainer-withDescription">
|
||||
<input is="emby-input" type="number" id="txtBackdropScreensaverInterval" pattern="[0-9]*" required="required" min="1" max="3600" step="1" label="${LabelBackdropScreensaverInterval}" />
|
||||
<div class="fieldDescription">${LabelBackdropScreensaverIntervalHelp}</div>
|
||||
</div>
|
||||
|
||||
<div class="checkboxContainer checkboxContainer-withDescription">
|
||||
<label>
|
||||
<input type="checkbox" is="emby-checkbox" id="chkFadein" />
|
||||
|
|
|
@ -416,7 +416,7 @@ export function setContentType(parent, contentType) {
|
|||
}
|
||||
}
|
||||
|
||||
parent.querySelector('.chkEnableLUFSScan').classList.toggle('hide', contentType !== 'music');
|
||||
parent.querySelector('.chkEnableLUFSScanContainer').classList.toggle('hide', contentType !== 'music');
|
||||
|
||||
if (contentType === 'tvshows') {
|
||||
parent.querySelector('.chkEnableEmbeddedEpisodeInfosContainer').classList.remove('hide');
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
<div class="fieldDescription checkboxFieldDescription">${LabelEnableRealtimeMonitorHelp}</div>
|
||||
</div>
|
||||
|
||||
<div class="checkboxContainer checkboxContainer-withDescription advanced">
|
||||
<div class="checkboxContainer checkboxContainer-withDescription chkEnableLUFSScanContainer advanced">
|
||||
<label>
|
||||
<input type="checkbox" is="emby-checkbox" class="chkEnableLUFSScan" checked />
|
||||
<span>${LabelEnableLUFSScan}</span>
|
||||
|
|
|
@ -352,7 +352,7 @@ export default function (options) {
|
|||
minRatio: 1,
|
||||
toggle: true
|
||||
},
|
||||
autoplay: !swiperOptions.interactive || !!swiperOptions.autoplay,
|
||||
autoplay: swiperOptions.autoplay ?? !swiperOptions.interactive,
|
||||
keyboard: {
|
||||
enabled: true
|
||||
},
|
||||
|
|
|
@ -54,7 +54,7 @@ function init(instance) {
|
|||
playbackManager.setSubtitleOffset(inputOffset, player);
|
||||
// synchronize with slider value
|
||||
subtitleSyncSlider.updateOffset(
|
||||
getPercentageFromOffset(inputOffset));
|
||||
getSliderValueFromOffset(inputOffset));
|
||||
} else {
|
||||
this.textContent = (playbackManager.getPlayerSubtitleOffset(player) || 0) + 's';
|
||||
}
|
||||
|
@ -79,17 +79,17 @@ function init(instance) {
|
|||
}
|
||||
};
|
||||
|
||||
subtitleSyncSlider.updateOffset = function (percent) {
|
||||
// default value is 0s = 50%
|
||||
this.value = percent === undefined ? 50 : percent;
|
||||
subtitleSyncSlider.updateOffset = function (sliderValue) {
|
||||
// default value is 0s = 0ms
|
||||
this.value = sliderValue === undefined ? 0 : sliderValue;
|
||||
};
|
||||
|
||||
subtitleSyncSlider.addEventListener('change', function () {
|
||||
// set new offset
|
||||
playbackManager.setSubtitleOffset(getOffsetFromPercentage(this.value), player);
|
||||
playbackManager.setSubtitleOffset(getOffsetFromSliderValue(this.value), player);
|
||||
// synchronize with textField value
|
||||
subtitleSyncTextField.updateOffset(
|
||||
getOffsetFromPercentage(this.value));
|
||||
getOffsetFromSliderValue(this.value));
|
||||
});
|
||||
|
||||
subtitleSyncSlider.getBubbleHtml = function (value) {
|
||||
|
@ -108,20 +108,22 @@ function init(instance) {
|
|||
}
|
||||
|
||||
function getOffsetFromPercentage(value) {
|
||||
// convert percent to fraction
|
||||
// convert percentage to fraction
|
||||
let offset = (value - 50) / 50;
|
||||
// multiply by offset min/max range value (-x to +x) :
|
||||
offset *= 30;
|
||||
return offset.toFixed(1);
|
||||
}
|
||||
|
||||
function getPercentageFromOffset(value) {
|
||||
// divide by offset min/max range value (-x to +x) :
|
||||
let percentValue = value / 30;
|
||||
// convert fraction to percent
|
||||
percentValue *= 50;
|
||||
percentValue += 50;
|
||||
return Math.min(100, Math.max(0, percentValue.toFixed(1)));
|
||||
function getOffsetFromSliderValue(value) {
|
||||
// convert slider value to offset
|
||||
const offset = value / 10;
|
||||
return offset.toFixed(1);
|
||||
}
|
||||
|
||||
function getSliderValueFromOffset(value) {
|
||||
const sliderValue = value * 10;
|
||||
return Math.min(300, Math.max(-300, sliderValue.toFixed(1)));
|
||||
}
|
||||
|
||||
class SubtitleSync {
|
||||
|
@ -155,8 +157,8 @@ class SubtitleSync {
|
|||
if (playbackManager.isShowingSubtitleOffsetEnabled(player) && playbackManager.canHandleOffsetOnCurrentSubtitle(player)) {
|
||||
// if no subtitle offset is defined or element has focus (offset being defined)
|
||||
if (!(playbackManager.getPlayerSubtitleOffset(player) || subtitleSyncTextField.hasFocus)) {
|
||||
// set default offset to '0' = 50%
|
||||
subtitleSyncSlider.value = '50';
|
||||
// set default offset to '0' = 0ms
|
||||
subtitleSyncSlider.value = '0';
|
||||
subtitleSyncTextField.textContent = '0s';
|
||||
playbackManager.setSubtitleOffset(0, player);
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<button type="button" is="paper-icon-button-light" class="subtitleSync-closeButton"><span class="material-icons close" aria-hidden="true"></span></button>
|
||||
<div class="subtitleSyncTextField" contenteditable="true" spellcheck="false">0s</div>
|
||||
<div class="sliderContainer subtitleSyncSliderContainer">
|
||||
<input is="emby-slider" type="range" step=".1" min="0" max="100" value="50" class="subtitleSyncSlider" data-slider-keep-progress="true" />
|
||||
<input is="emby-slider" type="range" step="1" min="-300" max="300" value="0" class="subtitleSyncSlider" data-slider-keep-progress="true" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue