mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
Merge branch 'master' into patch-10
This commit is contained in:
commit
686fea165c
136 changed files with 2844 additions and 1818 deletions
|
@ -21,7 +21,11 @@
|
|||
}
|
||||
|
||||
.libraryPage {
|
||||
padding-top: 7em;
|
||||
padding-top: 7em !important;
|
||||
}
|
||||
|
||||
.layout-mobile .libraryPage {
|
||||
padding-top: 4em !important;
|
||||
}
|
||||
|
||||
.itemDetailPage {
|
||||
|
@ -128,10 +132,6 @@
|
|||
margin-top: 0;
|
||||
}
|
||||
|
||||
.layout-mobile .pageTitleWithDefaultLogo {
|
||||
background-image: url(../img/icon-transparent.png);
|
||||
}
|
||||
|
||||
.headerLeft,
|
||||
.skinHeader {
|
||||
display: -webkit-box;
|
||||
|
@ -246,6 +246,7 @@
|
|||
}
|
||||
|
||||
@media all and (min-width: 40em) {
|
||||
.dashboardDocument .adminDrawerLogo,
|
||||
.dashboardDocument .mainDrawerButton {
|
||||
display: none !important;
|
||||
}
|
||||
|
@ -313,7 +314,7 @@
|
|||
}
|
||||
|
||||
.dashboardDocument .mainDrawer-scrollContainer {
|
||||
margin-top: 4.6em !important;
|
||||
margin-top: 4.65em !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -606,12 +607,11 @@
|
|||
}
|
||||
|
||||
.detailLogo {
|
||||
width: 67.25vw;
|
||||
height: 14.5vh;
|
||||
width: 30vw;
|
||||
height: 25vh;
|
||||
position: absolute;
|
||||
top: 15vh;
|
||||
right: 0;
|
||||
-webkit-background-size: contain;
|
||||
top: 10vh;
|
||||
right: 20vw;
|
||||
background-size: contain;
|
||||
}
|
||||
|
||||
|
@ -619,26 +619,8 @@
|
|||
display: none;
|
||||
}
|
||||
|
||||
@media all and (max-width: 87.5em) {
|
||||
.detailLogo {
|
||||
right: 5%;
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (max-width: 75em) {
|
||||
.detailLogo {
|
||||
right: 2%;
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (max-width: 68.75em) {
|
||||
.detailLogo {
|
||||
width: 14.91em;
|
||||
height: 3.5em;
|
||||
right: 5%;
|
||||
bottom: 5%;
|
||||
top: auto;
|
||||
background-position: center right;
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
@ -1119,50 +1101,3 @@ div:not(.sectionTitleContainer-cards) > .sectionTitle-cards {
|
|||
.itemsViewSettingsContainer > .button-flat {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.layout-mobile #myPreferencesMenuPage {
|
||||
padding-top: 3.75em;
|
||||
}
|
||||
|
||||
.itemDetailsGroup {
|
||||
margin-bottom: 1.5em;
|
||||
}
|
||||
|
||||
.trackSelections {
|
||||
max-width: 44em;
|
||||
}
|
||||
|
||||
.detailsGroupItem,
|
||||
.trackSelections .selectContainer {
|
||||
display: flex;
|
||||
max-width: 44em;
|
||||
margin: 0 0 0.5em !important;
|
||||
}
|
||||
|
||||
.trackSelections .selectContainer {
|
||||
margin: 0 0 0.3em !important;
|
||||
}
|
||||
|
||||
.detailsGroupItem .label,
|
||||
.trackSelections .selectContainer .selectLabel {
|
||||
cursor: default;
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
flex-basis: 6.25em;
|
||||
margin: 0 0.6em 0 0;
|
||||
}
|
||||
|
||||
.trackSelections .selectContainer .selectLabel {
|
||||
margin: 0 0.2em 0 0;
|
||||
}
|
||||
|
||||
.trackSelections .selectContainer .detailTrackSelect {
|
||||
font-size: inherit;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.trackSelections .selectContainer .selectArrowContainer .selectArrow {
|
||||
margin-top: 0;
|
||||
font-size: 1.4em;
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ _define("document-register-element", function() {
|
|||
// fetch
|
||||
var fetch = require("whatwg-fetch");
|
||||
_define("fetch", function() {
|
||||
return fetch
|
||||
return fetch;
|
||||
});
|
||||
|
||||
// query-string
|
||||
|
@ -85,15 +85,15 @@ _define("webcomponents", function() {
|
|||
});
|
||||
|
||||
// libass-wasm
|
||||
var libass_wasm = require("libass-wasm");
|
||||
var libassWasm = require("libass-wasm");
|
||||
_define("JavascriptSubtitlesOctopus", function() {
|
||||
return libass_wasm;
|
||||
return libassWasm;
|
||||
});
|
||||
|
||||
// material-icons
|
||||
var material_icons = require("material-design-icons-iconfont/dist/material-design-icons.css");
|
||||
var materialIcons = require("material-design-icons-iconfont/dist/material-design-icons.css");
|
||||
_define("material-icons", function() {
|
||||
return material_icons;
|
||||
return materialIcons;
|
||||
});
|
||||
|
||||
// noto font
|
||||
|
@ -113,13 +113,36 @@ _define("polyfill", function () {
|
|||
return polyfill;
|
||||
});
|
||||
|
||||
// Date-FNS
|
||||
var date_fns = require("date-fns");
|
||||
_define("date-fns", function () {
|
||||
return date_fns;
|
||||
// domtokenlist-shim
|
||||
var classlist = require("classlist.js");
|
||||
_define("classlist-polyfill", function () {
|
||||
return classlist;
|
||||
});
|
||||
|
||||
var date_fns_locale = require("date-fns/locale");
|
||||
_define("date-fns/locale", function () {
|
||||
return date_fns_locale;
|
||||
// Date-FNS
|
||||
var dateFns = require("date-fns");
|
||||
_define("date-fns", function () {
|
||||
return dateFns;
|
||||
});
|
||||
|
||||
var dateFnsLocale = require("date-fns/locale");
|
||||
_define("date-fns/locale", function () {
|
||||
return dateFnsLocale;
|
||||
});
|
||||
|
||||
var fast_text_encoding = require("fast-text-encoding");
|
||||
_define("fast-text-encoding", function () {
|
||||
return fast_text_encoding;
|
||||
});
|
||||
|
||||
// intersection-observer
|
||||
var intersection_observer = require("intersection-observer");
|
||||
_define("intersection-observer", function () {
|
||||
return intersection_observer;
|
||||
});
|
||||
|
||||
// screenfull
|
||||
var screenfull = require("screenfull");
|
||||
_define("screenfull", function () {
|
||||
return screenfull;
|
||||
});
|
||||
|
|
|
@ -16,7 +16,7 @@ define(["events", "globalize", "dom", "date-fns", "dfnshelper", "userSettings",
|
|||
html += '<i class="listItemIcon material-icons" style="width:2em!important;height:2em!important;padding:0;color:transparent;background-color:' + color + ";background-image:url('" + apiClient.getUserImageUrl(entry.UserId, {
|
||||
type: "Primary",
|
||||
tag: entry.UserPrimaryImageTag
|
||||
}) + "');background-repeat:no-repeat;background-position:center center;background-size: cover;\">dvr</i>"
|
||||
}) + "');background-repeat:no-repeat;background-position:center center;background-size: cover;\">dvr</i>";
|
||||
} else {
|
||||
html += '<i class="listItemIcon material-icons" style="background-color:' + color + '">' + icon + '</i>';
|
||||
}
|
||||
|
|
|
@ -268,6 +268,7 @@ define(['loading', 'globalize', 'events', 'viewManager', 'layoutManager', 'skinM
|
|||
}
|
||||
|
||||
function getMaxBandwidth() {
|
||||
/* eslint-disable compat/compat */
|
||||
if (navigator.connection) {
|
||||
var max = navigator.connection.downlinkMax;
|
||||
if (max && max > 0 && max < Number.POSITIVE_INFINITY) {
|
||||
|
@ -279,6 +280,7 @@ define(['loading', 'globalize', 'events', 'viewManager', 'layoutManager', 'skinM
|
|||
return max;
|
||||
}
|
||||
}
|
||||
/* eslint-enable compat/compat */
|
||||
|
||||
return null;
|
||||
}
|
||||
|
@ -577,8 +579,9 @@ define(['loading', 'globalize', 'events', 'viewManager', 'layoutManager', 'skinM
|
|||
|
||||
function showDirect(path) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
resolveOnNextShow = resolve, page.show(baseUrl()+path)
|
||||
})
|
||||
resolveOnNextShow = resolve;
|
||||
page.show(baseUrl() + path);
|
||||
});
|
||||
}
|
||||
|
||||
function show(path, options) {
|
||||
|
|
|
@ -279,8 +279,8 @@ define(["appSettings", "browser", "events", "htmlMediaHelper", "webSettings"], f
|
|||
features.push("screensaver");
|
||||
|
||||
webSettings.enableMultiServer().then(enabled => {
|
||||
if (enabled) features.push("multiserver")
|
||||
})
|
||||
if (enabled) features.push("multiserver");
|
||||
});
|
||||
|
||||
if (!browser.orsay && !browser.msie && (browser.firefox || browser.ps4 || browser.edge || supportsCue())) {
|
||||
features.push("subtitleappearancesettings");
|
||||
|
@ -351,8 +351,6 @@ define(["appSettings", "browser", "events", "htmlMediaHelper", "webSettings"], f
|
|||
var deviceName;
|
||||
var appName = "Jellyfin Web";
|
||||
var appVersion = "10.5.0";
|
||||
var visibilityChange;
|
||||
var visibilityState;
|
||||
|
||||
var appHost = {
|
||||
getWindowState: function () {
|
||||
|
@ -383,7 +381,7 @@ define(["appSettings", "browser", "events", "htmlMediaHelper", "webSettings"], f
|
|||
return window.NativeShell.AppHost.getDefaultLayout();
|
||||
}
|
||||
|
||||
return getDefaultLayout()
|
||||
return getDefaultLayout();
|
||||
},
|
||||
getDeviceProfile: getDeviceProfile,
|
||||
init: function () {
|
||||
|
@ -426,40 +424,26 @@ define(["appSettings", "browser", "events", "htmlMediaHelper", "webSettings"], f
|
|||
}
|
||||
};
|
||||
|
||||
var doc = self.document;
|
||||
var isHidden = false;
|
||||
var hidden;
|
||||
var visibilityChange;
|
||||
|
||||
if (doc) {
|
||||
if (void 0 !== doc.visibilityState) {
|
||||
visibilityChange = "visibilitychange";
|
||||
visibilityState = "hidden";
|
||||
if (typeof document.hidden !== "undefined") { /* eslint-disable-line compat/compat */
|
||||
hidden = "hidden";
|
||||
visibilityChange = "visibilitychange";
|
||||
} else if (typeof document.webkitHidden !== "undefined") {
|
||||
hidden = "webkitHidden";
|
||||
visibilityChange = "webkitvisibilitychange";
|
||||
}
|
||||
|
||||
document.addEventListener(visibilityChange, function () {
|
||||
/* eslint-disable-next-line compat/compat */
|
||||
if (document[hidden]) {
|
||||
onAppHidden();
|
||||
} else {
|
||||
if (void 0 !== doc.mozHidden) {
|
||||
visibilityChange = "mozvisibilitychange";
|
||||
visibilityState = "mozVisibilityState";
|
||||
} else {
|
||||
if (void 0 !== doc.msHidden) {
|
||||
visibilityChange = "msvisibilitychange";
|
||||
visibilityState = "msVisibilityState";
|
||||
} else {
|
||||
if (void 0 !== doc.webkitHidden) {
|
||||
visibilityChange = "webkitvisibilitychange";
|
||||
visibilityState = "webkitVisibilityState";
|
||||
}
|
||||
}
|
||||
}
|
||||
onAppVisible();
|
||||
}
|
||||
}
|
||||
|
||||
if (doc) {
|
||||
doc.addEventListener(visibilityChange, function () {
|
||||
if (document[visibilityState]) {
|
||||
onAppHidden();
|
||||
} else {
|
||||
onAppVisible();
|
||||
}
|
||||
});
|
||||
}
|
||||
}, false);
|
||||
|
||||
if (self.addEventListener) {
|
||||
self.addEventListener("focus", onAppVisible);
|
||||
|
|
|
@ -52,5 +52,5 @@ define(["connectionManager"], function (connectionManager) {
|
|||
currentSlideshow = null;
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
});
|
||||
|
|
|
@ -188,9 +188,9 @@ define(['events'], function (events) {
|
|||
return apiClient.getEndpointInfo().then(function (endpoint) {
|
||||
if (endpoint.IsInNetwork) {
|
||||
return apiClient.getPublicSystemInfo().then(function (info) {
|
||||
var localAddress = info.LocalAddress
|
||||
var localAddress = info.LocalAddress;
|
||||
if (!localAddress) {
|
||||
console.debug("No valid local address returned, defaulting to external one")
|
||||
console.debug("No valid local address returned, defaulting to external one");
|
||||
localAddress = serverAddress;
|
||||
}
|
||||
addToCache(serverAddress, localAddress);
|
||||
|
|
|
@ -7,11 +7,11 @@ define(['loading', 'dialogHelper', 'dom', 'listViewStyle', 'emby-input', 'paper-
|
|||
systemInfo = info;
|
||||
return info;
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function onDialogClosed() {
|
||||
loading.hide()
|
||||
loading.hide();
|
||||
}
|
||||
|
||||
function refreshDirectoryBrowser(page, path, fileOptions, updatePathOnError) {
|
||||
|
@ -24,7 +24,7 @@ define(['loading', 'dialogHelper', 'dom', 'listViewStyle', 'emby-input', 'paper-
|
|||
var promises = [];
|
||||
|
||||
if ("Network" === path) {
|
||||
promises.push(ApiClient.getNetworkDevices())
|
||||
promises.push(ApiClient.getNetworkDevices());
|
||||
} else {
|
||||
if (path) {
|
||||
promises.push(ApiClient.getDirectoryContents(path, fileOptions));
|
||||
|
@ -101,7 +101,7 @@ define(['loading', 'dialogHelper', 'dom', 'listViewStyle', 'emby-input', 'paper-
|
|||
html += Globalize.translate("MessageDirectoryPickerLinuxInstruction");
|
||||
html += "<br/>";
|
||||
}
|
||||
html += "</div>"
|
||||
html += "</div>";
|
||||
}
|
||||
html += '<form style="margin:auto;">';
|
||||
html += '<div class="inputContainer" style="display: flex; align-items: center;">';
|
||||
|
@ -144,13 +144,13 @@ define(['loading', 'dialogHelper', 'dom', 'listViewStyle', 'emby-input', 'paper-
|
|||
function alertText(text) {
|
||||
alertTextWithOptions({
|
||||
text: text
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
function alertTextWithOptions(options) {
|
||||
require(["alert"], function(alert) {
|
||||
alert(options)
|
||||
})
|
||||
alert(options);
|
||||
});
|
||||
}
|
||||
|
||||
function validatePath(path, validateWriteable, apiClient) {
|
||||
|
@ -171,12 +171,12 @@ define(['loading', 'dialogHelper', 'dom', 'listViewStyle', 'emby-input', 'paper-
|
|||
if (validateWriteable) {
|
||||
alertText(Globalize.translate("WriteAccessRequired"));
|
||||
} else {
|
||||
alertText(Globalize.translate("PathNotFound"))
|
||||
alertText(Globalize.translate("PathNotFound"));
|
||||
}
|
||||
return Promise.reject()
|
||||
return Promise.reject();
|
||||
}
|
||||
}
|
||||
return Promise.resolve()
|
||||
return Promise.resolve();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -188,7 +188,7 @@ define(['loading', 'dialogHelper', 'dom', 'listViewStyle', 'emby-input', 'paper-
|
|||
if (lnkPath.classList.contains("lnkFile")) {
|
||||
content.querySelector("#txtDirectoryPickerPath").value = path;
|
||||
} else {
|
||||
refreshDirectoryBrowser(content, path, fileOptions, true)
|
||||
refreshDirectoryBrowser(content, path, fileOptions, true);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -275,7 +275,7 @@ define(['loading', 'dialogHelper', 'dom', 'listViewStyle', 'emby-input', 'paper-
|
|||
dlg.addEventListener("close", onDialogClosed);
|
||||
dialogHelper.open(dlg);
|
||||
dlg.querySelector(".btnCloseDialog").addEventListener("click", function() {
|
||||
dialogHelper.close(dlg)
|
||||
dialogHelper.close(dlg);
|
||||
});
|
||||
currentDialog = dlg;
|
||||
dlg.querySelector("#txtDirectoryPickerPath").value = initialPath;
|
||||
|
@ -293,9 +293,9 @@ define(['loading', 'dialogHelper', 'dom', 'listViewStyle', 'emby-input', 'paper-
|
|||
if (currentDialog) {
|
||||
dialogHelper.close(currentDialog);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
var systemInfo;
|
||||
return directoryBrowser
|
||||
return directoryBrowser;
|
||||
});
|
||||
|
|
|
@ -186,6 +186,8 @@ define(['require', 'browser', 'layoutManager', 'appSettings', 'pluginManager', '
|
|||
context.querySelector('#selectLanguage').value = userSettings.language() || '';
|
||||
context.querySelector('.selectDateTimeLocale').value = userSettings.dateTimeLocale() || '';
|
||||
|
||||
context.querySelector('#txtLibraryPageSize').value = userSettings.libraryPageSize();
|
||||
|
||||
selectDashboardTheme.value = userSettings.dashboardTheme() || '';
|
||||
selectTheme.value = userSettings.theme() || '';
|
||||
|
||||
|
@ -215,6 +217,8 @@ define(['require', 'browser', 'layoutManager', 'appSettings', 'pluginManager', '
|
|||
userSettingsInstance.soundEffects(context.querySelector('.selectSoundEffects').value);
|
||||
userSettingsInstance.screensaver(context.querySelector('.selectScreensaver').value);
|
||||
|
||||
userSettingsInstance.libraryPageSize(context.querySelector('#txtLibraryPageSize').value);
|
||||
|
||||
userSettingsInstance.skin(context.querySelector('.selectSkin').value);
|
||||
|
||||
userSettingsInstance.enableFastFadein(context.querySelector('#chkFadein').checked);
|
||||
|
|
|
@ -143,6 +143,11 @@
|
|||
<select is="emby-select" class="selectSoundEffects" label="${LabelSoundEffects}"></select>
|
||||
</div>
|
||||
|
||||
<div class="inputContainer inputContainer-withDescription fldFadein">
|
||||
<input is="emby-input" type="number" id="txtLibraryPageSize" pattern="[0-9]*" required="required" min="0" max="1000" step="1" label="${LabelLibraryPageSize}" />
|
||||
<div class="fieldDescription">${LabelLibraryPageSizeHelp}</div>
|
||||
</div>
|
||||
|
||||
<div class="checkboxContainer checkboxContainer-withDescription fldFadein">
|
||||
<label>
|
||||
<input type="checkbox" is="emby-checkbox" id="chkFadein" />
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import multiDownload from "multi-download"
|
||||
import multiDownload from "multi-download";
|
||||
|
||||
export function download(items) {
|
||||
|
||||
if (window.NativeShell) {
|
||||
items.map(function (item) {
|
||||
window.NativeShell.downloadFile(item.url);
|
||||
window.NativeShell.downloadFile(item);
|
||||
});
|
||||
} else {
|
||||
multiDownload(items.map(function (item) {
|
||||
|
|
|
@ -1,103 +0,0 @@
|
|||
define(['events', 'dom', 'apphost', 'browser'], function (events, dom, appHost, browser) {
|
||||
'use strict';
|
||||
|
||||
function fullscreenManager() {
|
||||
|
||||
}
|
||||
|
||||
fullscreenManager.prototype.requestFullscreen = function (element) {
|
||||
|
||||
element = element || document.documentElement;
|
||||
|
||||
if (element.requestFullscreen) {
|
||||
element.requestFullscreen();
|
||||
return;
|
||||
} else if (element.mozRequestFullScreen) {
|
||||
element.mozRequestFullScreen();
|
||||
return;
|
||||
} else if (element.webkitRequestFullscreen) {
|
||||
element.webkitRequestFullscreen();
|
||||
return;
|
||||
} else if (element.msRequestFullscreen) {
|
||||
element.msRequestFullscreen();
|
||||
return;
|
||||
}
|
||||
|
||||
// Hack - This is only available for video elements in ios safari
|
||||
if (element.tagName !== 'VIDEO') {
|
||||
element = document.querySelector('video') || element;
|
||||
}
|
||||
if (element.webkitEnterFullscreen) {
|
||||
element.webkitEnterFullscreen();
|
||||
}
|
||||
};
|
||||
|
||||
fullscreenManager.prototype.exitFullscreen = function () {
|
||||
|
||||
if (!this.isFullScreen()) {
|
||||
return;
|
||||
}
|
||||
if (document.exitFullscreen) {
|
||||
document.exitFullscreen();
|
||||
} else if (document.mozCancelFullScreen) {
|
||||
document.mozCancelFullScreen();
|
||||
} else if (document.webkitExitFullscreen) {
|
||||
document.webkitExitFullscreen();
|
||||
} else if (document.webkitCancelFullscreen) {
|
||||
document.webkitCancelFullscreen();
|
||||
} else if (document.msExitFullscreen) {
|
||||
document.msExitFullscreen();
|
||||
}
|
||||
};
|
||||
|
||||
// TODO: use screenfull.js
|
||||
fullscreenManager.prototype.isFullScreen = function () {
|
||||
return document.fullscreen ||
|
||||
document.mozFullScreen ||
|
||||
document.webkitIsFullScreen ||
|
||||
document.msFullscreenElement || /* IE/Edge syntax */
|
||||
document.fullscreenElement || /* Standard syntax */
|
||||
document.webkitFullscreenElement || /* Chrome, Safari and Opera syntax */
|
||||
document.mozFullScreenElement; /* Firefox syntax */
|
||||
};
|
||||
|
||||
var manager = new fullscreenManager();
|
||||
|
||||
function onFullScreenChange() {
|
||||
events.trigger(manager, 'fullscreenchange');
|
||||
}
|
||||
|
||||
dom.addEventListener(document, 'fullscreenchange', onFullScreenChange, {
|
||||
passive: true
|
||||
});
|
||||
|
||||
dom.addEventListener(document, 'webkitfullscreenchange', onFullScreenChange, {
|
||||
passive: true
|
||||
});
|
||||
|
||||
dom.addEventListener(document, 'mozfullscreenchange', onFullScreenChange, {
|
||||
passive: true
|
||||
});
|
||||
|
||||
function isTargetValid(target) {
|
||||
return !dom.parentWithTag(target, ['BUTTON', 'INPUT', 'TEXTAREA']);
|
||||
}
|
||||
if (appHost.supports("fullscreenchange") && (browser.edgeUwp || -1 !== navigator.userAgent.toLowerCase().indexOf("electron"))) {
|
||||
|
||||
dom.addEventListener(window, 'dblclick', function (e) {
|
||||
|
||||
if (isTargetValid(e.target)) {
|
||||
if (manager.isFullScreen()) {
|
||||
manager.exitFullscreen();
|
||||
} else {
|
||||
manager.requestFullscreen();
|
||||
}
|
||||
}
|
||||
|
||||
}, {
|
||||
passive: true
|
||||
});
|
||||
}
|
||||
|
||||
return manager;
|
||||
});
|
|
@ -1,4 +1,4 @@
|
|||
define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager', 'scrollHelper', 'serverNotifications', 'loading', 'datetime', 'focusManager', 'playbackManager', 'userSettings', 'imageLoader', 'events', 'layoutManager', 'itemShortcuts', 'dom', 'css!./guide.css', 'programStyles', 'material-icons', 'scrollStyles', 'emby-button', 'paper-icon-button-light', 'emby-tabs', 'emby-scroller', 'flexStyles', 'registerElement'], function (require, inputManager, browser, globalize, connectionManager, scrollHelper, serverNotifications, loading, datetime, focusManager, playbackManager, userSettings, imageLoader, events, layoutManager, itemShortcuts, dom) {
|
||||
define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager', 'scrollHelper', 'serverNotifications', 'loading', 'datetime', 'focusManager', 'playbackManager', 'userSettings', 'imageLoader', 'events', 'layoutManager', 'itemShortcuts', 'dom', 'css!./guide.css', 'programStyles', 'material-icons', 'scrollStyles', 'emby-programcell', 'emby-button', 'paper-icon-button-light', 'emby-tabs', 'emby-scroller', 'flexStyles', 'registerElement'], function (require, inputManager, browser, globalize, connectionManager, scrollHelper, serverNotifications, loading, datetime, focusManager, playbackManager, userSettings, imageLoader, events, layoutManager, itemShortcuts, dom) {
|
||||
'use strict';
|
||||
|
||||
function showViewSettings(instance) {
|
||||
|
@ -1252,18 +1252,5 @@ define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager',
|
|||
});
|
||||
}
|
||||
|
||||
var ProgramCellPrototype = Object.create(HTMLButtonElement.prototype);
|
||||
|
||||
ProgramCellPrototype.detachedCallback = function () {
|
||||
this.posLeft = null;
|
||||
this.posWidth = null;
|
||||
this.guideProgramName = null;
|
||||
};
|
||||
|
||||
document.registerElement('emby-programcell', {
|
||||
prototype: ProgramCellPrototype,
|
||||
extends: 'button'
|
||||
});
|
||||
|
||||
return Guide;
|
||||
});
|
||||
|
|
|
@ -10,6 +10,13 @@
|
|||
<div class="fieldDescription">${LabelPleaseRestart}</div>
|
||||
</div>
|
||||
|
||||
<div class="verticalSection verticalSection-extrabottompadding">
|
||||
<label class="checkboxContainer">
|
||||
<input class="chkHidePlayedFromLatest" type="checkbox" is="emby-checkbox" />
|
||||
<span>${HideWatchedContentFromLatestMedia}</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="selectContainer">
|
||||
<select is="emby-select" id="selectHomeSection1" label="{section1label}">
|
||||
<option value="smalllibrarytiles">${HeaderMyMedia}</option>
|
||||
|
@ -110,13 +117,6 @@
|
|||
|
||||
<div class="perLibrarySettings"></div>
|
||||
|
||||
<div class="verticalSection verticalSection-extrabottompadding">
|
||||
<label class="checkboxContainer">
|
||||
<input class="chkHidePlayedFromLatest" type="checkbox" is="emby-checkbox" />
|
||||
<span>${HideWatchedContentFromLatestMedia}</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="verticalSection verticalSection-extrabottompadding">
|
||||
<h2 class="sectionTitle">${HeaderLibraryFolders}</h2>
|
||||
<div>
|
||||
|
|
|
@ -64,18 +64,18 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
|
|||
} else {
|
||||
var noLibDescription;
|
||||
if (user['Policy'] && user['Policy']['IsAdministrator']) {
|
||||
noLibDescription = Globalize.translate("NoCreatedLibraries", '<a id="button-createLibrary" class="button-link">', '</a>')
|
||||
noLibDescription = Globalize.translate("NoCreatedLibraries", '<a id="button-createLibrary" class="button-link">', '</a>');
|
||||
} else {
|
||||
noLibDescription = Globalize.translate("AskAdminToCreateLibrary");
|
||||
}
|
||||
|
||||
html += '<div class="centerMessage padded-left padded-right">';
|
||||
html += '<h2>' + Globalize.translate("MessageNothingHere") + '</h2>';
|
||||
html += '<p>' + noLibDescription + '</p>'
|
||||
html += '<p>' + noLibDescription + '</p>';
|
||||
html += '</div>';
|
||||
elem.innerHTML = html;
|
||||
|
||||
var createNowLink = elem.querySelector("#button-createLibrary")
|
||||
var createNowLink = elem.querySelector("#button-createLibrary");
|
||||
if (createNowLink) {
|
||||
createNowLink.addEventListener("click", function () {
|
||||
Dashboard.navigate("library.html");
|
||||
|
@ -131,7 +131,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
|
|||
} else if (section === 'librarytiles' || section === 'smalllibrarytiles' || section === 'smalllibrarytiles-automobile' || section === 'librarytiles-automobile') {
|
||||
loadLibraryTiles(elem, apiClient, user, userSettings, 'smallBackdrop', userViews, allSections);
|
||||
} else if (section === 'librarybuttons') {
|
||||
loadlibraryButtons(elem, apiClient, user, userSettings, userViews, allSections);
|
||||
loadlibraryButtons(elem, apiClient, user, userSettings, userViews);
|
||||
} else if (section === 'resume') {
|
||||
loadResumeVideo(elem, apiClient, userId);
|
||||
} else if (section === 'resumeaudio') {
|
||||
|
@ -640,7 +640,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
|
|||
|
||||
if (enableScrollX()) {
|
||||
html += '<div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-centerfocus="true">';
|
||||
html += '<div is="emby-itemscontainer" class="itemsContainer scrollSlider focuscontainer-x">'
|
||||
html += '<div is="emby-itemscontainer" class="itemsContainer scrollSlider focuscontainer-x">';
|
||||
} else {
|
||||
html += '<div is="emby-itemscontainer" class="itemsContainer padded-left padded-right vertical-wrap focuscontainer-x">';
|
||||
}
|
||||
|
@ -714,7 +714,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
|
|||
|
||||
if (enableScrollX()) {
|
||||
html += '<div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-centerfocus="true">';
|
||||
html += '<div is="emby-itemscontainer" class="itemsContainer scrollSlider focuscontainer-x" data-monitor="videoplayback,markplayed">'
|
||||
html += '<div is="emby-itemscontainer" class="itemsContainer scrollSlider focuscontainer-x" data-monitor="videoplayback,markplayed">';
|
||||
} else {
|
||||
html += '<div is="emby-itemscontainer" class="itemsContainer padded-left padded-right vertical-wrap focuscontainer-x" data-monitor="videoplayback,markplayed">';
|
||||
}
|
||||
|
@ -786,7 +786,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
|
|||
|
||||
if (enableScrollX()) {
|
||||
html += '<div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-centerfocus="true">';
|
||||
html += '<div is="emby-itemscontainer" class="itemsContainer scrollSlider focuscontainer-x">'
|
||||
html += '<div is="emby-itemscontainer" class="itemsContainer scrollSlider focuscontainer-x">';
|
||||
} else {
|
||||
html += '<div is="emby-itemscontainer" class="itemsContainer padded-left padded-right vertical-wrap focuscontainer-x">';
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ define(['appSettings', 'browser', 'events'], function (appSettings, browser, eve
|
|||
}
|
||||
|
||||
function enableHlsShakaPlayer(item, mediaSource, mediaType) {
|
||||
|
||||
/* eslint-disable-next-line compat/compat */
|
||||
if (!!window.MediaSource && !!MediaSource.isTypeSupported) {
|
||||
|
||||
if (canPlayNativeHls()) {
|
||||
|
@ -162,7 +162,7 @@ define(['appSettings', 'browser', 'events'], function (appSettings, browser, eve
|
|||
}
|
||||
}
|
||||
|
||||
function seekOnPlaybackStart(instance, element, ticks) {
|
||||
function seekOnPlaybackStart(instance, element, ticks, onMediaReady) {
|
||||
|
||||
var seconds = (ticks || 0) / 10000000;
|
||||
|
||||
|
@ -171,13 +171,31 @@ define(['appSettings', 'browser', 'events'], function (appSettings, browser, eve
|
|||
|
||||
// Appending #t=xxx to the query string doesn't seem to work with HLS
|
||||
// For plain video files, not all browsers support it either
|
||||
var delay = browser.safari ? 2500 : 0;
|
||||
if (delay) {
|
||||
setTimeout(function () {
|
||||
setCurrentTimeIfNeeded(element, seconds);
|
||||
}, delay);
|
||||
} else {
|
||||
|
||||
if (element.duration >= seconds) {
|
||||
// media is ready, seek immediately
|
||||
setCurrentTimeIfNeeded(element, seconds);
|
||||
if (onMediaReady) onMediaReady();
|
||||
} else {
|
||||
// update video player position when media is ready to be sought
|
||||
var events = ["durationchange", "loadeddata", "play", "loadedmetadata"];
|
||||
var onMediaChange = function(e) {
|
||||
if (element.currentTime === 0 && element.duration >= seconds) {
|
||||
// seek only when video position is exactly zero,
|
||||
// as this is true only if video hasn't started yet or
|
||||
// user rewound to the very beginning
|
||||
// (but rewinding cannot happen as the first event with media of non-empty duration)
|
||||
console.debug(`seeking to ${seconds} on ${e.type} event`);
|
||||
setCurrentTimeIfNeeded(element, seconds);
|
||||
events.map(function(name) {
|
||||
element.removeEventListener(name, onMediaChange);
|
||||
});
|
||||
if (onMediaReady) onMediaReady();
|
||||
}
|
||||
};
|
||||
events.map(function (name) {
|
||||
element.addEventListener(name, onMediaChange);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -101,7 +101,7 @@ define(['events', 'browser', 'require', 'apphost', 'appSettings', 'htmlMediaHelp
|
|||
self._timeUpdated = false;
|
||||
self._currentTime = null;
|
||||
|
||||
var elem = createMediaElement(options);
|
||||
var elem = createMediaElement();
|
||||
return setCurrentSrc(elem, options);
|
||||
};
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackManager', 'appRouter', 'appSettings', 'connectionManager', 'htmlMediaHelper', 'itemHelper', 'fullscreenManager', 'globalize'], function (browser, require, events, appHost, loading, dom, playbackManager, appRouter, appSettings, connectionManager, htmlMediaHelper, itemHelper, fullscreenManager, globalize) {
|
||||
define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackManager', 'appRouter', 'appSettings', 'connectionManager', 'htmlMediaHelper', 'itemHelper', 'screenfull', 'globalize'], function (browser, require, events, appHost, loading, dom, playbackManager, appRouter, appSettings, connectionManager, htmlMediaHelper, itemHelper, screenfull, globalize) {
|
||||
"use strict";
|
||||
/* globals cast */
|
||||
|
||||
|
@ -116,8 +116,9 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
|
|||
});
|
||||
}
|
||||
|
||||
function normalizeTrackEventText(text) {
|
||||
return text.replace(/\\N/gi, '\n');
|
||||
function normalizeTrackEventText(text, useHtml) {
|
||||
var result = text.replace(/\\N/gi, '\n').replace(/\r/gi, '');
|
||||
return useHtml ? result.replace(/\n/gi, '<br>') : result;
|
||||
}
|
||||
|
||||
function setTracks(elem, tracks, item, mediaSource) {
|
||||
|
@ -567,19 +568,19 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
|
|||
self.resetSubtitleOffset = function() {
|
||||
currentTrackOffset = 0;
|
||||
showTrackOffset = false;
|
||||
}
|
||||
};
|
||||
|
||||
self.enableShowingSubtitleOffset = function() {
|
||||
showTrackOffset = true;
|
||||
}
|
||||
};
|
||||
|
||||
self.disableShowingSubtitleOffset = function() {
|
||||
showTrackOffset = false;
|
||||
}
|
||||
};
|
||||
|
||||
self.isShowingSubtitleOffsetEnabled = function() {
|
||||
return showTrackOffset;
|
||||
}
|
||||
};
|
||||
|
||||
function getTextTrack() {
|
||||
var videoElement = self._mediaElement;
|
||||
|
@ -599,8 +600,9 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
|
|||
var offsetValue = parseFloat(offset);
|
||||
|
||||
// if .ass currently rendering
|
||||
if (currentAssRenderer) {
|
||||
if (currentSubtitlesOctopus) {
|
||||
updateCurrentTrackOffset(offsetValue);
|
||||
currentSubtitlesOctopus.timeOffset = offsetValue;
|
||||
} else {
|
||||
var trackElement = getTextTrack();
|
||||
// if .vtt currently rendering
|
||||
|
@ -651,7 +653,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
|
|||
|
||||
self.getSubtitleOffset = function() {
|
||||
return currentTrackOffset;
|
||||
}
|
||||
};
|
||||
|
||||
function isAudioStreamSupported(stream, deviceProfile) {
|
||||
|
||||
|
@ -793,7 +795,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
|
|||
dlg.parentNode.removeChild(dlg);
|
||||
}
|
||||
|
||||
fullscreenManager.exitFullscreen();
|
||||
screenfull.exit();
|
||||
};
|
||||
|
||||
function onEnded() {
|
||||
|
@ -855,7 +857,9 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
|
|||
|
||||
loading.hide();
|
||||
|
||||
htmlMediaHelper.seekOnPlaybackStart(self, e.target, self._currentPlayOptions.playerStartPositionTicks);
|
||||
htmlMediaHelper.seekOnPlaybackStart(self, e.target, self._currentPlayOptions.playerStartPositionTicks, function () {
|
||||
if (currentSubtitlesOctopus) currentSubtitlesOctopus.resize();
|
||||
});
|
||||
|
||||
if (self._currentPlayOptions.fullscreen) {
|
||||
|
||||
|
@ -1019,7 +1023,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
|
|||
xhr.onerror = function (e) {
|
||||
reject(e);
|
||||
decrementFetchQueue();
|
||||
}
|
||||
};
|
||||
|
||||
xhr.send();
|
||||
});
|
||||
|
@ -1048,11 +1052,12 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
|
|||
|
||||
function renderSsaAss(videoElement, track, item) {
|
||||
var attachments = self._currentPlayOptions.mediaSource.MediaAttachments || [];
|
||||
var apiClient = connectionManager.getApiClient(item);
|
||||
var options = {
|
||||
video: videoElement,
|
||||
subUrl: getTextTrackUrl(track, item),
|
||||
fonts: attachments.map(function (i) {
|
||||
return i.DeliveryUrl;
|
||||
return apiClient.getUrl(i.DeliveryUrl);
|
||||
}),
|
||||
workerUrl: appRouter.baseUrl() + "/libraries/subtitles-octopus-worker.js",
|
||||
legacyWorkerUrl: appRouter.baseUrl() + "/libraries/subtitles-octopus-worker-legacy.js",
|
||||
|
@ -1208,7 +1213,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
|
|||
data.TrackEvents.forEach(function (trackEvent) {
|
||||
|
||||
var trackCueObject = window.VTTCue || window.TextTrackCue;
|
||||
var cue = new trackCueObject(trackEvent.StartPositionTicks / 10000000, trackEvent.EndPositionTicks / 10000000, normalizeTrackEventText(trackEvent.Text));
|
||||
var cue = new trackCueObject(trackEvent.StartPositionTicks / 10000000, trackEvent.EndPositionTicks / 10000000, normalizeTrackEventText(trackEvent.Text, false));
|
||||
|
||||
trackElement.addCue(cue);
|
||||
});
|
||||
|
@ -1218,11 +1223,6 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
|
|||
|
||||
function updateSubtitleText(timeMs) {
|
||||
|
||||
// handle offset for ass tracks
|
||||
if (currentTrackOffset) {
|
||||
timeMs += (currentTrackOffset * 1000);
|
||||
}
|
||||
|
||||
var clock = currentClock;
|
||||
if (clock) {
|
||||
try {
|
||||
|
@ -1249,8 +1249,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
|
|||
}
|
||||
|
||||
if (selectedTrackEvent && selectedTrackEvent.Text) {
|
||||
|
||||
subtitleTextElement.innerHTML = normalizeTrackEventText(selectedTrackEvent.Text);
|
||||
subtitleTextElement.innerHTML = normalizeTrackEventText(selectedTrackEvent.Text, true);
|
||||
subtitleTextElement.classList.remove('hide');
|
||||
|
||||
} else {
|
||||
|
@ -1427,11 +1426,11 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
|
|||
}
|
||||
|
||||
if (browser.safari || browser.iOS || browser.iPad) {
|
||||
list.push('AirPlay')
|
||||
list.push('AirPlay');
|
||||
}
|
||||
|
||||
list.push('SetBrightness');
|
||||
list.push("SetAspectRatio")
|
||||
list.push("SetAspectRatio");
|
||||
|
||||
return list;
|
||||
}
|
||||
|
@ -1554,11 +1553,11 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
|
|||
if (video) {
|
||||
if (isEnabled) {
|
||||
video.requestAirPlay().catch(function(err) {
|
||||
console.error("Error requesting AirPlay", err)
|
||||
console.error("Error requesting AirPlay", err);
|
||||
});
|
||||
} else {
|
||||
document.exitAirPLay().catch(function(err) {
|
||||
console.error("Error exiting AirPlay", err)
|
||||
console.error("Error exiting AirPlay", err);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1691,12 +1690,12 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
|
|||
var mediaElement = this._mediaElement;
|
||||
if (mediaElement) {
|
||||
if ("auto" === val) {
|
||||
mediaElement.style.removeProperty("object-fit")
|
||||
mediaElement.style.removeProperty("object-fit");
|
||||
} else {
|
||||
mediaElement.style["object-fit"] = val
|
||||
mediaElement.style["object-fit"] = val;
|
||||
}
|
||||
}
|
||||
this._currentAspectRatio = val
|
||||
this._currentAspectRatio = val;
|
||||
};
|
||||
|
||||
HtmlVideoPlayer.prototype.getAspectRatio = function () {
|
||||
|
@ -1713,7 +1712,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
|
|||
}, {
|
||||
name: "Fill",
|
||||
id: "fill"
|
||||
}]
|
||||
}];
|
||||
};
|
||||
|
||||
HtmlVideoPlayer.prototype.togglePictureInPicture = function () {
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
define(['lazyLoader', 'imageFetcher', 'layoutManager', 'browser', 'appSettings', 'userSettings', 'require', 'css!./style'], function (lazyLoader, imageFetcher, layoutManager, browser, appSettings, userSettings, require) {
|
||||
'use strict';
|
||||
|
||||
var requestIdleCallback = window.requestIdleCallback || function (fn) {
|
||||
fn();
|
||||
};
|
||||
|
||||
var self = {};
|
||||
|
||||
function fillImage(elem, source, enableEffects) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
define(['datetime', 'itemHelper', 'css!./indicators.css', 'material-icons'], function (datetime, itemHelper) {
|
||||
define(['datetime', 'itemHelper', 'emby-progressbar', 'css!./indicators.css', 'material-icons'], function (datetime, itemHelper) {
|
||||
'use strict';
|
||||
|
||||
function enableProgressIndicator(item) {
|
||||
|
@ -183,45 +183,6 @@ define(['datetime', 'itemHelper', 'css!./indicators.css', 'material-icons'], fun
|
|||
return '';
|
||||
}
|
||||
|
||||
var ProgressBarPrototype = Object.create(HTMLDivElement.prototype);
|
||||
|
||||
function onAutoTimeProgress() {
|
||||
var start = parseInt(this.getAttribute('data-starttime'));
|
||||
var end = parseInt(this.getAttribute('data-endtime'));
|
||||
|
||||
var now = new Date().getTime();
|
||||
var total = end - start;
|
||||
var pct = 100 * ((now - start) / total);
|
||||
|
||||
pct = Math.min(100, pct);
|
||||
pct = Math.max(0, pct);
|
||||
|
||||
var itemProgressBarForeground = this.querySelector('.itemProgressBarForeground');
|
||||
itemProgressBarForeground.style.width = pct + '%';
|
||||
}
|
||||
|
||||
ProgressBarPrototype.attachedCallback = function () {
|
||||
if (this.timeInterval) {
|
||||
clearInterval(this.timeInterval);
|
||||
}
|
||||
|
||||
if (this.getAttribute('data-automode') === 'time') {
|
||||
this.timeInterval = setInterval(onAutoTimeProgress.bind(this), 60000);
|
||||
}
|
||||
};
|
||||
|
||||
ProgressBarPrototype.detachedCallback = function () {
|
||||
if (this.timeInterval) {
|
||||
clearInterval(this.timeInterval);
|
||||
this.timeInterval = null;
|
||||
}
|
||||
};
|
||||
|
||||
document.registerElement('emby-progressbar', {
|
||||
prototype: ProgressBarPrototype,
|
||||
extends: 'div'
|
||||
});
|
||||
|
||||
return {
|
||||
getProgressHtml: getProgressHtml,
|
||||
getProgressBarHtml: getProgressBarHtml,
|
||||
|
|
|
@ -184,7 +184,7 @@ require(['apphost'], function (appHost) {
|
|||
function allowInput() {
|
||||
|
||||
// This would be nice but always seems to return true with electron
|
||||
if (!isElectron && document.hidden) {
|
||||
if (!isElectron && document.hidden) { /* eslint-disable-line compat/compat */
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -254,7 +254,7 @@ require(['apphost'], function (appHost) {
|
|||
var inputLoopTimer;
|
||||
function runInputLoop() {
|
||||
// Get the latest gamepad state.
|
||||
var gamepads = navigator.getGamepads();
|
||||
var gamepads = navigator.getGamepads(); /* eslint-disable-line compat/compat */
|
||||
for (var i = 0, len = gamepads.length; i < len; i++) {
|
||||
var gamepad = gamepads[i];
|
||||
if (!gamepad) {
|
||||
|
@ -362,7 +362,7 @@ require(['apphost'], function (appHost) {
|
|||
}
|
||||
|
||||
function isGamepadConnected() {
|
||||
var gamepads = navigator.getGamepads();
|
||||
var gamepads = navigator.getGamepads(); /* eslint-disable-line compat/compat */
|
||||
for (var i = 0, len = gamepads.length; i < len; i++) {
|
||||
var gamepad = gamepads[i];
|
||||
if (gamepad && gamepad.connected) {
|
||||
|
@ -373,6 +373,7 @@ require(['apphost'], function (appHost) {
|
|||
}
|
||||
|
||||
function onFocusOrGamepadAttach(e) {
|
||||
/* eslint-disable-next-line compat/compat */
|
||||
if (isGamepadConnected() && document.hasFocus()) {
|
||||
console.log("Gamepad connected! Starting input loop");
|
||||
startInputLoop();
|
||||
|
@ -380,6 +381,7 @@ require(['apphost'], function (appHost) {
|
|||
}
|
||||
|
||||
function onFocusOrGamepadDetach(e) {
|
||||
/* eslint-disable-next-line compat/compat */
|
||||
if (!isGamepadConnected() || !document.hasFocus()) {
|
||||
console.log("Gamepad disconnected! No other gamepads are connected, stopping input loop");
|
||||
stopInputLoop();
|
||||
|
|
|
@ -159,7 +159,9 @@ function attachGamepadScript(e) {
|
|||
}
|
||||
|
||||
// No need to check for gamepads manually at load time, the eventhandler will be fired for that
|
||||
window.addEventListener("gamepadconnected", attachGamepadScript);
|
||||
if (navigator.getGamepads) { /* eslint-disable-line compat/compat */
|
||||
window.addEventListener("gamepadconnected", attachGamepadScript);
|
||||
}
|
||||
|
||||
export default {
|
||||
enable: enable,
|
||||
|
|
|
@ -116,7 +116,7 @@ define(["dialogHelper", "require", "layoutManager", "globalize", "userSettings",
|
|||
}
|
||||
|
||||
function createAttribute(label, value) {
|
||||
return '<span class="mediaInfoLabel">' + label + '</span><span class="mediaInfoAttribute">' + value + "</span>"
|
||||
return '<span class="mediaInfoLabel">' + label + '</span><span class="mediaInfoAttribute">' + value + "</span>";
|
||||
}
|
||||
|
||||
function showMediaInfoMore(itemId, serverId, template) {
|
||||
|
|
|
@ -339,7 +339,9 @@ define(["apphost", "globalize", "connectionManager", "itemHelper", "appRouter",
|
|||
fileDownloader.download([{
|
||||
url: downloadHref,
|
||||
itemId: itemId,
|
||||
serverId: serverId
|
||||
serverId: serverId,
|
||||
title: item.Name,
|
||||
filename: item.Path.replace(/^.*[\\\/]/, '')
|
||||
}]);
|
||||
getResolveFunction(getResolveFunction(resolve, id), id)();
|
||||
});
|
||||
|
@ -352,6 +354,7 @@ define(["apphost", "globalize", "connectionManager", "itemHelper", "appRouter",
|
|||
document.body.appendChild(textArea);
|
||||
textArea.focus();
|
||||
textArea.select();
|
||||
|
||||
if (document.execCommand("copy")) {
|
||||
require(["toast"], function (toast) {
|
||||
toast(globalize.translate("CopyStreamURLSuccess"));
|
||||
|
@ -361,14 +364,19 @@ define(["apphost", "globalize", "connectionManager", "itemHelper", "appRouter",
|
|||
}
|
||||
document.body.removeChild(textArea);
|
||||
};
|
||||
|
||||
/* eslint-disable-next-line compat/compat */
|
||||
if (navigator.clipboard === undefined) {
|
||||
textAreaCopy();
|
||||
} else {
|
||||
/* eslint-disable-next-line compat/compat */
|
||||
navigator.clipboard.writeText(downloadHref).then(function () {
|
||||
require(["toast"], function (toast) {
|
||||
toast(globalize.translate("CopyStreamURLSuccess"));
|
||||
});
|
||||
}, textAreaCopy);
|
||||
}).catch(function () {
|
||||
textAreaCopy();
|
||||
});
|
||||
}
|
||||
getResolveFunction(resolve, id)();
|
||||
break;
|
||||
|
|
|
@ -4,10 +4,6 @@ define(['visibleinviewport', 'dom', 'browser'], function (visibleinviewport, dom
|
|||
var thresholdX;
|
||||
var thresholdY;
|
||||
|
||||
var requestIdleCallback = window.requestIdleCallback || function (fn) {
|
||||
fn();
|
||||
};
|
||||
|
||||
function resetThresholds() {
|
||||
|
||||
var threshold = 0.3;
|
||||
|
|
|
@ -36,7 +36,7 @@ define(["globalize", "dom", "emby-checkbox", "emby-select", "emby-input"], funct
|
|||
html += "<option value='" + culture.TwoLetterISORegionName + "'>" + culture.DisplayName + "</option>";
|
||||
}
|
||||
select.innerHTML = html;
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
function populateRefreshInterval(select) {
|
||||
|
@ -120,7 +120,7 @@ define(["globalize", "dom", "emby-checkbox", "emby-select", "emby-input"], funct
|
|||
html += plugin.Name;
|
||||
html += "</h3>";
|
||||
html += "</div>";
|
||||
i > 0 ? html += '<button type="button" is="paper-icon-button-light" title="' + globalize.translate("ButtonUp") + '" class="btnSortableMoveUp btnSortable" data-pluginindex="' + i + '"><i class="material-icons keyboard_arrow_up"></i></button>' : plugins.length > 1 && (html += '<button type="button" is="paper-icon-button-light" title="' + globalize.translate("ButtonDown") + '" class="btnSortableMoveDown btnSortable" data-pluginindex="' + i + '"><i class="material-icons keyboard_arrow_down"></i></button>'), html += "</div>"
|
||||
i > 0 ? html += '<button type="button" is="paper-icon-button-light" title="' + globalize.translate("ButtonUp") + '" class="btnSortableMoveUp btnSortable" data-pluginindex="' + i + '"><i class="material-icons keyboard_arrow_up"></i></button>' : plugins.length > 1 && (html += '<button type="button" is="paper-icon-button-light" title="' + globalize.translate("ButtonDown") + '" class="btnSortableMoveDown btnSortable" data-pluginindex="' + i + '"><i class="material-icons keyboard_arrow_down"></i></button>'), html += "</div>";
|
||||
}
|
||||
html += "</div>";
|
||||
html += '<div class="fieldDescription">' + globalize.translate("LabelMetadataDownloadersHelp") + "</div>";
|
||||
|
@ -265,10 +265,10 @@ define(["globalize", "dom", "emby-checkbox", "emby-select", "emby-input"], funct
|
|||
renderMetadataFetchers(parent, availableOptions, {});
|
||||
renderSubtitleFetchers(parent, availableOptions, {});
|
||||
renderImageFetchers(parent, availableOptions, {});
|
||||
availableOptions.SubtitleFetchers.length ? parent.querySelector(".subtitleDownloadSettings").classList.remove("hide") : parent.querySelector(".subtitleDownloadSettings").classList.add("hide")
|
||||
availableOptions.SubtitleFetchers.length ? parent.querySelector(".subtitleDownloadSettings").classList.remove("hide") : parent.querySelector(".subtitleDownloadSettings").classList.add("hide");
|
||||
}).catch(function() {
|
||||
return Promise.resolve();
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
function adjustSortableListElement(elem) {
|
||||
|
@ -296,8 +296,8 @@ define(["globalize", "dom", "emby-checkbox", "emby-select", "emby-input"], funct
|
|||
Type: type
|
||||
}, currentLibraryOptions.TypeOptions.push(typeOptions));
|
||||
var availableOptions = getTypeOptions(currentAvailableOptions || {}, type);
|
||||
(new ImageOptionsEditor).show(type, typeOptions, availableOptions)
|
||||
})
|
||||
(new ImageOptionsEditor).show(type, typeOptions, availableOptions);
|
||||
});
|
||||
}
|
||||
|
||||
function onImageFetchersContainerClick(e) {
|
||||
|
@ -315,12 +315,12 @@ define(["globalize", "dom", "emby-checkbox", "emby-select", "emby-input"], funct
|
|||
var list = dom.parentWithClass(li, "paperList");
|
||||
if (btnSortable.classList.contains("btnSortableMoveDown")) {
|
||||
var next = li.nextSibling;
|
||||
next && (li.parentNode.removeChild(li), next.parentNode.insertBefore(li, next.nextSibling))
|
||||
next && (li.parentNode.removeChild(li), next.parentNode.insertBefore(li, next.nextSibling));
|
||||
} else {
|
||||
var prev = li.previousSibling;
|
||||
prev && (li.parentNode.removeChild(li), prev.parentNode.insertBefore(li, prev))
|
||||
prev && (li.parentNode.removeChild(li), prev.parentNode.insertBefore(li, prev));
|
||||
}
|
||||
Array.prototype.forEach.call(list.querySelectorAll(".sortableOption"), adjustSortableListElement)
|
||||
Array.prototype.forEach.call(list.querySelectorAll(".sortableOption"), adjustSortableListElement);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -407,13 +407,13 @@ define(["globalize", "dom", "emby-checkbox", "emby-select", "emby-input"], funct
|
|||
|
||||
function setSubtitleFetchersIntoOptions(parent, options) {
|
||||
options.DisabledSubtitleFetchers = Array.prototype.map.call(Array.prototype.filter.call(parent.querySelectorAll(".chkSubtitleFetcher"), function(elem) {
|
||||
return !elem.checked
|
||||
return !elem.checked;
|
||||
}), function(elem) {
|
||||
return elem.getAttribute("data-pluginname")
|
||||
return elem.getAttribute("data-pluginname");
|
||||
});
|
||||
|
||||
options.SubtitleFetcherOrder = Array.prototype.map.call(parent.querySelectorAll(".subtitleFetcherItem"), function(elem) {
|
||||
return elem.getAttribute("data-pluginname")
|
||||
return elem.getAttribute("data-pluginname");
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -455,13 +455,13 @@ define(["globalize", "dom", "emby-checkbox", "emby-select", "emby-input"], funct
|
|||
}
|
||||
|
||||
typeOptions.ImageFetchers = Array.prototype.map.call(Array.prototype.filter.call(section.querySelectorAll(".chkImageFetcher"), function(elem) {
|
||||
return elem.checked
|
||||
return elem.checked;
|
||||
}), function(elem) {
|
||||
return elem.getAttribute("data-pluginname")
|
||||
return elem.getAttribute("data-pluginname");
|
||||
});
|
||||
|
||||
typeOptions.ImageFetcherOrder = Array.prototype.map.call(section.querySelectorAll(".imageFetcherItem"), function(elem) {
|
||||
return elem.getAttribute("data-pluginname")
|
||||
return elem.getAttribute("data-pluginname");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -505,20 +505,20 @@ define(["globalize", "dom", "emby-checkbox", "emby-select", "emby-input"], funct
|
|||
SaveSubtitlesWithMedia: parent.querySelector("#chkSaveSubtitlesLocally").checked,
|
||||
RequirePerfectSubtitleMatch: parent.querySelector("#chkRequirePerfectMatch").checked,
|
||||
MetadataSavers: Array.prototype.map.call(Array.prototype.filter.call(parent.querySelectorAll(".chkMetadataSaver"), function(elem) {
|
||||
return elem.checked
|
||||
return elem.checked;
|
||||
}), function(elem) {
|
||||
return elem.getAttribute("data-pluginname")
|
||||
return elem.getAttribute("data-pluginname");
|
||||
}),
|
||||
TypeOptions: []
|
||||
};
|
||||
|
||||
options.LocalMetadataReaderOrder = Array.prototype.map.call(parent.querySelectorAll(".localReaderOption"), function(elem) {
|
||||
return elem.getAttribute("data-pluginname")
|
||||
return elem.getAttribute("data-pluginname");
|
||||
});
|
||||
options.SubtitleDownloadLanguages = Array.prototype.map.call(Array.prototype.filter.call(parent.querySelectorAll(".chkSubtitleLanguage"), function(elem) {
|
||||
return elem.checked
|
||||
return elem.checked;
|
||||
}), function(elem) {
|
||||
return elem.getAttribute("data-lang")
|
||||
return elem.getAttribute("data-lang");
|
||||
});
|
||||
setSubtitleFetchersIntoOptions(parent, options);
|
||||
setMetadataFetchersIntoOptions(parent, options);
|
||||
|
@ -531,7 +531,7 @@ define(["globalize", "dom", "emby-checkbox", "emby-select", "emby-input"], funct
|
|||
function getOrderedPlugins(plugins, configuredOrder) {
|
||||
plugins = plugins.slice(0);
|
||||
plugins.sort(function(a, b) {
|
||||
return a = configuredOrder.indexOf(a.Name), b = configuredOrder.indexOf(b.Name), a < b ? -1 : a > b ? 1 : 0
|
||||
return a = configuredOrder.indexOf(a.Name), b = configuredOrder.indexOf(b.Name), a < b ? -1 : a > b ? 1 : 0;
|
||||
});
|
||||
return plugins;
|
||||
}
|
||||
|
@ -558,10 +558,10 @@ define(["globalize", "dom", "emby-checkbox", "emby-select", "emby-input"], funct
|
|||
parent.querySelector("#chkSkipIfAudioTrackPresent").checked = options.SkipSubtitlesIfAudioTrackMatches;
|
||||
parent.querySelector("#chkRequirePerfectMatch").checked = options.RequirePerfectSubtitleMatch;
|
||||
Array.prototype.forEach.call(parent.querySelectorAll(".chkMetadataSaver"), function(elem) {
|
||||
elem.checked = options.MetadataSavers ? -1 !== options.MetadataSavers.indexOf(elem.getAttribute("data-pluginname")) : "true" === elem.getAttribute("data-defaultenabled")
|
||||
elem.checked = options.MetadataSavers ? -1 !== options.MetadataSavers.indexOf(elem.getAttribute("data-pluginname")) : "true" === elem.getAttribute("data-defaultenabled");
|
||||
});
|
||||
Array.prototype.forEach.call(parent.querySelectorAll(".chkSubtitleLanguage"), function(elem) {
|
||||
elem.checked = !!options.SubtitleDownloadLanguages && -1 !== options.SubtitleDownloadLanguages.indexOf(elem.getAttribute("data-lang"))
|
||||
elem.checked = !!options.SubtitleDownloadLanguages && -1 !== options.SubtitleDownloadLanguages.indexOf(elem.getAttribute("data-lang"));
|
||||
});
|
||||
renderMetadataReaders(parent, getOrderedPlugins(parent.availableOptions.MetadataReaders, options.LocalMetadataReaderOrder || []));
|
||||
renderMetadataFetchers(parent, parent.availableOptions, options);
|
||||
|
@ -578,5 +578,5 @@ define(["globalize", "dom", "emby-checkbox", "emby-select", "emby-input"], funct
|
|||
getLibraryOptions: getLibraryOptions,
|
||||
setLibraryOptions: setLibraryOptions,
|
||||
setAdvancedVisible: setAdvancedVisible
|
||||
}
|
||||
};
|
||||
});
|
||||
|
|
|
@ -188,5 +188,5 @@ define(["pluginManager"], function (pluginManager) {
|
|||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
});
|
||||
|
|
|
@ -6,6 +6,7 @@ define(['serverNotifications', 'playbackManager', 'events', 'globalize', 'requir
|
|||
document.removeEventListener('keydown', onOneDocumentClick);
|
||||
|
||||
if (window.Notification) {
|
||||
/* eslint-disable-next-line compat/compat */
|
||||
Notification.requestPermission();
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +27,7 @@ define(['serverNotifications', 'playbackManager', 'events', 'globalize', 'requir
|
|||
}
|
||||
|
||||
function resetRegistration() {
|
||||
/* eslint-disable-next-line compat/compat */
|
||||
var serviceWorker = navigator.serviceWorker;
|
||||
if (serviceWorker) {
|
||||
serviceWorker.ready.then(function (registration) {
|
||||
|
|
|
@ -187,29 +187,15 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader',
|
|||
volumeSliderContainer.classList.remove('hide');
|
||||
}
|
||||
|
||||
var volumeSliderTimer;
|
||||
|
||||
function setVolume() {
|
||||
clearTimeout(volumeSliderTimer);
|
||||
volumeSliderTimer = null;
|
||||
|
||||
if (currentPlayer) {
|
||||
currentPlayer.setVolume(this.value);
|
||||
}
|
||||
}
|
||||
|
||||
function setVolumeDelayed() {
|
||||
if (!volumeSliderTimer) {
|
||||
var that = this;
|
||||
volumeSliderTimer = setTimeout(function () {
|
||||
setVolume.call(that);
|
||||
}, 700);
|
||||
}
|
||||
}
|
||||
|
||||
volumeSlider.addEventListener('change', setVolume);
|
||||
volumeSlider.addEventListener('mousemove', setVolumeDelayed);
|
||||
volumeSlider.addEventListener('touchmove', setVolumeDelayed);
|
||||
volumeSlider.addEventListener('mousemove', setVolume);
|
||||
volumeSlider.addEventListener('touchmove', setVolume);
|
||||
|
||||
positionSlider = elem.querySelector('.nowPlayingBarPositionSlider');
|
||||
positionSlider.addEventListener('change', function () {
|
||||
|
@ -241,7 +227,7 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader',
|
|||
elem.addEventListener('click', function (e) {
|
||||
|
||||
if (!dom.parentWithTag(e.target, ['BUTTON', 'INPUT', 'A'])) {
|
||||
showRemoteControl(0);
|
||||
showRemoteControl();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'playQueueManager', 'userSettings', 'globalize', 'connectionManager', 'loading', 'apphost', 'fullscreenManager'], function (events, datetime, appSettings, itemHelper, pluginManager, PlayQueueManager, userSettings, globalize, connectionManager, loading, apphost, fullscreenManager) {
|
||||
define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'playQueueManager', 'userSettings', 'globalize', 'connectionManager', 'loading', 'apphost', 'screenfull'], function (events, datetime, appSettings, itemHelper, pluginManager, PlayQueueManager, userSettings, globalize, connectionManager, loading, apphost, screenfull) {
|
||||
'use strict';
|
||||
|
||||
function enableLocalPlaylistManagement(player) {
|
||||
|
@ -17,7 +17,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla
|
|||
}
|
||||
|
||||
function bindToFullscreenChange(player) {
|
||||
events.on(fullscreenManager, 'fullscreenchange', function () {
|
||||
screenfull.on('change', function () {
|
||||
events.trigger(player, 'fullscreenchange');
|
||||
});
|
||||
}
|
||||
|
@ -1518,7 +1518,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla
|
|||
return player.isFullscreen();
|
||||
}
|
||||
|
||||
return fullscreenManager.isFullScreen();
|
||||
return screenfull.isFullscreen;
|
||||
};
|
||||
|
||||
self.toggleFullscreen = function (player) {
|
||||
|
@ -1528,10 +1528,8 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla
|
|||
return player.toggleFulscreen();
|
||||
}
|
||||
|
||||
if (fullscreenManager.isFullScreen()) {
|
||||
fullscreenManager.exitFullscreen();
|
||||
} else {
|
||||
fullscreenManager.requestFullscreen();
|
||||
if (screenfull.isEnabled) {
|
||||
screenfull.toggle();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1633,29 +1631,29 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla
|
|||
self.supportSubtitleOffset = function(player) {
|
||||
player = player || self._currentPlayer;
|
||||
return player && 'setSubtitleOffset' in player;
|
||||
}
|
||||
};
|
||||
|
||||
self.enableShowingSubtitleOffset = function(player) {
|
||||
player = player || self._currentPlayer;
|
||||
player.enableShowingSubtitleOffset();
|
||||
}
|
||||
};
|
||||
|
||||
self.disableShowingSubtitleOffset = function(player) {
|
||||
player = player || self._currentPlayer;
|
||||
if (player.disableShowingSubtitleOffset) {
|
||||
player.disableShowingSubtitleOffset();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
self.isShowingSubtitleOffsetEnabled = function(player) {
|
||||
player = player || self._currentPlayer;
|
||||
return player.isShowingSubtitleOffsetEnabled();
|
||||
}
|
||||
};
|
||||
|
||||
self.isSubtitleStreamExternal = function(index, player) {
|
||||
var stream = getSubtitleStream(player, index);
|
||||
return stream ? getDeliveryMethod(stream) === 'External' : false;
|
||||
}
|
||||
};
|
||||
|
||||
self.setSubtitleOffset = function (value, player) {
|
||||
player = player || self._currentPlayer;
|
||||
|
@ -1669,12 +1667,12 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla
|
|||
if (player.getSubtitleOffset) {
|
||||
return player.getSubtitleOffset();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
self.canHandleOffsetOnCurrentSubtitle = function(player) {
|
||||
var index = self.getSubtitleStreamIndex(player);
|
||||
return index !== -1 && self.isSubtitleStreamExternal(index, player);
|
||||
}
|
||||
};
|
||||
|
||||
self.seek = function (ticks, player) {
|
||||
|
||||
|
@ -3140,7 +3138,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla
|
|||
AllowVideoStreamCopy: false,
|
||||
AllowAudioStreamCopy: currentlyPreventsAudioStreamCopy || currentlyPreventsVideoStreamCopy ? false : null
|
||||
|
||||
}, true);
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -3282,7 +3280,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla
|
|||
|
||||
function onPlaybackVolumeChange(e) {
|
||||
var player = this;
|
||||
sendProgressUpdate(player, 'volumechange');
|
||||
sendProgressUpdateDelayed(player, 'volumechange');
|
||||
}
|
||||
|
||||
function onRepeatModeChange(e) {
|
||||
|
@ -3377,7 +3375,15 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla
|
|||
|
||||
pluginManager.ofType('mediaplayer').map(initMediaPlayer);
|
||||
|
||||
/** Delay timer for sendProgressUpdate */
|
||||
var sendProgressUpdateTimer;
|
||||
|
||||
/** Delay time in ms for sendProgressUpdate */
|
||||
var sendProgressUpdateDelay = 700;
|
||||
|
||||
function sendProgressUpdate(player, progressEventName, reportPlaylist) {
|
||||
clearTimeout(sendProgressUpdateTimer);
|
||||
sendProgressUpdateTimer = null;
|
||||
|
||||
if (!player) {
|
||||
throw new Error('player cannot be null');
|
||||
|
@ -3403,6 +3409,14 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla
|
|||
}
|
||||
}
|
||||
|
||||
function sendProgressUpdateDelayed(player, progressEventName, reportPlaylist) {
|
||||
if (!sendProgressUpdateTimer) {
|
||||
sendProgressUpdateTimer = setTimeout(function () {
|
||||
sendProgressUpdate(player, progressEventName, reportPlaylist);
|
||||
}, sendProgressUpdateDelay);
|
||||
}
|
||||
}
|
||||
|
||||
function getLiveStreamMediaInfo(player, streamInfo, mediaSource, liveStreamId, serverId) {
|
||||
|
||||
console.debug('getLiveStreamMediaInfo');
|
||||
|
|
|
@ -17,6 +17,7 @@ define(['playbackManager', 'layoutManager', 'events'], function (playbackManager
|
|||
var isLocalVideo = player.isLocalPlayer && !player.isExternalPlayer && playbackManager.isPlayingVideo(player);
|
||||
|
||||
if (isLocalVideo && layoutManager.mobile) {
|
||||
/* eslint-disable-next-line compat/compat */
|
||||
var lockOrientation = screen.lockOrientation || screen.mozLockOrientation || screen.msLockOrientation || (screen.orientation && screen.orientation.lock);
|
||||
|
||||
if (lockOrientation) {
|
||||
|
@ -40,6 +41,7 @@ define(['playbackManager', 'layoutManager', 'events'], function (playbackManager
|
|||
|
||||
if (orientationLocked && !playbackStopInfo.nextMediaType) {
|
||||
|
||||
/* eslint-disable-next-line compat/compat */
|
||||
var unlockOrientation = screen.unlockOrientation || screen.mozUnlockOrientation || screen.msUnlockOrientation || (screen.orientation && screen.orientation.unlock);
|
||||
|
||||
if (unlockOrientation) {
|
||||
|
|
|
@ -614,27 +614,13 @@ define(["browser", "datetime", "backdrop", "libraryBrowser", "listView", "imageL
|
|||
return datetime.getDisplayRunningTime(ticks);
|
||||
};
|
||||
|
||||
var volumeSliderTimer;
|
||||
|
||||
function setVolume() {
|
||||
clearTimeout(volumeSliderTimer);
|
||||
volumeSliderTimer = null;
|
||||
|
||||
playbackManager.setVolume(this.value, currentPlayer);
|
||||
}
|
||||
|
||||
function setVolumeDelayed() {
|
||||
if (!volumeSliderTimer) {
|
||||
var that = this;
|
||||
volumeSliderTimer = setTimeout(function () {
|
||||
setVolume.call(that);
|
||||
}, 700);
|
||||
}
|
||||
}
|
||||
|
||||
context.querySelector(".nowPlayingVolumeSlider").addEventListener("change", setVolume);
|
||||
context.querySelector(".nowPlayingVolumeSlider").addEventListener("mousemove", setVolumeDelayed);
|
||||
context.querySelector(".nowPlayingVolumeSlider").addEventListener("touchmove", setVolumeDelayed);
|
||||
context.querySelector(".nowPlayingVolumeSlider").addEventListener("mousemove", setVolume);
|
||||
context.querySelector(".nowPlayingVolumeSlider").addEventListener("touchmove", setVolume);
|
||||
context.querySelector(".buttonMute").addEventListener("click", function () {
|
||||
playbackManager.toggleMute(currentPlayer);
|
||||
});
|
||||
|
|
|
@ -1,8 +1,18 @@
|
|||
define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'focusManager', 'browser', 'apphost', 'loading', 'css!./style', 'material-icons', 'paper-icon-button-light'], function (dialogHelper, inputManager, connectionManager, layoutManager, focusManager, browser, appHost, loading) {
|
||||
/**
|
||||
* Image viewer component
|
||||
* @module components/slideshow/slideshow
|
||||
*/
|
||||
define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'focusManager', 'browser', 'apphost', 'css!./style', 'material-icons', 'paper-icon-button-light'], function (dialogHelper, inputManager, connectionManager, layoutManager, focusManager, browser, appHost) {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Retrieves an item's image URL from the API.
|
||||
* @param {object|string} item - Item used to generate the image URL.
|
||||
* @param {object} options - Options of the image.
|
||||
* @param {object} apiClient - API client instance used to retrieve the image.
|
||||
* @returns {null|string} URL of the item's image.
|
||||
*/
|
||||
function getImageUrl(item, options, apiClient) {
|
||||
|
||||
options = options || {};
|
||||
options.type = options.type || "Primary";
|
||||
|
||||
|
@ -11,7 +21,6 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
|
|||
}
|
||||
|
||||
if (item.ImageTags && item.ImageTags[options.type]) {
|
||||
|
||||
options.tag = item.ImageTags[options.type];
|
||||
return apiClient.getScaledImageUrl(item.Id, options);
|
||||
}
|
||||
|
@ -27,8 +36,14 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a backdrop's image URL from the API.
|
||||
* @param {object} item - Item used to generate the image URL.
|
||||
* @param {object} options - Options of the image.
|
||||
* @param {object} apiClient - API client instance used to retrieve the image.
|
||||
* @returns {null|string} URL of the item's backdrop.
|
||||
*/
|
||||
function getBackdropImageUrl(item, options, apiClient) {
|
||||
|
||||
options = options || {};
|
||||
options.type = options.type || "Backdrop";
|
||||
|
||||
|
@ -46,19 +61,19 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
|
|||
return null;
|
||||
}
|
||||
|
||||
function getImgUrl(item, original) {
|
||||
|
||||
/**
|
||||
* Dispatches a request for an item's image to its respective handler.
|
||||
* @param {object} item - Item used to generate the image URL.
|
||||
* @returns {string} URL of the item's image.
|
||||
*/
|
||||
function getImgUrl(item) {
|
||||
var apiClient = connectionManager.getApiClient(item.ServerId);
|
||||
var imageOptions = {};
|
||||
|
||||
if (!original) {
|
||||
imageOptions.maxWidth = screen.availWidth;
|
||||
}
|
||||
if (item.BackdropImageTags && item.BackdropImageTags.length) {
|
||||
return getBackdropImageUrl(item, imageOptions, apiClient);
|
||||
} else {
|
||||
|
||||
if (item.MediaType === 'Photo' && original) {
|
||||
if (item.MediaType === 'Photo') {
|
||||
return apiClient.getItemDownloadUrl(item.Id);
|
||||
}
|
||||
imageOptions.type = "Primary";
|
||||
|
@ -66,15 +81,25 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a button using the specified icon, classes and properties.
|
||||
* @param {string} icon - Name of the material icon on the button
|
||||
* @param {string} cssClass - CSS classes to assign to the button
|
||||
* @param {boolean} canFocus - Flag to set the tabindex attribute on the button to -1.
|
||||
* @param {boolean} autoFocus - Flag to set the autofocus attribute on the button.
|
||||
* @returns {string} The HTML markup of the button.
|
||||
*/
|
||||
function getIcon(icon, cssClass, canFocus, autoFocus) {
|
||||
|
||||
var tabIndex = canFocus ? '' : ' tabindex="-1"';
|
||||
autoFocus = autoFocus ? ' autofocus' : '';
|
||||
return '<button is="paper-icon-button-light" class="autoSize ' + cssClass + '"' + tabIndex + autoFocus + '><i class="material-icons slideshowButtonIcon ' + icon + '"></i></button>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the viewport meta tag to enable or disable scaling by the user.
|
||||
* @param {boolean} scalable - Flag to set the scalability of the viewport.
|
||||
*/
|
||||
function setUserScalable(scalable) {
|
||||
|
||||
try {
|
||||
appHost.setUserScalable(scalable);
|
||||
} catch (err) {
|
||||
|
@ -83,23 +108,31 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
|
|||
}
|
||||
|
||||
return function (options) {
|
||||
|
||||
var self = this;
|
||||
/** Initialized instance of Swiper. */
|
||||
var swiperInstance;
|
||||
var dlg;
|
||||
var currentTimeout;
|
||||
var currentIntervalMs;
|
||||
/** Initialized instance of the dialog containing the Swiper instance. */
|
||||
var dialog;
|
||||
/** Options of the slideshow components */
|
||||
var currentOptions;
|
||||
var currentIndex;
|
||||
/** ID of the timeout used to hide the OSD. */
|
||||
var hideTimeout;
|
||||
/** Last coordinates of the mouse pointer. */
|
||||
var lastMouseMoveData;
|
||||
/** Visibility status of the OSD. */
|
||||
var _osdOpen = false;
|
||||
|
||||
// small hack since this is not possible anyway
|
||||
if (browser.chromecast) {
|
||||
options.interactive = false;
|
||||
}
|
||||
// Use autoplay on Chromecast since it is non-interactive.
|
||||
options.interactive = !browser.chromecast;
|
||||
|
||||
/**
|
||||
* Creates the HTML markup for the dialog and the OSD.
|
||||
* @param {Object} options - Options used to create the dialog and slideshow.
|
||||
*/
|
||||
function createElements(options) {
|
||||
currentOptions = options;
|
||||
|
||||
dlg = dialogHelper.createDialog({
|
||||
dialog = dialogHelper.createDialog({
|
||||
exitAnimationDuration: options.interactive ? 400 : 800,
|
||||
size: 'fullscreen',
|
||||
autoFocus: false,
|
||||
|
@ -108,17 +141,15 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
|
|||
removeOnClose: true
|
||||
});
|
||||
|
||||
dlg.classList.add('slideshowDialog');
|
||||
dialog.classList.add('slideshowDialog');
|
||||
|
||||
var html = '';
|
||||
|
||||
if (options.interactive) {
|
||||
html += '<div class="slideshowSwiperContainer"><div class="swiper-wrapper"></div></div>';
|
||||
|
||||
if (options.interactive && !layoutManager.tv) {
|
||||
var actionButtonsOnTop = layoutManager.mobile;
|
||||
|
||||
html += '<div>';
|
||||
html += '<div class="slideshowSwiperContainer"><div class="swiper-wrapper"></div></div>';
|
||||
|
||||
html += getIcon('keyboard_arrow_left', 'btnSlideshowPrevious slideshowButton hide-mouse-idle-tv', false);
|
||||
html += getIcon('keyboard_arrow_right', 'btnSlideshowNext slideshowButton hide-mouse-idle-tv', false);
|
||||
|
||||
|
@ -137,7 +168,7 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
|
|||
if (!actionButtonsOnTop) {
|
||||
html += '<div class="slideshowBottomBar hide">';
|
||||
|
||||
html += getIcon('pause', 'btnSlideshowPause slideshowButton', true, true);
|
||||
html += getIcon('play_arrow', 'btnSlideshowPause slideshowButton', true, true);
|
||||
if (appHost.supports('filedownload')) {
|
||||
html += getIcon('file_download', 'btnDownload slideshowButton', true);
|
||||
}
|
||||
|
@ -148,33 +179,28 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
|
|||
html += '</div>';
|
||||
}
|
||||
|
||||
html += '</div>';
|
||||
|
||||
} else {
|
||||
html += '<div class="slideshowImage"></div><h1 class="slideshowImageText"></h1>';
|
||||
}
|
||||
|
||||
dlg.innerHTML = html;
|
||||
dialog.innerHTML = html;
|
||||
|
||||
if (options.interactive) {
|
||||
dlg.querySelector('.btnSlideshowExit').addEventListener('click', function (e) {
|
||||
|
||||
dialogHelper.close(dlg);
|
||||
if (options.interactive && !layoutManager.tv) {
|
||||
dialog.querySelector('.btnSlideshowExit').addEventListener('click', function (e) {
|
||||
dialogHelper.close(dialog);
|
||||
});
|
||||
dlg.querySelector('.btnSlideshowNext').addEventListener('click', nextImage);
|
||||
dlg.querySelector('.btnSlideshowPrevious').addEventListener('click', previousImage);
|
||||
|
||||
var btnPause = dlg.querySelector('.btnSlideshowPause');
|
||||
var btnPause = dialog.querySelector('.btnSlideshowPause');
|
||||
if (btnPause) {
|
||||
btnPause.addEventListener('click', playPause);
|
||||
}
|
||||
|
||||
var btnDownload = dlg.querySelector('.btnDownload');
|
||||
var btnDownload = dialog.querySelector('.btnDownload');
|
||||
if (btnDownload) {
|
||||
btnDownload.addEventListener('click', download);
|
||||
}
|
||||
|
||||
var btnShare = dlg.querySelector('.btnShare');
|
||||
var btnShare = dialog.querySelector('.btnShare');
|
||||
if (btnShare) {
|
||||
btnShare.addEventListener('click', share);
|
||||
}
|
||||
|
@ -182,81 +208,106 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
|
|||
|
||||
setUserScalable(true);
|
||||
|
||||
dialogHelper.open(dlg).then(function () {
|
||||
|
||||
dialogHelper.open(dialog).then(function () {
|
||||
setUserScalable(false);
|
||||
stopInterval();
|
||||
});
|
||||
|
||||
inputManager.on(window, onInputCommand);
|
||||
document.addEventListener((window.PointerEvent ? 'pointermove' : 'mousemove'), onPointerMove);
|
||||
|
||||
dlg.addEventListener('close', onDialogClosed);
|
||||
dialog.addEventListener('close', onDialogClosed);
|
||||
|
||||
if (options.interactive) {
|
||||
loadSwiper(dlg);
|
||||
}
|
||||
loadSwiper(dialog, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles OSD changes when the autoplay is started.
|
||||
*/
|
||||
function onAutoplayStart() {
|
||||
var btnSlideshowPause = dlg.querySelector('.btnSlideshowPause i');
|
||||
var btnSlideshowPause = dialog.querySelector('.btnSlideshowPause i');
|
||||
if (btnSlideshowPause) {
|
||||
btnSlideshowPause.classList.remove("play_arrow");
|
||||
btnSlideshowPause.classList.add("pause");
|
||||
btnSlideshowPause.classList.replace("play_arrow", "pause");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles OSD changes when the autoplay is stopped.
|
||||
*/
|
||||
function onAutoplayStop() {
|
||||
var btnSlideshowPause = dlg.querySelector('.btnSlideshowPause i');
|
||||
var btnSlideshowPause = dialog.querySelector('.btnSlideshowPause i');
|
||||
if (btnSlideshowPause) {
|
||||
btnSlideshowPause.classList.remove("pause");
|
||||
btnSlideshowPause.classList.add("play_arrow");
|
||||
btnSlideshowPause.classList.replace("pause", "play_arrow");
|
||||
}
|
||||
}
|
||||
|
||||
function loadSwiper(dlg) {
|
||||
|
||||
/**
|
||||
* Initializes the Swiper instance and binds the relevant events.
|
||||
* @param {HTMLElement} dialog - Element containing the dialog.
|
||||
* @param {Object} options - Options used to initialize the Swiper instance.
|
||||
*/
|
||||
function loadSwiper(dialog, options) {
|
||||
var slides;
|
||||
if (currentOptions.slides) {
|
||||
dlg.querySelector('.swiper-wrapper').innerHTML = currentOptions.slides.map(getSwiperSlideHtmlFromSlide).join('');
|
||||
slides = currentOptions.slides;
|
||||
} else {
|
||||
dlg.querySelector('.swiper-wrapper').innerHTML = currentOptions.items.map(getSwiperSlideHtmlFromItem).join('');
|
||||
slides = currentOptions.items;
|
||||
}
|
||||
|
||||
require(['swiper'], function (Swiper) {
|
||||
|
||||
swiperInstance = new Swiper(dlg.querySelector('.slideshowSwiperContainer'), {
|
||||
// Optional parameters
|
||||
swiperInstance = new Swiper(dialog.querySelector('.slideshowSwiperContainer'), {
|
||||
direction: 'horizontal',
|
||||
loop: options.loop !== false,
|
||||
autoplay: {
|
||||
delay: options.interval || 8000
|
||||
// Loop is disabled due to the virtual slides option not supporting it.
|
||||
loop: false,
|
||||
autoplay: !options.interactive,
|
||||
keyboard: {
|
||||
enabled: true
|
||||
},
|
||||
// Disable preloading of all images
|
||||
preloadImages: false,
|
||||
// Enable lazy loading
|
||||
lazy: true,
|
||||
loadPrevNext: true,
|
||||
disableOnInteraction: false,
|
||||
preloadImages: true,
|
||||
slidesPerView: 1,
|
||||
slidesPerColumn: 1,
|
||||
initialSlide: options.startIndex || 0,
|
||||
speed: 240
|
||||
speed: 240,
|
||||
navigation: {
|
||||
nextEl: '.btnSlideshowNext',
|
||||
prevEl: '.btnSlideshowPrevious'
|
||||
},
|
||||
// Virtual slides reduce memory consumption for large libraries while allowing preloading of images;
|
||||
virtual: {
|
||||
slides: slides,
|
||||
cache: true,
|
||||
renderSlide: getSwiperSlideHtml,
|
||||
addSlidesBefore: 1,
|
||||
addSlidesAfter: 1
|
||||
}
|
||||
});
|
||||
|
||||
swiperInstance.on('autoplayStart', onAutoplayStart);
|
||||
swiperInstance.on('autoplayStop', onAutoplayStop);
|
||||
|
||||
if (layoutManager.mobile) {
|
||||
pause();
|
||||
} else {
|
||||
play();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getSwiperSlideHtmlFromItem(item) {
|
||||
/**
|
||||
* Renders the HTML markup of a slide for an item or a slide.
|
||||
* @param {Object} item - The item used to render the slide.
|
||||
* @param {number} index - The index of the item in the Swiper instance.
|
||||
* @returns {string} The HTML markup of the slide.
|
||||
*/
|
||||
function getSwiperSlideHtml(item, index) {
|
||||
if (currentOptions.slides) {
|
||||
return getSwiperSlideHtmlFromSlide(item);
|
||||
} else {
|
||||
return getSwiperSlideHtmlFromItem(item);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the HTML markup of a slide for an item.
|
||||
* @param {Object} item - Item used to generate the slide.
|
||||
* @returns {string} The HTML markup of the slide.
|
||||
*/
|
||||
function getSwiperSlideHtmlFromItem(item) {
|
||||
return getSwiperSlideHtmlFromSlide({
|
||||
imageUrl: getImgUrl(item),
|
||||
originalImage: getImgUrl(item, true),
|
||||
originalImage: getImgUrl(item),
|
||||
//title: item.Name,
|
||||
//description: item.Overview
|
||||
Id: item.Id,
|
||||
|
@ -264,11 +315,17 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the HTML markup of a slide for a slide object.
|
||||
* @param {Object} item - Slide object used to generate the slide.
|
||||
* @returns {string} The HTML markup of the slide.
|
||||
*/
|
||||
function getSwiperSlideHtmlFromSlide(item) {
|
||||
|
||||
var html = '';
|
||||
html += '<div class="swiper-slide" data-imageurl="' + item.imageUrl + '" data-original="' + item.originalImage + '" data-itemid="' + item.Id + '" data-serverid="' + item.ServerId + '">';
|
||||
html += '<img data-src="' + item.imageUrl + '" class="swiper-lazy swiper-slide-img">';
|
||||
html += '<div class="swiper-slide" data-original="' + item.originalImage + '" data-itemid="' + item.Id + '" data-serverid="' + item.ServerId + '">';
|
||||
html += '<div class="slider-zoom-container">';
|
||||
html += '<img src="' + item.originalImage + '" class="swiper-slide-img">';
|
||||
html += '</div>';
|
||||
if (item.title || item.subtitle) {
|
||||
html += '<div class="slideText">';
|
||||
html += '<div class="slideTextInner">';
|
||||
|
@ -290,42 +347,18 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
|
|||
return html;
|
||||
}
|
||||
|
||||
function previousImage() {
|
||||
if (swiperInstance) {
|
||||
swiperInstance.slidePrev();
|
||||
} else {
|
||||
stopInterval();
|
||||
showNextImage(currentIndex - 1);
|
||||
}
|
||||
}
|
||||
|
||||
function nextImage() {
|
||||
if (swiperInstance) {
|
||||
|
||||
if (options.loop === false) {
|
||||
|
||||
if (swiperInstance.activeIndex >= swiperInstance.slides.length - 1) {
|
||||
dialogHelper.close(dlg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
swiperInstance.slideNext();
|
||||
} else {
|
||||
stopInterval();
|
||||
showNextImage(currentIndex + 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the information of the currently displayed slide.
|
||||
* @returns {null|{itemId: string, shareUrl: string, serverId: string, url: string}} Object containing the information of the currently displayed slide.
|
||||
*/
|
||||
function getCurrentImageInfo() {
|
||||
|
||||
if (swiperInstance) {
|
||||
var slide = document.querySelector('.swiper-slide-active');
|
||||
|
||||
if (slide) {
|
||||
return {
|
||||
url: slide.getAttribute('data-original'),
|
||||
shareUrl: slide.getAttribute('data-imageurl'),
|
||||
shareUrl: slide.getAttribute('data-original'),
|
||||
itemId: slide.getAttribute('data-itemid'),
|
||||
serverId: slide.getAttribute('data-serverid')
|
||||
};
|
||||
|
@ -336,8 +369,10 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a download for the currently displayed slide.
|
||||
*/
|
||||
function download() {
|
||||
|
||||
var imageInfo = getCurrentImageInfo();
|
||||
|
||||
require(['fileDownloader'], function (fileDownloader) {
|
||||
|
@ -345,8 +380,10 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Shares the currently displayed slide using the browser's built-in sharing feature.
|
||||
*/
|
||||
function share() {
|
||||
|
||||
var imageInfo = getCurrentImageInfo();
|
||||
|
||||
navigator.share({
|
||||
|
@ -354,20 +391,29 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the autoplay feature of the Swiper instance.
|
||||
*/
|
||||
function play() {
|
||||
if (swiperInstance.autoplay) {
|
||||
swiperInstance.autoplay.start();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pauses the autoplay feature of the Swiper instance;
|
||||
*/
|
||||
function pause() {
|
||||
if (swiperInstance.autoplay) {
|
||||
swiperInstance.autoplay.stop();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles the autoplay feature of the Swiper instance.
|
||||
*/
|
||||
function playPause() {
|
||||
var paused = !dlg.querySelector('.btnSlideshowPause i').classList.contains("pause");
|
||||
var paused = !dialog.querySelector('.btnSlideshowPause i').classList.contains("pause");
|
||||
if (paused) {
|
||||
play();
|
||||
} else {
|
||||
|
@ -375,8 +421,10 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the dialog and destroys the Swiper instance.
|
||||
*/
|
||||
function onDialogClosed() {
|
||||
|
||||
var swiper = swiperInstance;
|
||||
if (swiper) {
|
||||
swiper.destroy(true, true);
|
||||
|
@ -387,53 +435,38 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
|
|||
document.removeEventListener((window.PointerEvent ? 'pointermove' : 'mousemove'), onPointerMove);
|
||||
}
|
||||
|
||||
function startInterval(options) {
|
||||
|
||||
currentOptions = options;
|
||||
|
||||
stopInterval();
|
||||
createElements(options);
|
||||
|
||||
if (!options.interactive) {
|
||||
currentIntervalMs = options.interval || 11000;
|
||||
showNextImage(options.startIndex || 0, true);
|
||||
}
|
||||
}
|
||||
|
||||
var _osdOpen = false;
|
||||
|
||||
function isOsdOpen() {
|
||||
return _osdOpen;
|
||||
}
|
||||
|
||||
function getOsdBottom() {
|
||||
return dlg.querySelector('.slideshowBottomBar');
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the OSD.
|
||||
*/
|
||||
function showOsd() {
|
||||
|
||||
var bottom = getOsdBottom();
|
||||
var bottom = dialog.querySelector('.slideshowBottomBar');
|
||||
if (bottom) {
|
||||
slideUpToShow(bottom);
|
||||
startHideTimer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides the OSD.
|
||||
*/
|
||||
function hideOsd() {
|
||||
|
||||
var bottom = getOsdBottom();
|
||||
var bottom = dialog.querySelector('.slideshowBottomBar');
|
||||
if (bottom) {
|
||||
slideDownToHide(bottom);
|
||||
}
|
||||
}
|
||||
|
||||
var hideTimeout;
|
||||
|
||||
/**
|
||||
* Starts the timer used to automatically hide the OSD.
|
||||
*/
|
||||
function startHideTimer() {
|
||||
stopHideTimer();
|
||||
hideTimeout = setTimeout(hideOsd, 4000);
|
||||
hideTimeout = setTimeout(hideOsd, 3000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops the timer used to automatically hide the OSD.
|
||||
*/
|
||||
function stopHideTimer() {
|
||||
if (hideTimeout) {
|
||||
clearTimeout(hideTimeout);
|
||||
|
@ -441,71 +474,76 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
|
|||
}
|
||||
}
|
||||
|
||||
function slideUpToShow(elem) {
|
||||
|
||||
if (!elem.classList.contains('hide')) {
|
||||
/**
|
||||
* Shows the OSD by sliding it into view.
|
||||
* @param {HTMLElement} element - Element containing the OSD.
|
||||
*/
|
||||
function slideUpToShow(element) {
|
||||
if (!element.classList.contains('hide')) {
|
||||
return;
|
||||
}
|
||||
|
||||
_osdOpen = true;
|
||||
elem.classList.remove('hide');
|
||||
element.classList.remove('hide');
|
||||
|
||||
var onFinish = function () {
|
||||
focusManager.focus(elem.querySelector('.btnSlideshowPause'));
|
||||
focusManager.focus(element.querySelector('.btnSlideshowPause'));
|
||||
};
|
||||
|
||||
if (!elem.animate) {
|
||||
if (!element.animate) {
|
||||
onFinish();
|
||||
return;
|
||||
}
|
||||
|
||||
requestAnimationFrame(function () {
|
||||
|
||||
var keyframes = [
|
||||
{ transform: 'translate3d(0,' + elem.offsetHeight + 'px,0)', opacity: '.3', offset: 0 },
|
||||
{ transform: 'translate3d(0,' + element.offsetHeight + 'px,0)', opacity: '.3', offset: 0 },
|
||||
{ transform: 'translate3d(0,0,0)', opacity: '1', offset: 1 }
|
||||
];
|
||||
var timing = { duration: 300, iterations: 1, easing: 'ease-out' };
|
||||
elem.animate(keyframes, timing).onfinish = onFinish;
|
||||
element.animate(keyframes, timing).onfinish = onFinish;
|
||||
});
|
||||
}
|
||||
|
||||
function slideDownToHide(elem) {
|
||||
|
||||
if (elem.classList.contains('hide')) {
|
||||
/**
|
||||
* Hides the OSD by sliding it out of view.
|
||||
* @param {HTMLElement} element - Element containing the OSD.
|
||||
*/
|
||||
function slideDownToHide(element) {
|
||||
if (element.classList.contains('hide')) {
|
||||
return;
|
||||
}
|
||||
|
||||
var onFinish = function () {
|
||||
elem.classList.add('hide');
|
||||
element.classList.add('hide');
|
||||
_osdOpen = false;
|
||||
};
|
||||
|
||||
if (!elem.animate) {
|
||||
if (!element.animate) {
|
||||
onFinish();
|
||||
return;
|
||||
}
|
||||
|
||||
requestAnimationFrame(function () {
|
||||
|
||||
var keyframes = [
|
||||
{ transform: 'translate3d(0,0,0)', opacity: '1', offset: 0 },
|
||||
{ transform: 'translate3d(0,' + elem.offsetHeight + 'px,0)', opacity: '.3', offset: 1 }
|
||||
{ transform: 'translate3d(0,' + element.offsetHeight + 'px,0)', opacity: '.3', offset: 1 }
|
||||
];
|
||||
var timing = { duration: 300, iterations: 1, easing: 'ease-out' };
|
||||
elem.animate(keyframes, timing).onfinish = onFinish;
|
||||
element.animate(keyframes, timing).onfinish = onFinish;
|
||||
});
|
||||
}
|
||||
|
||||
var lastMouseMoveData;
|
||||
|
||||
function onPointerMove(e) {
|
||||
|
||||
var pointerType = e.pointerType || (layoutManager.mobile ? 'touch' : 'mouse');
|
||||
/**
|
||||
* Shows the OSD when moving the mouse pointer or touching the screen.
|
||||
* @param {Event} event - Pointer movement event.
|
||||
*/
|
||||
function onPointerMove(event) {
|
||||
var pointerType = event.pointerType || (layoutManager.mobile ? 'touch' : 'mouse');
|
||||
|
||||
if (pointerType === 'mouse') {
|
||||
var eventX = e.screenX || 0;
|
||||
var eventY = e.screenY || 0;
|
||||
var eventX = event.screenX || 0;
|
||||
var eventY = event.screenY || 0;
|
||||
|
||||
var obj = lastMouseMoveData;
|
||||
if (!obj) {
|
||||
|
@ -528,125 +566,46 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
|
|||
}
|
||||
}
|
||||
|
||||
function onInputCommand(e) {
|
||||
|
||||
switch (e.detail.command) {
|
||||
|
||||
case 'left':
|
||||
if (!isOsdOpen()) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
previousImage();
|
||||
}
|
||||
break;
|
||||
case 'right':
|
||||
if (!isOsdOpen()) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
nextImage();
|
||||
}
|
||||
break;
|
||||
/**
|
||||
* Dispatches keyboard inputs to their proper handlers.
|
||||
* @param {Event} event - Keyboard input event.
|
||||
*/
|
||||
function onInputCommand(event) {
|
||||
switch (event.detail.command) {
|
||||
case 'up':
|
||||
case 'down':
|
||||
case 'select':
|
||||
case 'menu':
|
||||
case 'info':
|
||||
case 'play':
|
||||
case 'playpause':
|
||||
case 'pause':
|
||||
showOsd();
|
||||
break;
|
||||
case 'play':
|
||||
play();
|
||||
break;
|
||||
case 'pause':
|
||||
pause();
|
||||
break;
|
||||
case 'playpause':
|
||||
playPause();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function showNextImage(index, skipPreload) {
|
||||
|
||||
index = Math.max(0, index);
|
||||
if (index >= currentOptions.items.length) {
|
||||
index = 0;
|
||||
}
|
||||
currentIndex = index;
|
||||
|
||||
var options = currentOptions;
|
||||
var items = options.items;
|
||||
var item = items[index];
|
||||
var imgUrl = getImgUrl(item);
|
||||
|
||||
var onSrcLoaded = function () {
|
||||
var cardImageContainer = dlg.querySelector('.slideshowImage');
|
||||
|
||||
var newCardImageContainer = document.createElement('div');
|
||||
newCardImageContainer.className = cardImageContainer.className;
|
||||
|
||||
if (options.cover) {
|
||||
newCardImageContainer.classList.add('slideshowImage-cover');
|
||||
}
|
||||
|
||||
newCardImageContainer.style.backgroundImage = "url('" + imgUrl + "')";
|
||||
newCardImageContainer.classList.add('hide');
|
||||
cardImageContainer.parentNode.appendChild(newCardImageContainer);
|
||||
|
||||
if (options.showTitle) {
|
||||
dlg.querySelector('.slideshowImageText').innerHTML = item.Name;
|
||||
} else {
|
||||
dlg.querySelector('.slideshowImageText').innerHTML = '';
|
||||
}
|
||||
|
||||
newCardImageContainer.classList.remove('hide');
|
||||
var onAnimationFinished = function () {
|
||||
|
||||
var parentNode = cardImageContainer.parentNode;
|
||||
if (parentNode) {
|
||||
parentNode.removeChild(cardImageContainer);
|
||||
}
|
||||
};
|
||||
|
||||
if (newCardImageContainer.animate) {
|
||||
|
||||
var keyframes = [
|
||||
{ opacity: '0', offset: 0 },
|
||||
{ opacity: '1', offset: 1 }
|
||||
];
|
||||
var timing = { duration: 1200, iterations: 1 };
|
||||
newCardImageContainer.animate(keyframes, timing).onfinish = onAnimationFinished;
|
||||
} else {
|
||||
onAnimationFinished();
|
||||
}
|
||||
|
||||
stopInterval();
|
||||
currentTimeout = setTimeout(function () {
|
||||
showNextImage(index + 1, true);
|
||||
|
||||
}, currentIntervalMs);
|
||||
};
|
||||
|
||||
if (!skipPreload) {
|
||||
var img = new Image();
|
||||
img.onload = onSrcLoaded;
|
||||
img.src = imgUrl;
|
||||
} else {
|
||||
onSrcLoaded();
|
||||
}
|
||||
}
|
||||
|
||||
function stopInterval() {
|
||||
if (currentTimeout) {
|
||||
clearTimeout(currentTimeout);
|
||||
currentTimeout = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the slideshow component.
|
||||
*/
|
||||
self.show = function () {
|
||||
startInterval(options);
|
||||
createElements(options);
|
||||
};
|
||||
|
||||
/**
|
||||
* Hides the slideshow element.
|
||||
*/
|
||||
self.hide = function () {
|
||||
|
||||
var dialog = dlg;
|
||||
var dialog = dialog;
|
||||
if (dialog) {
|
||||
|
||||
dialogHelper.close(dialog);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -30,7 +30,7 @@ define(['playbackManager', 'layoutManager', 'text!./subtitlesync.template.html',
|
|||
|
||||
subtitleSyncTextField.updateOffset = function(offset) {
|
||||
this.textContent = offset + "s";
|
||||
}
|
||||
};
|
||||
|
||||
subtitleSyncTextField.addEventListener("keypress", function(event) {
|
||||
|
||||
|
@ -66,7 +66,7 @@ define(['playbackManager', 'layoutManager', 'text!./subtitlesync.template.html',
|
|||
subtitleSyncSlider.updateOffset = function(percent) {
|
||||
// default value is 0s = 50%
|
||||
this.value = percent === undefined ? 50 : percent;
|
||||
}
|
||||
};
|
||||
|
||||
subtitleSyncSlider.addEventListener("change", function () {
|
||||
// set new offset
|
||||
|
@ -132,7 +132,7 @@ define(['playbackManager', 'layoutManager', 'text!./subtitlesync.template.html',
|
|||
elem.parentNode.removeChild(elem);
|
||||
this.element = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
SubtitleSync.prototype.toggle = function(action) {
|
||||
|
||||
|
@ -166,7 +166,7 @@ define(['playbackManager', 'layoutManager', 'text!./subtitlesync.template.html',
|
|||
}
|
||||
/* eslint-enable no-fallthrough */
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return SubtitleSync;
|
||||
});
|
||||
|
|
|
@ -95,7 +95,7 @@ define(["loading", "appRouter", "layoutManager", "appSettings", "apphost", "focu
|
|||
}
|
||||
|
||||
function showServerConnectionFailure() {
|
||||
alertText(globalize.translate("MessageUnableToConnectToServer"), globalize.translate("HeaderConnectionFailure"));
|
||||
alertText(globalize.translate("MessageUnableToConnectToServer"));
|
||||
}
|
||||
|
||||
return function (view, params) {
|
||||
|
|
|
@ -29,5 +29,5 @@ define(["datetime", "loading", "apphost", "listViewStyle", "emby-button", "flexS
|
|||
loading.hide();
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
|
|
|
@ -49,12 +49,12 @@ define(["loading", "libraryMenu", "globalize", "listViewStyle", "emby-button"],
|
|||
}
|
||||
page.querySelector(".notificationList").innerHTML = html;
|
||||
loading.hide();
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
return function(view, params) {
|
||||
view.addEventListener("viewshow", function() {
|
||||
reload(view);
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
|
|
|
@ -7,7 +7,7 @@ define(["jQuery", "loading", "events", "globalize", "serverNotifications", "date
|
|||
}).then(function(tasks) {
|
||||
populateList(page, tasks);
|
||||
loading.hide();
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
function populateList(page, tasks) {
|
||||
|
@ -69,7 +69,7 @@ define(["jQuery", "loading", "events", "globalize", "serverNotifications", "date
|
|||
var endtime = Date.parse(task.LastExecutionResult.EndTimeUtc);
|
||||
var starttime = Date.parse(task.LastExecutionResult.StartTimeUtc);
|
||||
html += globalize.translate("LabelScheduledTaskLastRan", datefns.formatDistanceToNow(endtime, dfnshelper.localeWithSuffix),
|
||||
datefns.formatDistance(starttime, endtime, dfnshelper.localeWithSuffix));
|
||||
datefns.formatDistance(starttime, endtime, { locale: dfnshelper.getLocale() }));
|
||||
if (task.LastExecutionResult.Status === "Failed") {
|
||||
html += " <span style='color:#FF0000;'>(" + globalize.translate("LabelFailed") + ")</span>";
|
||||
} else if (task.LastExecutionResult.Status === "Cancelled") {
|
||||
|
@ -155,7 +155,7 @@ define(["jQuery", "loading", "events", "globalize", "serverNotifications", "date
|
|||
ApiClient.startScheduledTask(id).then(function() {
|
||||
updateTaskButton(button, "Running");
|
||||
reloadList(view);
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
$(".divScheduledTasks", view).on("click", ".btnStopTask", function() {
|
||||
|
@ -164,7 +164,7 @@ define(["jQuery", "loading", "events", "globalize", "serverNotifications", "date
|
|||
ApiClient.stopScheduledTask(id).then(function() {
|
||||
updateTaskButton(button, "");
|
||||
reloadList(view);
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
view.addEventListener("viewbeforehide", function() {
|
||||
|
@ -178,5 +178,5 @@ define(["jQuery", "loading", "events", "globalize", "serverNotifications", "date
|
|||
reloadList(view);
|
||||
events.on(serverNotifications, "ScheduledTasksInfo", onScheduledTasksUpdate);
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
|
|
|
@ -14,6 +14,7 @@ define(["jQuery", "loading", "globalize", "dom", "libraryMenu"], function ($, lo
|
|||
$("#txtVaapiDevice", page).val(config.VaapiDevice || "");
|
||||
page.querySelector("#selectEncoderPreset").value = config.EncoderPreset || "";
|
||||
page.querySelector("#txtH264Crf").value = config.H264Crf || "";
|
||||
page.querySelector("#selectDeinterlaceMethod").value = config.DeinterlaceMethod || "";
|
||||
page.querySelector("#chkEnableSubtitleExtraction").checked = config.EnableSubtitleExtraction || false;
|
||||
page.querySelector("#chkEnableThrottling").checked = config.EnableThrottling || false;
|
||||
page.querySelector("#selectVideoDecoder").dispatchEvent(new CustomEvent("change", {
|
||||
|
@ -58,6 +59,7 @@ define(["jQuery", "loading", "globalize", "dom", "libraryMenu"], function ($, lo
|
|||
config.VaapiDevice = $("#txtVaapiDevice", form).val();
|
||||
config.EncoderPreset = form.querySelector("#selectEncoderPreset").value;
|
||||
config.H264Crf = parseInt(form.querySelector("#txtH264Crf").value || "0");
|
||||
config.DeinterlaceMethod = form.querySelector("#selectDeinterlaceMethod").value;
|
||||
config.EnableSubtitleExtraction = form.querySelector("#chkEnableSubtitleExtraction").checked;
|
||||
config.EnableThrottling = form.querySelector("#chkEnableThrottling").checked;
|
||||
config.HardwareDecodingCodecs = Array.prototype.map.call(Array.prototype.filter.call(form.querySelectorAll(".chkDecodeCodec"), function (c) {
|
||||
|
|
|
@ -14,7 +14,7 @@ define(["globalize", "loading", "libraryMenu", "emby-checkbox", "emby-button", "
|
|||
}, {
|
||||
href: "metadatanfo.html",
|
||||
name: Globalize.translate("TabNfoSettings")
|
||||
}]
|
||||
}];
|
||||
}
|
||||
|
||||
return function(view, params) {
|
||||
|
@ -27,14 +27,10 @@ define(["globalize", "loading", "libraryMenu", "emby-checkbox", "emby-button", "
|
|||
view.querySelector("#chkSaveMetadataHidden").checked = config.SaveMetadataHidden;
|
||||
});
|
||||
ApiClient.getNamedConfiguration("metadata").then(function(metadata) {
|
||||
loadMetadataConfig(this, metadata)
|
||||
view.querySelector("#selectDateAdded").selectedIndex = metadata.UseFileCreationTimeForDateAdded ? 1 : 0;
|
||||
});
|
||||
}
|
||||
|
||||
function loadMetadataConfig(page, config) {
|
||||
$("#selectDateAdded", page).val(config.UseFileCreationTimeForDateAdded ? "1" : "0");
|
||||
}
|
||||
|
||||
view.querySelector("form").addEventListener("submit", function(e) {
|
||||
loading.show();
|
||||
var form = this;
|
||||
|
@ -67,5 +63,5 @@ define(["globalize", "loading", "libraryMenu", "emby-checkbox", "emby-button", "
|
|||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
define(["cardBuilder", "imageLoader", "libraryBrowser", "loading", "events", "emby-itemscontainer"], function (cardBuilder, imageLoader, libraryBrowser, loading, events) {
|
||||
define(["cardBuilder", "imageLoader", "libraryBrowser", "loading", "events", "userSettings", "emby-itemscontainer"], function (cardBuilder, imageLoader, libraryBrowser, loading, events, userSettings) {
|
||||
"use strict";
|
||||
|
||||
return function (view, params, tabContent) {
|
||||
|
@ -7,12 +7,15 @@ define(["cardBuilder", "imageLoader", "libraryBrowser", "loading", "events", "em
|
|||
pageData = {
|
||||
query: {
|
||||
StartIndex: 0,
|
||||
Limit: 100,
|
||||
Fields: "PrimaryImageAspectRatio"
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (userSettings.libraryPageSize() > 0) {
|
||||
pageData.query['Limit'] = userSettings.libraryPageSize();
|
||||
}
|
||||
|
||||
return pageData;
|
||||
}
|
||||
|
||||
|
@ -39,7 +42,9 @@ define(["cardBuilder", "imageLoader", "libraryBrowser", "loading", "events", "em
|
|||
return;
|
||||
}
|
||||
|
||||
query.StartIndex += query.Limit;
|
||||
if (userSettings.libraryPageSize() > 0) {
|
||||
query.StartIndex += query.Limit;
|
||||
}
|
||||
reloadItems(context);
|
||||
}
|
||||
|
||||
|
@ -48,7 +53,9 @@ define(["cardBuilder", "imageLoader", "libraryBrowser", "loading", "events", "em
|
|||
return;
|
||||
}
|
||||
|
||||
query.StartIndex -= query.Limit;
|
||||
if (userSettings.libraryPageSize() > 0) {
|
||||
query.StartIndex = Math.max(0, query.StartIndex - query.Limit);
|
||||
}
|
||||
reloadItems(context);
|
||||
}
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ define(["layoutManager", "cardBuilder", "apphost", "imageLoader", "loading", "sc
|
|||
}
|
||||
|
||||
function getBackdropShape() {
|
||||
return enableScrollX() ? "overflowBackdrop" : "backdrop"
|
||||
return enableScrollX() ? "overflowBackdrop" : "backdrop";
|
||||
}
|
||||
|
||||
function renderActiveRecordings(context, promise) {
|
||||
|
|
|
@ -7,10 +7,10 @@ define(["jQuery", "dom", "loading", "libraryMenu", "listViewStyle"], function($,
|
|||
html += "<option value=''></option>";
|
||||
for (var i = 0, length = languages.length; i < length; i++) {
|
||||
var culture = languages[i];
|
||||
html += "<option value='" + culture.TwoLetterISOLanguageName + "'>" + culture.DisplayName + "</option>"
|
||||
html += "<option value='" + culture.TwoLetterISOLanguageName + "'>" + culture.DisplayName + "</option>";
|
||||
}
|
||||
select.innerHTML = html
|
||||
})
|
||||
select.innerHTML = html;
|
||||
});
|
||||
}
|
||||
|
||||
function populateCountries(select) {
|
||||
|
@ -19,25 +19,25 @@ define(["jQuery", "dom", "loading", "libraryMenu", "listViewStyle"], function($,
|
|||
html += "<option value=''></option>";
|
||||
for (var i = 0, length = allCountries.length; i < length; i++) {
|
||||
var culture = allCountries[i];
|
||||
html += "<option value='" + culture.TwoLetterISORegionName + "'>" + culture.DisplayName + "</option>"
|
||||
html += "<option value='" + culture.TwoLetterISORegionName + "'>" + culture.DisplayName + "</option>";
|
||||
}
|
||||
select.innerHTML = html
|
||||
})
|
||||
select.innerHTML = html;
|
||||
});
|
||||
}
|
||||
|
||||
function loadPage(page) {
|
||||
var promises = [ApiClient.getServerConfiguration(), populateLanguages(page.querySelector("#selectLanguage")), populateCountries(page.querySelector("#selectCountry"))];
|
||||
Promise.all(promises).then(function(responses) {
|
||||
var config = responses[0];
|
||||
page.querySelector("#selectLanguage").value = config.PreferredMetadataLanguage || "", page.querySelector("#selectCountry").value = config.MetadataCountryCode || "", loading.hide()
|
||||
})
|
||||
page.querySelector("#selectLanguage").value = config.PreferredMetadataLanguage || "", page.querySelector("#selectCountry").value = config.MetadataCountryCode || "", loading.hide();
|
||||
});
|
||||
}
|
||||
|
||||
function onSubmit() {
|
||||
var form = this;
|
||||
return loading.show(), ApiClient.getServerConfiguration().then(function(config) {
|
||||
config.PreferredMetadataLanguage = form.querySelector("#selectLanguage").value, config.MetadataCountryCode = form.querySelector("#selectCountry").value, ApiClient.updateServerConfiguration(config).then(Dashboard.processServerConfigurationUpdateResult)
|
||||
}), !1
|
||||
config.PreferredMetadataLanguage = form.querySelector("#selectLanguage").value, config.MetadataCountryCode = form.querySelector("#selectCountry").value, ApiClient.updateServerConfiguration(config).then(Dashboard.processServerConfigurationUpdateResult);
|
||||
}), !1;
|
||||
}
|
||||
|
||||
function getTabs() {
|
||||
|
@ -53,12 +53,12 @@ define(["jQuery", "dom", "loading", "libraryMenu", "listViewStyle"], function($,
|
|||
}, {
|
||||
href: "metadatanfo.html",
|
||||
name: Globalize.translate("TabNfoSettings")
|
||||
}]
|
||||
}];
|
||||
}
|
||||
|
||||
$(document).on("pageinit", "#metadataImagesConfigurationPage", function() {
|
||||
$(".metadataImagesConfigurationForm").off("submit", onSubmit).on("submit", onSubmit)
|
||||
$(".metadataImagesConfigurationForm").off("submit", onSubmit).on("submit", onSubmit);
|
||||
}).on("pageshow", "#metadataImagesConfigurationPage", function() {
|
||||
libraryMenu.setTabs("metadata", 2, getTabs), loading.show(), loadPage(this)
|
||||
})
|
||||
libraryMenu.setTabs("metadata", 2, getTabs), loading.show(), loadPage(this);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
define(["loading", "events", "libraryBrowser", "imageLoader", "listView", "cardBuilder", "apphost", "emby-itemscontainer"], function (loading, events, libraryBrowser, imageLoader, listView, cardBuilder, appHost) {
|
||||
define(["loading", "events", "libraryBrowser", "imageLoader", "listView", "cardBuilder", "userSettings", "emby-itemscontainer"], function (loading, events, libraryBrowser, imageLoader, listView, cardBuilder, userSettings) {
|
||||
"use strict";
|
||||
|
||||
return function (view, params, tabContent) {
|
||||
|
@ -16,11 +16,15 @@ define(["loading", "events", "libraryBrowser", "imageLoader", "listView", "cardB
|
|||
Fields: "PrimaryImageAspectRatio,SortName",
|
||||
ImageTypeLimit: 1,
|
||||
EnableImageTypes: "Primary,Backdrop,Banner,Thumb",
|
||||
StartIndex: 0,
|
||||
Limit: pageSize
|
||||
StartIndex: 0
|
||||
},
|
||||
view: libraryBrowser.getSavedView(key) || "Poster"
|
||||
};
|
||||
|
||||
if (userSettings.libraryPageSize() > 0) {
|
||||
pageData.query['Limit'] = userSettings.libraryPageSize();
|
||||
}
|
||||
|
||||
pageData.query.ParentId = params.topParentId;
|
||||
libraryBrowser.loadSavedQueryValues(key, pageData.query);
|
||||
}
|
||||
|
@ -65,7 +69,9 @@ define(["loading", "events", "libraryBrowser", "imageLoader", "listView", "cardB
|
|||
return;
|
||||
}
|
||||
|
||||
query.StartIndex += query.Limit;
|
||||
if (userSettings.libraryPageSize() > 0) {
|
||||
query.StartIndex += query.Limit;
|
||||
}
|
||||
reloadItems(tabContent);
|
||||
}
|
||||
|
||||
|
@ -74,7 +80,9 @@ define(["loading", "events", "libraryBrowser", "imageLoader", "listView", "cardB
|
|||
return;
|
||||
}
|
||||
|
||||
query.StartIndex -= query.Limit;
|
||||
if (userSettings.libraryPageSize() > 0) {
|
||||
query.StartIndex = Math.max(0, query.StartIndex - query.Limit);
|
||||
}
|
||||
reloadItems(tabContent);
|
||||
}
|
||||
|
||||
|
@ -180,7 +188,6 @@ define(["loading", "events", "libraryBrowser", "imageLoader", "listView", "cardB
|
|||
}
|
||||
|
||||
var self = this;
|
||||
var pageSize = 100;
|
||||
var data = {};
|
||||
var isLoading = false;
|
||||
|
||||
|
|
|
@ -184,12 +184,12 @@ define(["layoutManager", "loading", "libraryBrowser", "cardBuilder", "lazyLoader
|
|||
};
|
||||
|
||||
self.getCurrentViewStyle = function () {
|
||||
return getPageData(tabContent).view;
|
||||
return getPageData().view;
|
||||
};
|
||||
|
||||
self.setCurrentViewStyle = function (viewStyle) {
|
||||
getPageData(tabContent).view = viewStyle;
|
||||
libraryBrowser.saveViewSetting(getSavedQueryKey(tabContent), viewStyle);
|
||||
getPageData().view = viewStyle;
|
||||
libraryBrowser.saveViewSetting(getSavedQueryKey(), viewStyle);
|
||||
fullyReload();
|
||||
};
|
||||
|
||||
|
|
|
@ -32,7 +32,9 @@ define(["loading", "layoutManager", "userSettings", "events", "libraryBrowser",
|
|||
return;
|
||||
}
|
||||
|
||||
query.StartIndex += query.Limit;
|
||||
if (userSettings.libraryPageSize() > 0) {
|
||||
query.StartIndex += query.Limit;
|
||||
}
|
||||
itemsContainer.refreshItems();
|
||||
}
|
||||
|
||||
|
@ -41,7 +43,9 @@ define(["loading", "layoutManager", "userSettings", "events", "libraryBrowser",
|
|||
return;
|
||||
}
|
||||
|
||||
query.StartIndex -= query.Limit;
|
||||
if (userSettings.libraryPageSize() > 0) {
|
||||
query.StartIndex = Math.max(0, query.StartIndex - query.Limit);
|
||||
}
|
||||
itemsContainer.refreshItems();
|
||||
}
|
||||
|
||||
|
@ -250,9 +254,13 @@ define(["loading", "layoutManager", "userSettings", "events", "libraryBrowser",
|
|||
ImageTypeLimit: 1,
|
||||
EnableImageTypes: "Primary,Backdrop,Banner,Thumb",
|
||||
StartIndex: 0,
|
||||
Limit: 100,
|
||||
ParentId: params.topParentId
|
||||
};
|
||||
|
||||
if (userSettings.libraryPageSize() > 0) {
|
||||
query['Limit'] = userSettings.libraryPageSize();
|
||||
}
|
||||
|
||||
var isLoading = false;
|
||||
|
||||
if (options.mode === "favorites") {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
define(["layoutManager", "loading", "events", "libraryBrowser", "imageLoader", "alphaPicker", "listView", "cardBuilder", "apphost", "emby-itemscontainer"], function (layoutManager, loading, events, libraryBrowser, imageLoader, alphaPicker, listView, cardBuilder, appHost) {
|
||||
define(["layoutManager", "loading", "events", "libraryBrowser", "imageLoader", "alphaPicker", "listView", "cardBuilder", "userSettings", "emby-itemscontainer"], function (layoutManager, loading, events, libraryBrowser, imageLoader, alphaPicker, listView, cardBuilder, userSettings) {
|
||||
"use strict";
|
||||
|
||||
return function (view, params, tabContent) {
|
||||
|
@ -16,11 +16,15 @@ define(["layoutManager", "loading", "events", "libraryBrowser", "imageLoader", "
|
|||
Fields: "PrimaryImageAspectRatio,SortName,BasicSyncInfo",
|
||||
ImageTypeLimit: 1,
|
||||
EnableImageTypes: "Primary,Backdrop,Banner,Thumb",
|
||||
StartIndex: 0,
|
||||
Limit: pageSize
|
||||
StartIndex: 0
|
||||
},
|
||||
view: libraryBrowser.getSavedView(key) || "Poster"
|
||||
};
|
||||
|
||||
if (userSettings.libraryPageSize() > 0) {
|
||||
pageData.query['Limit'] = userSettings.libraryPageSize();
|
||||
}
|
||||
|
||||
libraryBrowser.loadSavedQueryValues(key, pageData.query);
|
||||
}
|
||||
|
||||
|
@ -49,7 +53,9 @@ define(["layoutManager", "loading", "events", "libraryBrowser", "imageLoader", "
|
|||
return;
|
||||
}
|
||||
|
||||
query.StartIndex += query.Limit;
|
||||
if (userSettings.libraryPageSize() > 0) {
|
||||
query.StartIndex += query.Limit;
|
||||
}
|
||||
reloadItems();
|
||||
}
|
||||
|
||||
|
@ -58,7 +64,9 @@ define(["layoutManager", "loading", "events", "libraryBrowser", "imageLoader", "
|
|||
return;
|
||||
}
|
||||
|
||||
query.StartIndex -= query.Limit;
|
||||
if (userSettings.libraryPageSize() > 0) {
|
||||
query.StartIndex = Math.max(0, query.StartIndex - query.Limit);
|
||||
}
|
||||
reloadItems();
|
||||
}
|
||||
|
||||
|
@ -168,7 +176,6 @@ define(["layoutManager", "loading", "events", "libraryBrowser", "imageLoader", "
|
|||
}
|
||||
|
||||
var self = this;
|
||||
var pageSize = 100;
|
||||
var data = {};
|
||||
var isLoading = false;
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
define(["layoutManager", "playbackManager", "loading", "events", "libraryBrowser", "imageLoader", "alphaPicker", "listView", "cardBuilder", "apphost", "emby-itemscontainer"], function (layoutManager, playbackManager, loading, events, libraryBrowser, imageLoader, alphaPicker, listView, cardBuilder, appHost) {
|
||||
define(["layoutManager", "playbackManager", "loading", "events", "libraryBrowser", "imageLoader", "alphaPicker", "listView", "cardBuilder", "userSettings", "emby-itemscontainer"], function (layoutManager, playbackManager, loading, events, libraryBrowser, imageLoader, alphaPicker, listView, cardBuilder, userSettings) {
|
||||
"use strict";
|
||||
|
||||
return function (view, params, tabContent) {
|
||||
|
@ -30,11 +30,15 @@ define(["layoutManager", "playbackManager", "loading", "events", "libraryBrowser
|
|||
Fields: "PrimaryImageAspectRatio,SortName,BasicSyncInfo",
|
||||
ImageTypeLimit: 1,
|
||||
EnableImageTypes: "Primary,Backdrop,Banner,Thumb",
|
||||
StartIndex: 0,
|
||||
Limit: pageSize
|
||||
StartIndex: 0
|
||||
},
|
||||
view: libraryBrowser.getSavedView(key) || "Poster"
|
||||
};
|
||||
|
||||
if (userSettings.libraryPageSize() > 0) {
|
||||
pageData.query['Limit'] = userSettings.libraryPageSize();
|
||||
}
|
||||
|
||||
pageData.query.ParentId = params.topParentId;
|
||||
libraryBrowser.loadSavedQueryValues(key, pageData.query);
|
||||
}
|
||||
|
@ -79,7 +83,9 @@ define(["layoutManager", "playbackManager", "loading", "events", "libraryBrowser
|
|||
return;
|
||||
}
|
||||
|
||||
query.StartIndex += query.Limit;
|
||||
if (userSettings.libraryPageSize() > 0) {
|
||||
query.StartIndex += query.Limit;
|
||||
}
|
||||
reloadItems(tabContent);
|
||||
}
|
||||
|
||||
|
@ -88,7 +94,9 @@ define(["layoutManager", "playbackManager", "loading", "events", "libraryBrowser
|
|||
return;
|
||||
}
|
||||
|
||||
query.StartIndex -= query.Limit;
|
||||
if (userSettings.libraryPageSize() > 0) {
|
||||
query.StartIndex = Math.max(0, query.StartIndex - query.Limit);
|
||||
}
|
||||
reloadItems(tabContent);
|
||||
}
|
||||
|
||||
|
@ -175,7 +183,6 @@ define(["layoutManager", "playbackManager", "loading", "events", "libraryBrowser
|
|||
var savedQueryKey;
|
||||
var pageData;
|
||||
var self = this;
|
||||
var pageSize = 100;
|
||||
var isLoading = false;
|
||||
|
||||
self.showFilterMenu = function () {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
define(["layoutManager", "loading", "events", "libraryBrowser", "imageLoader", "alphaPicker", "listView", "cardBuilder", "apphost", "emby-itemscontainer"], function (layoutManager, loading, events, libraryBrowser, imageLoader, alphaPicker, listView, cardBuilder, appHost) {
|
||||
define(["layoutManager", "loading", "events", "libraryBrowser", "imageLoader", "alphaPicker", "listView", "cardBuilder", "apphost", "userSettings", "emby-itemscontainer"], function (layoutManager, loading, events, libraryBrowser, imageLoader, alphaPicker, listView, cardBuilder, appHost, userSettings) {
|
||||
"use strict";
|
||||
|
||||
return function (view, params, tabContent) {
|
||||
|
@ -7,17 +7,22 @@ define(["layoutManager", "loading", "events", "libraryBrowser", "imageLoader", "
|
|||
var pageData = data[key];
|
||||
|
||||
if (!pageData) {
|
||||
var queryValues = {
|
||||
SortBy: "SortName",
|
||||
SortOrder: "Ascending",
|
||||
Recursive: true,
|
||||
Fields: "PrimaryImageAspectRatio,SortName,BasicSyncInfo",
|
||||
StartIndex: 0,
|
||||
ImageTypeLimit: 1,
|
||||
EnableImageTypes: "Primary,Backdrop,Banner,Thumb"
|
||||
};
|
||||
|
||||
if (userSettings.libraryPageSize() > 0) {
|
||||
queryValues['Limit'] = userSettings.libraryPageSize();
|
||||
}
|
||||
|
||||
pageData = data[key] = {
|
||||
query: {
|
||||
SortBy: "SortName",
|
||||
SortOrder: "Ascending",
|
||||
Recursive: true,
|
||||
Fields: "PrimaryImageAspectRatio,SortName,BasicSyncInfo",
|
||||
StartIndex: 0,
|
||||
ImageTypeLimit: 1,
|
||||
EnableImageTypes: "Primary,Backdrop,Banner,Thumb",
|
||||
Limit: 100
|
||||
},
|
||||
query: queryValues,
|
||||
view: libraryBrowser.getSavedView(key) || "Poster"
|
||||
};
|
||||
pageData.query.ParentId = params.topParentId;
|
||||
|
@ -67,7 +72,9 @@ define(["layoutManager", "loading", "events", "libraryBrowser", "imageLoader", "
|
|||
return;
|
||||
}
|
||||
|
||||
query.StartIndex += query.Limit;
|
||||
if (userSettings.libraryPageSize() > 0) {
|
||||
query.StartIndex += query.Limit;
|
||||
}
|
||||
reloadItems(tabContent);
|
||||
}
|
||||
|
||||
|
@ -76,7 +83,9 @@ define(["layoutManager", "loading", "events", "libraryBrowser", "imageLoader", "
|
|||
return;
|
||||
}
|
||||
|
||||
query.StartIndex -= query.Limit;
|
||||
if (userSettings.libraryPageSize() > 0) {
|
||||
query.StartIndex = Math.max(0, query.StartIndex - query.Limit);
|
||||
}
|
||||
reloadItems(tabContent);
|
||||
}
|
||||
|
||||
|
|
|
@ -107,12 +107,12 @@ define(["libraryBrowser", "cardBuilder", "apphost", "imageLoader", "loading"], f
|
|||
};
|
||||
|
||||
self.getCurrentViewStyle = function () {
|
||||
return getPageData(tabContent).view;
|
||||
return getPageData().view;
|
||||
};
|
||||
|
||||
self.setCurrentViewStyle = function (viewStyle) {
|
||||
getPageData(tabContent).view = viewStyle;
|
||||
libraryBrowser.saveViewSetting(getSavedQueryKey(tabContent), viewStyle);
|
||||
getPageData().view = viewStyle;
|
||||
libraryBrowser.saveViewSetting(getSavedQueryKey(), viewStyle);
|
||||
fullyReload();
|
||||
};
|
||||
|
||||
|
|
|
@ -69,7 +69,7 @@ define(["libraryBrowser", "cardBuilder", "apphost", "imageLoader", "loading"], f
|
|||
var data = {};
|
||||
|
||||
self.getCurrentViewStyle = function () {
|
||||
return getPageData(tabContent).view;
|
||||
return getPageData().view;
|
||||
};
|
||||
|
||||
var promise;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
define(["events", "libraryBrowser", "imageLoader", "listView", "loading", "emby-itemscontainer"], function (events, libraryBrowser, imageLoader, listView, loading) {
|
||||
define(["events", "libraryBrowser", "imageLoader", "listView", "loading", "userSettings", "emby-itemscontainer"], function (events, libraryBrowser, imageLoader, listView, loading, userSettings) {
|
||||
"use strict";
|
||||
|
||||
return function (view, params, tabContent) {
|
||||
|
@ -14,12 +14,16 @@ define(["events", "libraryBrowser", "imageLoader", "listView", "loading", "emby-
|
|||
IncludeItemTypes: "Audio",
|
||||
Recursive: true,
|
||||
Fields: "AudioInfo,ParentId",
|
||||
Limit: 100,
|
||||
StartIndex: 0,
|
||||
ImageTypeLimit: 1,
|
||||
EnableImageTypes: "Primary"
|
||||
}
|
||||
};
|
||||
|
||||
if (userSettings.libraryPageSize() > 0) {
|
||||
pageData.query['Limit'] = userSettings.libraryPageSize();
|
||||
}
|
||||
|
||||
pageData.query.ParentId = params.topParentId;
|
||||
libraryBrowser.loadSavedQueryValues(key, pageData.query);
|
||||
}
|
||||
|
@ -49,7 +53,9 @@ define(["events", "libraryBrowser", "imageLoader", "listView", "loading", "emby-
|
|||
return;
|
||||
}
|
||||
|
||||
query.StartIndex += query.Limit;
|
||||
if (userSettings.libraryPageSize() > 0) {
|
||||
query.StartIndex += query.Limit;
|
||||
}
|
||||
reloadItems(tabContent);
|
||||
}
|
||||
|
||||
|
@ -58,7 +64,9 @@ define(["events", "libraryBrowser", "imageLoader", "listView", "loading", "emby-
|
|||
return;
|
||||
}
|
||||
|
||||
query.StartIndex -= query.Limit;
|
||||
if (userSettings.libraryPageSize() > 0) {
|
||||
query.StartIndex = Math.max(0, query.StartIndex - query.Limit);
|
||||
}
|
||||
reloadItems(tabContent);
|
||||
}
|
||||
|
||||
|
|
|
@ -1152,7 +1152,7 @@ define(["playbackManager", "dom", "inputManager", "datetime", "itemHelper", "med
|
|||
case "GamepadDPadLeft":
|
||||
case "GamepadLeftThumbstickLeft":
|
||||
// Ignores gamepad events that are always triggered, even when not focused.
|
||||
if (document.hasFocus()) {
|
||||
if (document.hasFocus()) { /* eslint-disable-line compat/compat */
|
||||
playbackManager.rewind(currentPlayer);
|
||||
showOsd();
|
||||
}
|
||||
|
@ -1161,7 +1161,7 @@ define(["playbackManager", "dom", "inputManager", "datetime", "itemHelper", "med
|
|||
case "GamepadDPadRight":
|
||||
case "GamepadLeftThumbstickRight":
|
||||
// Ignores gamepad events that are always triggered, even when not focused.
|
||||
if (document.hasFocus()) {
|
||||
if (document.hasFocus()) { /* eslint-disable-line compat/compat */
|
||||
playbackManager.fastForward(currentPlayer);
|
||||
showOsd();
|
||||
}
|
||||
|
@ -1272,7 +1272,6 @@ define(["playbackManager", "dom", "inputManager", "datetime", "itemHelper", "med
|
|||
var programEndDateMs = 0;
|
||||
var playbackStartTimeTicks = 0;
|
||||
var subtitleSyncOverlay;
|
||||
var volumeSliderTimer;
|
||||
var nowPlayingVolumeSlider = view.querySelector(".osdVolumeSlider");
|
||||
var nowPlayingVolumeSliderContainer = view.querySelector(".osdVolumeSliderContainer");
|
||||
var nowPlayingPositionSlider = view.querySelector(".osdPositionSlider");
|
||||
|
@ -1423,27 +1422,15 @@ define(["playbackManager", "dom", "inputManager", "datetime", "itemHelper", "med
|
|||
}
|
||||
|
||||
function setVolume() {
|
||||
clearTimeout(volumeSliderTimer);
|
||||
volumeSliderTimer = null;
|
||||
|
||||
playbackManager.setVolume(this.value, currentPlayer);
|
||||
}
|
||||
|
||||
function setVolumeDelayed() {
|
||||
if (!volumeSliderTimer) {
|
||||
var that = this;
|
||||
volumeSliderTimer = setTimeout(function () {
|
||||
setVolume.call(that);
|
||||
}, 700);
|
||||
}
|
||||
}
|
||||
|
||||
view.querySelector(".buttonMute").addEventListener("click", function () {
|
||||
playbackManager.toggleMute(currentPlayer);
|
||||
});
|
||||
nowPlayingVolumeSlider.addEventListener("change", setVolume);
|
||||
nowPlayingVolumeSlider.addEventListener("mousemove", setVolumeDelayed);
|
||||
nowPlayingVolumeSlider.addEventListener("touchmove", setVolumeDelayed);
|
||||
nowPlayingVolumeSlider.addEventListener("mousemove", setVolume);
|
||||
nowPlayingVolumeSlider.addEventListener("touchmove", setVolume);
|
||||
|
||||
nowPlayingPositionSlider.addEventListener("change", function () {
|
||||
var player = currentPlayer;
|
||||
|
|
|
@ -36,7 +36,7 @@ define(["jQuery", "loading", "libraryMenu"], function ($, loading, libraryMenu)
|
|||
}
|
||||
|
||||
$(document).on("pageinit", "#playbackConfigurationPage", function () {
|
||||
$(".playbackConfigurationForm").off("submit", onSubmit).on("submit", onSubmit)
|
||||
$(".playbackConfigurationForm").off("submit", onSubmit).on("submit", onSubmit);
|
||||
}).on("pageshow", "#playbackConfigurationPage", function () {
|
||||
loading.show();
|
||||
libraryMenu.setTabs("playback", 1, getTabs);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
define(["loading", "events", "libraryBrowser", "imageLoader", "listView", "cardBuilder", "emby-itemscontainer"], function (loading, events, libraryBrowser, imageLoader, listView, cardBuilder) {
|
||||
define(["loading", "events", "libraryBrowser", "imageLoader", "listView", "cardBuilder", "userSettings", "emby-itemscontainer"], function (loading, events, libraryBrowser, imageLoader, listView, cardBuilder, userSettings) {
|
||||
"use strict";
|
||||
|
||||
return function (view, params, tabContent) {
|
||||
|
@ -17,11 +17,15 @@ define(["loading", "events", "libraryBrowser", "imageLoader", "listView", "cardB
|
|||
IsMissing: false,
|
||||
ImageTypeLimit: 1,
|
||||
EnableImageTypes: "Primary,Backdrop,Thumb",
|
||||
StartIndex: 0,
|
||||
Limit: pageSize
|
||||
StartIndex: 0
|
||||
},
|
||||
view: libraryBrowser.getSavedView(key) || "Poster"
|
||||
};
|
||||
|
||||
if (userSettings.libraryPageSize() > 0) {
|
||||
pageData.query['Limit'] = userSettings.libraryPageSize();
|
||||
}
|
||||
|
||||
pageData.query.ParentId = params.topParentId;
|
||||
libraryBrowser.loadSavedQueryValues(key, pageData.query);
|
||||
}
|
||||
|
@ -66,7 +70,9 @@ define(["loading", "events", "libraryBrowser", "imageLoader", "listView", "cardB
|
|||
return;
|
||||
}
|
||||
|
||||
query.StartIndex += query.Limit;
|
||||
if (userSettings.libraryPageSize() > 0) {
|
||||
query.StartIndex += query.Limit;
|
||||
}
|
||||
reloadItems(tabContent);
|
||||
}
|
||||
|
||||
|
@ -75,7 +81,9 @@ define(["loading", "events", "libraryBrowser", "imageLoader", "listView", "cardB
|
|||
return;
|
||||
}
|
||||
|
||||
query.StartIndex -= query.Limit;
|
||||
if (userSettings.libraryPageSize() > 0) {
|
||||
query.StartIndex = Math.max(0, query.StartIndex - query.Limit);
|
||||
}
|
||||
reloadItems(tabContent);
|
||||
}
|
||||
|
||||
|
@ -152,7 +160,6 @@ define(["loading", "events", "libraryBrowser", "imageLoader", "listView", "cardB
|
|||
}
|
||||
|
||||
var self = this;
|
||||
var pageSize = 100;
|
||||
var data = {};
|
||||
var isLoading = false;
|
||||
|
||||
|
|
|
@ -177,12 +177,12 @@ define(["layoutManager", "loading", "libraryBrowser", "cardBuilder", "lazyLoader
|
|||
};
|
||||
|
||||
self.getCurrentViewStyle = function () {
|
||||
return getPageData(tabContent).view;
|
||||
return getPageData().view;
|
||||
};
|
||||
|
||||
self.setCurrentViewStyle = function (viewStyle) {
|
||||
getPageData(tabContent).view = viewStyle;
|
||||
libraryBrowser.saveViewSetting(getSavedQueryKey(tabContent), viewStyle);
|
||||
getPageData().view = viewStyle;
|
||||
libraryBrowser.saveViewSetting(getSavedQueryKey(), viewStyle);
|
||||
fullyReload();
|
||||
};
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
define(["layoutManager", "loading", "events", "libraryBrowser", "imageLoader", "listView", "cardBuilder", "alphaPicker", "emby-itemscontainer"], function (layoutManager, loading, events, libraryBrowser, imageLoader, listView, cardBuilder, alphaPicker) {
|
||||
define(["layoutManager", "loading", "events", "libraryBrowser", "imageLoader", "listView", "cardBuilder", "alphaPicker", "userSettings", "emby-itemscontainer"], function (layoutManager, loading, events, libraryBrowser, imageLoader, listView, cardBuilder, alphaPicker, userSettings) {
|
||||
"use strict";
|
||||
|
||||
return function (view, params, tabContent) {
|
||||
|
@ -16,11 +16,15 @@ define(["layoutManager", "loading", "events", "libraryBrowser", "imageLoader", "
|
|||
Fields: "PrimaryImageAspectRatio,BasicSyncInfo",
|
||||
ImageTypeLimit: 1,
|
||||
EnableImageTypes: "Primary,Backdrop,Banner,Thumb",
|
||||
StartIndex: 0,
|
||||
Limit: pageSize
|
||||
StartIndex: 0
|
||||
},
|
||||
view: libraryBrowser.getSavedView(key) || "Poster"
|
||||
};
|
||||
|
||||
if (userSettings.libraryPageSize() > 0) {
|
||||
pageData.query['Limit'] = userSettings.libraryPageSize();
|
||||
}
|
||||
|
||||
pageData.query.ParentId = params.topParentId;
|
||||
libraryBrowser.loadSavedQueryValues(key, pageData.query);
|
||||
}
|
||||
|
@ -65,7 +69,9 @@ define(["layoutManager", "loading", "events", "libraryBrowser", "imageLoader", "
|
|||
return;
|
||||
}
|
||||
|
||||
query.StartIndex += query.Limit;
|
||||
if (userSettings.libraryPageSize() > 0) {
|
||||
query.StartIndex += query.Limit;
|
||||
}
|
||||
reloadItems(tabContent);
|
||||
}
|
||||
|
||||
|
@ -74,7 +80,9 @@ define(["layoutManager", "loading", "events", "libraryBrowser", "imageLoader", "
|
|||
return;
|
||||
}
|
||||
|
||||
query.StartIndex -= query.Limit;
|
||||
if (userSettings.libraryPageSize() > 0) {
|
||||
query.StartIndex = Math.max(0, query.StartIndex - query.Limit);
|
||||
}
|
||||
reloadItems(tabContent);
|
||||
}
|
||||
|
||||
|
@ -185,7 +193,6 @@ define(["layoutManager", "loading", "events", "libraryBrowser", "imageLoader", "
|
|||
}
|
||||
|
||||
var self = this;
|
||||
var pageSize = 100;
|
||||
var data = {};
|
||||
var isLoading = false;
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
define(["displaySettings", "userSettingsBuilder", "userSettings", "autoFocuser"], function (DisplaySettings, userSettingsBuilder, currentUserSettings, autoFocuser) {
|
||||
define(["displaySettings", "userSettings", "autoFocuser"], function (DisplaySettings, userSettings, autoFocuser) {
|
||||
"use strict";
|
||||
|
||||
return function (view, params) {
|
||||
|
@ -11,7 +11,7 @@ define(["displaySettings", "userSettingsBuilder", "userSettings", "autoFocuser"]
|
|||
var settingsInstance;
|
||||
var hasChanges;
|
||||
var userId = params.userId || ApiClient.getCurrentUserId();
|
||||
var userSettings = userId === ApiClient.getCurrentUserId() ? currentUserSettings : new userSettingsBuilder();
|
||||
var currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new userSettings();
|
||||
view.addEventListener("viewshow", function () {
|
||||
window.addEventListener("beforeunload", onBeforeUnload);
|
||||
|
||||
|
@ -22,7 +22,7 @@ define(["displaySettings", "userSettingsBuilder", "userSettings", "autoFocuser"]
|
|||
serverId: ApiClient.serverId(),
|
||||
userId: userId,
|
||||
element: view.querySelector(".settingsContainer"),
|
||||
userSettings: userSettings,
|
||||
userSettings: currentSettings,
|
||||
enableSaveButton: false,
|
||||
enableSaveConfirmation: false,
|
||||
autoFocus: autoFocuser.isEnabled()
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
define(["homescreenSettings", "userSettingsBuilder", "dom", "globalize", "loading", "userSettings", "autoFocuser", "listViewStyle"], function (HomescreenSettings, userSettingsBuilder, dom, globalize, loading, currentUserSettings, autoFocuser) {
|
||||
define(["homescreenSettings", "dom", "globalize", "loading", "userSettings", "autoFocuser", "listViewStyle"], function (HomescreenSettings, dom, globalize, loading, userSettings, autoFocuser) {
|
||||
"use strict";
|
||||
|
||||
return function (view, params) {
|
||||
|
@ -11,7 +11,7 @@ define(["homescreenSettings", "userSettingsBuilder", "dom", "globalize", "loadin
|
|||
var homescreenSettingsInstance;
|
||||
var hasChanges;
|
||||
var userId = params.userId || ApiClient.getCurrentUserId();
|
||||
var userSettings = userId === ApiClient.getCurrentUserId() ? currentUserSettings : new userSettingsBuilder();
|
||||
var currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new userSettings();
|
||||
view.addEventListener("viewshow", function () {
|
||||
window.addEventListener("beforeunload", onBeforeUnload);
|
||||
|
||||
|
@ -22,7 +22,7 @@ define(["homescreenSettings", "userSettingsBuilder", "dom", "globalize", "loadin
|
|||
serverId: ApiClient.serverId(),
|
||||
userId: userId,
|
||||
element: view.querySelector(".homeScreenSettingsContainer"),
|
||||
userSettings: userSettings,
|
||||
userSettings: currentSettings,
|
||||
enableSaveButton: false,
|
||||
enableSaveConfirmation: false,
|
||||
autoFocus: autoFocuser.isEnabled()
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
define(["playbackSettings", "userSettingsBuilder", "dom", "globalize", "loading", "userSettings", "autoFocuser", "listViewStyle"], function (PlaybackSettings, userSettingsBuilder, dom, globalize, loading, currentUserSettings, autoFocuser) {
|
||||
define(["playbackSettings", "dom", "globalize", "loading", "userSettings", "autoFocuser", "listViewStyle"], function (PlaybackSettings, dom, globalize, loading, userSettings, autoFocuser) {
|
||||
"use strict";
|
||||
|
||||
return function (view, params) {
|
||||
|
@ -11,7 +11,7 @@ define(["playbackSettings", "userSettingsBuilder", "dom", "globalize", "loading"
|
|||
var settingsInstance;
|
||||
var hasChanges;
|
||||
var userId = params.userId || ApiClient.getCurrentUserId();
|
||||
var userSettings = userId === ApiClient.getCurrentUserId() ? currentUserSettings : new userSettingsBuilder();
|
||||
var currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new userSettings();
|
||||
view.addEventListener("viewshow", function () {
|
||||
window.addEventListener("beforeunload", onBeforeUnload);
|
||||
|
||||
|
@ -22,7 +22,7 @@ define(["playbackSettings", "userSettingsBuilder", "dom", "globalize", "loading"
|
|||
serverId: ApiClient.serverId(),
|
||||
userId: userId,
|
||||
element: view.querySelector(".settingsContainer"),
|
||||
userSettings: userSettings,
|
||||
userSettings: currentSettings,
|
||||
enableSaveButton: false,
|
||||
enableSaveConfirmation: false,
|
||||
autoFocus: autoFocuser.isEnabled()
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
define(["subtitleSettings", "userSettingsBuilder", "userSettings", "autoFocuser"], function (SubtitleSettings, userSettingsBuilder, currentUserSettings, autoFocuser) {
|
||||
define(["subtitleSettings", "userSettings", "autoFocuser"], function (SubtitleSettings, userSettings, autoFocuser) {
|
||||
"use strict";
|
||||
|
||||
return function (view, params) {
|
||||
|
@ -11,7 +11,7 @@ define(["subtitleSettings", "userSettingsBuilder", "userSettings", "autoFocuser"
|
|||
var subtitleSettingsInstance;
|
||||
var hasChanges;
|
||||
var userId = params.userId || ApiClient.getCurrentUserId();
|
||||
var userSettings = userId === ApiClient.getCurrentUserId() ? currentUserSettings : new userSettingsBuilder();
|
||||
var currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new userSettings();
|
||||
view.addEventListener("viewshow", function () {
|
||||
window.addEventListener("beforeunload", onBeforeUnload);
|
||||
|
||||
|
@ -22,7 +22,7 @@ define(["subtitleSettings", "userSettingsBuilder", "userSettings", "autoFocuser"
|
|||
serverId: ApiClient.serverId(),
|
||||
userId: userId,
|
||||
element: view.querySelector(".settingsContainer"),
|
||||
userSettings: userSettings,
|
||||
userSettings: currentSettings,
|
||||
enableSaveButton: false,
|
||||
enableSaveConfirmation: false,
|
||||
autoFocus: autoFocuser.isEnabled()
|
||||
|
|
16
src/elements/emby-programcell/emby-programcell.js
Normal file
16
src/elements/emby-programcell/emby-programcell.js
Normal file
|
@ -0,0 +1,16 @@
|
|||
define([], function() {
|
||||
'use strict';
|
||||
|
||||
var ProgramCellPrototype = Object.create(HTMLButtonElement.prototype);
|
||||
|
||||
ProgramCellPrototype.detachedCallback = function () {
|
||||
this.posLeft = null;
|
||||
this.posWidth = null;
|
||||
this.guideProgramName = null;
|
||||
};
|
||||
|
||||
document.registerElement('emby-programcell', {
|
||||
prototype: ProgramCellPrototype,
|
||||
extends: 'button'
|
||||
});
|
||||
});
|
42
src/elements/emby-progressbar/emby-progressbar.js
Normal file
42
src/elements/emby-progressbar/emby-progressbar.js
Normal file
|
@ -0,0 +1,42 @@
|
|||
define([], function() {
|
||||
'use strict';
|
||||
|
||||
var ProgressBarPrototype = Object.create(HTMLDivElement.prototype);
|
||||
|
||||
function onAutoTimeProgress() {
|
||||
var start = parseInt(this.getAttribute('data-starttime'));
|
||||
var end = parseInt(this.getAttribute('data-endtime'));
|
||||
|
||||
var now = new Date().getTime();
|
||||
var total = end - start;
|
||||
var pct = 100 * ((now - start) / total);
|
||||
|
||||
pct = Math.min(100, pct);
|
||||
pct = Math.max(0, pct);
|
||||
|
||||
var itemProgressBarForeground = this.querySelector('.itemProgressBarForeground');
|
||||
itemProgressBarForeground.style.width = pct + '%';
|
||||
}
|
||||
|
||||
ProgressBarPrototype.attachedCallback = function () {
|
||||
if (this.timeInterval) {
|
||||
clearInterval(this.timeInterval);
|
||||
}
|
||||
|
||||
if (this.getAttribute('data-automode') === 'time') {
|
||||
this.timeInterval = setInterval(onAutoTimeProgress.bind(this), 60000);
|
||||
}
|
||||
};
|
||||
|
||||
ProgressBarPrototype.detachedCallback = function () {
|
||||
if (this.timeInterval) {
|
||||
clearInterval(this.timeInterval);
|
||||
this.timeInterval = null;
|
||||
}
|
||||
};
|
||||
|
||||
document.registerElement('emby-progressbar', {
|
||||
prototype: ProgressBarPrototype,
|
||||
extends: 'div'
|
||||
});
|
||||
});
|
|
@ -402,7 +402,7 @@ define(['browser', 'dom', 'layoutManager', 'keyboardnavigation', 'css!./emby-sli
|
|||
this.addEventListener('keydown', onKeyDown);
|
||||
this.keyboardDraggingEnabled = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Set steps for keyboard input.
|
||||
|
@ -413,7 +413,7 @@ define(['browser', 'dom', 'layoutManager', 'keyboardnavigation', 'css!./emby-sli
|
|||
EmbySliderPrototype.setKeyboardSteps = function (stepDown, stepUp) {
|
||||
this.keyboardStepDown = stepDown || stepUp || 1;
|
||||
this.keyboardStepUp = stepUp || stepDown || 1;
|
||||
}
|
||||
};
|
||||
|
||||
function setRange(elem, startPercent, endPercent) {
|
||||
|
||||
|
|
|
@ -136,6 +136,14 @@
|
|||
<div class="fieldDescription">${H264CrfHelp}</div>
|
||||
</div>
|
||||
|
||||
<div class="selectContainer">
|
||||
<select is="emby-select" id="selectDeinterlaceMethod" label="${LabelDeinterlaceMethod}">
|
||||
<option value="yadif">${Yadif}</option>
|
||||
<option value="yadif_bob">${YadifBob}</option>
|
||||
</select>
|
||||
<div class="fieldDescription">${DeinterlaceMethodHelp}</div>
|
||||
</div>
|
||||
|
||||
<div class="checkboxContainer checkboxContainer-withDescription">
|
||||
<label>
|
||||
<input is="emby-checkbox" type="checkbox" id="chkEnableSubtitleExtraction" />
|
||||
|
|
|
@ -92,7 +92,7 @@
|
|||
left: 0;
|
||||
bottom: 0;
|
||||
z-index: 1;
|
||||
width: 10px;
|
||||
width: 0.8em;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
|
|
@ -186,8 +186,8 @@
|
|||
</div>
|
||||
|
||||
<div id="additionalPartsCollapsible" class="verticalSection detailVerticalSection hide">
|
||||
<h2 class="sectionTitle sectionTitle-cards padded-left">${HeaderAdditionalParts}</h2>
|
||||
<div id="additionalPartsContent" is="emby-itemscontainer" class="itemsContainer vertical-wrap"></div>
|
||||
<h2 class="sectionTitle sectionTitle-cards padded-left padded-right">${HeaderAdditionalParts}</h2>
|
||||
<div id="additionalPartsContent" is="emby-itemscontainer" class="itemsContainer vertical-wrap padded-left padded-right"></div>
|
||||
</div>
|
||||
|
||||
<div class="verticalSection itemVerticalSection moreFromSeasonSection hide">
|
||||
|
@ -213,17 +213,17 @@
|
|||
|
||||
<div id="seriesScheduleSection" class="verticalSection detailVerticalSection hide">
|
||||
<h2 class="sectionTitle padded-left padded-right">${HeaderUpcomingOnTV}</h2>
|
||||
<div id="seriesScheduleList" is="emby-itemscontainer" class="itemsContainer vertical-list"></div>
|
||||
<div id="seriesScheduleList" is="emby-itemscontainer" class="itemsContainer vertical-list padded-left padded-right"></div>
|
||||
</div>
|
||||
|
||||
<div id="specialsCollapsible" class="verticalSection detailVerticalSection hide">
|
||||
<h2 class="sectionTitle sectionTitle-cards padded-left">${HeaderSpecialFeatures}</h2>
|
||||
<div id="specialsContent" is="emby-itemscontainer" class="itemsContainer vertical-wrap"></div>
|
||||
<h2 class="sectionTitle sectionTitle-cards padded-left padded-right">${HeaderSpecialFeatures}</h2>
|
||||
<div id="specialsContent" is="emby-itemscontainer" class="itemsContainer vertical-wrap padded-left padded-right"></div>
|
||||
</div>
|
||||
|
||||
<div id="musicVideosCollapsible" class="verticalSection detailVerticalSection hide">
|
||||
<h2 class="sectionTitle sectionTitle-cards padded-left">${HeaderMusicVideos}</h2>
|
||||
<div id="musicVideosContent" is="emby-itemscontainer" class="itemsContainer vertical-wrap"></div>
|
||||
<h2 class="sectionTitle sectionTitle-cards padded-left padded-right">${HeaderMusicVideos}</h2>
|
||||
<div id="musicVideosContent" is="emby-itemscontainer" class="itemsContainer vertical-wrap padded-left padded-right"></div>
|
||||
</div>
|
||||
|
||||
<div id="scenesCollapsible" class="verticalSection itemVerticalSection verticalSection-extrabottompadding hide">
|
||||
|
|
|
@ -2,19 +2,23 @@ Dashboard.confirm = function(message, title, callback) {
|
|||
"use strict";
|
||||
require(["confirm"], function(confirm) {
|
||||
confirm(message, title).then(function() {
|
||||
callback(!0)
|
||||
}, function() {
|
||||
callback(!1)
|
||||
})
|
||||
})
|
||||
}, Dashboard.showLoadingMsg = function() {
|
||||
"use strict";
|
||||
require(["loading"], function(loading) {
|
||||
loading.show()
|
||||
})
|
||||
}, Dashboard.hideLoadingMsg = function() {
|
||||
"use strict";
|
||||
require(["loading"], function(loading) {
|
||||
loading.hide()
|
||||
})
|
||||
callback(!0);
|
||||
}).catch(function() {
|
||||
callback(!1);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
Dashboard.showLoadingMsg = function() {
|
||||
"use strict";
|
||||
require(["loading"], function(loading) {
|
||||
loading.show();
|
||||
});
|
||||
};
|
||||
|
||||
Dashboard.hideLoadingMsg = function() {
|
||||
"use strict";
|
||||
require(["loading"], function(loading) {
|
||||
loading.hide();
|
||||
});
|
||||
};
|
||||
|
|
|
@ -2,9 +2,11 @@ define(["jQuery"], function($) {
|
|||
"use strict";
|
||||
$.fn.checked = function(value) {
|
||||
return !0 === value || !1 === value ? $(this).each(function() {
|
||||
this.checked = value
|
||||
}) : this.length && this[0].checked
|
||||
}, $.fn.checkboxradio = function() {
|
||||
return this
|
||||
}
|
||||
this.checked = value;
|
||||
}) : this.length && this[0].checked;
|
||||
};
|
||||
|
||||
$.fn.checkboxradio = function() {
|
||||
return this;
|
||||
};
|
||||
});
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
define(["jQuery"], function($) {
|
||||
"use strict";
|
||||
$.fn.selectmenu = function() {
|
||||
return this
|
||||
}
|
||||
return this;
|
||||
};
|
||||
});
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
</div>
|
||||
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" type="text" id="txtManualName" required="required" label="${LabelUser}" autocomplete="username" />
|
||||
<input is="emby-input" type="text" id="txtManualName" required="required" label="${LabelUser}" autocomplete="username" autocapitalize="off" />
|
||||
</div>
|
||||
|
||||
<div class="inputContainer">
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
var script = document.createElement("script");
|
||||
if (self.dashboardVersion) {
|
||||
src += "?v=" + self.dashboardVersion;
|
||||
src += `?v=${self.dashboardVersion}`;
|
||||
}
|
||||
script.src = src;
|
||||
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
define(["backdrop", "userSettings", "libraryMenu"], function (backdrop, userSettings, libraryMenu) {
|
||||
"use strict";
|
||||
|
||||
var cache = {};
|
||||
|
||||
function enabled() {
|
||||
return userSettings.enableBackdrops();
|
||||
}
|
||||
|
||||
function getBackdropItemIds(apiClient, userId, types, parentId) {
|
||||
var key = "backdrops2_" + userId + (types || "") + (parentId || "");
|
||||
var key = `backdrops2_${userId + (types || "") + (parentId || "")}`;
|
||||
var data = cache[key];
|
||||
|
||||
if (data) {
|
||||
console.debug("Found backdrop id list in cache. Key: " + key);
|
||||
console.debug(`Found backdrop id list in cache. Key: ${key}`);
|
||||
data = JSON.parse(data);
|
||||
return Promise.resolve(data);
|
||||
}
|
||||
|
@ -54,7 +56,6 @@ define(["backdrop", "userSettings", "libraryMenu"], function (backdrop, userSett
|
|||
}
|
||||
}
|
||||
|
||||
var cache = {};
|
||||
pageClassOn("pageshow", "page", function () {
|
||||
var page = this;
|
||||
|
||||
|
|
|
@ -292,6 +292,7 @@ define([], function () {
|
|||
}
|
||||
|
||||
if (typeof document !== 'undefined') {
|
||||
/* eslint-disable-next-line compat/compat */
|
||||
if (('ontouchstart' in window) || (navigator.maxTouchPoints > 0)) {
|
||||
browser.touch = true;
|
||||
}
|
||||
|
|
|
@ -1,99 +1,57 @@
|
|||
import { ar, be, bg, ca, cs, da, de, el, enGB, enUS, es, faIR, fi, fr, frCA, he, hi, hr, hu, id, it, kk, ko, lt, ms, nb, nl, pl, ptBR, pt, ro, ru, sk, sl, sv, tr, uk, vi, zhCN, zhTW } from 'date-fns/locale';
|
||||
import { ar, be, bg, ca, cs, da, de, el, enGB, enUS, es, faIR, fi, fr, frCA, he, hi, hr, hu, id, it, ja, kk, ko, lt, ms, nb,
|
||||
nl, pl, ptBR, pt, ro, ru, sk, sl, sv, tr, uk, vi, zhCN, zhTW } from 'date-fns/locale';
|
||||
import globalize from 'globalize';
|
||||
|
||||
const dateLocales = (locale) => ({
|
||||
'ar': ar,
|
||||
'be-by': be,
|
||||
'bg-bg': bg,
|
||||
'ca': ca,
|
||||
'cs': cs,
|
||||
'da': da,
|
||||
'de': de,
|
||||
'el': el,
|
||||
'en-gb': enGB,
|
||||
'en-us': enUS,
|
||||
'es': es,
|
||||
'es-ar': es,
|
||||
'es-mx': es,
|
||||
'fa': faIR,
|
||||
'fi': fi,
|
||||
'fr': fr,
|
||||
'fr-ca': frCA,
|
||||
'gsw': de,
|
||||
'he': he,
|
||||
'hi-in': hi,
|
||||
'hr': hr,
|
||||
'hu': hu,
|
||||
'id': id,
|
||||
'it': it,
|
||||
'ja': ja,
|
||||
'kk': kk,
|
||||
'ko': ko,
|
||||
'lt-lt': lt,
|
||||
'ms': ms,
|
||||
'nb': nb,
|
||||
'nl': nl,
|
||||
'pl': pl,
|
||||
'pt-br': ptBR,
|
||||
'pt-pt': pt,
|
||||
'ro': ro,
|
||||
'ru': ru,
|
||||
'sk': sk,
|
||||
'sl-si': sl,
|
||||
'sv': sv,
|
||||
'tr': tr,
|
||||
'uk': uk,
|
||||
'vi': vi,
|
||||
'zh-cn': zhCN,
|
||||
'zh-hk': zhCN,
|
||||
'zh-tw': zhTW
|
||||
})[locale];
|
||||
|
||||
export function getLocale() {
|
||||
switch (globalize.getCurrentLocale()) {
|
||||
case 'ar':
|
||||
return ar;
|
||||
case 'be-by':
|
||||
return be;
|
||||
case 'bg-bg':
|
||||
return bg;
|
||||
case 'ca':
|
||||
return ca;
|
||||
case 'cs':
|
||||
return cs;
|
||||
case 'da':
|
||||
return da;
|
||||
case 'de':
|
||||
return de;
|
||||
case 'el':
|
||||
return el;
|
||||
case 'en-gb':
|
||||
return enGB;
|
||||
case 'en-us':
|
||||
return enUS;
|
||||
case 'es':
|
||||
return es;
|
||||
case 'es-ar':
|
||||
return es;
|
||||
case 'es-mx':
|
||||
return es;
|
||||
case 'fa':
|
||||
return faIR;
|
||||
case 'fi':
|
||||
return fi;
|
||||
case 'fr':
|
||||
return fr;
|
||||
case 'fr-ca':
|
||||
return frCA;
|
||||
case 'gsw':
|
||||
return de;
|
||||
case 'he':
|
||||
return he;
|
||||
case 'hi-in':
|
||||
return hi;
|
||||
case 'hr':
|
||||
return hr;
|
||||
case 'hu':
|
||||
return hu;
|
||||
case 'id':
|
||||
return id;
|
||||
case 'it':
|
||||
return it;
|
||||
case 'kk':
|
||||
return kk;
|
||||
case 'ko':
|
||||
return ko;
|
||||
case 'lt-lt':
|
||||
return lt;
|
||||
case 'ms':
|
||||
return ms;
|
||||
case 'nb':
|
||||
return nb;
|
||||
case 'nl':
|
||||
return nl;
|
||||
case 'pl':
|
||||
return pl;
|
||||
case 'pt-br':
|
||||
return ptBR;
|
||||
case 'pt-pt':
|
||||
return pt;
|
||||
case 'ro':
|
||||
return ro;
|
||||
case 'ru':
|
||||
return ru;
|
||||
case 'sk':
|
||||
return sk;
|
||||
case 'sl-si':
|
||||
return sl;
|
||||
case 'sv':
|
||||
return sv;
|
||||
case 'tr':
|
||||
return tr;
|
||||
case 'uk':
|
||||
return uk;
|
||||
case 'vi':
|
||||
return vi;
|
||||
case 'zh-cn':
|
||||
return zhCN;
|
||||
case 'zh-hk':
|
||||
return zhCN;
|
||||
case 'zh-tw':
|
||||
return zhTW;
|
||||
default:
|
||||
return enUS;
|
||||
}
|
||||
return dateLocales(globalize.getCurrentLocale()) || enUS;
|
||||
}
|
||||
|
||||
export const localeWithSuffix = { addSuffix: true, locale: getLocale() };
|
||||
|
@ -101,4 +59,4 @@ export const localeWithSuffix = { addSuffix: true, locale: getLocale() };
|
|||
export default {
|
||||
getLocale: getLocale,
|
||||
localeWithSuffix: localeWithSuffix
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
define(['connectionManager', 'userSettings', 'events'], function (connectionManager, userSettings, events) {
|
||||
define(['userSettings', 'events'], function (userSettings, events) {
|
||||
'use strict';
|
||||
var fallbackCulture = 'en-us';
|
||||
|
||||
|
@ -253,7 +253,6 @@ define(['connectionManager', 'userSettings', 'events'], function (connectionMana
|
|||
|
||||
updateCurrentCulture();
|
||||
|
||||
events.on(connectionManager, 'localusersignedin', updateCurrentCulture);
|
||||
events.on(userSettings, 'change', function (e, name) {
|
||||
if (name === 'language' || name === 'datetimelocale') {
|
||||
updateCurrentCulture();
|
||||
|
@ -269,6 +268,7 @@ define(['connectionManager', 'userSettings', 'events'], function (connectionMana
|
|||
defaultModule: defaultModule,
|
||||
getCurrentLocale: getCurrentLocale,
|
||||
getCurrentDateTimeLocale: getCurrentDateTimeLocale,
|
||||
register: register
|
||||
register: register,
|
||||
updateCurrentCulture: updateCurrentCulture
|
||||
};
|
||||
});
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
define(["browser"], function (browser) {
|
||||
"use strict";
|
||||
/* eslint-disable indent */
|
||||
|
||||
function getDeviceIcon(device) {
|
||||
import browser from 'browser';
|
||||
|
||||
export function getDeviceIcon(device) {
|
||||
var baseUrl = "assets/img/devices/";
|
||||
switch (device.AppName || device.Client) {
|
||||
case "Samsung Smart TV":
|
||||
|
@ -42,7 +43,7 @@ define(["browser"], function (browser) {
|
|||
}
|
||||
}
|
||||
|
||||
function getLibraryIcon(library) {
|
||||
export function getLibraryIcon(library) {
|
||||
switch (library) {
|
||||
case "movies":
|
||||
return "video_library";
|
||||
|
@ -71,8 +72,9 @@ define(["browser"], function (browser) {
|
|||
}
|
||||
}
|
||||
|
||||
return {
|
||||
getDeviceIcon: getDeviceIcon,
|
||||
getLibraryIcon: getLibraryIcon
|
||||
};
|
||||
});
|
||||
/* eslint-enable indent */
|
||||
|
||||
export default {
|
||||
getDeviceIcon: getDeviceIcon,
|
||||
getLibraryIcon: getLibraryIcon
|
||||
};
|
||||
|
|
|
@ -1,44 +1,49 @@
|
|||
define(['playbackManager', 'focusManager', 'appRouter', 'dom', 'apphost'], function (playbackManager, focusManager, appRouter, dom, appHost) {
|
||||
'use strict';
|
||||
import playbackManager from 'playbackManager';
|
||||
import focusManager from 'focusManager';
|
||||
import appRouter from 'appRouter';
|
||||
import dom from 'dom';
|
||||
import appHost from 'apphost';
|
||||
|
||||
var lastInputTime = new Date().getTime();
|
||||
/* eslint-disable indent */
|
||||
|
||||
function notify() {
|
||||
let lastInputTime = new Date().getTime();
|
||||
|
||||
export function notify() {
|
||||
lastInputTime = new Date().getTime();
|
||||
handleCommand('unknown');
|
||||
}
|
||||
|
||||
function notifyMouseMove() {
|
||||
export function notifyMouseMove() {
|
||||
lastInputTime = new Date().getTime();
|
||||
}
|
||||
|
||||
function idleTime() {
|
||||
export function idleTime() {
|
||||
return new Date().getTime() - lastInputTime;
|
||||
}
|
||||
|
||||
function select(sourceElement) {
|
||||
export function select(sourceElement) {
|
||||
sourceElement.click();
|
||||
}
|
||||
|
||||
var eventListenerCount = 0;
|
||||
function on(scope, fn) {
|
||||
let eventListenerCount = 0;
|
||||
export function on(scope, fn) {
|
||||
eventListenerCount++;
|
||||
dom.addEventListener(scope, 'command', fn, {});
|
||||
}
|
||||
|
||||
function off(scope, fn) {
|
||||
export function off(scope, fn) {
|
||||
if (eventListenerCount) {
|
||||
eventListenerCount--;
|
||||
}
|
||||
dom.removeEventListener(scope, 'command', fn, {});
|
||||
}
|
||||
|
||||
var commandTimes = {};
|
||||
let commandTimes = {};
|
||||
|
||||
function checkCommandTime(command) {
|
||||
|
||||
var last = commandTimes[command] || 0;
|
||||
var now = new Date().getTime();
|
||||
const last = commandTimes[command] || 0;
|
||||
const now = new Date().getTime();
|
||||
|
||||
if ((now - last) < 1000) {
|
||||
return false;
|
||||
|
@ -48,11 +53,11 @@ define(['playbackManager', 'focusManager', 'appRouter', 'dom', 'apphost'], funct
|
|||
return true;
|
||||
}
|
||||
|
||||
function handleCommand(name, options) {
|
||||
export function handleCommand(commandName, options) {
|
||||
|
||||
lastInputTime = new Date().getTime();
|
||||
|
||||
var sourceElement = (options ? options.sourceElement : null);
|
||||
let sourceElement = (options ? options.sourceElement : null);
|
||||
|
||||
if (sourceElement) {
|
||||
sourceElement = focusManager.focusableParent(sourceElement);
|
||||
|
@ -61,7 +66,7 @@ define(['playbackManager', 'focusManager', 'appRouter', 'dom', 'apphost'], funct
|
|||
if (!sourceElement) {
|
||||
sourceElement = document.activeElement || window;
|
||||
|
||||
var dlg = document.querySelector('.dialogContainer .dialog.opened');
|
||||
const dlg = document.querySelector('.dialogContainer .dialog.opened');
|
||||
|
||||
if (dlg && (!sourceElement || !dlg.contains(sourceElement))) {
|
||||
sourceElement = dlg;
|
||||
|
@ -69,169 +74,164 @@ define(['playbackManager', 'focusManager', 'appRouter', 'dom', 'apphost'], funct
|
|||
}
|
||||
|
||||
if (eventListenerCount) {
|
||||
var customEvent = new CustomEvent("command", {
|
||||
const customEvent = new CustomEvent("command", {
|
||||
detail: {
|
||||
command: name
|
||||
command: commandName
|
||||
},
|
||||
bubbles: true,
|
||||
cancelable: true
|
||||
});
|
||||
|
||||
var eventResult = sourceElement.dispatchEvent(customEvent);
|
||||
const eventResult = sourceElement.dispatchEvent(customEvent);
|
||||
if (!eventResult) {
|
||||
// event cancelled
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
switch (name) {
|
||||
case 'up':
|
||||
const keyActions = (command) => ({
|
||||
'up': () => {
|
||||
focusManager.moveUp(sourceElement);
|
||||
break;
|
||||
case 'down':
|
||||
},
|
||||
'down': () => {
|
||||
focusManager.moveDown(sourceElement);
|
||||
break;
|
||||
case 'left':
|
||||
},
|
||||
'left': () => {
|
||||
focusManager.moveLeft(sourceElement);
|
||||
break;
|
||||
case 'right':
|
||||
},
|
||||
'right': () => {
|
||||
focusManager.moveRight(sourceElement);
|
||||
break;
|
||||
case 'home':
|
||||
},
|
||||
'home': () => {
|
||||
appRouter.goHome();
|
||||
break;
|
||||
case 'settings':
|
||||
},
|
||||
'settings': () => {
|
||||
appRouter.showSettings();
|
||||
break;
|
||||
case 'back':
|
||||
},
|
||||
'back': () => {
|
||||
if (appRouter.canGoBack()) {
|
||||
appRouter.back();
|
||||
} else if (appHost.supports('exit')) {
|
||||
appHost.exit();
|
||||
}
|
||||
break;
|
||||
case 'forward':
|
||||
break;
|
||||
case 'select':
|
||||
},
|
||||
'select': () => {
|
||||
select(sourceElement);
|
||||
break;
|
||||
case 'pageup':
|
||||
break;
|
||||
case 'pagedown':
|
||||
break;
|
||||
case 'end':
|
||||
break;
|
||||
case 'menu':
|
||||
break;
|
||||
case 'info':
|
||||
break;
|
||||
case 'nextchapter':
|
||||
},
|
||||
'nextchapter': () => {
|
||||
playbackManager.nextChapter();
|
||||
break;
|
||||
case 'next':
|
||||
case 'nexttrack':
|
||||
},
|
||||
'next': () => {
|
||||
playbackManager.nextTrack();
|
||||
break;
|
||||
case 'previous':
|
||||
case 'previoustrack':
|
||||
},
|
||||
'nexttrack': () => {
|
||||
playbackManager.nextTrack();
|
||||
},
|
||||
'previous': () => {
|
||||
playbackManager.previousTrack();
|
||||
break;
|
||||
case 'previouschapter':
|
||||
},
|
||||
'previoustrack': () => {
|
||||
playbackManager.previousTrack();
|
||||
},
|
||||
'previouschapter': () => {
|
||||
playbackManager.previousChapter();
|
||||
break;
|
||||
case 'guide':
|
||||
},
|
||||
'guide': () => {
|
||||
appRouter.showGuide();
|
||||
break;
|
||||
case 'recordedtv':
|
||||
},
|
||||
'recordedtv': () => {
|
||||
appRouter.showRecordedTV();
|
||||
break;
|
||||
case 'record':
|
||||
break;
|
||||
case 'livetv':
|
||||
},
|
||||
'livetv': () => {
|
||||
appRouter.showLiveTV();
|
||||
break;
|
||||
case 'mute':
|
||||
},
|
||||
'mute': () => {
|
||||
playbackManager.setMute(true);
|
||||
break;
|
||||
case 'unmute':
|
||||
},
|
||||
'unmute': () => {
|
||||
playbackManager.setMute(false);
|
||||
break;
|
||||
case 'togglemute':
|
||||
},
|
||||
'togglemute': () => {
|
||||
playbackManager.toggleMute();
|
||||
break;
|
||||
case 'channelup':
|
||||
},
|
||||
'channelup': () => {
|
||||
playbackManager.channelUp();
|
||||
break;
|
||||
case 'channeldown':
|
||||
},
|
||||
'channeldown': () => {
|
||||
playbackManager.channelDown();
|
||||
break;
|
||||
case 'volumedown':
|
||||
},
|
||||
'volumedown': () => {
|
||||
playbackManager.volumeDown();
|
||||
break;
|
||||
case 'volumeup':
|
||||
},
|
||||
'volumeup': () => {
|
||||
playbackManager.volumeUp();
|
||||
break;
|
||||
case 'play':
|
||||
},
|
||||
'play': () => {
|
||||
playbackManager.unpause();
|
||||
break;
|
||||
case 'pause':
|
||||
},
|
||||
'pause': () => {
|
||||
playbackManager.pause();
|
||||
break;
|
||||
case 'playpause':
|
||||
},
|
||||
'playpause': () => {
|
||||
playbackManager.playPause();
|
||||
break;
|
||||
case 'stop':
|
||||
},
|
||||
'stop': () => {
|
||||
if (checkCommandTime('stop')) {
|
||||
playbackManager.stop();
|
||||
}
|
||||
break;
|
||||
case 'changezoom':
|
||||
},
|
||||
'changezoom': () => {
|
||||
playbackManager.toggleAspectRatio();
|
||||
break;
|
||||
case 'changeaudiotrack':
|
||||
},
|
||||
'changeaudiotrack': () => {
|
||||
playbackManager.changeAudioStream();
|
||||
break;
|
||||
case 'changesubtitletrack':
|
||||
},
|
||||
'changesubtitletrack': () => {
|
||||
playbackManager.changeSubtitleStream();
|
||||
break;
|
||||
case 'search':
|
||||
},
|
||||
'search': () => {
|
||||
appRouter.showSearch();
|
||||
break;
|
||||
case 'favorites':
|
||||
},
|
||||
'favorites': () => {
|
||||
appRouter.showFavorites();
|
||||
break;
|
||||
case 'fastforward':
|
||||
},
|
||||
'fastforward': () => {
|
||||
playbackManager.fastForward();
|
||||
break;
|
||||
case 'rewind':
|
||||
},
|
||||
'rewind': () => {
|
||||
playbackManager.rewind();
|
||||
break;
|
||||
case 'togglefullscreen':
|
||||
},
|
||||
'togglefullscreen': () => {
|
||||
playbackManager.toggleFullscreen();
|
||||
break;
|
||||
case 'disabledisplaymirror':
|
||||
},
|
||||
'disabledisplaymirror': () => {
|
||||
playbackManager.enableDisplayMirroring(false);
|
||||
break;
|
||||
case 'enabledisplaymirror':
|
||||
},
|
||||
'enabledisplaymirror': () => {
|
||||
playbackManager.enableDisplayMirroring(true);
|
||||
break;
|
||||
case 'toggledisplaymirror':
|
||||
},
|
||||
'toggledisplaymirror': () => {
|
||||
playbackManager.toggleDisplayMirroring();
|
||||
break;
|
||||
case 'nowplaying':
|
||||
},
|
||||
'nowplaying': () => {
|
||||
appRouter.showNowPlaying();
|
||||
break;
|
||||
case 'repeatnone':
|
||||
},
|
||||
'repeatnone': () => {
|
||||
playbackManager.setRepeatMode('RepeatNone');
|
||||
break;
|
||||
case 'repeatall':
|
||||
},
|
||||
'repeatall': () => {
|
||||
playbackManager.setRepeatMode('RepeatAll');
|
||||
break;
|
||||
case 'repeatone':
|
||||
},
|
||||
'repeatone': () => {
|
||||
playbackManager.setRepeatMode('RepeatOne');
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
})[command];
|
||||
|
||||
const action = keyActions(commandName);
|
||||
if (action !== undefined) {
|
||||
action.call();
|
||||
} else {
|
||||
console.debug(`inputManager: tried to process command with no action assigned: ${commandName}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -239,13 +239,14 @@ define(['playbackManager', 'focusManager', 'appRouter', 'dom', 'apphost'], funct
|
|||
passive: true
|
||||
});
|
||||
|
||||
return {
|
||||
trigger: handleCommand,
|
||||
handle: handleCommand,
|
||||
notify: notify,
|
||||
notifyMouseMove: notifyMouseMove,
|
||||
idleTime: idleTime,
|
||||
on: on,
|
||||
off: off
|
||||
};
|
||||
});
|
||||
/* eslint-enable indent */
|
||||
|
||||
export default {
|
||||
trigger: handleCommand,
|
||||
handle: handleCommand,
|
||||
notify: notify,
|
||||
notifyMouseMove: notifyMouseMove,
|
||||
idleTime: idleTime,
|
||||
on: on,
|
||||
off: off
|
||||
};
|
||||
|
|
|
@ -63,7 +63,9 @@ define(["dom", "layoutManager", "inputManager", "connectionManager", "events", "
|
|||
hasImage = true;
|
||||
}
|
||||
|
||||
headerUserButton.classList.remove("hide");
|
||||
if (!layoutManager.mobile) {
|
||||
headerUserButton.classList.remove("hide");
|
||||
}
|
||||
} else {
|
||||
headerUserButton.classList.add("hide");
|
||||
}
|
||||
|
@ -73,7 +75,7 @@ define(["dom", "layoutManager", "inputManager", "connectionManager", "events", "
|
|||
}
|
||||
|
||||
if (user && user.localUser) {
|
||||
if (headerHomeButton && !layoutManager.mobile) {
|
||||
if (headerHomeButton) {
|
||||
headerHomeButton.classList.remove("hide");
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ define(["listView"], function (listView) {
|
|||
EnableImageTypes: "Primary,Backdrop,Banner,Thumb",
|
||||
UserId: ApiClient.getCurrentUserId()
|
||||
};
|
||||
return ApiClient.getJSON(ApiClient.getUrl("Playlists/" + itemId + "/Items", query));
|
||||
return ApiClient.getJSON(ApiClient.getUrl(`Playlists/${itemId}/Items`, query));
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
define(["loading", "listView", "cardBuilder", "libraryMenu", "libraryBrowser", "apphost", "imageLoader", "emby-itemscontainer"], function (loading, listView, cardBuilder, libraryMenu, libraryBrowser, appHost, imageLoader) {
|
||||
define(["loading", "listView", "cardBuilder", "libraryMenu", "libraryBrowser", "apphost", "imageLoader", "userSettings", "emby-itemscontainer"], function (loading, listView, cardBuilder, libraryMenu, libraryBrowser, appHost, imageLoader, userSettings) {
|
||||
"use strict";
|
||||
|
||||
return function (view, params) {
|
||||
|
@ -14,11 +14,15 @@ define(["loading", "listView", "cardBuilder", "libraryMenu", "libraryBrowser", "
|
|||
IncludeItemTypes: "Playlist",
|
||||
Recursive: true,
|
||||
Fields: "PrimaryImageAspectRatio,SortName,CumulativeRunTimeTicks,CanDelete",
|
||||
StartIndex: 0,
|
||||
Limit: 100
|
||||
StartIndex: 0
|
||||
},
|
||||
view: libraryBrowser.getSavedView(key) || "Poster"
|
||||
};
|
||||
|
||||
if (userSettings.libraryPageSize() > 0) {
|
||||
pageData.query['Limit'] = userSettings.libraryPageSize();
|
||||
}
|
||||
|
||||
pageData.query.ParentId = libraryMenu.getTopParentId();
|
||||
libraryBrowser.loadSavedQueryValues(key, pageData.query);
|
||||
}
|
||||
|
@ -137,7 +141,9 @@ define(["loading", "listView", "cardBuilder", "libraryMenu", "libraryBrowser", "
|
|||
|
||||
if (btnNextPage) {
|
||||
btnNextPage.addEventListener("click", function () {
|
||||
query.StartIndex += query.Limit;
|
||||
if (userSettings.libraryPageSize() > 0) {
|
||||
query.StartIndex += query.Limit;
|
||||
}
|
||||
reloadItems();
|
||||
});
|
||||
}
|
||||
|
@ -146,7 +152,9 @@ define(["loading", "listView", "cardBuilder", "libraryMenu", "libraryBrowser", "
|
|||
|
||||
if (btnPreviousPage) {
|
||||
btnPreviousPage.addEventListener("click", function () {
|
||||
query.StartIndex -= query.Limit;
|
||||
if (userSettings.libraryPageSize() > 0) {
|
||||
query.StartIndex = Math.max(0, query.StartIndex - query.Limit);
|
||||
}
|
||||
reloadItems();
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
define(['appStorage', 'events'], function (appStorage, events) {
|
||||
'use strict';
|
||||
/* eslint-disable indent */
|
||||
|
||||
import appStorage from 'appStorage';
|
||||
import events from 'events';
|
||||
|
||||
function getKey(name, userId) {
|
||||
if (userId) {
|
||||
|
@ -9,26 +11,23 @@ define(['appStorage', 'events'], function (appStorage, events) {
|
|||
return name;
|
||||
}
|
||||
|
||||
function AppSettings() {
|
||||
}
|
||||
|
||||
AppSettings.prototype.enableAutoLogin = function (val) {
|
||||
export function enableAutoLogin(val) {
|
||||
if (val != null) {
|
||||
this.set('enableAutoLogin', val.toString());
|
||||
}
|
||||
|
||||
return this.get('enableAutoLogin') !== 'false';
|
||||
};
|
||||
}
|
||||
|
||||
AppSettings.prototype.enableSystemExternalPlayers = function (val) {
|
||||
export function enableSystemExternalPlayers(val) {
|
||||
if (val !== null) {
|
||||
this.set('enableSystemExternalPlayers', val.toString());
|
||||
}
|
||||
|
||||
return this.get('enableSystemExternalPlayers') === 'true';
|
||||
};
|
||||
}
|
||||
|
||||
AppSettings.prototype.enableAutomaticBitrateDetection = function (isInNetwork, mediaType, val) {
|
||||
export function enableAutomaticBitrateDetection(isInNetwork, mediaType, val) {
|
||||
var key = 'enableautobitratebitrate-' + mediaType + '-' + isInNetwork;
|
||||
if (val != null) {
|
||||
if (isInNetwork && mediaType === 'Audio') {
|
||||
|
@ -43,9 +42,9 @@ define(['appStorage', 'events'], function (appStorage, events) {
|
|||
} else {
|
||||
return this.get(key) !== 'false';
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
AppSettings.prototype.maxStreamingBitrate = function (isInNetwork, mediaType, val) {
|
||||
export function maxStreamingBitrate(isInNetwork, mediaType, val) {
|
||||
var key = 'maxbitrate-' + mediaType + '-' + isInNetwork;
|
||||
if (val != null) {
|
||||
if (isInNetwork && mediaType === 'Audio') {
|
||||
|
@ -61,43 +60,43 @@ define(['appStorage', 'events'], function (appStorage, events) {
|
|||
} else {
|
||||
return parseInt(this.get(key) || '0') || 1500000;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
AppSettings.prototype.maxStaticMusicBitrate = function (val) {
|
||||
export function maxStaticMusicBitrate(val) {
|
||||
if (val !== undefined) {
|
||||
this.set('maxStaticMusicBitrate', val);
|
||||
}
|
||||
|
||||
var defaultValue = 320000;
|
||||
return parseInt(this.get('maxStaticMusicBitrate') || defaultValue.toString()) || defaultValue;
|
||||
};
|
||||
}
|
||||
|
||||
AppSettings.prototype.maxChromecastBitrate = function (val) {
|
||||
export function maxChromecastBitrate(val) {
|
||||
if (val != null) {
|
||||
this.set('chromecastBitrate1', val);
|
||||
}
|
||||
|
||||
val = this.get('chromecastBitrate1');
|
||||
return val ? parseInt(val) : null;
|
||||
};
|
||||
}
|
||||
|
||||
AppSettings.prototype.syncOnlyOnWifi = function (val) {
|
||||
export function syncOnlyOnWifi(val) {
|
||||
if (val != null) {
|
||||
this.set('syncOnlyOnWifi', val.toString());
|
||||
}
|
||||
|
||||
return this.get('syncOnlyOnWifi') !== 'false';
|
||||
};
|
||||
}
|
||||
|
||||
AppSettings.prototype.syncPath = function (val) {
|
||||
export function syncPath(val) {
|
||||
if (val != null) {
|
||||
this.set('syncPath', val);
|
||||
}
|
||||
|
||||
return this.get('syncPath');
|
||||
};
|
||||
}
|
||||
|
||||
AppSettings.prototype.cameraUploadServers = function (val) {
|
||||
export function cameraUploadServers(val) {
|
||||
if (val != null) {
|
||||
this.set('cameraUploadServers', val.join(','));
|
||||
}
|
||||
|
@ -108,28 +107,42 @@ define(['appStorage', 'events'], function (appStorage, events) {
|
|||
}
|
||||
|
||||
return [];
|
||||
};
|
||||
}
|
||||
|
||||
AppSettings.prototype.runAtStartup = function (val) {
|
||||
export function runAtStartup(val) {
|
||||
if (val != null) {
|
||||
this.set('runatstartup', val.toString());
|
||||
}
|
||||
|
||||
return this.get('runatstartup') === 'true';
|
||||
};
|
||||
}
|
||||
|
||||
AppSettings.prototype.set = function (name, value, userId) {
|
||||
export function set(name, value, userId) {
|
||||
var currentValue = this.get(name, userId);
|
||||
appStorage.setItem(getKey(name, userId), value);
|
||||
|
||||
if (currentValue !== value) {
|
||||
events.trigger(this, 'change', [name]);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
AppSettings.prototype.get = function (name, userId) {
|
||||
export function get(name, userId) {
|
||||
return appStorage.getItem(getKey(name, userId));
|
||||
};
|
||||
}
|
||||
|
||||
return new AppSettings();
|
||||
});
|
||||
/* eslint-enable indent */
|
||||
|
||||
export default {
|
||||
enableAutoLogin: enableAutoLogin,
|
||||
enableSystemExternalPlayers: enableSystemExternalPlayers,
|
||||
enableAutomaticBitrateDetection: enableAutomaticBitrateDetection,
|
||||
maxStreamingBitrate: maxStreamingBitrate,
|
||||
maxStaticMusicBitrate: maxStaticMusicBitrate,
|
||||
maxChromecastBitrate: maxChromecastBitrate,
|
||||
syncOnlyOnWifi: syncOnlyOnWifi,
|
||||
syncPath: syncPath,
|
||||
cameraUploadServers: cameraUploadServers,
|
||||
runAtStartup: runAtStartup,
|
||||
set: set,
|
||||
get: get
|
||||
};
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
define(['appSettings', 'events'], function (appSettings, events) {
|
||||
'use strict';
|
||||
/* eslint-disable indent */
|
||||
|
||||
import appSettings from 'appSettings';
|
||||
import events from 'events';
|
||||
|
||||
function onSaveTimeout() {
|
||||
var self = this;
|
||||
|
@ -15,10 +17,7 @@ define(['appSettings', 'events'], function (appSettings, events) {
|
|||
instance.saveTimeout = setTimeout(onSaveTimeout.bind(instance), 50);
|
||||
}
|
||||
|
||||
function UserSettings() {
|
||||
}
|
||||
|
||||
UserSettings.prototype.setUserInfo = function (userId, apiClient) {
|
||||
export function setUserInfo(userId, apiClient) {
|
||||
if (this.saveTimeout) {
|
||||
clearTimeout(this.saveTimeout);
|
||||
}
|
||||
|
@ -37,17 +36,17 @@ define(['appSettings', 'events'], function (appSettings, events) {
|
|||
result.CustomPrefs = result.CustomPrefs || {};
|
||||
self.displayPrefs = result;
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
UserSettings.prototype.getData = function () {
|
||||
export function getData() {
|
||||
return this.displayPrefs;
|
||||
};
|
||||
}
|
||||
|
||||
UserSettings.prototype.importFrom = function (instance) {
|
||||
export function importFrom(instance) {
|
||||
this.displayPrefs = instance.getData();
|
||||
};
|
||||
}
|
||||
|
||||
UserSettings.prototype.set = function (name, value, enableOnServer) {
|
||||
export function set(name, value, enableOnServer) {
|
||||
var userId = this.currentUserId;
|
||||
var currentValue = this.get(name, enableOnServer);
|
||||
var result = appSettings.set(name, value, userId);
|
||||
|
@ -62,18 +61,18 @@ define(['appSettings', 'events'], function (appSettings, events) {
|
|||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
UserSettings.prototype.get = function (name, enableOnServer) {
|
||||
export function get(name, enableOnServer) {
|
||||
var userId = this.currentUserId;
|
||||
if (enableOnServer !== false && this.displayPrefs) {
|
||||
return this.displayPrefs.CustomPrefs[name];
|
||||
}
|
||||
|
||||
return appSettings.get(name, userId);
|
||||
};
|
||||
}
|
||||
|
||||
UserSettings.prototype.serverConfig = function (config) {
|
||||
export function serverConfig(config) {
|
||||
var apiClient = this.currentApiClient;
|
||||
if (config) {
|
||||
return apiClient.updateUserConfiguration(this.currentUserId, config);
|
||||
|
@ -82,135 +81,149 @@ define(['appSettings', 'events'], function (appSettings, events) {
|
|||
return apiClient.getUser(this.currentUserId).then(function (user) {
|
||||
return user.Configuration;
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
UserSettings.prototype.enableCinemaMode = function (val) {
|
||||
export function enableCinemaMode(val) {
|
||||
if (val != null) {
|
||||
return this.set('enableCinemaMode', val.toString(), false);
|
||||
}
|
||||
|
||||
val = this.get('enableCinemaMode', false);
|
||||
return val !== 'false';
|
||||
};
|
||||
}
|
||||
|
||||
UserSettings.prototype.enableNextVideoInfoOverlay = function (val) {
|
||||
export function enableNextVideoInfoOverlay(val) {
|
||||
if (val != null) {
|
||||
return this.set('enableNextVideoInfoOverlay', val.toString());
|
||||
}
|
||||
|
||||
val = this.get('enableNextVideoInfoOverlay', false);
|
||||
return val !== 'false';
|
||||
};
|
||||
}
|
||||
|
||||
UserSettings.prototype.enableThemeSongs = function (val) {
|
||||
export function enableThemeSongs(val) {
|
||||
if (val != null) {
|
||||
return this.set('enableThemeSongs', val.toString(), false);
|
||||
}
|
||||
|
||||
val = this.get('enableThemeSongs', false);
|
||||
return val !== 'false';
|
||||
};
|
||||
}
|
||||
|
||||
UserSettings.prototype.enableThemeVideos = function (val) {
|
||||
export function enableThemeVideos(val) {
|
||||
if (val != null) {
|
||||
return this.set('enableThemeVideos', val.toString(), false);
|
||||
}
|
||||
|
||||
val = this.get('enableThemeVideos', false);
|
||||
return val !== 'false';
|
||||
};
|
||||
}
|
||||
|
||||
UserSettings.prototype.enableFastFadein = function (val) {
|
||||
export function enableFastFadein(val) {
|
||||
if (val != null) {
|
||||
return this.set('fastFadein', val.toString(), false);
|
||||
}
|
||||
|
||||
val = this.get('fastFadein', false);
|
||||
return val !== 'false';
|
||||
};
|
||||
}
|
||||
|
||||
UserSettings.prototype.enableBackdrops = function (val) {
|
||||
export function enableBackdrops(val) {
|
||||
if (val != null) {
|
||||
return this.set('enableBackdrops', val.toString(), false);
|
||||
}
|
||||
|
||||
val = this.get('enableBackdrops', false);
|
||||
return val !== 'false';
|
||||
};
|
||||
}
|
||||
|
||||
UserSettings.prototype.language = function (val) {
|
||||
export function language(val) {
|
||||
if (val != null) {
|
||||
return this.set('language', val.toString(), false);
|
||||
}
|
||||
|
||||
return this.get('language', false);
|
||||
};
|
||||
}
|
||||
|
||||
UserSettings.prototype.dateTimeLocale = function (val) {
|
||||
export function dateTimeLocale(val) {
|
||||
if (val != null) {
|
||||
return this.set('datetimelocale', val.toString(), false);
|
||||
}
|
||||
|
||||
return this.get('datetimelocale', false);
|
||||
};
|
||||
}
|
||||
|
||||
UserSettings.prototype.skipBackLength = function (val) {
|
||||
export function skipBackLength(val) {
|
||||
if (val != null) {
|
||||
return this.set('skipBackLength', val.toString());
|
||||
}
|
||||
|
||||
return parseInt(this.get('skipBackLength') || '10000');
|
||||
};
|
||||
}
|
||||
|
||||
UserSettings.prototype.skipForwardLength = function (val) {
|
||||
export function skipForwardLength(val) {
|
||||
if (val != null) {
|
||||
return this.set('skipForwardLength', val.toString());
|
||||
}
|
||||
|
||||
return parseInt(this.get('skipForwardLength') || '30000');
|
||||
};
|
||||
}
|
||||
|
||||
UserSettings.prototype.dashboardTheme = function (val) {
|
||||
export function dashboardTheme(val) {
|
||||
if (val != null) {
|
||||
return this.set('dashboardTheme', val);
|
||||
}
|
||||
|
||||
return this.get('dashboardTheme');
|
||||
};
|
||||
}
|
||||
|
||||
UserSettings.prototype.skin = function (val) {
|
||||
export function skin(val) {
|
||||
if (val != null) {
|
||||
return this.set('skin', val, false);
|
||||
}
|
||||
|
||||
return this.get('skin', false);
|
||||
};
|
||||
}
|
||||
|
||||
UserSettings.prototype.theme = function (val) {
|
||||
export function theme(val) {
|
||||
if (val != null) {
|
||||
return this.set('appTheme', val, false);
|
||||
}
|
||||
|
||||
return this.get('appTheme', false);
|
||||
};
|
||||
}
|
||||
|
||||
UserSettings.prototype.screensaver = function (val) {
|
||||
export function screensaver(val) {
|
||||
if (val != null) {
|
||||
return this.set('screensaver', val, false);
|
||||
}
|
||||
|
||||
return this.get('screensaver', false);
|
||||
};
|
||||
}
|
||||
|
||||
UserSettings.prototype.soundEffects = function (val) {
|
||||
export function libraryPageSize(val) {
|
||||
if (val != null) {
|
||||
return this.set('libraryPageSize', parseInt(val, 10), false);
|
||||
}
|
||||
|
||||
var libraryPageSize = parseInt(this.get('libraryPageSize', false), 10);
|
||||
if (libraryPageSize === 0) {
|
||||
// Explicitly return 0 to avoid returning 100 because 0 is falsy.
|
||||
return 0;
|
||||
} else {
|
||||
return libraryPageSize || 100;
|
||||
}
|
||||
}
|
||||
|
||||
export function soundEffects(val) {
|
||||
if (val != null) {
|
||||
return this.set('soundeffects', val, false);
|
||||
}
|
||||
|
||||
return this.get('soundeffects', false);
|
||||
};
|
||||
}
|
||||
|
||||
UserSettings.prototype.loadQuerySettings = function (key, query) {
|
||||
export function loadQuerySettings(key, query) {
|
||||
var values = this.get(key);
|
||||
if (values) {
|
||||
values = JSON.parse(values);
|
||||
|
@ -218,9 +231,9 @@ define(['appSettings', 'events'], function (appSettings, events) {
|
|||
}
|
||||
|
||||
return query;
|
||||
};
|
||||
}
|
||||
|
||||
UserSettings.prototype.saveQuerySettings = function (key, query) {
|
||||
export function saveQuerySettings(key, query) {
|
||||
var values = {};
|
||||
if (query.SortBy) {
|
||||
values.SortBy = query.SortBy;
|
||||
|
@ -231,25 +244,24 @@ define(['appSettings', 'events'], function (appSettings, events) {
|
|||
}
|
||||
|
||||
return this.set(key, JSON.stringify(values));
|
||||
};
|
||||
}
|
||||
|
||||
UserSettings.prototype.getSubtitleAppearanceSettings = function (key) {
|
||||
export function getSubtitleAppearanceSettings(key) {
|
||||
key = key || 'localplayersubtitleappearance3';
|
||||
return JSON.parse(this.get(key, false) || '{}');
|
||||
};
|
||||
}
|
||||
|
||||
UserSettings.prototype.setSubtitleAppearanceSettings = function (value, key) {
|
||||
export function setSubtitleAppearanceSettings(value, key) {
|
||||
key = key || 'localplayersubtitleappearance3';
|
||||
return this.set(key, JSON.stringify(value), false);
|
||||
};
|
||||
}
|
||||
|
||||
UserSettings.prototype.setFilter = function (key, value) {
|
||||
export function setFilter(key, value) {
|
||||
return this.set(key, value, true);
|
||||
};
|
||||
}
|
||||
|
||||
UserSettings.prototype.getFilter = function (key) {
|
||||
export function getFilter(key) {
|
||||
return this.get(key, true);
|
||||
};
|
||||
}
|
||||
|
||||
return UserSettings;
|
||||
});
|
||||
/* eslint-enable indent */
|
|
@ -323,11 +323,11 @@ var AppInfo = {};
|
|||
}
|
||||
|
||||
function getElementsPath() {
|
||||
return "elements"
|
||||
return "elements";
|
||||
}
|
||||
|
||||
function getScriptsPath() {
|
||||
return "scripts"
|
||||
return "scripts";
|
||||
}
|
||||
|
||||
function getPlaybackManager(playbackManager) {
|
||||
|
@ -452,6 +452,9 @@ var AppInfo = {};
|
|||
require(["autoFocuser"], function(autoFocuser) {
|
||||
autoFocuser.enable();
|
||||
});
|
||||
require(['globalize', 'connectionManager', 'events'], function (globalize, connectionManager, events) {
|
||||
events.on(connectionManager, 'localusersignedin', globalize.updateCurrentCulture);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -585,7 +588,7 @@ var AppInfo = {};
|
|||
}
|
||||
}
|
||||
|
||||
require(["playerSelectionMenu", "fullscreenManager"]);
|
||||
require(["playerSelectionMenu"]);
|
||||
|
||||
var apiClient = window.ConnectionManager && window.ConnectionManager.currentApiClient();
|
||||
if (apiClient) {
|
||||
|
@ -612,13 +615,17 @@ var AppInfo = {};
|
|||
}
|
||||
|
||||
function registerServiceWorker() {
|
||||
if (navigator.serviceWorker && "cordova" !== self.appMode && "android" !== self.appMode) {
|
||||
/* eslint-disable compat/compat */
|
||||
if (navigator.serviceWorker && self.appMode !== "cordova" && self.appMode !== "android") {
|
||||
try {
|
||||
navigator.serviceWorker.register("serviceworker.js");
|
||||
} catch (err) {
|
||||
console.error("error registering serviceWorker: " + err);
|
||||
}
|
||||
} else {
|
||||
console.warn("serviceWorker unsupported");
|
||||
}
|
||||
/* eslint-enable compat/compat */
|
||||
}
|
||||
|
||||
function onWebComponentsReady(browser) {
|
||||
|
@ -696,7 +703,11 @@ var AppInfo = {};
|
|||
"jellyfin-noto",
|
||||
"date-fns",
|
||||
"page",
|
||||
"polyfill"
|
||||
"polyfill",
|
||||
"fast-text-encoding",
|
||||
"intersection-observer",
|
||||
"classlist-polyfill",
|
||||
"screenfull"
|
||||
]
|
||||
},
|
||||
urlArgs: urlArgs,
|
||||
|
@ -705,6 +716,9 @@ var AppInfo = {};
|
|||
});
|
||||
|
||||
require(["polyfill"]);
|
||||
require(["fast-text-encoding"]);
|
||||
require(["intersection-observer"]);
|
||||
require(["classlist-polyfill"]);
|
||||
|
||||
// Expose jQuery globally
|
||||
require(["jQuery"], function(jQuery) {
|
||||
|
@ -767,13 +781,19 @@ var AppInfo = {};
|
|||
define("emby-slider", [elementsPath + "/emby-slider/emby-slider"], returnFirstDependency);
|
||||
define("emby-textarea", [elementsPath + "/emby-textarea/emby-textarea"], returnFirstDependency);
|
||||
define("emby-toggle", [elementsPath + "/emby-toggle/emby-toggle"], returnFirstDependency);
|
||||
define("emby-scroller", [elementsPath + "/emby-scroller/emby-scroller"], returnFirstDependency);
|
||||
define("emby-tabs", [elementsPath + "/emby-tabs/emby-tabs"], returnFirstDependency);
|
||||
define("emby-scrollbuttons", [elementsPath + "/emby-scrollbuttons/emby-scrollbuttons"], returnFirstDependency);
|
||||
define("emby-itemrefreshindicator", [elementsPath + "/emby-itemrefreshindicator/emby-itemrefreshindicator"], returnFirstDependency);
|
||||
define("emby-itemscontainer", [elementsPath + "/emby-itemscontainer/emby-itemscontainer"], returnFirstDependency);
|
||||
define("emby-playstatebutton", [elementsPath + "/emby-playstatebutton/emby-playstatebutton"], returnFirstDependency);
|
||||
define("emby-ratingbutton", [elementsPath + "/emby-ratingbutton/emby-ratingbutton"], returnFirstDependency);
|
||||
define("emby-progressbar", [elementsPath + "/emby-progressbar/emby-progressbar"], returnFirstDependency);
|
||||
define("emby-programcell", [elementsPath + "/emby-programcell/emby-programcell"], returnFirstDependency);
|
||||
|
||||
define("webSettings", [scriptsPath + "/settings/webSettings"], returnFirstDependency);
|
||||
define("appSettings", [scriptsPath + "/settings/appSettings"], returnFirstDependency);
|
||||
define("userSettingsBuilder", [scriptsPath + "/settings/userSettingsBuilder"], returnFirstDependency);
|
||||
define("userSettings", ["userSettingsBuilder"], function(userSettingsBuilder) {
|
||||
return new userSettingsBuilder();
|
||||
});
|
||||
define("userSettings", [scriptsPath + "/settings/userSettings"], returnFirstDependency);
|
||||
|
||||
define("chromecastHelper", [componentsPath + "/chromecast/chromecasthelpers"], returnFirstDependency);
|
||||
define("mediaSession", [componentsPath + "/playback/mediasession"], returnFirstDependency);
|
||||
|
@ -788,12 +808,7 @@ var AppInfo = {};
|
|||
define("playerSettingsMenu", [componentsPath + "/playback/playersettingsmenu"], returnFirstDependency);
|
||||
define("playMethodHelper", [componentsPath + "/playback/playmethodhelper"], returnFirstDependency);
|
||||
define("brightnessOsd", [componentsPath + "/playback/brightnessosd"], returnFirstDependency);
|
||||
define("emby-itemscontainer", [componentsPath + "/emby-itemscontainer/emby-itemscontainer"], returnFirstDependency);
|
||||
define("alphaNumericShortcuts", [componentsPath + "/alphanumericshortcuts/alphanumericshortcuts"], returnFirstDependency);
|
||||
define("emby-scroller", [componentsPath + "/emby-scroller/emby-scroller"], returnFirstDependency);
|
||||
define("emby-tabs", [componentsPath + "/emby-tabs/emby-tabs"], returnFirstDependency);
|
||||
define("emby-scrollbuttons", [componentsPath + "/emby-scrollbuttons/emby-scrollbuttons"], returnFirstDependency);
|
||||
define("emby-itemrefreshindicator", [componentsPath + "/emby-itemrefreshindicator/emby-itemrefreshindicator"], returnFirstDependency);
|
||||
define("multiSelect", [componentsPath + "/multiselect/multiselect"], returnFirstDependency);
|
||||
define("alphaPicker", [componentsPath + "/alphapicker/alphapicker"], returnFirstDependency);
|
||||
define("tabbedView", [componentsPath + "/tabbedview/tabbedview"], returnFirstDependency);
|
||||
|
@ -820,8 +835,6 @@ var AppInfo = {};
|
|||
define("searchFields", [componentsPath + "/search/searchfields"], returnFirstDependency);
|
||||
define("searchResults", [componentsPath + "/search/searchresults"], returnFirstDependency);
|
||||
define("upNextDialog", [componentsPath + "/upnextdialog/upnextdialog"], returnFirstDependency);
|
||||
define("fullscreen-doubleclick", [componentsPath + "/fullscreen/fullscreen-dc"], returnFirstDependency);
|
||||
define("fullscreenManager", [componentsPath + "/fullscreenManager", "events"], returnFirstDependency);
|
||||
define("subtitleAppearanceHelper", [componentsPath + "/subtitlesettings/subtitleappearancehelper"], returnFirstDependency);
|
||||
define("subtitleSettings", [componentsPath + "/subtitlesettings/subtitlesettings"], returnFirstDependency);
|
||||
define("displaySettings", [componentsPath + "/displaysettings/displaysettings"], returnFirstDependency);
|
||||
|
@ -850,8 +863,6 @@ var AppInfo = {};
|
|||
define("objectassign", [componentsPath + "/polyfills/objectassign"], returnFirstDependency);
|
||||
define("focusPreventScroll", [componentsPath + "/polyfills/focusPreventScroll"], returnFirstDependency);
|
||||
define("userdataButtons", [componentsPath + "/userdatabuttons/userdatabuttons"], returnFirstDependency);
|
||||
define("emby-playstatebutton", [componentsPath + "/userdatabuttons/emby-playstatebutton"], returnFirstDependency);
|
||||
define("emby-ratingbutton", [componentsPath + "/userdatabuttons/emby-ratingbutton"], returnFirstDependency);
|
||||
define("listView", [componentsPath + "/listview/listview"], returnFirstDependency);
|
||||
define("indicators", [componentsPath + "/indicators/indicators"], returnFirstDependency);
|
||||
define("viewSettings", [componentsPath + "/viewsettings/viewsettings"], returnFirstDependency);
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
define(["dom", "emby-button"], function (dom) {
|
||||
"use strict";
|
||||
|
||||
function onSubmit(e) {
|
||||
if (dom.parentWithClass(this, "page").querySelector(".chkAccept").checked) {
|
||||
Dashboard.navigate("wizardfinish.html");
|
||||
} else {
|
||||
Dashboard.alert({
|
||||
message: Globalize.translate("MessagePleaseAcceptTermsOfServiceBeforeContinuing"),
|
||||
title: ""
|
||||
});
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
|
||||
return function (view, params) {
|
||||
view.querySelector(".wizardAgreementForm").addEventListener("submit", onSubmit);
|
||||
view.addEventListener("viewshow", function () {
|
||||
document.querySelector(".skinHeader").classList.add("noHomeButtonHeader");
|
||||
});
|
||||
view.addEventListener("viewhide", function () {
|
||||
document.querySelector(".skinHeader").classList.remove("noHomeButtonHeader");
|
||||
});
|
||||
};
|
||||
});
|
|
@ -919,7 +919,7 @@
|
|||
"HeaderFavoriteArtists": "الفنانون المفضلون",
|
||||
"Shows": "الحلقات",
|
||||
"Books": "الكتب",
|
||||
"ValueSpecialEpisodeName": "مميز - {0}",
|
||||
"ValueSpecialEpisodeName": "خاص - {0}",
|
||||
"HeaderFavoriteAlbums": "الألبومات المفضلة",
|
||||
"HeaderAlbumArtists": "فناني الألبومات",
|
||||
"Genres": "الأنواع",
|
||||
|
@ -952,7 +952,7 @@
|
|||
"Artists": "الفنانين",
|
||||
"Art": "فن",
|
||||
"Anytime": "اي وقت",
|
||||
"AnyLanguage": "اي لغة",
|
||||
"AnyLanguage": "أي لغة",
|
||||
"AlwaysPlaySubtitlesHelp": "الترجمة التي تطابق تفضيلات اللغة سيتم تحميلها بغض النظر عن لغة الصوت.",
|
||||
"AlwaysPlaySubtitles": "شغل الترجمة دائماً",
|
||||
"AllowedRemoteAddressesHelp": "قائمة لعناوين IP أو إدخالات IP / قناع الشبكة مفصولة بفاصلة للشبكات التي سيتم السماح لها بالاتصال عن بعد. إذا تركت فارغة ، فسيتم السماح بجميع العناوين البعيدة.",
|
||||
|
@ -1040,5 +1040,10 @@
|
|||
"DatePlayed": "تاريخ التشغيل",
|
||||
"DateAdded": "تاريخ الاضافة",
|
||||
"CriticRating": "تقييم النقاد",
|
||||
"ResumeAt": "اكمل من {0}"
|
||||
"ResumeAt": "اكمل من {0}",
|
||||
"AskAdminToCreateLibrary": "أطلب من الأدمن إنشاء مكتبة.",
|
||||
"Artist": "الفنان",
|
||||
"AllowFfmpegThrottling": "إبطاء الترميزات",
|
||||
"AlbumArtist": "المؤدي",
|
||||
"Album": "الألبوم"
|
||||
}
|
||||
|
|
|
@ -305,7 +305,7 @@
|
|||
"LabelCustomCertificatePath": "Път към потребителския сертификат:",
|
||||
"LabelCustomCertificatePathHelp": "Път до файл с шифровъчен стандарт №12 (PKCS #12), съдържащ сертификат и частен ключ за поддръжка на протокол TLS на собствен домейн.",
|
||||
"LabelCustomCss": "CSS по избор:",
|
||||
"LabelCustomCssHelp": "Използвайте собствен CSS към мрежовия интерфейс.",
|
||||
"LabelCustomCssHelp": "Добавете собствен стил за Уеб-интерфейса.",
|
||||
"LabelCustomDeviceDisplayName": "Показвано име:",
|
||||
"LabelCustomRating": "Оценка по избор:",
|
||||
"LabelDashboardTheme": "Облик на сървърното табло:",
|
||||
|
@ -786,7 +786,7 @@
|
|||
"AllowMediaConversion": "Разрешаване на медийни преобразувания",
|
||||
"AllLanguages": "Всички езици",
|
||||
"AllEpisodes": "Всички епизоди",
|
||||
"AllComplexFormats": "Всички комплексни формати (ASS, SSA, VOBSUB, PGS, SUB/IDX, и т.н.)",
|
||||
"AllComplexFormats": "Всички общи формати (ASS, SSA, VOBSUB, PGS, SUB/IDX, и др. )",
|
||||
"AllChannels": "Всички канали",
|
||||
"Alerts": "Известия",
|
||||
"AdditionalNotificationServices": "Разгледайте каталога с добавки за допълнителни услуги за известяване.",
|
||||
|
@ -836,10 +836,47 @@
|
|||
"AddItemToCollectionHelp": "Добавяне към колекция чрез търсенето им и използване на дясно-щракване с мишката или контекстното меню.",
|
||||
"Absolute": "Aбсолютен",
|
||||
"LabelLanNetworks": "Локални мрежи:",
|
||||
"LabelKodiMetadataSaveImagePathsHelp": "Препоръчително е ако имате изображения, пътят към които не е съобразен с изискванията на Коди.",
|
||||
"LabelKodiMetadataSaveImagePathsHelp": "Това е препоръчително ако имате изображения, пътят към които не е съобразен с изискванията на Kodi",
|
||||
"LabelKodiMetadataSaveImagePaths": "Записване на пътеките към изображенията в nfo файловете",
|
||||
"LabelChannels": "Канали:",
|
||||
"DropShadow": "Сянка",
|
||||
"Raised": "Повишено",
|
||||
"OptionResElement": "рес. елемент"
|
||||
"OptionResElement": "рес. елемент",
|
||||
"ButtonChangeServer": "Смяна на сървър",
|
||||
"ButtonAddImage": "Добавяне на изображение",
|
||||
"BrowsePluginCatalogMessage": "За да видите наличните добавки, прегледайте каталога с добавките.",
|
||||
"Box": "Кутия",
|
||||
"AlwaysPlaySubtitlesHelp": "Поднадписите, съвпадащи с езика от настройките, ще се зареждат, независимо от езика на аудио то.",
|
||||
"BookLibraryHelp": "Поддържат се звукови и текстови книги. Преглед на инструкция за наименоване {1} на книга {0}.",
|
||||
"Blacklist": "Списък с блокирани",
|
||||
"BirthLocation": "Месторождение",
|
||||
"Banner": "Банер",
|
||||
"AspectRatio": "Съотношение",
|
||||
"AskAdminToCreateLibrary": "Помолете администратора за създаване на библиотека.",
|
||||
"Ascending": "Възходящо",
|
||||
"AsManyAsPossible": "Колкото е възможно повече",
|
||||
"Artist": "Артист",
|
||||
"AroundTime": "Към {0}",
|
||||
"Anytime": "По всяко време",
|
||||
"AnyLanguage": "Който и да е език",
|
||||
"AlwaysPlaySubtitles": "Постоянно изпълнение",
|
||||
"AllowRemoteAccessHelp": "Ако не е маркирано, всеки отдалечен достъп ще бъде блокиран.",
|
||||
"AllowRemoteAccess": "Позволяване на отдалечен достъп до този Jellyfin сървър.",
|
||||
"AllowFfmpegThrottling": "Подтискане на прекодирането",
|
||||
"AllowMediaConversionHelp": "Даване или отнемане на права за функциите за конвертиране на медия.",
|
||||
"AlbumArtist": "Изпълнител",
|
||||
"Album": "Албум",
|
||||
"ClientSettings": "Клиентски настройки",
|
||||
"ChannelNumber": "Номер на канала",
|
||||
"ChannelNameOnly": "Само {0} канал",
|
||||
"CancelSeries": "Откажи сериите",
|
||||
"CancelRecording": "Откажи записа",
|
||||
"ButtonSplit": "Раздели",
|
||||
"ButtonResetEasyPassword": "Нулиране на бързия ПИН код",
|
||||
"ButtonRevoke": "Отмени",
|
||||
"ButtonEditOtherUserPreferences": "Редакция на потребителския профил, изображение и лични предпочитания.",
|
||||
"BoxRear": "Комплект (стар)",
|
||||
"BoxSet": "Комплект",
|
||||
"AuthProviderHelp": "Избор на доставчик на услуга за Автентификация, която ще се използва за автентификация на потребителската парола.",
|
||||
"AllowedRemoteAddressesHelp": "Списък с IP адреси или IP/маска записи, разделени със запетая, които ще имат отдалечен достъп. Ако полето не е попълнено всички адреси ще имат отдалечен достъп."
|
||||
}
|
||||
|
|
|
@ -426,7 +426,7 @@
|
|||
"Images": "Obrázky",
|
||||
"ImportFavoriteChannelsHelp": "Pokud je povoleno, jen kanály označené jako oblíbené budou importována na zařízení tuneru.",
|
||||
"ImportMissingEpisodesHelp": "Pokud je povoleno, budou informace o chybějících epizodách importovány do databáze Jellyfin a zobrazí se v sezónách seriálu. To může způsobit podstatně delší skenování knihovny.",
|
||||
"InstallingPackage": "Instalace {0}",
|
||||
"InstallingPackage": "Instalace {0} (Verze {1})",
|
||||
"InstantMix": "Okamžité míchání",
|
||||
"ItemCount": "{0} položek",
|
||||
"Items": "Položky",
|
||||
|
@ -999,9 +999,9 @@
|
|||
"OptionWeekly": "Týdenní",
|
||||
"OriginalAirDateValue": "Datum vysílání originálu: {0}",
|
||||
"Overview": "Přehled/Obsah",
|
||||
"PackageInstallCancelled": "Instalace {0} zrušena.",
|
||||
"PackageInstallCompleted": "Instalace {0} dokončena.",
|
||||
"PackageInstallFailed": "Instalace {0} selhala.",
|
||||
"PackageInstallCancelled": "Instalace {0} (verze {1}) zrušena.",
|
||||
"PackageInstallCompleted": "Instalace {0} (verze {1}) dokončena.",
|
||||
"PackageInstallFailed": "Instalace {0} (verze {1}) selhala.",
|
||||
"ParentalRating": "Rodičovské hodnocení",
|
||||
"PasswordMatchError": "Heslo a potvrzení hesla musí souhlasit.",
|
||||
"PasswordResetComplete": "Heslo bylo obnoveno.",
|
||||
|
@ -1022,7 +1022,7 @@
|
|||
"PlayNext": "Přehrát další",
|
||||
"PlayNextEpisodeAutomatically": "Automaticky přehrávat další epizodu",
|
||||
"PlayOnAnotherDevice": "Přehrát na jiném zařízení",
|
||||
"PlaybackErrorNoCompatibleStream": "Žádné kompatibilní streamy nejsou v současné době k dispozici. Zkuste to prosím později, nebo pro více podrobností kontaktujte svého správce systému.",
|
||||
"PlaybackErrorNoCompatibleStream": "Tento klient není kompatibilní s médiem a server neodesílá kompatibilní formát médií.",
|
||||
"PlaybackErrorNotAllowed": "V současné době nejste oprávněni přehrávat tento obsah. Pro více informací se obraťte se na správce systému.",
|
||||
"PlaybackErrorPlaceHolder": "Chcete-li toto video přehrát, vložte disk.",
|
||||
"Played": "Přehráno",
|
||||
|
@ -1223,7 +1223,7 @@
|
|||
"AirDate": "Datum vysílání",
|
||||
"Aired": "Vysíláno",
|
||||
"Alerts": "Upozornění",
|
||||
"AllComplexFormats": "Všechny komplexní formáty (ASS, SSA, VOBSUB, PGS, SUB/IDX, atd.)",
|
||||
"AllComplexFormats": "Všechny komplexní formáty (ASS, SSA, VOBSUB, PGS, SUB/IDX, atd.)",
|
||||
"AllLibraries": "Všechny knihovny",
|
||||
"AllowDeletionFromAll": "Povolit smazání médií ze všech knihoven",
|
||||
"AllowMediaConversion": "Povolit konverzi médií",
|
||||
|
@ -1248,7 +1248,7 @@
|
|||
"Blacklist": "Černá listina",
|
||||
"BobAndWeaveWithHelp": "Bob and weave (vyšší kvalita, ale pomalejší)",
|
||||
"Browse": "Procházet",
|
||||
"BurnSubtitlesHelp": "Určuje, zda má server vypalovat titulky při překódování videa. Vynechání tohoto zlepší výkon serveru. Chcete-li vypálit grafické formáty (VOBSUB, PGS, SUB / IDX atd.) a některé titulky ASS / SSA, vyberte možnost Auto.",
|
||||
"BurnSubtitlesHelp": "Určuje, zda má server vypalovat titulky při překódování videa. Vynechání tohoto zlepší výkon serveru. Chcete-li vypálit grafické formáty (VOBSUB, PGS, SUB / IDX atd.) a některé titulky ASS nebo SSA, vyberte možnost Auto.",
|
||||
"ButtonInfo": "Info",
|
||||
"ButtonMenu": "Menu",
|
||||
"ButtonOk": "Ok",
|
||||
|
@ -1584,5 +1584,23 @@
|
|||
"ClientSettings": "Nastavení klienta",
|
||||
"Artist": "Interpret",
|
||||
"AlbumArtist": "Interpret alba",
|
||||
"Album": "Album"
|
||||
"Album": "Album",
|
||||
"OnApplicationStartup": "Při zapnutí aplikace",
|
||||
"EveryXHours": "Každých {0} hodin",
|
||||
"EveryHour": "Každou hodinu",
|
||||
"EveryXMinutes": "Každých {0} minut",
|
||||
"OnWakeFromSleep": "Při probuzení",
|
||||
"DailyAt": "Denně v {0}",
|
||||
"PersonRole": "jako {0}",
|
||||
"ListPaging": "{0}-{1} ze {2}",
|
||||
"WriteAccessRequired": "Jellyfin Server potřebuje oprávnění pro zápis v této složce. Zkontrolujte oprávnění a zkuste to znovu.",
|
||||
"PathNotFound": "Cesta nebyla nalezena. Zkontrolujte, zda je platná a zkuste to znovu.",
|
||||
"WeeklyAt": "V {0} v {1}",
|
||||
"LastSeen": "Naposledy zobrazené {0}",
|
||||
"YadifBob": "Yadif Bob",
|
||||
"Yadif": "Yadif",
|
||||
"LabelLibraryPageSizeHelp": "Určuje počet položek k zobrazení na stránce knihovny. Nastavte na 0 pro vypnutí stránkování.",
|
||||
"LabelLibraryPageSize": "Velikost stránky knihovny:",
|
||||
"LabelDeinterlaceMethod": "Metoda odstranění prokládání:",
|
||||
"DeinterlaceMethodHelp": "Vyberte metodu odstranění prokládání obrazu při překódování obsahu."
|
||||
}
|
||||
|
|
|
@ -12,11 +12,11 @@
|
|||
"AllChannels": "Alle kanaler",
|
||||
"AllEpisodes": "Alle episoder",
|
||||
"AllLibraries": "Alle biblioteker",
|
||||
"AllowHWTranscodingHelp": "Hvis aktiveret, omkoder tuneren streams on-the-fly. Dette kan hjælpe med at reducere omkodning der kræves af Jellyfin Server.",
|
||||
"AllowHWTranscodingHelp": "Lader tuneren omkode streams on-the-fly. Dette kan hjælpe med at reducere omkodning der kræves af serveren.",
|
||||
"AllowMediaConversion": "Tillad media konvertering",
|
||||
"AllowMediaConversionHelp": "Giv eller nægt adgang til Konvertér Media featuren.",
|
||||
"AllowOnTheFlySubtitleExtraction": "Tillad udtræk af undertekster on-the-fly",
|
||||
"AllowOnTheFlySubtitleExtractionHelp": "Indeholdte undertekster kan trækkes ud af videoer og leveres til Jellyfin apps i ren tekst for at afhjælpe video kodning. På nogle systemer kan dette tage lang tid og forårsage at afspilning kan hænge mens den udtrækker. Slå dette fra, for at have undertekster brændt ind i video kodningen når det er supporteret på klient enheden.",
|
||||
"AllowOnTheFlySubtitleExtractionHelp": "Indeholdte undertekster kan trækkes ud af videoer og leveres til klienter i ren tekst for at afhjælpe video kodning. På nogle systemer kan dette tage lang tid og forårsage at afspilning kan hænge mens den udtrækker. Slå dette fra, for at have undertekster brændt ind i video kodningen når det er supporteret på klient enheden.",
|
||||
"AllowRemoteAccess": "Tillad fjernadgang til denne Jellyfin Server.",
|
||||
"AllowRemoteAccessHelp": "Hvis ikke markeret, vil alle fjernforbindelser blive blokeret.",
|
||||
"AllowedRemoteAddressesHelp": "Komma seperareret liste over IP adresser og netmasker der har ret til fjernadgang. Hvis blank er alle adresser tilladte.",
|
||||
|
@ -29,7 +29,7 @@
|
|||
"BirthDateValue": "Født: {0}",
|
||||
"BirthLocation": "Fødselslokation",
|
||||
"BirthPlaceValue": "Fødselssted: {0}",
|
||||
"BookLibraryHelp": "Lyd- og tekstbøger er understøttet. Se {0}Jellyfins guide til navngivning af bøger{1}.",
|
||||
"BookLibraryHelp": "Lyd- og tekstbøger er understøttet. Se {0}bog guide til navngivning af bøger{1}.",
|
||||
"Browse": "Gennemse",
|
||||
"BrowsePluginCatalogMessage": "Gennemse vores plugin-katalog for at se tilgængelige plugins.",
|
||||
"ButtonAdd": "Tilføj",
|
||||
|
@ -53,7 +53,7 @@
|
|||
"ButtonEdit": "Rediger",
|
||||
"ButtonEditImages": "Rediger billeder",
|
||||
"ButtonEditOtherUserPreferences": "Rediger denne brugers profil, billede og personlige indstillinger.",
|
||||
"ButtonForgotPassword": "Glemt adgangskode",
|
||||
"ButtonForgotPassword": "Glemt Adgangskode",
|
||||
"ButtonFullscreen": "Fuld skærm",
|
||||
"ButtonGotIt": "Forstået",
|
||||
"ButtonHelp": "Hjælp",
|
||||
|
@ -136,30 +136,30 @@
|
|||
"DoNotRecord": "Optag ikke",
|
||||
"Download": "Hent",
|
||||
"DrmChannelsNotImported": "Kanaler med DRM importeres ikke.",
|
||||
"EasyPasswordHelp": "Din pinkode bruges til offline adgang til understøttede Jellyfin apps, og kan også bruges til nemt login inden for eget netværk.",
|
||||
"EasyPasswordHelp": "Din nemme pin-kode bruges til offline adgang på understøttede klienter og kan også bruges til nem login på netværket.",
|
||||
"Edit": "Rediger",
|
||||
"EditImages": "Rediger billeder",
|
||||
"EditSubtitles": "Rediger undertekster",
|
||||
"EnableCinemaMode": "Aktiver biograftilstand",
|
||||
"EnableColorCodedBackgrounds": "Aktiver farvekodet baggrunde",
|
||||
"EnableCinemaMode": "Aktiver Biograftilstand",
|
||||
"EnableColorCodedBackgrounds": "Aktiver Farvekodet baggrunde",
|
||||
"EnableHardwareEncoding": "Aktiver hardware indkoding",
|
||||
"EnablePhotos": "Aktiver fotos",
|
||||
"EnablePhotosHelp": "Fotos bliver opdaget og vist sammen med andre mediefiler.",
|
||||
"EnablePhotos": "Vis fotoer",
|
||||
"EnablePhotosHelp": "Billeder registreres og vises sammen med andre mediefiler.",
|
||||
"EnableStreamLooping": "Auto-gentag live streams",
|
||||
"EnableStreamLoopingHelp": "Aktiver dette hvis live streams kun indeholder få sekunders data og skal efterspørgsel hele tiden. Aktivering af dette uden det er nødvendigt kan forårsage problemer.",
|
||||
"Ended": "Færdig",
|
||||
"EndsAtValue": "Slutter {0}",
|
||||
"ErrorAddingListingsToSchedulesDirect": "Der opstod en fejl under tilføjelse af opstilling til din Schedules Direct-konto. Schedules Direct tillader kun et begrænset antal opstillinger pr. konto. Du bliver muligvis nød til at logge på Schedules Direct-hjemmesiden og fjerne andre lister fra din konto for at fortsætte.",
|
||||
"ErrorAddingListingsToSchedulesDirect": "Der opstod en fejl ved tilføjelse af lineup til din Schedules Direct-konto. Schedules Direct tillader kun et begrænset antal opstillinger pr. Konto. Det kan være nødvendigt at du logger ind på Schedules Direct-webstedet og fjerner andre lister fra din konto, før du fortsætter.",
|
||||
"ErrorAddingMediaPathToVirtualFolder": "Der opstod en fejl under tilføjelse af mediesti. Kontroller venligst at stien er gyldig og at Jellyfin Server-processen har adgang til denne lokation.",
|
||||
"ErrorAddingTunerDevice": "Der opstod en fejl under tilføjelse af tuner-enhed. Kontroller venligst at den er tilgængelig og prøv igen.",
|
||||
"ErrorAddingXmlTvFile": "Der opstod en fejl under tilgang til XmlTV-filen. Kontroller venligst at filen findes og prøv igen.",
|
||||
"ErrorGettingTvLineups": "Der opstod en fejl under download af tv-opstillinger. Kontroller venligst at dine informationer er korrekte og prøv igen.",
|
||||
"ErrorAddingXmlTvFile": "Der opstod en fejl under tilgang til XMLTV-filen. Kontroller venligst at filen findes og prøv igen.",
|
||||
"ErrorGettingTvLineups": "Der opstod en fejl under download af TV-opstillinger. Kontroller venligst at dine informationer er korrekte og prøv igen.",
|
||||
"ErrorMessageStartHourGreaterThanEnd": "Slut tid skal være større end start tid.",
|
||||
"ErrorPleaseSelectLineup": "Vælg venligst en opstilling og prøv igen. Hvis ingen opstillinger er tilgængelige, så kontroller venligst at dit brugernavn, adgangskode og postnummer er korrekt.",
|
||||
"ErrorSavingTvProvider": "Der opstod en fejl i forsøget på at gemme udbyder. Kontroller venligst at den er tilgængelig og prøv igen.",
|
||||
"EveryNDays": "Hver {0} dage",
|
||||
"ExitFullscreen": "Afslut fuldskærm",
|
||||
"ExtractChapterImagesHelp": "Udvinding af kapitelbilleder lader Jellyfin apps vise grafiske menuer for scenevalg. Processen kan være langsom, cpu-intensiv og kræver muligvis adskillige gigabytes af lagerplads. Den køres når videoer opdages og desuden som en planlagt opgave, natligt. Den planlagte opgave kan konfigureres i området for planlagte opgaver. Det anbefales ikke at køre denne opgave under timer med spidsbelastning.",
|
||||
"ExtractChapterImagesHelp": "Udtrækning af kapitelbilleder giver klienter mulighed for at vise grafiske scenevalgmenuer. Processen kan være langsom, ressourcekrævende og kan kræve flere gigabyte plads. Det kører, når videoer opdages, og også som en planlagt nat opgave. Skemaet kan konfigureres i det planlagte opgaverområde. Det anbefales ikke at køre denne opgave i de mest brugte timer.",
|
||||
"FFmpegSavePathNotFound": "Vi er ikke i stand til at finde FFmpeg via stien du har angivet. FFprobe er også påkrævet og skal findes i samme mappe. Disse komponenter er som regel pakket i den samme download. Kontroller venligst stien og prøv igen.",
|
||||
"FastForward": "Spol fremad",
|
||||
"Favorite": "Favorit",
|
||||
|
@ -170,9 +170,9 @@
|
|||
"FolderTypeBooks": "Bøger",
|
||||
"FolderTypeMovies": "Film",
|
||||
"FolderTypeMusic": "Musik",
|
||||
"FolderTypeMusicVideos": "Musikvideoer",
|
||||
"FolderTypeMusicVideos": "Musik Videoer",
|
||||
"FolderTypeTvShows": "TV",
|
||||
"FolderTypeUnset": "Ikke valgt (blandet indhold)",
|
||||
"FolderTypeUnset": "Blandet Indhold",
|
||||
"Friday": "Fredag",
|
||||
"Fullscreen": "Fuldskærm",
|
||||
"General": "Generel",
|
||||
|
@ -183,7 +183,7 @@
|
|||
"H264CrfHelp": "Den Konstante Ratefaktor (CRF) er standardindstillingen for X264-koderen. Du kan sætte værdien i mellem 0 og 51, hvor de lavere værdier resulterer i bedre kvalitet (på bekostning af større filstørrelser). Fornuftige værdier er i mellem 18 og 28. Standarden for X264 er 23, så du kan bruge dette som udgangspunkt.",
|
||||
"EncoderPresetHelp": "Vælg en hurtigere værdi for at forbedre ydeevne, eller en langsommere værdi for at forbedre kvalitet.",
|
||||
"HDPrograms": "HD-programmer",
|
||||
"HardwareAccelerationWarning": "Aktivering af hardwareacceleration kan forårsage ustabilitet i nogle miljøer. Kontroller at dit operativsystem og videodriver er ajourført. Hvis du har problemer med at afspille video efter aktivering af dette, bliver du nød til at skifte tilbage til Auto.",
|
||||
"HardwareAccelerationWarning": "Aktivering af hardwareacceleration kan forårsage ustabilitet i nogle miljøer. Kontroller at dit operativsystem og videodriver er opdateret. Hvis du har problemer med at afspille video efter aktivering af dette, bliver du nød til at skifte tilbage til Ingen.",
|
||||
"HeaderAccessSchedule": "Adgangsskema",
|
||||
"HeaderAccessScheduleHelp": "Skab et adgangsskema for at begrænse adgangen til bestemte tidsrum.",
|
||||
"HeaderActiveDevices": "Aktive enheder",
|
||||
|
@ -197,9 +197,9 @@
|
|||
"HeaderAdditionalParts": "Andre stier",
|
||||
"HeaderAlert": "Advarsel",
|
||||
"HeaderAllowMediaDeletionFrom": "Tillad Media Sletning Fra",
|
||||
"HeaderApiKey": "API nøgle",
|
||||
"HeaderApiKeys": "API nøgler",
|
||||
"HeaderApiKeysHelp": "Eksterne applikationer skal have en API nøgle for at kunne kommunikere med Jellyfin. Nøgler udstedes ved at logge ind med en Jellyfin konto, eller ved manuelt at tildele applikationen en nøgle.",
|
||||
"HeaderApiKey": "API Nøgle",
|
||||
"HeaderApiKeys": "API Nøgler",
|
||||
"HeaderApiKeysHelp": "Eksterne applikationer skal have en API-nøgle for at kunne kommunikere med Jellyfin. Nøgler udstedes ved at logge ind med en Jellyfin konto, eller ved manuelt at tildele applikationen en nøgle.",
|
||||
"HeaderAudioSettings": "Lydindstillinger",
|
||||
"HeaderAutomaticUpdates": "Automatiske opdateringer",
|
||||
"HeaderBlockItemsWithNoRating": "Klokér titler uden eller med ukendt bedømmelses information:",
|
||||
|
@ -266,7 +266,7 @@
|
|||
"HeaderItems": "Element",
|
||||
"HeaderKeepRecording": "Bevar Optagelse",
|
||||
"HeaderKeepSeries": "Bevar Serie",
|
||||
"HeaderKodiMetadataHelp": "For at aktivere NFO metadata, rediger et bibliotek i Jellyfin biblioteks redigering og find metadata gemmer sektionen.",
|
||||
"HeaderKodiMetadataHelp": "For at aktivere eller deaktivere NFO-metadata skal du redigere et bibliotek i Jellyfin-biblioteksopsætningen og finde afsnittet om metadata.",
|
||||
"HeaderLatestEpisodes": "Sidste episoder",
|
||||
"HeaderLatestMedia": "Seneste medier",
|
||||
"HeaderLatestMovies": "Seneste film",
|
||||
|
@ -287,7 +287,7 @@
|
|||
"HeaderMusicVideos": "Musikvideoer",
|
||||
"HeaderMyDevice": "Min Enhed",
|
||||
"HeaderMyMedia": "Mine medier",
|
||||
"HeaderNewApiKey": "Ny API nøgle",
|
||||
"HeaderNewApiKey": "Ny API Nøgle",
|
||||
"HeaderNewDevices": "Nye Enheder",
|
||||
"HeaderNextUp": "Næste",
|
||||
"HeaderOnNow": "Vises Nu",
|
||||
|
@ -373,7 +373,7 @@
|
|||
"Images": "Billeder",
|
||||
"ImportFavoriteChannelsHelp": "Hvis aktiveret, importeres der udelukkende kanaler der er markeret som favoritter på tuner-enheden.",
|
||||
"ImportMissingEpisodesHelp": "hvis aktiveret, vil information omkring manglende episoder bliver importeret ind i din Jellyfin-database og blive vist i sæsoner og serier. Dette medfører muligvis længere biblioteksscanninger.",
|
||||
"InstallingPackage": "Installerer {0}",
|
||||
"InstallingPackage": "Installerer {0} (version {1})",
|
||||
"InstantMix": "Instant Mix",
|
||||
"ItemCount": "{0} elementer",
|
||||
"Items": "emner",
|
||||
|
@ -397,13 +397,13 @@
|
|||
"LabelAll": "Alle",
|
||||
"LabelAllowHWTranscoding": "Tillad hardware-omkodning",
|
||||
"LabelAllowServerAutoRestart": "Tillad serveren at genstarte automatisk for at påføre opdateringer",
|
||||
"LabelAllowServerAutoRestartHelp": "Serveren vil kun genstarte i inaktive perioder, når ingen brugere er aktive",
|
||||
"LabelAllowServerAutoRestartHelp": "Serveren vil kun genstarte i inaktive perioder, når ingen brugere er aktive.",
|
||||
"LabelAllowedRemoteAddresses": "Fjernadgang IP adresse filter:",
|
||||
"LabelAllowedRemoteAddressesMode": "Fjernadgang IP adresse filter mode:",
|
||||
"LabelAppName": "App navn",
|
||||
"LabelAppNameExample": "F. eks: Sickbeard, NzbDrone",
|
||||
"LabelAppNameExample": "F. eks: Sickbeard, Sonarr",
|
||||
"LabelArtists": "Artister:",
|
||||
"LabelArtistsHelp": "Angiv flere ved at sætte mellem dem ;",
|
||||
"LabelArtistsHelp": "Angiv flere ved at sætte ;",
|
||||
"LabelAudioLanguagePreference": "Foretrukket lydsprog:",
|
||||
"LabelAutomaticallyRefreshInternetMetadataEvery": "Genopfrisk automatisk metadata fra internettet:",
|
||||
"LabelBindToLocalNetworkAddress": "Bind til lokal netværksadresse:",
|
||||
|
@ -411,9 +411,9 @@
|
|||
"LabelBirthDate": "Fødselsdato:",
|
||||
"LabelBirthYear": "Fødselsår:",
|
||||
"LabelBlastMessageInterval": "Interval mellem 'i live' beskeder (sekunder)",
|
||||
"LabelBlastMessageIntervalHelp": "Angiver intervallet i sekunder mellem serverens 'i live' beskeder.",
|
||||
"LabelBlastMessageIntervalHelp": "Bestemmer varigheden i sekunder mellem eksplosive levende meddelelser.",
|
||||
"LabelCachePath": "Cachesti:",
|
||||
"LabelCachePathHelp": "Angiv en brugerdefineret lokation for server cachefiler, så som billeder. Efterlad blankt for at benytte serverens standard.",
|
||||
"LabelCachePathHelp": "Angiv en brugerdefineret placering for servercache-filer, såsom billeder. Lad være tom for at bruge serverens standard.",
|
||||
"LabelCancelled": "Annulleret",
|
||||
"LabelChannels": "Kanaler:",
|
||||
"LabelCollection": "Samling:",
|
||||
|
@ -425,8 +425,8 @@
|
|||
"LabelCustomCertificatePath": "Brugerdefineret SSL certifikat sti:",
|
||||
"LabelCustomCertificatePathHelp": "Sti til PKCS #12 fil indeholdende et certifikat og privat nøgle for at aktivere TLS understøttelse på et brugerdefineret domæne.",
|
||||
"LabelCustomCss": "Brugerdefineret CSS:",
|
||||
"LabelCustomCssHelp": "Anvend din egen css til webinterfacet.",
|
||||
"LabelCustomDeviceDisplayName": "Vist navn:",
|
||||
"LabelCustomCssHelp": "Anvend din egen stil til webinterfacet.",
|
||||
"LabelCustomDeviceDisplayName": "Visningsnavn:",
|
||||
"LabelCustomDeviceDisplayNameHelp": "Angiv en brugerdefineret navn. hvis der ikke angives et navn, bruges det navn enheden sender.",
|
||||
"LabelCustomRating": "Brugerdefineret bedømmelse:",
|
||||
"LabelDateAdded": "Dato for tilføjelse:",
|
||||
|
@ -444,24 +444,24 @@
|
|||
"LabelDisplayOrder": "Visningsorden:",
|
||||
"LabelDisplaySpecialsWithinSeasons": "Vis specialepisoder sammen med den sæson de blev sent i",
|
||||
"LabelDownMixAudioScale": "Forøg lydstyrke ved nedmiksning:",
|
||||
"LabelDownMixAudioScaleHelp": "Forøg lydstyrken når der nedmikses. Sæt værdien til 1 for at beholde den originale lydstyrke.",
|
||||
"LabelDownMixAudioScaleHelp": "Forøg lydstyrken når der nedmikses. Sæt værdien til en, for at beholde den originale lydstyrke.",
|
||||
"LabelDownloadLanguages": "Hent sprog:",
|
||||
"LabelDropImageHere": "Smid billede her.",
|
||||
"LabelDropImageHere": "Drop billede her, eller Tryk for at vælge.",
|
||||
"LabelEasyPinCode": "Pinkode:",
|
||||
"LabelEmbedAlbumArtDidl": "Indsæt album billede i DIDL",
|
||||
"LabelEmbedAlbumArtDidlHelp": "Nogle enheder foretrækker denne metode til overførsel af album billede. Andre kan fejle når dette er aktiveret.",
|
||||
"LabelEnableAutomaticPortMap": "Aktiver automatisk port mapping",
|
||||
"LabelEnableAutomaticPortMapHelp": "Forsøg at mappe den offentlige port til den lokale port med uPnP. Dette virker ikke med alle routere.",
|
||||
"LabelEnableAutomaticPortMapHelp": "Forsøg at mappe den offentlige port til den lokale port med uPnP. Dette virker ikke med alle routere. Ændringerne vil først træde i kræft et en server genstart.",
|
||||
"LabelEnableBlastAliveMessages": "Masseudsend 'i live' beskeder",
|
||||
"LabelEnableBlastAliveMessagesHelp": "Aktiver dette hvis UPnP enheder har problemer med forbindelsen til serveren.",
|
||||
"LabelEnableDlnaClientDiscoveryInterval": "Interval for klientsøgning (sekunder)",
|
||||
"LabelEnableDlnaClientDiscoveryIntervalHelp": "angiver intervallet i sekunder mellem Jellyfins SSDP søgninger.",
|
||||
"LabelEnableDlnaDebugLogging": "Aktiver debu logning af DLNA",
|
||||
"LabelEnableDlnaDebugLoggingHelp": "Dette generer meget store logfiler, og er kun anbefalet at bruge til fejlfindingsformål.",
|
||||
"LabelEnableDlnaDebugLoggingHelp": "Opret store logfiler og skal kun bruges efter behov til fejlfinding.",
|
||||
"LabelEnableDlnaPlayTo": "Aktiver DLNA \"Afspil Til\"",
|
||||
"LabelEnableDlnaPlayToHelp": "Jellyfin kan finde enheder i dit netværk og tilbyde at kontrollere dem.",
|
||||
"LabelEnableDlnaServer": "Aktiver DNLA server",
|
||||
"LabelEnableDlnaServerHelp": "Tillader UPnP enheder i dit netværk at gennemse og afspille Jellyfins indhold.",
|
||||
"LabelEnableDlnaPlayToHelp": "Find enheder i dit netværk og tilbyd at fjernstyre dem.",
|
||||
"LabelEnableDlnaServer": "Aktiver DLNA server",
|
||||
"LabelEnableDlnaServerHelp": "Tillader UPnP enheder i dit netværk at gennemse og afspille indhold.",
|
||||
"LabelEnableRealtimeMonitor": "Aktiver realtidsovervågning",
|
||||
"LabelEnableRealtimeMonitorHelp": "Ændringer vil blive behandlet øjeblikkeligt på understøttede filsystemer.",
|
||||
"LabelEnableSingleImageInDidlLimit": "Begræns til et enkelt indlejret billede",
|
||||
|
@ -471,56 +471,56 @@
|
|||
"LabelEvent": "Hændelse:",
|
||||
"LabelEveryXMinutes": "Hver:",
|
||||
"LabelExtractChaptersDuringLibraryScan": "Udtræk kapitelbilleder under biblioteksskanning",
|
||||
"LabelExtractChaptersDuringLibraryScanHelp": "Aktiver dette for at udtrække kapitelbillleder mens videofiler bliver importeret under biblioteksskanningen. Hvi det ikke er aktiveret, bliver de udtrukket når den planlagte opgave kapitelbilleder kører, og lader den almindelige biblioteksskanning afslutte hurtigere.",
|
||||
"LabelExtractChaptersDuringLibraryScanHelp": "Generere kapitelbillleder mens videofiler bliver importeret under biblioteksskanningen. Alternativt bliver de udtrukket når den planlagte opgave kapitelbilleder kører, hvilket tillader den almindelige biblioteksskanning at afslutte hurtigere.",
|
||||
"LabelFailed": "Fejlet",
|
||||
"LabelFileOrUrl": "Fil eller url:",
|
||||
"LabelFileOrUrl": "Fil eller URL:",
|
||||
"LabelFinish": "Afslut",
|
||||
"LabelForgotPasswordUsernameHelp": "Indtast dit brugernavn, hvis du kan huske det.",
|
||||
"LabelFriendlyName": "System venligt navn:",
|
||||
"LabelServerNameHelp": "Dette navn bruges til at identificere serveren. Hvis det ikke udfyldes, bruges computerens navn.",
|
||||
"LabelServerNameHelp": "Dette navn bruges til at identificere serveren. Som udgangspunkt anvendes computerens navn.",
|
||||
"LabelGroupMoviesIntoCollections": "Grupper film i samlinger",
|
||||
"LabelGroupMoviesIntoCollectionsHelp": "Film i samlinger vil blive vist som en samlet enhed i filmlister.",
|
||||
"LabelH264Crf": "H264-kodning CRF:",
|
||||
"LabelEncoderPreset": "Forudindstillet H264-kodning:",
|
||||
"LabelHardwareAccelerationType": "Hardwareacceleration:",
|
||||
"LabelHardwareAccelerationTypeHelp": "Kun tilgængelig for understøttede systemer.",
|
||||
"LabelHardwareAccelerationTypeHelp": "Hardwareacceleration kræver yderligere konfiguration.",
|
||||
"LabelHttpsPort": "Lokalt HTTPS portnummer:",
|
||||
"LabelHttpsPortHelp": "Det portnummer Jellyfins https-server bruger.",
|
||||
"LabelIconMaxHeight": "Max højde på ikoner:",
|
||||
"LabelIconMaxHeightHelp": "Maksimumopløsningen på ikoner der bliver vist med upnp:icon",
|
||||
"LabelIconMaxWidth": "Max bredde på ikoner:",
|
||||
"LabelIconMaxWidthHelp": "Maksimumopløsningen på ikoner der bliver vist med upnp:icon",
|
||||
"LabelHttpsPortHelp": "Det TCP-portnummer, som Jellyfins HTTPS-server skal benytte.",
|
||||
"LabelIconMaxHeight": "Maximal højde af ikoner:",
|
||||
"LabelIconMaxHeightHelp": "Maksimalopløsningen af ikoner, der bliver vist med upnp:icon.",
|
||||
"LabelIconMaxWidth": "Maximal bredde på ikoner:",
|
||||
"LabelIconMaxWidthHelp": "Maksimalopløsningen på ikoner der bliver vist med upnp:icon.",
|
||||
"LabelIdentificationFieldHelp": "En case-insensitive substring eller regex ekspression.",
|
||||
"LabelImageFetchersHelp": "Aktiver og ranger dine fortrukne billede-hentere i en prioriteret rækkefølge.",
|
||||
"LabelImageType": "Billedtype:",
|
||||
"LabelImportOnlyFavoriteChannels": "Begræns til kanaler der er markeret som favoritter",
|
||||
"LabelInNetworkSignInWithEasyPassword": "Tillad login inden for eget netværk med pinkode",
|
||||
"LabelInNetworkSignInWithEasyPasswordHelp": "Aktiver dette for at loge ind i Jellyfin apps med din pinkode inden for dit eget netværk. Din almindelige adgangskode skal du så kun bruge når du ikke er hjemme. Hvis pinkoden er tom, kan du logge ind uden adgangskode inden for dit eget netværk.",
|
||||
"LabelInNetworkSignInWithEasyPasswordHelp": "Brug den lette pinkode til at logge ind på klienter i dit lokale netværk. Din almindelige adgangskode er kun nødvendig hjemmefra. Hvis pinkoden efterlades tom, behøver du ikke en adgangskode på dit hjemmenetværk.",
|
||||
"LabelKeepUpTo": "Bevar op til:",
|
||||
"LabelKidsCategories": "Børnekategorier:",
|
||||
"LabelKodiMetadataDateFormat": "Format for udgivelsesdato:",
|
||||
"LabelKodiMetadataDateFormatHelp": "Alle datoer i NFO-filer vil blive læst og skrevet med dette format.",
|
||||
"LabelKodiMetadataEnableExtraThumbs": "kopier extrafanart til extrathumbs",
|
||||
"LabelKodiMetadataDateFormatHelp": "Alle datoer i NFO-filer vil blive analyseret med dette format.",
|
||||
"LabelKodiMetadataEnableExtraThumbs": "Kopier ekstra fanart til extrathumbs",
|
||||
"LabelKodiMetadataEnableExtraThumbsHelp": "Ved hentning af billeder, kan de gemmes i både extrafanart og extrathumbs. Dette giver maksimal Kodi skin kompatibilitet.",
|
||||
"LabelKodiMetadataEnablePathSubstitution": "Aktiver stisubstitution",
|
||||
"LabelKodiMetadataEnablePathSubstitutionHelp": "Aktiverer stisubstitution for billedstier med serverens stisubstitutionsindstillinger.",
|
||||
"LabelKodiMetadataSaveImagePaths": "Gem stier til billeder i Nfo-filer",
|
||||
"LabelKodiMetadataSaveImagePathsHelp": "Dette er anbefalet hvis du har billedfiler med navne der ikke lever op til Kodis retningslinjer.",
|
||||
"LabelKodiMetadataUser": "Gem brugers set data til NFO'er for:",
|
||||
"LabelKodiMetadataUserHelp": "Aktiver dette for at komme set data til NFO filer som andre programmer kan bruge.",
|
||||
"LabelKodiMetadataUser": "Gem brugerdata til NFO-filer til:",
|
||||
"LabelKodiMetadataUserHelp": "Gem overvågningsdata til NFO-filer til andre applikationer.",
|
||||
"LabelLanNetworks": "LAN netwærk:",
|
||||
"LabelLanguage": "Sprog:",
|
||||
"LabelLineup": "Opstilling:",
|
||||
"LabelLocalHttpServerPortNumber": "Lokalt http portnummer:",
|
||||
"LabelLocalHttpServerPortNumberHelp": "Det portnummer Jellyfins http-server bruger.",
|
||||
"LabelLocalHttpServerPortNumber": "Lokalt HTTP-portnummer:",
|
||||
"LabelLocalHttpServerPortNumberHelp": "Det TCP-portnummer, som Jellyfin's HTTP-server skal binde til.",
|
||||
"LabelLockItemToPreventChanges": "Lås for at undgå fremtidige ændringer",
|
||||
"LabelLoginDisclaimer": "Login ansvarsfraskrivelse:",
|
||||
"LabelLoginDisclaimerHelp": "Dette bliver vist i bunden af loginsiden.",
|
||||
"LabelManufacturer": "Producent",
|
||||
"LabelManufacturerUrl": "Producent url",
|
||||
"LabelLoginDisclaimerHelp": "En besked, som vises i bunden af loginsiden.",
|
||||
"LabelManufacturer": "Producent:",
|
||||
"LabelManufacturerUrl": "Producentens URL",
|
||||
"LabelMaxBackdropsPerItem": "Maksimum antal af bagtæpper per element:",
|
||||
"LabelMaxParentalRating": "Højst tilladte aldersgrænse:",
|
||||
"LabelMaxResumePercentage": "Maks. fortsæt procentdel:",
|
||||
"LabelMaxResumePercentage": "Maksimal fortsæt procentdel:",
|
||||
"LabelMaxResumePercentageHelp": "Medier anses som fuldt afspillet, hvis de stoppes efter denne tid.",
|
||||
"LabelMaxScreenshotsPerItem": "Maksimum antal af skærmbilleder per element:",
|
||||
"LabelMaxStreamingBitrate": "Maks. streaming kvalitet:",
|
||||
|
@ -538,9 +538,9 @@
|
|||
"LabelMethod": "Metode:",
|
||||
"LabelMinBackdropDownloadWidth": "Minimum baggrundsbillede bredde:",
|
||||
"LabelMinResumeDuration": "Min. fortsæt tidsrum (sekunder):",
|
||||
"LabelMinResumeDurationHelp": "Medier med kortere afspilningstid en denne kan ikke fortsættes.",
|
||||
"LabelMinResumePercentage": "Min. fortsæt procentdel:",
|
||||
"LabelMinResumePercentageHelp": "Medier anses om ikke afspillet, hvis de stoppes inden denne tid.",
|
||||
"LabelMinResumeDurationHelp": "Den korteste videolængde i sekunder, der gemmer afspilningsplacering og giver dig mulighed for at genoptage.",
|
||||
"LabelMinResumePercentage": "Minimal fortsæt procentdel:",
|
||||
"LabelMinResumePercentageHelp": "Medier anses som ikke afspillede, hvis de stoppes inden denne tid.",
|
||||
"LabelMinScreenshotDownloadWidth": "Minimum skærmbillede bredde:",
|
||||
"LabelModelDescription": "Modelbeskrivelse",
|
||||
"LabelModelName": "Modelnavn",
|
||||
|
@ -548,10 +548,10 @@
|
|||
"LabelMonitorUsers": "Overvåg aktivitet fra:",
|
||||
"LabelMovieCategories": "Filmkategorier:",
|
||||
"LabelMoviePrefix": "Film-præfiks:",
|
||||
"LabelMoviePrefixHelp": "Angiv venligst her hvis der tilføjes et præfiks til filmtitler, så Jellyfin kan håndtere det korrekt.",
|
||||
"LabelMoviePrefixHelp": "Angiv venligst her hvis der tilføjes et præfiks til filmtitler, så serveren kan håndtere det korrekt.",
|
||||
"LabelMovieRecordingPath": "Film afspilningssti (valgfri):",
|
||||
"LabelMusicStreamingTranscodingBitrate": "Bitrate for musiktranskodning:",
|
||||
"LabelMusicStreamingTranscodingBitrateHelp": "Angiv en maksimal bitrate når der streames musik",
|
||||
"LabelMusicStreamingTranscodingBitrateHelp": "Angiv en maksimal bitrate når der streames musik.",
|
||||
"LabelName": "Navn:",
|
||||
"LabelNewName": "Nyt navn:",
|
||||
"LabelNewPassword": "Ny kode:",
|
||||
|
@ -590,10 +590,10 @@
|
|||
"LabelProtocol": "Protokol:",
|
||||
"LabelProtocolInfo": "Protokolinformation:",
|
||||
"LabelProtocolInfoHelp": "Den værdi der bruges til svar på GetProtocolInfo-forespørgsler fra enheden.",
|
||||
"LabelPublicHttpPort": "Offentligt http portnummer:",
|
||||
"LabelPublicHttpPortHelp": "Det offentlige portnummer som bliver knyttet til det lokale http portnummer.",
|
||||
"LabelPublicHttpsPort": "Offentligt https portnummer:",
|
||||
"LabelPublicHttpsPortHelp": "Det offentlige portnummer som bliver knyttet til det lokale https portnummer.",
|
||||
"LabelPublicHttpPort": "Offentligt HTTP-portnummer:",
|
||||
"LabelPublicHttpPortHelp": "Det offentlige portnummer som bliver knyttet til det lokale HTTP-portnummer.",
|
||||
"LabelPublicHttpsPort": "Offentligt HTTPS portnummer:",
|
||||
"LabelPublicHttpsPortHelp": "Det offentlige portnummer som bliver knyttet til det lokale HTTPS portnummer.",
|
||||
"LabelReadHowYouCanContribute": "Lær hvordan du kan bidrage.",
|
||||
"LabelRecord": "Optag:",
|
||||
"LabelRecordingPath": "Standard afspilningssti:",
|
||||
|
@ -614,7 +614,7 @@
|
|||
"LabelSerialNumber": "Serienummer",
|
||||
"LabelSeriesRecordingPath": "Serier afspilningssti (valgfri):",
|
||||
"LabelServerHost": "Vært:",
|
||||
"LabelServerHostHelp": "F. eks: 192.168.1.100 eller https://myserver.com",
|
||||
"LabelServerHostHelp": "F. eks: 192.168.1.100:8096 eller https://myserver.com",
|
||||
"LabelSimultaneousConnectionLimit": "samtidige stream begrænsning:",
|
||||
"LabelSkipIfAudioTrackPresent": "Undlad hvis standardlydsporet er det samme sprog",
|
||||
"LabelSkipIfAudioTrackPresentHelp": "Angiv ikke dette for at sikre at alle videoer har undertekster, uanset hvilket sprog lydsporet anvender.",
|
||||
|
@ -647,7 +647,7 @@
|
|||
"LabelTranscodingTempPathHelp": "Definér en bugerdefineret sti til transkodede filer til klienter. Lad den stå tom for at bruge standardmappen i serverens datamappe.",
|
||||
"LabelTranscodingTemporaryFiles": "Midlertidige filer til omkodning:",
|
||||
"LabelTranscodingThreadCount": "Antal af omkodningstråde:",
|
||||
"LabelTranscodingThreadCountHelp": "Vælg det maksimale antal af tråde der bruges under omkodning. Reduktion af antallet af tråde sænker cpu-forbrug, men resulterer muligvis i at konverteringer ikke foregår hurtigt nok til en jævn afspilning.",
|
||||
"LabelTranscodingThreadCountHelp": "Vælg det maksimale antal af tråde der bruges under transcoding. Reduktion af antallet af tråde sænker CPU-forbrug, men resulterer muligvis i at konverteringer ikke foregår hurtigt nok til en jævn afspilning.",
|
||||
"LabelTriggerType": "Udløsertype:",
|
||||
"LabelTunerIpAddress": "IP-adresse for Tuner:",
|
||||
"LabelTunerType": "Tunertype:",
|
||||
|
@ -707,37 +707,37 @@
|
|||
"MessageConfirmRemoveMediaLocation": "Er du sikker på du ønsker at fjerne denne lokalisation?",
|
||||
"MessageConfirmRestart": "Er du sikker på du ønsker at genstarte Jellyfin?",
|
||||
"MessageConfirmRevokeApiKey": "Er du sikker på du ønsker at invalidere denne api nøgle? Applikationens forbindelse til Jellyfin vil blive afbrudt øjeblikkeligt.",
|
||||
"MessageConfirmShutdown": "Er du sikker på du ønsker at lukke Jellyfin?",
|
||||
"MessageConfirmShutdown": "Er du sikker på du ønsker at slukke for serveren?",
|
||||
"MessageContactAdminToResetPassword": "Kontakt venligst din systemadministrator for at nulstille din adgangskode.",
|
||||
"MessageCreateAccountAt": "Opret en konto hos {0}",
|
||||
"MessageDeleteTaskTrigger": "Er du sikker på du ønsker at slette denne task trigger?",
|
||||
"MessageDirectoryPickerBSDInstruction": "For BSD skal du muligvis konfigurere lager i dit FreeNAS Jail, før Jellyfin kan tilgå det.",
|
||||
"MessageDirectoryPickerInstruction": "Netværksstier kan indtastes manuelt i tilfælde af at netværksknappen ikke kan lokalisere dine enheder. Foreksempel, {0} eller {1}.",
|
||||
"MessageDirectoryPickerLinuxInstruction": "For Linux på Arch Linux, CentOS, Debian, Fedora, OpenSuse eller Ubuntu skal du give Jellyfin-systembrugeren minimum læseadgang til dine lagerlokationer.",
|
||||
"MessageDirectoryPickerLinuxInstruction": "For Linux på Arch Linux, CentOS, Debian, Fedora, openSUSE eller Ubuntu, skal du give servicebrugeren mindst læseadgang til dine lagerpladser.",
|
||||
"MessageDownloadQueued": "Download sat i kø.",
|
||||
"MessageEnablingOptionLongerScans": "Aktivering af denne indstilling kan resultere i væsentlig længere biblioteks skan.",
|
||||
"MessageFileReadError": "Der opstod en fejl i forsøget på at læse filen.",
|
||||
"MessageForgotPasswordFileCreated": "Den følgende fil er blevet oprettet på din server og indeholder instruktioner vedrørende hvordan du skal fortsætte:",
|
||||
"MessageForgotPasswordInNetworkRequired": "Prøv igen inde i dit hjemmenetværk for at igangsætte nulstilling af din adgangskode.",
|
||||
"MessageInstallPluginFromApp": "Dette plugin skal være installeret inde i den app du ønsker at benytte det fra.",
|
||||
"MessageInstallPluginFromApp": "Dette plugin skal installeres fra den app, du har til hensigt at bruge det i.",
|
||||
"MessageInvalidForgotPasswordPin": "En ugyldig eller udløbet pinkode blev indtastet. Prøv igen.",
|
||||
"MessageInvalidUser": "Ukendt brugernavn eller adgangskode. Prøv igen.",
|
||||
"MessageItemSaved": "Element gemt.",
|
||||
"MessageItemsAdded": "Emne tilføjet.",
|
||||
"MessageLeaveEmptyToInherit": "Efterlad tom for at arve indstillinger fra en overliggende post eller den globale standardværdi.",
|
||||
"MessageLeaveEmptyToInherit": "Lad være tom for at arve indstillinger fra et overordnet element eller den globale standardværdi.",
|
||||
"MessageNoAvailablePlugins": "Ingen tilgængelige plugins.",
|
||||
"MessageNoMovieSuggestionsAvailable": "Ingen filmforslag er tilgængelige. Begynd at se og vurder dine film, og kom tilbage for at se dine anbefalinger.",
|
||||
"MessageNoPluginsInstalled": "Du har ingen plugins installeret.",
|
||||
"MessageNoTrailersFound": "Ingen trailere fundet. Installer Trailer kanalen for at tilføje et bibliotek med trailere fra internettet.",
|
||||
"MessageNothingHere": "Her er ingenting.",
|
||||
"MessagePasswordResetForUsers": "Adgangskoder blev fjernet for følgende brugere. For at logge ind, skal der benyttes en blank adgangskode.",
|
||||
"MessagePasswordResetForUsers": "Følgende brugere har fået nulstillet deres adgangskoder. De kan nu logge på med de pinkoder, der blev brugt til at udføre nulstillingen.",
|
||||
"MessagePleaseEnsureInternetMetadata": "Sørg venligst for at hentning af metadata fra internettet er aktiveret.",
|
||||
"MessagePleaseWait": "Vent venligst. Dette kan tage et minut.",
|
||||
"MessagePluginConfigurationRequiresLocalAccess": "For at konfigurerer dette plugin log da venligst direkte ind på din lokale server.",
|
||||
"MessagePluginInstallDisclaimer": "Plugins fremstillet af medlemmer fra Jellyfin-fællesskabet er en alle tiders måde at forbedre din oplevelse af Jellyfin med yderligere features og fordele. Før installation, bedes du venligst være opmærksom på de effekter de kan have på din Jellyfin Server; så som lange scantider på biblioteker, yderligere baggrundsbehandling og forringet systemstabilitet.",
|
||||
"MessageReenableUser": "Se nedenfor om genaktivering",
|
||||
"MessageSettingsSaved": "Indstillinger er gemt.",
|
||||
"MessageTheFollowingLocationWillBeRemovedFromLibrary": "Følgende medielokationer bliver fjernet fra dit Jellyfin-bibliotek:",
|
||||
"MessageTheFollowingLocationWillBeRemovedFromLibrary": "Følgende medieplaceringer fjernes fra dit bibliotek:",
|
||||
"MessageUnableToConnectToServer": "Vi kan ikke forbinde til den valgte server på nuværende tidspunkt. Sikrer dig venligst at serveren kører og prøv igen.",
|
||||
"MessageUnsetContentHelp": "Indhold vil blive vist som almindelige mapper. For det bedste resultat benyt metadata manageren til at vælge indholdstypen i undermapper.",
|
||||
"MessageYouHaveVersionInstalled": "Du har version {0} installeret.",
|
||||
|
@ -747,10 +747,10 @@
|
|||
"MinutesBefore": "minutter før",
|
||||
"Monday": "Mandag",
|
||||
"MoreFromValue": "Mere fra {0}",
|
||||
"MoreUsersCanBeAddedLater": "Flere brugere kan tilføjes senere i betjeningspanelet.",
|
||||
"MoreUsersCanBeAddedLater": "Flere brugere kan tilføjes senere fra dashboardet.",
|
||||
"MoveLeft": "Flyt mod venstre",
|
||||
"MoveRight": "Flyt mod højre",
|
||||
"MovieLibraryHelp": "Gennemse {0}Jellyfin film navngivningsguiden{1}.",
|
||||
"MovieLibraryHelp": "Gennemse {0}film navngivningsguiden{1}.",
|
||||
"Movies": "Film",
|
||||
"Mute": "Afbryd lyd",
|
||||
"MySubtitles": "Mine Undertekster",
|
||||
|
@ -782,7 +782,7 @@
|
|||
"OptionAllowMediaPlaybackTranscodingHelp": "At begrænse adgang til omkodning kan forårsage afspilningsfejl i Jellyfin apps på grund af usupporterede medie formater.",
|
||||
"OptionAllowRemoteControlOthers": "Tillad fjernstyring af andre brugere",
|
||||
"OptionAllowRemoteSharedDevices": "Tillad fjernstyring af delte enheder",
|
||||
"OptionAllowRemoteSharedDevicesHelp": "DLNA-enheder er delte indtil en bruger begynder at bruge den.",
|
||||
"OptionAllowRemoteSharedDevicesHelp": "DLNA-enheder betragtes som delt, indtil en bruger begynder at kontrollere dem.",
|
||||
"OptionAllowSyncTranscoding": "Tillad medie hentning og synkronisering der kræver omkodning",
|
||||
"OptionAllowUserToManageServer": "Tillad denne bruger at administrere serveren",
|
||||
"OptionAllowVideoPlaybackRemuxing": "Tillad videoafspilning som kræver konvertering uden omkodning",
|
||||
|
@ -811,13 +811,13 @@
|
|||
"OptionDisableUserHelp": "Hvis deaktiveret vil serveren ikke tillade forbindelser fra denne bruger. Eksisterende forbindelser vil blive afbrudt øjeblikkeligt.",
|
||||
"OptionDislikes": "Ikke-Lide",
|
||||
"OptionDisplayFolderView": "Få vist en mappevisning til at se enkle mediemapper",
|
||||
"OptionDisplayFolderViewHelp": "Hvis aktiveret, vil Jellyfin apps vise en Mappekategori ved siden af dine mediebiblioteker. Dette er brugbart, hvis du vil have vist enkle mappevisninger.",
|
||||
"OptionDisplayFolderViewHelp": "Vis mapper sammen med dine andre mediebiblioteker. Dette kan være nyttigt, hvis du gerne vil have en almindelig mappevisning.",
|
||||
"OptionDownloadArtImage": "Billede",
|
||||
"OptionDownloadBackImage": "Bagside",
|
||||
"OptionDownloadBoxImage": "Boks",
|
||||
"OptionDownloadDiscImage": "Disk",
|
||||
"OptionDownloadImagesInAdvance": "Download billeder på forhånd",
|
||||
"OptionDownloadImagesInAdvanceHelp": "Som standard downloades billeder kun når de anmodes af en Jellyfin app. Aktiver denne indstilling for at downloade alle billeder på forhånd, i mens nyt medie importeres. Dette resulterer muligvis i længere scanninger af bibliotek.",
|
||||
"OptionDownloadImagesInAdvanceHelp": "Som standard downloades de fleste billeder kun, når de anmodes fra en Jellyfin-app. Aktivér denne mulighed for at downloade alle billeder på forhånd, da nye medier importeres. Dette kan forårsage betydeligt længere biblioteksscanninger.",
|
||||
"OptionDownloadPrimaryImage": "Primær",
|
||||
"OptionDownloadThumbImage": "Miniature",
|
||||
"OptionDvd": "DVD",
|
||||
|
@ -826,7 +826,7 @@
|
|||
"OptionEnableAccessToAllChannels": "Tillad adgang til alle kanaler",
|
||||
"OptionEnableAccessToAllLibraries": "Tillad adgang til alle biblioteker",
|
||||
"OptionEnableExternalContentInSuggestions": "Aktiver eksternt indhold i anbefalinger",
|
||||
"OptionEnableExternalContentInSuggestionsHelp": "Tillad at internet-trailers og live-tv-programmer bliver inkluderet i det anbefalede indhold.",
|
||||
"OptionEnableExternalContentInSuggestionsHelp": "Tillad at internet-trailers og live TV programmer bliver inkluderet i det anbefalede indhold.",
|
||||
"OptionEnableForAllTuners": "Aktiver for alle tuner-enheder",
|
||||
"OptionEnableM2tsMode": "Aktiver M2ts tilstand",
|
||||
"OptionEnableM2tsModeHelp": "Aktiver M2ts tilstand når der omkodes til mpegts.",
|
||||
|
@ -844,8 +844,8 @@
|
|||
"OptionHasThemeVideo": "Temavideo",
|
||||
"OptionHideUser": "Vis ikke denne bruger på loginsiden",
|
||||
"OptionHideUserFromLoginHelp": "Nyttigt for private kontoer eller skjulte administratorkontoer. Brugeren skal logge ind ved at skive sit brugernavn og adgangskode.",
|
||||
"OptionHlsSegmentedSubtitles": "Hls segmented undertekster",
|
||||
"OptionHomeVideos": "Hjemmevideoer og billeder",
|
||||
"OptionHlsSegmentedSubtitles": "HLS segmenterede undertekster",
|
||||
"OptionHomeVideos": "Billeder",
|
||||
"OptionIgnoreTranscodeByteRangeRequests": "Ignorer forespørgsler vedrørende transcode byte interval",
|
||||
"OptionIgnoreTranscodeByteRangeRequestsHelp": "Hvis aktiveret vil disse forespørgsler blive efterkommet, men byte range headeren ignoreret.",
|
||||
"OptionImdbRating": "IMDB bedømmelse",
|
||||
|
@ -883,7 +883,7 @@
|
|||
"OptionThursday": "Torsdag",
|
||||
"OptionTrackName": "Nummerets navn",
|
||||
"OptionTuesday": "Tirsdag",
|
||||
"OptionTvdbRating": "Tvdb bedømmelse",
|
||||
"OptionTvdbRating": "TVDB bedømmelse",
|
||||
"OptionUnairedEpisode": "Ikke sendte episoder",
|
||||
"OptionUnplayed": "Ikke afspillet",
|
||||
"OptionWakeFromSleep": "Vågner fra dvale",
|
||||
|
@ -893,9 +893,9 @@
|
|||
"OptionWeekly": "Ugentlig",
|
||||
"OriginalAirDateValue": "Originalt sendt: {0}",
|
||||
"Overview": "Overblik",
|
||||
"PackageInstallCancelled": "{0} installation afbrudt.",
|
||||
"PackageInstallCompleted": "{0} installation udført.",
|
||||
"PackageInstallFailed": "{0} installationen mislykkedes.",
|
||||
"PackageInstallCancelled": "{0} (version {1}) installation annulleret.",
|
||||
"PackageInstallCompleted": "{0} (version {1}) installation udført.",
|
||||
"PackageInstallFailed": "{0} (version {1}) installationen mislykkedes.",
|
||||
"ParentalRating": "Parental Rating",
|
||||
"PasswordMatchError": "Adgangskode og bekræft adgangskode skal være ens.",
|
||||
"PasswordResetComplete": "Adgangskoden er blevet nulstillet.",
|
||||
|
@ -913,7 +913,7 @@
|
|||
"Played": "Afspillet",
|
||||
"PleaseAddAtLeastOneFolder": "Tilføj venligst som minimum en enkelt mappe til dette bibliotek ved at klikke på Tilføj-knappen.",
|
||||
"PleaseConfirmPluginInstallation": "Klik venligst OK for at bekræfte at du har læst ovenstående og ønsker at fortsætte med installationen af plugin.",
|
||||
"PleaseEnterNameOrId": "Indtast venligst et navn eller eksternt Id.",
|
||||
"PleaseEnterNameOrId": "Indtast venligst et navn eller eksternt ID.",
|
||||
"PleaseRestartServerName": "Genstart venligst Jellyfin Server - {0}.",
|
||||
"PleaseSelectTwoItems": "Vælg venligst mindst to elementer.",
|
||||
"PluginInstalledMessage": "Plugin blev installeret med success. Jellyfin serveren skal genstartes for at aktivere det.",
|
||||
|
@ -1025,7 +1025,7 @@
|
|||
"TabProfiles": "Profiler",
|
||||
"TabRecordings": "Optagelser",
|
||||
"TabResponses": "Svar",
|
||||
"TabResumeSettings": "Indstillinger for Genoptag",
|
||||
"TabResumeSettings": "Genoptag",
|
||||
"TabScheduledTasks": "Planlagte opgaver",
|
||||
"TabSeries": "Serier",
|
||||
"TabSettings": "Indstillinger",
|
||||
|
@ -1044,13 +1044,13 @@
|
|||
"TitlePlayback": "Afspilning",
|
||||
"TrackCount": "{0} numre",
|
||||
"Tuesday": "Tirsdag",
|
||||
"TvLibraryHelp": "Gennemse {0}Jellyfin TV navngivningsguiden{1}.",
|
||||
"TvLibraryHelp": "Gennemgå {0} TV-navneguiden {1}.",
|
||||
"UninstallPluginConfirmation": "Er du sikker på du vil afinstallere {0}?",
|
||||
"UninstallPluginHeader": "Afinstaller plugin",
|
||||
"Unmute": "Genoptag lyd",
|
||||
"Unrated": "Ingen bedømmelse",
|
||||
"UserAgentHelp": "Angiv en brugerdefineret user-agent http header, hvis nødvendigt.",
|
||||
"UserProfilesIntro": "Jellyfin har indbygget understøttelse af brugerprofiler. Dette giver hver bruger sine egne indstillinger for visning, afspilningsstatus og forældrekontrol.",
|
||||
"UserAgentHelp": "Angiv en brugerdefineret bruger-agent HTTP-header.",
|
||||
"UserProfilesIntro": "Jellyfin inkluderer support til brugerprofiler med granuleret displayindstillinger, afspilningstilstand og forældrekontrol.",
|
||||
"ValueAlbumCount": "{0} album",
|
||||
"ValueAudioCodec": "Lyd codec: {0}",
|
||||
"ValueConditions": "Forhold: {0}",
|
||||
|
@ -1072,17 +1072,17 @@
|
|||
"ViewPlaybackInfo": "Vis afspilnings information",
|
||||
"Wednesday": "Onsdag",
|
||||
"WelcomeToProject": "Velkommen til Jellyfin!",
|
||||
"WizardCompleted": "Det er alt vi behøver for nu. Jellyfin er begyndt at indsamle information omkring dit mediebibliotek. Tjek nogle af vores apps og klik derefter på <b>Færdig</b> for at se <b>Server betjeningspanelet</b>.",
|
||||
"WizardCompleted": "Det er alt, hvad vi har brug for nu. Jellyfin er begyndt at indsamle information om dit mediebibliotek. Se nogle af vores apps, og klik derefter på <b>Udfør</b> for at se <b>Dashboard</b>.",
|
||||
"Writer": "Forfatter",
|
||||
"XmlDocumentAttributeListHelp": "Disse attributter bliver tilføjet til rodelementet i alle XML svar.",
|
||||
"XmlDocumentAttributeListHelp": "Disse attributter anvendes til rodelementet i hvert XML-svar.",
|
||||
"XmlTvKidsCategoriesHelp": "Programmer med disse kategorier bliver vist som programmer for børn. Adskil flere med '|'.",
|
||||
"XmlTvMovieCategoriesHelp": "Programmer med disse kategorier bliver vist som film. Adskil flere med '|'.",
|
||||
"XmlTvNewsCategoriesHelp": "Programmer med disse kategorier bliver vist som nyhedsprogrammer. Adskil flere med '|'.",
|
||||
"XmlTvPathHelp": "En sti til en xml tv-fil. Jellyfin læser denne fil og kontrollerer periodisk for opdateringer. Du er ansvarlig for at oprette og opdatere filen.",
|
||||
"XmlTvPathHelp": "En sti til en XMLTV fil. Jellyfin læser denne fil og kontrollerer periodisk for opdateringer. Du er ansvarlig for at oprette og opdatere filen.",
|
||||
"XmlTvSportsCategoriesHelp": "Programmer med disse kategorier bliver vist som sportsprogrammer. Adskil flere med '|'.",
|
||||
"Yesterday": "I går",
|
||||
"AirDate": "Luftdata",
|
||||
"Albums": "Album",
|
||||
"Albums": "Albums",
|
||||
"Artists": "Kunstnere",
|
||||
"Books": "Bøger",
|
||||
"Collections": "Samlinger",
|
||||
|
@ -1092,15 +1092,15 @@
|
|||
"Absolute": "Absolut",
|
||||
"AccessRestrictedTryAgainLater": "Adgang er begrænset. Prøv igen senere.",
|
||||
"Aired": "Blev sendt",
|
||||
"AllComplexFormats": "Alle komplekse formater (ASS, SSA, VOBSUB, PGS, SUB/IDX osv.)",
|
||||
"AllComplexFormats": "Alle Komplekse Formater (ASS, SSA, VOBSUB, PGS, SUB,IDX osv.)",
|
||||
"AllLanguages": "Alle sprog",
|
||||
"AlwaysPlaySubtitles": "Afspil altid undertekster",
|
||||
"AlwaysPlaySubtitles": "Afspil Altid",
|
||||
"AlwaysPlaySubtitlesHelp": "Undertekster, der matcher dine sprogindstillinger, vil altid blive indlæst uanset lydsprog.",
|
||||
"HeaderLiveTV": "Live-TV",
|
||||
"Shows": "Serier",
|
||||
"Songs": "Sange",
|
||||
"AndroidUnlockRestoreHelp": "For at gendanne dit tidligere køb skal du sørge for, at du er logget ind på enheden med den samme Google- eller Amazon-konto, som oprindeligt gjorde købet. Sørg for, at app store er aktiveret og ikke begrænset af forældrekontrol, og sørg for, at du har en aktiv internetforbindelse. Du skal kun gøre dette én gang for at gendanne dit tidligere køb.",
|
||||
"AnyLanguage": "Ethvert sprog",
|
||||
"AnyLanguage": "Hvilken som helst sprog",
|
||||
"Art": "Kunst",
|
||||
"Ascending": "Stigende",
|
||||
"AudioBitDepthNotSupported": "Lyd bit dybde ikke understøttet",
|
||||
|
@ -1121,7 +1121,7 @@
|
|||
"Blacklist": "Blackliste",
|
||||
"Box": "Boks",
|
||||
"BoxRear": "Boks (bagside)",
|
||||
"BurnSubtitlesHelp": "Bestemmer om serveren skal brænde underteksterne ind i videoen når den konverterer baseret på undertekstformatet. Det vil øge serverens ydeevne ikke at brænde underteksterne i filen. Vælg Automatisk for at brænde billedbaserede formater (VOBSUB, PGS, SUB/IDX, osv) og nogle ASS/SSA undertekster.",
|
||||
"BurnSubtitlesHelp": "Bestemmer om serveren skal brænde undertekster, når der afspilles transcoding videoer. Undgå dette vil forbedre ydelsen meget. Vælg Auto for at brænde billedbaserede formater (VOBSUB, PGS, SUB, IDX) og bestemte ASS- eller SSA-undertekster.",
|
||||
"ButtonFilter": "Filter",
|
||||
"ButtonGuide": "Vejledning",
|
||||
"ButtonInfo": "Information",
|
||||
|
@ -1174,14 +1174,14 @@
|
|||
"DisplayInOtherHomeScreenSections": "Visning på hjemmeskærm sektioner som seneste medier og se videre",
|
||||
"DisplayMissingEpisodesWithinSeasons": "Vis manglende afsnit inde i sæsoner",
|
||||
"DisplayMissingEpisodesWithinSeasonsHelp": "Dette skal også være aktiveret for TV biblioteker i serverens indstillinger.",
|
||||
"DisplayModeHelp": "Vælg skærmtypen du kører Jellyfin på.",
|
||||
"DisplayModeHelp": "Vælg det ønskede tema for grænsefladen.",
|
||||
"Down": "Ned",
|
||||
"DownloadItemLimitHelp": "Valgfri. Sæt en begrænsning på antallet af ting der vil blive hentet.",
|
||||
"Downloaded": "Hentet",
|
||||
"DownloadingDots": "Henter...",
|
||||
"Downloads": "Hentninger",
|
||||
"DownloadsValue": "{0} hentninger",
|
||||
"DropShadow": "Drop skygge",
|
||||
"DropShadow": "Drop Skygge",
|
||||
"DvrFeatureDescription": "Tidsindstil individuelle TV optagelser, serie optagelser, og mere med Jellyfin DVR.",
|
||||
"EditMetadata": "Redigér metadata",
|
||||
"EnableBackdrops": "Baggrundsbilleder",
|
||||
|
@ -1201,7 +1201,7 @@
|
|||
"ErrorAddingJellyfinConnectAccount1": "Der skete en fejl ved tilføjelsen af Jellyfin Connect kontoen. Har du lavet en Jellyfin konto? Registrer dig på {0}.",
|
||||
"ErrorAddingJellyfinConnectAccount2": "Hvis du stadig har et problem, så send venligst en email til {0} fra den email adresse tilknyttet Jellyfin kontoen.",
|
||||
"ErrorDeletingItem": "Der skete en fejl ved sletningen af mediet fra Jellyfin Server. Tjek venligst at Jellyfin Server har skrive adgang til mediemappen og prøv igen.",
|
||||
"ExtraLarge": "Ekstra stor",
|
||||
"ExtraLarge": "Ekstra Stor",
|
||||
"Extras": "Bonusmateriale",
|
||||
"Features": "Funktioner",
|
||||
"Filters": "Filtre",
|
||||
|
@ -1270,18 +1270,18 @@
|
|||
"LabelArtist": "Kunstner",
|
||||
"LabelAudio": "Lyd",
|
||||
"LabelBitrateMbps": "Bitrate (Mbps):",
|
||||
"LabelBlockContentWithTags": "Blokér filer med mærkerne:",
|
||||
"LabelBlockContentWithTags": "Blokér filer med etiketter:",
|
||||
"LabelBurnSubtitles": "Brænd undertekster:",
|
||||
"LabelCache": "Cache:",
|
||||
"LabelCertificatePassword": "Adgangskode til certifikat:",
|
||||
"LabelCertificatePasswordHelp": "Hvis dit certifikat kræver en adgangskode, skriv det benligst her.",
|
||||
"LabelCertificatePasswordHelp": "Hvis dit certifikat kræver en adgangskode, skriv det venligst her.",
|
||||
"LabelConvertTo": "Konvertér til:",
|
||||
"LabelDashboardTheme": "Server dashboard tema:",
|
||||
"LabelDateTimeLocale": "Dato og tid område:",
|
||||
"LabelDefaultScreen": "Standard skærm:",
|
||||
"LabelDisplayLanguage": "Visningssprog:",
|
||||
"LabelDisplayLanguageHelp": "Oversættelse af Jellyfin er et vedvarende projekt.",
|
||||
"LabelDisplayMode": "Visningsmodus:",
|
||||
"LabelDisplayMode": "Visningstilstand:",
|
||||
"LabelDropShadow": "Drop skygge:",
|
||||
"LabelDynamicExternalId": "{0} ID:",
|
||||
"LabelEmail": "Email:",
|
||||
|
@ -1297,7 +1297,7 @@
|
|||
"LabelMaxBitrate": "Maks bitrate:",
|
||||
"LabelMaxChromecastBitrate": "Chromecast streaming kvalitet:",
|
||||
"LabelMetadata": "Metadata:",
|
||||
"LabelModelUrl": "Model link",
|
||||
"LabelModelUrl": "Model URL",
|
||||
"LabelPreferredSubtitleLanguage": "Foretrukket undertekst sprog:",
|
||||
"LabelProfileCodecs": "Codecs:",
|
||||
"LabelProfileContainer": "Beholder:",
|
||||
|
@ -1378,7 +1378,7 @@
|
|||
"Off": "Fra",
|
||||
"OnlyForcedSubtitles": "Kun tvungne undertekster",
|
||||
"OnlyForcedSubtitlesHelp": "Kun undertekster markeret som tvungne vil blive indlæst.",
|
||||
"OnlyImageFormats": "Kun billedformater (VOBSUB, PGS, SUB, etc)",
|
||||
"OnlyImageFormats": "Kun billedformater (VOBSUB, PGS, SUB)",
|
||||
"Option2Player": "2+",
|
||||
"Option3D": "3D",
|
||||
"Option3Player": "3+",
|
||||
|
@ -1420,7 +1420,7 @@
|
|||
"PlayCount": "Afspilninger",
|
||||
"PlayNext": "Afspil næste",
|
||||
"PlayNextEpisodeAutomatically": "Afspil næste afsnit automatisk",
|
||||
"PlaybackErrorNoCompatibleStream": "Ingen kompatible streams er tilgængelige. Prøv venligst igen senere eller kontakt din system administrator for detaljer.",
|
||||
"PlaybackErrorNoCompatibleStream": "Denne klient er ikke kompatibel med medierne, og serveren sender ikke et kompatibelt medieformat.",
|
||||
"PlaybackErrorNotAllowed": "Du har ikke adgang til at afspille dette indhold. Kontakt venligst system administratoren for detaljer.",
|
||||
"PlaybackErrorPlaceHolder": "Indlæs venligst disken for at afspille denne video.",
|
||||
"PlaybackSettings": "Afspilningsindstillinger",
|
||||
|
@ -1436,7 +1436,7 @@
|
|||
"RefFramesNotSupported": "Antal af video reference billeder ikke understøttet",
|
||||
"RefreshMetadata": "Genopfrisk metadata",
|
||||
"RepeatAll": "Gentag alle",
|
||||
"RepeatMode": "Gentagelsesmode",
|
||||
"RepeatMode": "Gentagelses tilstand",
|
||||
"RepeatOne": "Gentag én",
|
||||
"RestartPleaseWaitMessage": "Vent venligst mens Jellyfin Server lukker og genstarter. Dette kan tage et minut eller to.",
|
||||
"RunAtStartup": "Kør ved opstart",
|
||||
|
@ -1444,7 +1444,7 @@
|
|||
"Schedule": "Tidsplan",
|
||||
"Screenshot": "Skærmbillede",
|
||||
"SecondaryAudioNotSupported": "Lydspor skift ikke understøttet",
|
||||
"SeriesDisplayOrderHelp": "Sortér afsnit efter sende dato, dvd rækkefølge eller obsolut nummering.",
|
||||
"SeriesDisplayOrderHelp": "Sortér episoder efter luftdato, DVD-orden eller absolut nummerering.",
|
||||
"ShowTitle": "Vis titel",
|
||||
"ShowYear": "Vis år",
|
||||
"Small": "Lille",
|
||||
|
@ -1532,5 +1532,110 @@
|
|||
"LabelServerName": "Server navn:",
|
||||
"LabelUserLoginAttemptsBeforeLockout": "Fejlede loginforsøg før bruger lukkes ude:",
|
||||
"HeaderRestartingServer": "Genstarter Server",
|
||||
"ButtonAddImage": "Tilføj billede"
|
||||
"ButtonAddImage": "Tilføj billede",
|
||||
"AllowFfmpegThrottlingHelp": "Når en omkodning eller remux kommer langt nok foran den nuværende afspildings position, pauses processen så der bruges færre resurser. Dette er mest brugbart når man ikke springer i filmen. Slå dette fra hvis du har problemer med playback.",
|
||||
"AllowFfmpegThrottling": "Begræns Omkodning",
|
||||
"AlbumArtist": "Album Artist",
|
||||
"Album": "Album",
|
||||
"EveryHour": "Hver time",
|
||||
"EveryXMinutes": "Hvert {0} minut",
|
||||
"OnWakeFromSleep": "Når du vågner fra søvn",
|
||||
"WeeklyAt": "{0}s ved {1}",
|
||||
"DailyAt": "Dagligt kl. {0}",
|
||||
"LastSeen": "Sidst set {0}",
|
||||
"PersonRole": "som {0}",
|
||||
"ListPaging": "{0}-{1} af {2}",
|
||||
"WriteAccessRequired": "Jellyfin Server kræver skriveadgang til denne mappe. Sørg for skriveadgang, og prøv igen.",
|
||||
"PathNotFound": "Stien blev ikke fundet. Sørg for, at stien er gyldig, og prøv igen.",
|
||||
"YadifBob": "YADIF Bob",
|
||||
"Yadif": "YADIF",
|
||||
"Track": "Spor",
|
||||
"TabNetworking": "Netværk",
|
||||
"SubtitleOffset": "Undertekst Offset",
|
||||
"SelectAdminUsername": "Vælg et brugernavn til administrator kontoen.",
|
||||
"Season": "Sæson",
|
||||
"ReleaseGroup": "Release Group",
|
||||
"Premiere": "Premiere",
|
||||
"PreferEmbeddedEpisodeInfosOverFileNames": "Foretrækker integreret episode information frem for filnavne",
|
||||
"PreferEmbeddedEpisodeInfosOverFileNamesHelp": "Dette bruger episode informationen fra de integrerede metadata, hvis den er tilgængelig.",
|
||||
"PlaybackData": "Afspilningsdata",
|
||||
"Person": "Person",
|
||||
"PasswordResetProviderHelp": "Vælg en leverandør af nulstil adgangskode, der skal bruges, når denne bruger anmoder om en nulstilling af adgangskode",
|
||||
"OtherArtist": "Anden kunstner",
|
||||
"OptionThumbCard": "Thumb card",
|
||||
"OptionThumb": "Thumb",
|
||||
"OptionRandom": "Tilfældig",
|
||||
"OptionPosterCard": "Plakatkort",
|
||||
"OptionPoster": "Plakat",
|
||||
"OptionLoginAttemptsBeforeLockoutHelp": "En værdi på nul betyder at arve standard for tre forsøg for normale brugere og fem for administratorer. Indstilling af dette til -1 vil deaktivere funktionen.",
|
||||
"OptionLoginAttemptsBeforeLockout": "Bestemmer, hvor mange forkerte loginforsøg, der kan gøres, før lockout finder sted.",
|
||||
"OptionList": "Liste",
|
||||
"OptionForceRemoteSourceTranscoding": "Tving transcoding af eksterne mediekilder (som LiveTV)",
|
||||
"NoCreatedLibraries": "Det ser ud til, at du ikke har oprettet nogen biblioteker endnu. {0} Vil du oprette en nu? {1}",
|
||||
"MusicVideo": "Musik Video",
|
||||
"MusicLibraryHelp": "Gennemgå {0} guide til navngivning af musik {1}.",
|
||||
"MusicArtist": "Musik Artist",
|
||||
"MusicAlbum": "Musik Album",
|
||||
"Movie": "Film",
|
||||
"MoreMediaInfo": "Medieinfo",
|
||||
"MessageNoServersAvailable": "Der er ikke fundet nogen servere ved hjælp af den automatiske serveropdagelse.",
|
||||
"MessageNoCollectionsAvailable": "Samlinger tillader dig at nyde personlige grupperinger af Film, Serier og Albums. Klik på + knappen for at skabe en samling.",
|
||||
"MessageConfirmAppExit": "Vil du afslutte?",
|
||||
"MediaInfoStreamTypeSubtitle": "Undertekst",
|
||||
"MediaInfoStreamTypeEmbeddedImage": "Indlejret billede",
|
||||
"MediaInfoStreamTypeAudio": "Lyd",
|
||||
"LaunchWebAppOnStartupHelp": "Åben web klienten i den standard web browser når serveren starter første gang. Dette vil ikke ske når restart server funktionen benyttes.",
|
||||
"LaunchWebAppOnStartup": "Åben webinterfacet når serveren startes",
|
||||
"LabelWeb": "Web:",
|
||||
"LabelVideoResolution": "Videoopløsning:",
|
||||
"LabelVideoBitrate": "Video bitrate:",
|
||||
"DashboardArchitecture": "Arkitektur: {0}",
|
||||
"DashboardOperatingSystem": "Styresystem: {0}",
|
||||
"DashboardServerName": "Server: {0}",
|
||||
"DashboardVersionNumber": "Version: {0}",
|
||||
"LabelTranscodingProgress": "Transcoding fremskridt:",
|
||||
"LabelTranscodingFramerate": "Transcoding framerate:",
|
||||
"LabelTranscodes": "Transcodes:",
|
||||
"LabelTranscodePath": "Transcode sti:",
|
||||
"LabelStreamType": "Stream type:",
|
||||
"LabelSonyAggregationFlags": "Sony aggregering flag:",
|
||||
"LabelSize": "Størrelse:",
|
||||
"EnableFastImageFadeInHelp": "Aktivér hurtigere fade-in-animation til indlæste billeder",
|
||||
"EnableFastImageFadeIn": "Hurtigt billede indtoning",
|
||||
"LabelPleaseRestart": "Ændringer vil træde i kraft efter web klienten er blevet genindlæst manuelt.",
|
||||
"LabelPlayMethod": "Afspilnings metode:",
|
||||
"LabelPlayerDimensions": "Afspillerdimensioner:",
|
||||
"LabelPlayer": "Afspiller:",
|
||||
"LabelPasswordResetProvider": "Udbyder til nulstilling as kodeord:",
|
||||
"LabelLibraryPageSizeHelp": "Indstiller mængden af genstande, der skal vises på en bibliotekside. Indstil til 0 for at deaktivere.",
|
||||
"LabelLibraryPageSize": "Biblioteks størrelse:",
|
||||
"LabelFolder": "Mappe:",
|
||||
"LabelBaseUrl": "Base URL:",
|
||||
"LabelBaseUrlHelp": "Du kan tilføje en speciel undermappe her for, at have adgang til serveren fra en mere unik URL.",
|
||||
"LabelDroppedFrames": "Tabte frames:",
|
||||
"LabelDeinterlaceMethod": "Konventerings metode:",
|
||||
"LabelCorruptedFrames": "Korrupte frames:",
|
||||
"LabelBitrate": "Bitrate:",
|
||||
"LabelAuthProvider": "Autentificeringsudbyder:",
|
||||
"LabelAudioSampleRate": "Lydeksempelfrekvens:",
|
||||
"LabelAudioCodec": "Lyd codec:",
|
||||
"LabelAudioChannels": "Lyd kanaler:",
|
||||
"LabelAudioBitrate": "Lyd bitrate:",
|
||||
"LabelAudioBitDepth": "Lyd bitdybde:",
|
||||
"HeaderFavoritePeople": "Foretrukne Personer",
|
||||
"HeaderFavoriteBooks": "Foretrukne Bøger",
|
||||
"FetchingData": "Henter yderligere data",
|
||||
"Episode": "Afsnit",
|
||||
"DeinterlaceMethodHelp": "Vælg hvilken konverteringsmulighed der skal bruges til transkodning af indhold.",
|
||||
"CopyStreamURLError": "Der skete en fejl med at kopiere URL'en.",
|
||||
"CopyStreamURLSuccess": "URL er kopiret succesfuldt.",
|
||||
"CopyStreamURL": "Kopir Stream URL",
|
||||
"ClientSettings": "Klient Indstillinger",
|
||||
"ButtonSplit": "Opdel",
|
||||
"BoxSet": "Box Set",
|
||||
"AuthProviderHelp": "Vælg en godkendelse udbyder, der skal bruges til at godkende denne brugers adgangskode.",
|
||||
"AskAdminToCreateLibrary": "Spørg en administrator om at oprette et bibliotek.",
|
||||
"Artist": "Artist",
|
||||
"EveryXHours": "Hver {0} time",
|
||||
"OnApplicationStartup": "Ved programstart"
|
||||
}
|
||||
|
|
|
@ -11,13 +11,13 @@
|
|||
"AddUser": "Benutzer anlegen",
|
||||
"AddUserByManually": "Lege einen lokalen User durch manuelle Eingabe der User-Informationen an.",
|
||||
"AddedOnValue": "{0} hinzugefügt",
|
||||
"AdditionalNotificationServices": "Schau im Pluginkatalog, um weitere Benachrichtigungsdienste zu installieren.",
|
||||
"AdditionalNotificationServices": "Durchsuche den Pluginkatalog, um weitere Benachrichtigungsdienste zu installieren.",
|
||||
"AirDate": "Erstausstrahlung",
|
||||
"Aired": "Ausgestrahlt",
|
||||
"Albums": "Alben",
|
||||
"All": "Alle",
|
||||
"AllChannels": "Alle Kanäle",
|
||||
"AllComplexFormats": "Alle komplexen Formate (ASS, SSA, VOBSUB, PGS, SUB/IDX, etc.)",
|
||||
"AllComplexFormats": "Alle komplexen Formate (ASS, SSA, VOBSUB, PGS, SUB/IDX)",
|
||||
"AllEpisodes": "Alle Folgen",
|
||||
"AllLanguages": "Alle Sprachen",
|
||||
"AllLibraries": "Alle Bibliotheken",
|
||||
|
@ -26,13 +26,13 @@
|
|||
"AllowMediaConversion": "Erlaube Medienkonvertierung",
|
||||
"AllowMediaConversionHelp": "Erlaube oder unterbinde Zugriff auf die Medienkonvertierung.",
|
||||
"AllowOnTheFlySubtitleExtraction": "Erlaube Untertitelextraktion \"on-the-fly\"",
|
||||
"AllowOnTheFlySubtitleExtractionHelp": "Eingebettete Untertitel können aus Videos extrahiert und im Textformat an Clients gesendet werden um die Videotranskodierung zu vermeiden. Auf manchen Systemen kann dieser Vorgang eine lange Zeit in Anspruch nehmen und die Videowiedergabe während der Extraktion unterbrochen werden. Deaktiviere diese Option um eingebettete Untertitel während der Videotranskodierung einbrennen zu lassen, wenn sie nicht nativ vom Client unterstützt werden.",
|
||||
"AllowOnTheFlySubtitleExtractionHelp": "Eingebettete Untertitel können aus Videos extrahiert und in Reintext an Clients gesendet werden, um eine Videotranskodierung zu vermeiden. Auf manchen Systemen kann dieser Vorgang eine lange Zeit in Anspruch nehmen und deswegen währenddessen die Videowiedergabe stoppen. Deaktiviere diese Option, um eingebettete Untertitel während des Videotranskodierens einbrennen zu lassen, wenn sie nicht nativ vom Client unterstützt werden.",
|
||||
"AllowRemoteAccess": "Erlaube externe Verbindungen zu diesem Jellyfin Server.",
|
||||
"AllowRemoteAccessHelp": "Wenn deaktiviert werden alle externen Verbindungen blockiert.",
|
||||
"AllowSeasonalThemes": "Erlaube automatische Jahreszeitenmotive",
|
||||
"AllowSeasonalThemesHelp": "Wenn aktiviert, werden Jahreszeitenmotive von Zeit zu Zeit deine Motiveinstellungen überschreiben.",
|
||||
"AllowedRemoteAddressesHelp": "Kommagetrennte Liste von IP Adressen oder IP/Netzmasken für Netzwerke, für die externe Verbindungen erlaubt sind. Wenn leer, sind alle Adressen erlaubt.",
|
||||
"AlwaysPlaySubtitles": "Untertitel immer einblenden",
|
||||
"AlwaysPlaySubtitles": "Immer anzeigen",
|
||||
"AlwaysPlaySubtitlesHelp": "Untertitel die den Spracheinstellungen entsprechen werden unabhängig von der Tonspursprache geladen.",
|
||||
"AnyLanguage": "Jede Sprache",
|
||||
"Anytime": "Jederzeit",
|
||||
|
@ -60,7 +60,7 @@
|
|||
"BoxRear": "Box (Rückseite)",
|
||||
"Browse": "Blättern",
|
||||
"BrowsePluginCatalogMessage": "Durchsuche unsere Bibliothek, um alle verfügbaren Plugins anzuzeigen.",
|
||||
"BurnSubtitlesHelp": "Legt fest, ob der Server die Untertitel basierend auf deren Format während der Videokonvertierung einbrennen soll. Die Vermeidung des Einbrennen von Untertiteln verbessert die Serverperformance. Wähle Auto, um Bildfomate (z.B. VOBSUB, PGS, SUB/IDX, etc.) sowie bestimmte ASS/SSA-Untertitel einbrennen zu lassen.",
|
||||
"BurnSubtitlesHelp": "Legt fest, ob der Server die Untertitel während der Videotranskodierung einbrennen soll. Deaktivieren verbessert die Serverperformance immens. Wähle Auto, um bildbasierte Formate (z.B. VOBSUB, PGS, SUB, IDX) sowie bestimmte ASS- oder SSA-Untertitel einbrennen zu lassen.",
|
||||
"ButtonAdd": "Hinzufügen",
|
||||
"ButtonAddMediaLibrary": "Füge Medienbibliothek hinzu",
|
||||
"ButtonAddScheduledTaskTrigger": "Auslöser hinzufügen",
|
||||
|
@ -185,7 +185,7 @@
|
|||
"DisplayInOtherHomeScreenSections": "Zeige auf dem Homescreen Bereiche wie 'Neueste Medien' oder 'Weiterschauen'",
|
||||
"DisplayMissingEpisodesWithinSeasons": "Zeige fehlende Episoden innerhalb von Staffeln",
|
||||
"DisplayMissingEpisodesWithinSeasonsHelp": "Dies muss auch für Serienbibliotheken in den Servereinstellungen aktiviert sein.",
|
||||
"DisplayModeHelp": "Bitte wähle den Typ des Bildschirms auf dem Du Jellyfin verwendest.",
|
||||
"DisplayModeHelp": "Wähle das Layout welches du für die Oberfläche verwenden möchtest.",
|
||||
"DoNotRecord": "Nicht aufnehmen",
|
||||
"Down": "Runter",
|
||||
"DownloadsValue": "{0} Downloads",
|
||||
|
@ -469,7 +469,7 @@
|
|||
"Images": "Bilder",
|
||||
"ImportFavoriteChannelsHelp": "Wenn aktiviert, werden nur auf dem Tuner favorisierte Kanäle importiert.",
|
||||
"ImportMissingEpisodesHelp": "Wenn aktiviert, werden Informationen über fehlende Episoden in Deine Jellyfin Datenbank importiert und innerhalb von Staffeln angezeigt. Dies kann zu deutlich längeren Bibliothek Scans führen.",
|
||||
"InstallingPackage": "Installiere {0}",
|
||||
"InstallingPackage": "Installiere {0} (Version {1})",
|
||||
"InstantMix": "Schnellmix",
|
||||
"ItemCount": "{0} Einträge",
|
||||
"Items": "Einträge",
|
||||
|
@ -908,15 +908,15 @@
|
|||
"NoNextUpItemsMessage": "Es wurde nichts gefunden. Schau dir deine Shows an!",
|
||||
"NoPluginConfigurationMessage": "Dieses Plugin hat keine konfigurierbaren Einstellungen.",
|
||||
"NoSubtitleSearchResultsFound": "Keine Ergebnisse gefunden.",
|
||||
"NoSubtitles": "Keine Untertitel",
|
||||
"NoSubtitles": "Keine",
|
||||
"NoSubtitlesHelp": "Untertitel werden standardmäßig nicht geladen. Sie können aber während der Wiedergabe manuell aktiviert werden.",
|
||||
"None": "Keines",
|
||||
"NumLocationsValue": "{0} Verzeichnisse",
|
||||
"Off": "Aus",
|
||||
"OneChannel": "Ein Kanal",
|
||||
"OnlyForcedSubtitles": "Nur erzwungene Untertitel",
|
||||
"OnlyForcedSubtitles": "Nur Erzwungene",
|
||||
"OnlyForcedSubtitlesHelp": "Nur Untertitel, die als erzwungen markiert wurden, werden geladen.",
|
||||
"OnlyImageFormats": "Nur Bildformate (VOBSUB, PGS, SUB, etc.)",
|
||||
"OnlyImageFormats": "Nur Bildformate (VOBSUB, PGS, SUB)",
|
||||
"OptionAdminUsers": "Administratoren",
|
||||
"OptionAlbumArtist": "Album-Interpret",
|
||||
"OptionAllUsers": "Alle Benutzer",
|
||||
|
@ -1036,9 +1036,9 @@
|
|||
"OptionWeekly": "Wöchentlich",
|
||||
"OriginalAirDateValue": "Erstausstrahlung: {0}",
|
||||
"Overview": "Übersicht",
|
||||
"PackageInstallCancelled": "{0} Installation abgebrochen.",
|
||||
"PackageInstallCompleted": "{0} Installation abgeschlossen.",
|
||||
"PackageInstallFailed": "{0} Installation fehlgeschlagen.",
|
||||
"PackageInstallCancelled": "{0} (Version {1}) Installation abgebrochen.",
|
||||
"PackageInstallCompleted": "{0} (Version {1}) Installation abgeschlossen.",
|
||||
"PackageInstallFailed": "{0} (Version {1}) Installation fehlgeschlagen.",
|
||||
"ParentalRating": "Altersfreigabe",
|
||||
"PasswordMatchError": "Die Passwörter müssen übereinstimmen.",
|
||||
"PasswordResetComplete": "Das Passwort wurde zurückgesetzt.",
|
||||
|
@ -1314,7 +1314,7 @@
|
|||
"LabelProfileCodecs": "Codecs:",
|
||||
"LabelProfileContainer": "Container:",
|
||||
"LabelSkin": "Textur:",
|
||||
"Art": "Kunst",
|
||||
"Art": "Coverkunst",
|
||||
"Name": "Name",
|
||||
"Songs": "Songs",
|
||||
"ValueSpecialEpisodeName": "Extra - {0}",
|
||||
|
@ -1400,7 +1400,7 @@
|
|||
"Thumb": "Miniaturansicht",
|
||||
"TitleSupport": "Hilfe",
|
||||
"Whitelist": "Erlaubt",
|
||||
"AuthProviderHelp": "Auswählen eines Authentifizierungsanbieter, der zur Authentifizierung des Passworts dieses Benutzes verwendet werden soll.",
|
||||
"AuthProviderHelp": "Authentifizierungsanbieter auswählen, der zur Authentifizierung des Benutzerpassworts verwendet werden soll.",
|
||||
"Features": "Funktionen",
|
||||
"HeaderFavoriteBooks": "Lieblingsbücher",
|
||||
"HeaderFavoriteMovies": "Lieblingsfilme",
|
||||
|
@ -1490,7 +1490,36 @@
|
|||
"AskAdminToCreateLibrary": "Bitten Sie einen Administrator, eine Bibliothek zu erstellen.",
|
||||
"NoCreatedLibraries": "Sieht so aus als hättest du bis jetzt keine Bibliothek erstellt. {0}Möchtest du jetzt eine Bibliothek erstellen?{1}",
|
||||
"AllowFfmpegThrottling": "Transkodierung drosseln",
|
||||
"PlaybackErrorNoCompatibleStream": "Es gab ein Problem bei der Erkennung des Wiedergabeprofils des Clients und der Server sendet kein kompatibles Format.",
|
||||
"PlaybackErrorNoCompatibleStream": "Dieser Client ist nicht mit den Medien kompatibel und der Server sendet kein kompatibles Medienformat.",
|
||||
"AllowFfmpegThrottlingHelp": "Wenn eine Transkodierung oder ein Remux weit genug über die aktuelle Abspielposition fortgeschritten ist, pausiere sie sodass weniger Ressourcen verbraucht werden. Dies ist am nützlichsten, wenn wenig geskippt wird. Bei Wiedergabeproblemen sollte diese Option deaktiviert werden.",
|
||||
"ClientSettings": "Client Einstellungen"
|
||||
"ClientSettings": "Client Einstellungen",
|
||||
"OnApplicationStartup": "Beim Starten der Applikation",
|
||||
"EveryXHours": "Alle {0} Stunden",
|
||||
"EveryHour": "Jede Stunde",
|
||||
"EveryXMinutes": "Alle {0} Minuten",
|
||||
"OnWakeFromSleep": "Beim Aufwachen aus \"Energie sparen\"",
|
||||
"WeeklyAt": "{0} um {1}",
|
||||
"DailyAt": "Täglich um {0}",
|
||||
"LastSeen": "Zuletzt gesehen {0}",
|
||||
"PersonRole": "als {0}",
|
||||
"ListPaging": "{0}-{1} von {2}",
|
||||
"WriteAccessRequired": "Jellyfin Server benötigt Schreibrechte auf diesem Ordner. Bitte prüfe die Schreibrechte und versuche es erneut.",
|
||||
"PathNotFound": "Der Pfad konnte nicht gefunden werden. Bitte versichere dich dass der Pfad korrekt ist und versuche es erneut.",
|
||||
"Track": "Track",
|
||||
"Season": "Staffel",
|
||||
"ReleaseGroup": "Veröffentlichungs-Gruppe",
|
||||
"Person": "Person",
|
||||
"OtherArtist": "Andere Künstler",
|
||||
"Movie": "Film",
|
||||
"Episode": "Episode",
|
||||
"Artist": "Künstler",
|
||||
"AlbumArtist": "Album Künstler",
|
||||
"Album": "Album",
|
||||
"BoxSet": "Box Set",
|
||||
"YadifBob": "YADIF Bob",
|
||||
"Yadif": "YADIF",
|
||||
"LabelLibraryPageSizeHelp": "Setzt die Anzahl der gezeigten Elemente auf einer Bibliotheksseite. Setze die Anzahl auf 0 um die Auflistung zu deaktivieren.",
|
||||
"LabelLibraryPageSize": "Bibliothek Seiten Größe:",
|
||||
"DeinterlaceMethodHelp": "Wähle die Deinterlacing-Methode zum Transkodieren von Inhalten im Zeilensprungverfahren (Interlace).",
|
||||
"LabelDeinterlaceMethod": "Deinterlacing-Methode:"
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue