diff --git a/.eslintrc.yml b/.eslintrc.yml index b215e15800..f5ce779d44 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -1,27 +1,71 @@ env: - es6: true + es6: false browser: true amd: true +globals: + # New browser globals + DataView: readonly + MediaMetadata: readonly + Promise: readonly + # Deprecated browser globals + DocumentTouch: readonly + # Tizen globals + tizen: readonly + webapis: readonly + # WebOS globals + webOS: readonly + # Dependency globals + $: readonly + jQuery: readonly + queryString: readonly + requirejs: readonly + # Jellyfin globals + ApiClient: writable + AppInfo: writable + chrome: writable + ConnectionManager: writable + DlnaProfilePage: writable + Dashboard: writable + DashboardPage: writable + Emby: readonly + Events: writable + getParameterByName: writable + getWindowLocationSearch: writable + Globalize: writable + Hls: writable + humaneDate: writable + humaneElapsed: writable + LibraryMenu: writable + LinkParser: writable + LiveTvHelpers: writable + MetadataEditor: writable + pageClassOn: writable + pageIdOn: writable + PlaylistViewer: writable + UserParentalControlPage: writable + Windows: readonly + +extends: + - eslint:recommended + rules: block-spacing: ["error"] brace-style: ["error"] comma-dangle: ["error", "never"] comma-spacing: ["error"] - eol-last: ["off"] + eol-last: ["error"] indent: ["error", 4, { "SwitchCase": 1 }] keyword-spacing: ["error"] - line-comment-position: ["off"] max-statements-per-line: ["error"] - no-empty: ["error"] - no-extra-semi: ["error"] no-floating-decimal: ["error"] no-multi-spaces: ["error"] no-multiple-empty-lines: ["error", { "max": 1 }] no-trailing-spaces: ["error"] - no-void: ["off"] one-var: ["error", "never"] - padding-line-between-statements: ["off"] - semi: ["off"] + semi: ["warn"] space-before-blocks: ["error"] - yoda: ["off"] + # TODO: Fix warnings and remove these rules + no-redeclare: ["warn"] + no-unused-vars: ["warn"] + no-useless-escape: ["warn"] diff --git a/.gitignore b/.gitignore index 2e12adf220..10b2d24f42 100644 --- a/.gitignore +++ b/.gitignore @@ -575,4 +575,4 @@ healthchecksdb # End of https://www.gitignore.io/api/node,rider,macos,linux,windows,visualstudio,visualstudiocode # dist for webpack output -dist \ No newline at end of file +dist diff --git a/.stylelintrc b/.stylelintrc index 93e3592099..a13acf428d 100644 --- a/.stylelintrc +++ b/.stylelintrc @@ -140,4 +140,4 @@ "value-list-comma-space-before": "never", "value-list-max-empty-lines": 0, } -} \ No newline at end of file +} diff --git a/package.json b/package.json index 87050382c5..dbc6c8fa8b 100644 --- a/package.json +++ b/package.json @@ -31,11 +31,10 @@ "jellyfin-noto": "https://github.com/jellyfin/jellyfin-noto", "jquery": "^3.4.1", "jstree": "^3.3.7", - "libass-wasm": "^2.1.1", + "libass-wasm": "https://github.com/jellyfin/JavascriptSubtitlesOctopus", "libjass": "^0.11.0", "material-design-icons-iconfont": "^5.0.1", "native-promise-only": "^0.8.0-a", - "requirejs": "^2.3.5", "resize-observer-polyfill": "^1.5.1", "shaka-player": "^2.5.9", "sortablejs": "^1.10.2", diff --git a/src/assets/css/fonts.css b/src/assets/css/fonts.css index f125bc6a03..cb0da0f80f 100644 --- a/src/assets/css/fonts.css +++ b/src/assets/css/fonts.css @@ -29,7 +29,7 @@ h3 { } .layout-tv { - font-size: 2.5vh; + font-size: 130%; } .layout-mobile { diff --git a/src/assets/css/librarybrowser.css b/src/assets/css/librarybrowser.css index 7a3e0ada68..d3a3438b0b 100644 --- a/src/assets/css/librarybrowser.css +++ b/src/assets/css/librarybrowser.css @@ -439,10 +439,42 @@ background-size: cover; background-repeat: no-repeat; background-position: center; + background-attachment: fixed; height: 50vh; position: relative; } +.layout-desktop .itemBackdrop::after, +.layout-tv .itemBackdrop::after { + content: ""; + width: 100%; + height: 100%; + background: rgba(0, 0, 0, 0.65); + display: block; +} + +.layout-desktop .noBackdrop .itemBackdrop, +.layout-tv .noBackdrop .itemBackdrop { + display: none; +} + +.detailPageContent { + display: flex; + flex-direction: column; + padding-left: 2%; + padding-right: 2%; +} + +.layout-desktop .noBackdrop .detailPageContent, +.layout-tv .noBackdrop .detailPageContent { + margin-top: 2.5em; +} + +.layout-desktop .noBackdrop .detailImageContainer img, +.layout-tv .noBackdrop .detailImageContainer img { + margin-top: 0; +} + .personBackdrop { background-size: contain; } @@ -509,8 +541,6 @@ display: flex; align-items: center; align-content: center; - position: sticky; - top: 3.85em; z-index: 2; } @@ -520,13 +550,21 @@ top: 0; } -.layout-tv .detailPagePrimaryContainer { +.layout-tv #itemDetailPage:not(.noBackdrop) .detailPagePrimaryContainer, +.layout-desktop #itemDetailPage:not(.noBackdrop) .detailPagePrimaryContainer { position: relative; top: 0; + padding-left: 32.45vw; } -.detailSticky { - background-color: #101010; +.layout-desktop .detailSticky, +.layout-tv .detailSticky { + margin-top: -7.2em; +} + +.layout-desktop .noBackdrop .detailSticky, +.layout-tv .noBackdrop .detailSticky { + margin-top: 0; } .infoWrapper { @@ -548,23 +586,17 @@ margin: 1.25em 0; } -.detailPageContent { - display: flex; - flex-direction: column; - padding-left: 2%; - padding-right: 2%; -} - .detailImageContainer { - position: sticky; - top: 25%; + position: relative; + margin-top: -25vh; float: left; - width: 22.786458333333332vw; + width: 25vw; + z-index: 3; } -.layout-mobile .detailImageContainer, -.layout-tv .detailImageContainer { - position: relative; +.layout-desktop .noBackdrop .detailImageContainer, +.layout-tv .noBackdrop .detailImageContainer { + margin-top: 0; } .detailPagePrimaryContent { @@ -572,15 +604,19 @@ } .detailLogo { - width: 25em; - height: 9.375em; + width: 67.25vw; + height: 14.5vh; position: absolute; - top: 14.5%; - right: 10.5%; + top: 15vh; + right: 0; -webkit-background-size: contain; background-size: contain; } +.noBackdrop .detailLogo { + display: none; +} + @media all and (max-width: 87.5em) { .detailLogo { right: 5%; @@ -607,8 +643,8 @@ .itemDetailImage { width: 100% !important; - box-shadow: 0 0.0725em 0.29em 0 rgba(0, 0, 0, 0.37); - -webkit-box-shadow: 0 0.0725em 0.29em 0 rgba(0, 0, 0, 0.37); + -webkit-box-shadow: 0 0.1em 0.5em 0 rgba(0, 0, 0, 0.75); + box-shadow: 0 0.1em 0.5em 0 rgba(0, 0, 0, 0.75); } div.itemDetailGalleryLink.defaultCardBackground { @@ -635,6 +671,16 @@ div.itemDetailGalleryLink.defaultCardBackground { position: relative; } + .layout-desktop .detailPageWrapperContainer, + .layout-tv .detailPageWrapperContainer { + margin-top: 7.2em; + } + + .layout-tv #itemDetailPage:not(.noBackdrop) .detailPagePrimaryContainer, + .layout-desktop #itemDetailPage:not(.noBackdrop) .detailPagePrimaryContainer { + padding-left: 3.3%; + } + .btnPlaySimple { display: none !important; } @@ -849,6 +895,11 @@ div.itemDetailGalleryLink.defaultCardBackground { border-collapse: collapse; } +.layout-desktop .noBackdrop .detailPageWrapperContainer, +.layout-tv .noBackdrop .detailPageWrapperContainer { + margin-top: 3.8em; +} + .mediaInfoStream { margin: 0 3em 0 0; display: inline-block; diff --git a/src/availableplugins.html b/src/availableplugins.html index ea1147fbfd..6c9b89c26d 100644 --- a/src/availableplugins.html +++ b/src/availableplugins.html @@ -5,4 +5,4 @@
- \ No newline at end of file + diff --git a/src/bundle.js b/src/bundle.js index b7bde65f80..6a352c5776 100644 --- a/src/bundle.js +++ b/src/bundle.js @@ -47,12 +47,6 @@ _define("howler", function() { return howler; }); -// native-promise-only -var nativePromise = require("native-promise-only"); -_define("native-promise-only", function() { - return nativePromise; -}); - // resize-observer-polyfill var resize = require("resize-observer-polyfill").default; _define("resize-observer-polyfill", function() { diff --git a/src/components/alert.js b/src/components/alert.js index 8a4dc11c20..8a37ac1845 100644 --- a/src/components/alert.js +++ b/src/components/alert.js @@ -42,4 +42,4 @@ define(['browser', 'dialog', 'globalize'], function (browser, dialog, globalize) return Promise.resolve(); }; -}); \ No newline at end of file +}); diff --git a/src/components/alphanumericshortcuts/alphanumericshortcuts.js b/src/components/alphanumericshortcuts/alphanumericshortcuts.js index 03d0118cbe..2bcf3712bb 100644 --- a/src/components/alphanumericshortcuts/alphanumericshortcuts.js +++ b/src/components/alphanumericshortcuts/alphanumericshortcuts.js @@ -10,7 +10,7 @@ define(['dom', 'focusManager'], function (dom, focusManager) { if (e.ctrlKey) { return; } - if (!!e.shiftKey) { + if (e.shiftKey) { return; } if (e.altKey) { @@ -127,4 +127,4 @@ define(['dom', 'focusManager'], function (dom, focusManager) { }; return AlphaNumericShortcuts; -}); \ No newline at end of file +}); diff --git a/src/components/alphapicker/alphapicker.js b/src/components/alphapicker/alphapicker.js index 9ac39e55be..455a43b46d 100644 --- a/src/components/alphapicker/alphapicker.js +++ b/src/components/alphapicker/alphapicker.js @@ -241,7 +241,7 @@ define(['focusManager', 'layoutManager', 'dom', 'css!./style.css', 'paper-icon-b try { btn = element.querySelector('.alphaPickerButton[data-value=\'' + value + '\']'); } catch (err) { - console.log('Error in querySelector: ' + err); + console.error('error in querySelector: ' + err); } if (btn && btn !== selected) { diff --git a/src/components/appRouter.js b/src/components/appRouter.js index 7b36d01bdd..74b1a5cd5f 100644 --- a/src/components/appRouter.js +++ b/src/components/appRouter.js @@ -14,6 +14,9 @@ define(['loading', 'globalize', 'events', 'viewManager', 'layoutManager', 'skinM }, showSettings: function () { show('/settings/settings.html'); + }, + showNowPlaying: function () { + show("/nowplaying.html"); } }; @@ -387,13 +390,13 @@ define(['loading', 'globalize', 'events', 'viewManager', 'layoutManager', 'skinM var apiClient = connectionManager.currentApiClient(); var pathname = ctx.pathname.toLowerCase(); - console.log('appRouter - processing path request ' + pathname); + console.debug('appRouter - processing path request ' + pathname); var isCurrentRouteStartup = currentRouteInfo ? currentRouteInfo.route.startup : true; var shouldExitApp = ctx.isBack && route.isDefaultRoute && isCurrentRouteStartup; if (!shouldExitApp && (!apiClient || !apiClient.isLoggedIn()) && !route.anonymous) { - console.log('appRouter - route does not allow anonymous access, redirecting to login'); + console.debug('appRouter - route does not allow anonymous access, redirecting to login'); beginConnectionWizard(); return; } @@ -408,10 +411,10 @@ define(['loading', 'globalize', 'events', 'viewManager', 'layoutManager', 'skinM if (apiClient && apiClient.isLoggedIn()) { - console.log('appRouter - user is authenticated'); + console.debug('appRouter - user is authenticated'); if (route.isDefaultRoute) { - console.log('appRouter - loading skin home page'); + console.debug('appRouter - loading skin home page'); loadUserSkinWithOptions(ctx); return; } else if (route.roles) { @@ -425,7 +428,7 @@ define(['loading', 'globalize', 'events', 'viewManager', 'layoutManager', 'skinM } } - console.log('appRouter - proceeding to ' + pathname); + console.debug('appRouter - proceeding to ' + pathname); callback(); } @@ -672,7 +675,7 @@ define(['loading', 'globalize', 'events', 'viewManager', 'layoutManager', 'skinM baseRoute = baseRoute.substring(0, baseRoute.length - 1); } - console.log('Setting page base to ' + baseRoute); + console.debug('setting page base to ' + baseRoute); page.base(baseRoute); } diff --git a/src/components/apphost.js b/src/components/apphost.js index 2a0b7b19e9..f3e89ed29e 100644 --- a/src/components/apphost.js +++ b/src/components/apphost.js @@ -186,7 +186,7 @@ define(["appSettings", "browser", "events", "htmlMediaHelper"], function (appSet return !!cue.length; } catch (err) { - console.log("error detecting cue support: " + err); + console.error("error detecting cue support: " + err); return false; } } @@ -194,7 +194,7 @@ define(["appSettings", "browser", "events", "htmlMediaHelper"], function (appSet function onAppVisible() { if (isHidden) { isHidden = false; - console.log("triggering app resume event"); + console.debug("triggering app resume event"); events.trigger(appHost, "resume"); } } @@ -202,7 +202,7 @@ define(["appSettings", "browser", "events", "htmlMediaHelper"], function (appSet function onAppHidden() { if (!isHidden) { isHidden = true; - console.log("app is hidden"); + console.debug("app is hidden"); } } @@ -314,7 +314,7 @@ define(["appSettings", "browser", "events", "htmlMediaHelper"], function (appSet window.close(); } } catch (err) { - console.log("error closing application: " + err); + console.error("error closing application: " + err); } } @@ -324,7 +324,7 @@ define(["appSettings", "browser", "events", "htmlMediaHelper"], function (appSet * Ask user for exit */ function askForExit() { - if (!!exitPromise) { + if (exitPromise) { return; } @@ -374,7 +374,7 @@ define(["appSettings", "browser", "events", "htmlMediaHelper"], function (appSet return -1 !== supportedFeatures.indexOf(command.toLowerCase()); }, preferVisualCards: browser.android || browser.chrome, - moreIcon: browser.android ? "dots-vert" : "dots-horiz", + moreIcon: browser.android ? "more_vert" : "more_horiz", getSyncProfile: getSyncProfile, getDefaultLayout: function () { if (window.NativeShell) { diff --git a/src/components/autoFocuser.js b/src/components/autoFocuser.js index 09ded814f2..6d99009e67 100644 --- a/src/components/autoFocuser.js +++ b/src/components/autoFocuser.js @@ -25,7 +25,7 @@ define(["focusManager", "layoutManager"], function (focusManager, layoutManager) activeElement = e.target; }); - console.log("AutoFocuser enabled"); + console.debug("AutoFocuser enabled"); } /** diff --git a/src/components/cardbuilder/card.css b/src/components/cardbuilder/card.css index 7e2855c85c..3cd038cd09 100644 --- a/src/components/cardbuilder/card.css +++ b/src/components/cardbuilder/card.css @@ -429,6 +429,12 @@ button::-moz-focus-inner { font-size: 1.66956521739130434em !important; } +.cardOverlayButtonIcon.material-icons { + /* material-icons override display, so we need to + make a better matching selector to set it to flex */ + display: flex; +} + .cardOverlayButton-centered { bottom: initial; right: initial; @@ -784,7 +790,7 @@ button::-moz-focus-inner { opacity: 0; transition: 0.2s; background: transparent; - padding: 0.5em; + padding: 0.25em; } .cardOverlayButtonIcon-hover { diff --git a/src/components/cardbuilder/cardBuilder.js b/src/components/cardbuilder/cardBuilder.js index 4e589c4a19..bec641f407 100644 --- a/src/components/cardbuilder/cardBuilder.js +++ b/src/components/cardbuilder/cardBuilder.js @@ -140,7 +140,6 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana } return 100 / 72; } - break; case 'overflowPortrait': if (layoutManager.tv) { @@ -166,7 +165,6 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana } return 100 / 42; } - break; case 'overflowSquare': if (layoutManager.tv) { return 100 / 15.5; @@ -191,7 +189,6 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana } return 100 / 42; } - break; case 'overflowBackdrop': if (layoutManager.tv) { return 100 / 23.3; @@ -216,7 +213,6 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana } return 100 / 72; } - break; default: return 4; } @@ -342,7 +338,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana try { newIndexValue = datetime.toLocaleDateString(datetime.parseISO8601Date(item.PremiereDate), { weekday: 'long', month: 'long', day: 'numeric' }); } catch (err) { - console.log('error parsing timestamp for premiere date'); + console.error('error parsing timestamp for premiere date'); } } } else if (options.indexBy === 'ProductionYear') { @@ -738,7 +734,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana airTimeText += ' - ' + datetime.getDisplayTime(date); } } catch (e) { - console.log("Error parsing date: " + item.StartDate); + console.error("error parsing date: " + item.StartDate); } } @@ -870,9 +866,10 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana if (item.PremiereDate) { try { - - lines.push(getPremiereDateText(item)); - + lines.push(datetime.toLocaleDateString( + datetime.parseISO8601Date(item.PremiereDate), + { weekday: 'long', month: 'long', day: 'numeric' } + )); } catch (err) { lines.push(''); @@ -1383,7 +1380,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana } if (item.Type === 'CollectionFolder' || item.CollectionType) { - var refreshClass = item.RefreshProgress || (item.RefreshStatus && virtualFolder.item !== 'Idle') ? '' : ' class="hide"'; + var refreshClass = item.RefreshProgress ? '' : ' class="hide"'; indicatorsHtml += '
'; requireRefreshIndicator(); } @@ -1497,13 +1494,13 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana case 'Person': return 'person'; case 'Movie': - return 'movie' + return 'movie'; case 'Series': - return 'tv' + return 'tv'; case 'Book': - return 'book' + return 'book'; case 'Folder': - return 'folder' + return 'folder'; } if (options && options.defaultCardImageIcon) { diff --git a/src/components/cardbuilder/chaptercardbuilder.js b/src/components/cardbuilder/chaptercardbuilder.js index 75b940285f..02d583abc0 100644 --- a/src/components/cardbuilder/chaptercardbuilder.js +++ b/src/components/cardbuilder/chaptercardbuilder.js @@ -90,7 +90,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'layoutManager', 'browse var cardImageContainer = imgUrl ? ('
') : ('
'); if (!imgUrl) { - cardImageContainer += 'local_movies'; + cardImageContainer += ''; } var nameHtml = ''; diff --git a/src/components/channelmapper/channelmapper.js b/src/components/channelmapper/channelmapper.js index 2b2de1870c..1b536f440b 100644 --- a/src/components/channelmapper/channelmapper.js +++ b/src/components/channelmapper/channelmapper.js @@ -84,7 +84,7 @@ define(["dialogHelper", "loading", "connectionManager", "globalize", "actionshee html += "
"; html += "
"; - html += ''; + html += ''; return html += ""; } diff --git a/src/components/chromecast/chromecasthelpers.js b/src/components/chromecast/chromecasthelpers.js index 9d6f811cb1..2fef0c68b3 100644 --- a/src/components/chromecast/chromecasthelpers.js +++ b/src/components/chromecast/chromecasthelpers.js @@ -131,8 +131,9 @@ define(['events'], function (events) { var links = []; var match; + // eslint-disable-next-line no-cond-assign while (match = linkRegExp.exec(text)) { - // console.log(matches); + console.debug(match); var txt = match[0]; var pos = match.index; var len = txt.length; @@ -189,7 +190,7 @@ define(['events'], function (events) { return apiClient.getPublicSystemInfo().then(function (info) { var localAddress = info.LocalAddress if (!localAddress) { - console.log("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); @@ -230,4 +231,4 @@ define(['events'], function (events) { return { getServerAddress: getServerAddress }; -}); \ No newline at end of file +}); diff --git a/src/components/chromecast/chromecastplayer.js b/src/components/chromecast/chromecastplayer.js index 112d2980ab..18103e433f 100644 --- a/src/components/chromecast/chromecastplayer.js +++ b/src/components/chromecast/chromecastplayer.js @@ -105,7 +105,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' this.sessionListener.bind(this), this.receiverListener.bind(this)); - console.log('chromecast.initialize'); + console.debug('chromecast.initialize'); chrome.cast.initialize(apiConfig, this.onInitSuccess.bind(this), this.errorHandler); }; @@ -114,14 +114,14 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' */ CastPlayer.prototype.onInitSuccess = function () { this.isInitialized = true; - console.log("chromecast init success"); + console.debug("chromecast init success"); }; /** * Generic error callback function */ CastPlayer.prototype.onError = function () { - console.log("chromecast error"); + console.debug("chromecast error"); }; /** @@ -177,10 +177,10 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' */ CastPlayer.prototype.receiverListener = function (e) { if (e === 'available') { - console.log("chromecast receiver found"); + console.debug("chromecast receiver found"); this.hasReceivers = true; } else { - console.log("chromecast receiver list empty"); + console.debug("chromecast receiver list empty"); this.hasReceivers = false; } }; @@ -190,7 +190,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' */ CastPlayer.prototype.sessionUpdateListener = function (isAlive) { if (isAlive) { - console.log('sessionUpdateListener: already alive'); + console.debug('sessionUpdateListener: already alive'); } else { this.session = null; this.deviceState = DEVICE_STATE.IDLE; @@ -198,7 +198,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' document.removeEventListener("volumeupbutton", onVolumeUpKeyDown, false); document.removeEventListener("volumedownbutton", onVolumeDownKeyDown, false); - console.log('sessionUpdateListener: setting currentMediaSession to null'); + console.debug('sessionUpdateListener: setting currentMediaSession to null'); this.currentMediaSession = null; sendConnectionResult(false); @@ -211,7 +211,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' * session request in opt_sessionRequest. */ CastPlayer.prototype.launchApp = function () { - console.log("chromecast launching app..."); + console.debug("chromecast launching app..."); chrome.cast.requestSession(this.onRequestSessionSuccess.bind(this), this.onLaunchError.bind(this)); }; @@ -220,7 +220,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' * @param {Object} e A chrome.cast.Session object */ CastPlayer.prototype.onRequestSessionSuccess = function (e) { - console.log("chromecast session success: " + e.sessionId); + console.debug("chromecast session success: " + e.sessionId); this.onSessionConnected(e); }; @@ -262,7 +262,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' * Callback function for launch error */ CastPlayer.prototype.onLaunchError = function () { - console.log("chromecast launch error"); + console.debug("chromecast launch error"); this.deviceState = DEVICE_STATE.ERROR; sendConnectionResult(false); }; @@ -280,7 +280,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' * Callback function for stop app success */ CastPlayer.prototype.onStopAppSuccess = function (message) { - console.log(message); + console.debug(message); this.deviceState = DEVICE_STATE.IDLE; this.castPlayerState = PLAYER_STATE.IDLE; @@ -296,7 +296,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' */ CastPlayer.prototype.loadMedia = function (options, command) { if (!this.session) { - console.log("no session"); + console.debug("no session"); return Promise.reject(); } @@ -377,7 +377,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' }; CastPlayer.prototype.onPlayCommandSuccess = function () { - //console.log('Message was sent to receiver ok.'); + console.debug('Message was sent to receiver ok.'); }; /** @@ -386,7 +386,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' */ CastPlayer.prototype.onMediaDiscovered = function (how, mediaSession) { - //console.log("chromecast new media session ID:" + mediaSession.mediaSessionId + ' (' + how + ')'); + console.debug("chromecast new media session ID:" + mediaSession.mediaSessionId + ' (' + how + ')'); this.currentMediaSession = mediaSession; if (how === 'loadMedia') { @@ -405,7 +405,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' * @param {!Boolean} e true/false */ CastPlayer.prototype.onMediaStatusUpdate = function (e) { - //console.log("chromecast updating media: " + e); + console.debug("chromecast updating media: " + e); if (e === false) { this.castPlayerState = PLAYER_STATE.IDLE; } @@ -417,7 +417,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' */ CastPlayer.prototype.setReceiverVolume = function (mute, vol) { if (!this.currentMediaSession) { - //console.log('this.currentMediaSession is null'); + console.debug('this.currentMediaSession is null'); return; } @@ -443,7 +443,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' * Callback function for media command success */ CastPlayer.prototype.mediaCommandSuccessCallback = function (info, e) { - //console.log(info); + console.debug(info); }; function normalizeImages(state) { @@ -493,7 +493,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' events.on(instance._castPlayer, eventName, function (e, data) { - //console.log('cc: ' + eventName); + console.debug('cc: ' + eventName); var state = instance.getPlayerStateInternal(data); events.trigger(instance, eventName, [state]); @@ -520,14 +520,14 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' playbackManager.setActivePlayer(PlayerName, instance.getCurrentTargetInfo()); } - console.log('cc: connect'); + console.debug('cc: connect'); // Reset this so that statechange will fire instance.lastPlayerData = null; }); events.on(instance._castPlayer, "playbackstart", function (e, data) { - console.log('cc: playbackstart'); + console.debug('cc: playbackstart'); instance._castPlayer.initializeCastPlayer(); @@ -537,7 +537,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' events.on(instance._castPlayer, "playbackstop", function (e, data) { - console.log('cc: playbackstop'); + console.debug('cc: playbackstop'); var state = instance.getPlayerStateInternal(data); events.trigger(instance, "playbackstop", [state]); @@ -555,7 +555,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' events.on(instance._castPlayer, "playbackprogress", function (e, data) { - //console.log('cc: positionchange'); + console.debug('cc: positionchange'); var state = instance.getPlayerStateInternal(data); events.trigger(instance, "timeupdate", [state]); @@ -569,7 +569,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' events.on(instance._castPlayer, "playstatechange", function (e, data) { - //console.log('cc: playstatechange'); + console.debug('cc: playstatechange'); var state = instance.getPlayerStateInternal(data); events.trigger(instance, "pause", [state]); @@ -664,7 +664,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' normalizeImages(data); - //console.log(JSON.stringify(data)); + console.debug(JSON.stringify(data)); if (triggerStateChange) { events.trigger(this, "statechange", [data]); diff --git a/src/components/confirm/nativeconfirm.js b/src/components/confirm/nativeconfirm.js index fd586ad1d5..7d72bc5eaf 100644 --- a/src/components/confirm/nativeconfirm.js +++ b/src/components/confirm/nativeconfirm.js @@ -24,4 +24,4 @@ define([], function () { return Promise.reject(); } }; -}); \ No newline at end of file +}); diff --git a/src/components/dialog/dialog.template.html b/src/components/dialog/dialog.template.html index eae210d14e..bee0ef7f73 100644 --- a/src/components/dialog/dialog.template.html +++ b/src/components/dialog/dialog.template.html @@ -12,4 +12,4 @@
-
\ No newline at end of file + diff --git a/src/components/dialogHelper/dialogHelper.js b/src/components/dialogHelper/dialogHelper.js index bddd839760..6ee96df318 100644 --- a/src/components/dialogHelper/dialogHelper.js +++ b/src/components/dialogHelper/dialogHelper.js @@ -32,7 +32,7 @@ define(['appRouter', 'focusManager', 'browser', 'layoutManager', 'inputManager', try { parentNode.removeChild(elem); } catch (err) { - console.log('Error removing dialog element: ' + err); + console.error('error removing dialog element: ' + err); } } } @@ -481,4 +481,4 @@ define(['appRouter', 'focusManager', 'browser', 'layoutManager', 'inputManager', globalOnOpenCallback = val; } }; -}); \ No newline at end of file +}); diff --git a/src/components/directorybrowser/directorybrowser.js b/src/components/directorybrowser/directorybrowser.js index 06f7773cf6..b71f7bbb05 100644 --- a/src/components/directorybrowser/directorybrowser.js +++ b/src/components/directorybrowser/directorybrowser.js @@ -76,7 +76,7 @@ define(['loading', 'dialogHelper', 'dom', 'listViewStyle', 'emby-input', 'paper- html += name; html += ""; html += ""; - html += 'arrow_forward'; + html += ''; html += ""; return html; } diff --git a/src/components/dom.js b/src/components/dom.js index da03b87428..072ff5c77c 100644 --- a/src/components/dom.js +++ b/src/components/dom.js @@ -63,13 +63,14 @@ define([], function () { var supportsCaptureOption = false; try { var opts = Object.defineProperty({}, 'capture', { + // eslint-disable-next-line getter-return get: function () { supportsCaptureOption = true; } }); window.addEventListener("test", null, opts); } catch (e) { - console.log('error checking capture support'); + console.debug('error checking capture support'); } function addEventListenerWithOptions(target, type, handler, options) { @@ -178,4 +179,4 @@ define([], function () { whichAnimationEvent: whichAnimationEvent, whichAnimationCancelEvent: whichAnimationCancelEvent }; -}); \ No newline at end of file +}); diff --git a/src/components/emby-itemrefreshindicator/emby-itemrefreshindicator.js b/src/components/emby-itemrefreshindicator/emby-itemrefreshindicator.js index be50abeb87..9864dbbb67 100644 --- a/src/components/emby-itemrefreshindicator/emby-itemrefreshindicator.js +++ b/src/components/emby-itemrefreshindicator/emby-itemrefreshindicator.js @@ -74,4 +74,4 @@ define(['emby-progressring', 'dom', 'serverNotifications', 'events', 'registerEl prototype: EmbyItemRefreshIndicatorPrototype, extends: 'div' }); -}); \ No newline at end of file +}); diff --git a/src/components/emby-itemscontainer/emby-itemscontainer.js b/src/components/emby-itemscontainer/emby-itemscontainer.js index 7cfb3e4a4a..c1aba9b6a0 100644 --- a/src/components/emby-itemscontainer/emby-itemscontainer.js +++ b/src/components/emby-itemscontainer/emby-itemscontainer.js @@ -467,7 +467,7 @@ define(['itemShortcuts', 'inputManager', 'connectionManager', 'playbackManager', focusManager.focus(newElement); return; } catch (err) { - console.log(err); + console.error(err); } } } @@ -479,4 +479,4 @@ define(['itemShortcuts', 'inputManager', 'connectionManager', 'playbackManager', prototype: ItemsContainerPrototype, extends: 'div' }); -}); \ No newline at end of file +}); diff --git a/src/components/emby-scroller/emby-scroller.js b/src/components/emby-scroller/emby-scroller.js index f943047f52..cb5bae818f 100644 --- a/src/components/emby-scroller/emby-scroller.js +++ b/src/components/emby-scroller/emby-scroller.js @@ -206,4 +206,4 @@ define(['scroller', 'dom', 'layoutManager', 'inputManager', 'focusManager', 'bro prototype: ScrollerPrototype, extends: 'div' }); -}); \ No newline at end of file +}); diff --git a/src/components/emby-tabs/emby-tabs.js b/src/components/emby-tabs/emby-tabs.js index 9fedf0bfe9..fa5979fa4c 100644 --- a/src/components/emby-tabs/emby-tabs.js +++ b/src/components/emby-tabs/emby-tabs.js @@ -338,4 +338,4 @@ define(['dom', 'scroller', 'browser', 'layoutManager', 'focusManager', 'register prototype: EmbyTabs, extends: 'div' }); -}); \ No newline at end of file +}); diff --git a/src/components/fetchhelper.js b/src/components/fetchhelper.js index bb7f21e75e..0b8d451736 100644 --- a/src/components/fetchhelper.js +++ b/src/components/fetchhelper.js @@ -51,7 +51,7 @@ define([], function () { function fetchWithTimeout(url, options, timeoutMs) { - console.log('fetchWithTimeout: timeoutMs: ' + timeoutMs + ', url: ' + url); + console.debug('fetchWithTimeout: timeoutMs: ' + timeoutMs + ', url: ' + url); return new Promise(function (resolve, reject) { @@ -63,14 +63,14 @@ define([], function () { fetch(url, options).then(function (response) { clearTimeout(timeout); - console.log('fetchWithTimeout: succeeded connecting to url: ' + url); + console.debug('fetchWithTimeout: succeeded connecting to url: ' + url); resolve(response); }, function (error) { clearTimeout(timeout); - console.log('fetchWithTimeout: timed out connecting to url: ' + url); + console.debug('fetchWithTimeout: timed out connecting to url: ' + url); reject(); }); @@ -93,21 +93,17 @@ define([], function () { } function ajax(request) { - if (!request) { throw new Error("Request cannot be null"); } request.headers = request.headers || {}; - console.log('requesting url: ' + request.url); + console.debug('requesting url: ' + request.url); return getFetchPromise(request).then(function (response) { - - console.log('response status: ' + response.status + ', url: ' + request.url); - + console.debug('response status: ' + response.status + ', url: ' + request.url); if (response.status < 400) { - if (request.dataType === 'json' || request.headers.accept === 'application/json') { return response.json(); } else if (request.dataType === 'text' || (response.headers.get('Content-Type') || '').toLowerCase().indexOf('text/') === 0) { @@ -118,10 +114,8 @@ define([], function () { } else { return Promise.reject(response); } - }, function (err) { - - console.log('request failed to url: ' + request.url); + console.error('request failed to url: ' + request.url); throw err; }); } @@ -129,4 +123,4 @@ define([], function () { getFetchPromise: getFetchPromise, ajax: ajax }; -}); \ No newline at end of file +}); diff --git a/src/components/filedownloader.js b/src/components/filedownloader.js index c5810b460e..08b6176a02 100644 --- a/src/components/filedownloader.js +++ b/src/components/filedownloader.js @@ -15,4 +15,4 @@ define(['multi-download'], function (multiDownload) { } } }; -}); \ No newline at end of file +}); diff --git a/src/components/filesystem.js b/src/components/filesystem.js index 3ab759b28a..aac697415e 100644 --- a/src/components/filesystem.js +++ b/src/components/filesystem.js @@ -15,4 +15,4 @@ define([], function () { return Promise.reject(); } }; -}); \ No newline at end of file +}); diff --git a/src/components/filtermenu/filtermenu.template.html b/src/components/filtermenu/filtermenu.template.html index 1cadab2d1f..1a5545baa3 100644 --- a/src/components/filtermenu/filtermenu.template.html +++ b/src/components/filtermenu/filtermenu.template.html @@ -105,4 +105,4 @@ - \ No newline at end of file + diff --git a/src/components/focusManager.js b/src/components/focusManager.js index 56ff324e23..1da58d75c8 100644 --- a/src/components/focusManager.js +++ b/src/components/focusManager.js @@ -43,7 +43,7 @@ define(['dom', 'scrollManager'], function (dom, scrollManager) { preventScroll: scrollManager.isEnabled() }); } catch (err) { - console.log('Error in focusManager.autoFocus: ' + err); + console.error('Error in focusManager.autoFocus: ' + err); } } diff --git a/src/components/guide/guide-settings.js b/src/components/guide/guide-settings.js index 9ee43be9f1..7409a7e943 100644 --- a/src/components/guide/guide-settings.js +++ b/src/components/guide/guide-settings.js @@ -89,20 +89,6 @@ define(['dialogHelper', 'globalize', 'userSettings', 'layoutManager', 'connectio } } - function onSortByChange() { - var newValue = this.value; - if (this.checked) { - var changed = options.query.SortBy !== newValue; - - options.query.SortBy = newValue.replace('_', ','); - options.query.StartIndex = 0; - - if (options.callback && changed) { - options.callback(); - } - } - } - function showEditor(options) { return new Promise(function (resolve, reject) { @@ -171,4 +157,4 @@ define(['dialogHelper', 'globalize', 'userSettings', 'layoutManager', 'connectio return { show: showEditor }; -}); \ No newline at end of file +}); diff --git a/src/components/guide/guide.js b/src/components/guide/guide.js index fd6931177a..a00baaa6f0 100644 --- a/src/components/guide/guide.js +++ b/src/components/guide/guide.js @@ -29,7 +29,6 @@ define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager', var offset = newPct - left; var pctOfWidth = (offset / width) * 100; - //console.log(pctOfWidth); var guideProgramName = cell.guideProgramName; if (!guideProgramName) { guideProgramName = cell.querySelector('.guideProgramName'); @@ -396,7 +395,7 @@ define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager', try { program.StartDateLocal = datetime.parseISO8601Date(program.StartDate, { toLocal: true }); } catch (err) { - console.log('error parsing timestamp for start date'); + console.error('error parsing timestamp for start date'); } } @@ -404,7 +403,7 @@ define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager', try { program.EndDateLocal = datetime.parseISO8601Date(program.EndDate, { toLocal: true }); } catch (err) { - console.log('error parsing timestamp for end date'); + console.error('error parsing timestamp for end date'); } } diff --git a/src/components/guide/tvguide.template.html b/src/components/guide/tvguide.template.html index 5dc16dba3b..ef3c4b58ca 100644 --- a/src/components/guide/tvguide.template.html +++ b/src/components/guide/tvguide.template.html @@ -33,6 +33,6 @@ diff --git a/src/components/headroom/headroom.js b/src/components/headroom/headroom.js index 9c058a8e82..3c0ada3ce9 100644 --- a/src/components/headroom/headroom.js +++ b/src/components/headroom/headroom.js @@ -340,4 +340,4 @@ define(['dom', 'layoutManager', 'browser', 'css!./headroom'], function (dom, lay }; return Headroom; -}); \ No newline at end of file +}); diff --git a/src/components/homescreensettings/homescreensettings.template.html b/src/components/homescreensettings/homescreensettings.template.html index 1ed2ec1b9c..d5bae685b8 100644 --- a/src/components/homescreensettings/homescreensettings.template.html +++ b/src/components/homescreensettings/homescreensettings.template.html @@ -129,4 +129,4 @@ - \ No newline at end of file + diff --git a/src/components/homesections/homesections.js b/src/components/homesections/homesections.js index 21373a1796..430c06bc57 100644 --- a/src/components/homesections/homesections.js +++ b/src/components/homesections/homesections.js @@ -77,7 +77,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la var createNowLink = elem.querySelector("#button-createLibrary") if (createNowLink) { - createNowLink.addEventListener("click", () => { + createNowLink.addEventListener("click", function () { Dashboard.navigate("library.html"); }); } @@ -290,7 +290,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la html += ''; if (enableScrollX()) { - html += '
'; + html += '
'; html += '
'; } else { html += '
'; @@ -343,7 +343,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la if (userViews.length) { html += '

' + globalize.translate('HeaderMyMedia') + '

'; if (enableScrollX()) { - html += '
'; + html += '
'; html += '
'; } else { html += '
'; @@ -423,7 +423,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la html += '

' + globalize.translate('HeaderContinueWatching') + '

'; if (enableScrollX()) { - html += '
'; + html += '
'; html += '
'; } else { html += '
'; @@ -496,7 +496,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la html += '

' + globalize.translate('HeaderContinueWatching') + '

'; if (enableScrollX()) { - html += '
'; + html += '
'; html += '
'; } else { html += '
'; @@ -582,7 +582,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la html += '
'; if (enableScrollX()) { - html += '
'; + html += '
'; html += '
'; } else { html += '
'; @@ -639,7 +639,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la html += '
'; if (enableScrollX()) { - html += '
'; + html += '
'; html += '
' } else { html += '
'; @@ -713,7 +713,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la html += '
'; if (enableScrollX()) { - html += '
'; + html += '
'; html += '
' } else { html += '
'; @@ -785,7 +785,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la html += '
'; if (enableScrollX()) { - html += '
'; + html += '
'; html += '
' } else { html += '
'; diff --git a/src/components/htmlMediaHelper.js b/src/components/htmlMediaHelper.js index 86f05dabfa..338b8e6fef 100644 --- a/src/components/htmlMediaHelper.js +++ b/src/components/htmlMediaHelper.js @@ -114,12 +114,12 @@ define(['appSettings', 'browser', 'events'], function (appSettings, browser, eve if (!recoverDecodingErrorDate || (now - recoverDecodingErrorDate) > 3000) { recoverDecodingErrorDate = now; - console.log('try to recover media Error ...'); + console.debug('try to recover media Error ...'); hlsPlayer.recoverMediaError(); } else { if (!recoverSwapAudioCodecDate || (now - recoverSwapAudioCodecDate) > 3000) { recoverSwapAudioCodecDate = now; - console.log('try to swap Audio Codec and recover media Error ...'); + console.debug('try to swap Audio Codec and recover media Error ...'); hlsPlayer.swapAudioCodec(); hlsPlayer.recoverMediaError(); } else { @@ -233,7 +233,7 @@ define(['appSettings', 'browser', 'events'], function (appSettings, browser, eve return Promise.resolve(); } } catch (err) { - console.log('error calling video.play: ' + err); + console.error('error calling video.play: ' + err); return Promise.reject(); } } @@ -245,7 +245,7 @@ define(['appSettings', 'browser', 'events'], function (appSettings, browser, eve try { player.unload(); } catch (err) { - console.log(err); + console.error(err); } instance._castPlayer = null; @@ -258,7 +258,7 @@ define(['appSettings', 'browser', 'events'], function (appSettings, browser, eve try { player.destroy(); } catch (err) { - console.log(err); + console.error(err); } instance._shakaPlayer = null; @@ -271,7 +271,7 @@ define(['appSettings', 'browser', 'events'], function (appSettings, browser, eve try { player.destroy(); } catch (err) { - console.log(err); + console.error(err); } instance._hlsPlayer = null; @@ -286,7 +286,7 @@ define(['appSettings', 'browser', 'events'], function (appSettings, browser, eve player.detachMediaElement(); player.destroy(); } catch (err) { - console.log(err); + console.error(err); } instance._flvPlayer = null; @@ -307,14 +307,14 @@ define(['appSettings', 'browser', 'events'], function (appSettings, browser, eve hls.on(Hls.Events.ERROR, function (event, data) { - console.log('HLS Error: Type: ' + data.type + ' Details: ' + (data.details || '') + ' Fatal: ' + (data.fatal || false)); + console.error('HLS Error: Type: ' + data.type + ' Details: ' + (data.details || '') + ' Fatal: ' + (data.fatal || false)); switch (data.type) { case Hls.ErrorTypes.NETWORK_ERROR: // try to recover network error if (data.response && data.response.code && data.response.code >= 400) { - console.log('hls.js response error code: ' + data.response.code); + console.debug('hls.js response error code: ' + data.response.code); // Trigger failure differently depending on whether this is prior to start of playback, or after hls.destroy(); @@ -343,7 +343,7 @@ define(['appSettings', 'browser', 'events'], function (appSettings, browser, eve // This could be a CORS error related to access control response headers - console.log('hls.js response error code: ' + data.response.code); + console.debug('hls.js response error code: ' + data.response.code); // Trigger failure differently depending on whether this is prior to start of playback, or after hls.destroy(); @@ -355,20 +355,20 @@ define(['appSettings', 'browser', 'events'], function (appSettings, browser, eve onErrorInternal(instance, 'network'); } } else { - console.log("fatal network error encountered, try to recover"); + console.debug("fatal network error encountered, try to recover"); hls.startLoad(); } break; case Hls.ErrorTypes.MEDIA_ERROR: - console.log("fatal media error encountered, try to recover"); + console.debug("fatal media error encountered, try to recover"); var currentReject = reject; reject = null; handleHlsJsMediaError(instance, currentReject); break; default: - console.log('Cannot recover from hls error - destroy and trigger error'); + console.debug('Cannot recover from hls error - destroy and trigger error'); // cannot recover // Trigger failure differently depending on whether this is prior to start of playback, or after hls.destroy(); @@ -463,4 +463,4 @@ define(['appSettings', 'browser', 'events'], function (appSettings, browser, eve getCrossOriginValue: getCrossOriginValue, getBufferedRanges: getBufferedRanges }; -}); \ No newline at end of file +}); diff --git a/src/components/htmlaudioplayer/plugin.js b/src/components/htmlaudioplayer/plugin.js index ef64bad046..8cae76bbee 100644 --- a/src/components/htmlaudioplayer/plugin.js +++ b/src/components/htmlaudioplayer/plugin.js @@ -16,7 +16,7 @@ define(['events', 'browser', 'require', 'apphost', 'appSettings', 'htmlMediaHelp // Need to record the starting volume on each pass rather than querying elem.volume // This is due to iOS safari not allowing volume changes and always returning the system volume value var newVolume = Math.max(0, startingVolume - 0.15); - console.log('fading volume to ' + newVolume); + console.debug('fading volume to ' + newVolume); elem.volume = newVolume; if (newVolume <= 0) { @@ -113,7 +113,7 @@ define(['events', 'browser', 'require', 'apphost', 'appSettings', 'htmlMediaHelp bindEvents(elem); var val = options.url; - console.log('playing url: ' + val); + console.debug('playing url: ' + val); // Convert to seconds var seconds = (options.playerStartPositionTicks || 0) / 10000000; @@ -298,7 +298,7 @@ define(['events', 'browser', 'require', 'apphost', 'appSettings', 'htmlMediaHelp var errorCode = this.error ? (this.error.code || 0) : 0; var errorMessage = this.error ? (this.error.message || '') : ''; - console.log('Media element error: ' + errorCode.toString() + ' ' + errorMessage); + console.error('media element error: ' + errorCode.toString() + ' ' + errorMessage); var type; diff --git a/src/components/htmlvideoplayer/plugin.js b/src/components/htmlvideoplayer/plugin.js index 45eff41dbe..d19187c9ed 100644 --- a/src/components/htmlvideoplayer/plugin.js +++ b/src/components/htmlvideoplayer/plugin.js @@ -1,5 +1,6 @@ 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) { "use strict"; + /* globals cast */ var mediaManager; @@ -11,7 +12,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa try { parentNode.removeChild(elem); } catch (err) { - console.log('Error removing dialog element: ' + err); + console.error('error removing dialog element: ' + err); } } } @@ -242,7 +243,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa loading.show(); - console.log('prefetching hls playlist: ' + hlsPlaylistUrl); + console.debug('prefetching hls playlist: ' + hlsPlaylistUrl); return connectionManager.getApiClient(item.ServerId).ajax({ @@ -251,7 +252,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa }).then(function () { - console.log('completed prefetching hls playlist: ' + hlsPlaylistUrl); + console.debug('completed prefetching hls playlist: ' + hlsPlaylistUrl); loading.hide(); streamInfo.url = hlsPlaylistUrl; @@ -260,7 +261,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa }, function () { - console.log('error prefetching hls playlist: ' + hlsPlaylistUrl); + console.error('error prefetching hls playlist: ' + hlsPlaylistUrl); loading.hide(); return Promise.resolve(); @@ -357,6 +358,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa return new Promise(function (resolve, reject) { require(['shaka'], function () { + /* globals shaka */ var player = new shaka.Player(elem); @@ -408,7 +410,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa lrd.media.streamType = cast.receiver.media.StreamType.OTHER; lrd.media.customData = options; - console.log('loading media url into mediaManager'); + console.debug('loading media url into media manager'); try { mediaManager.load(lrd); @@ -418,7 +420,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa return Promise.resolve(); } catch (err) { - console.log('mediaManager error: ' + err); + console.debug('media manager error: ' + err); return Promise.reject(); } } @@ -460,11 +462,11 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa protocol = cast.player.api.CreateSmoothStreamingProtocol(host); } - console.log('loading playback url: ' + url); - console.log('contentType: ' + contentType); + console.debug('loading playback url: ' + url); + console.debug('content type: ' + contentType); host.onError = function (errorCode) { - console.log("Fatal Error - " + errorCode); + console.error("fatal Error - " + errorCode); }; mediaElement.autoplay = false; @@ -499,7 +501,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa elem.removeEventListener('error', onError); var val = options.url; - console.log('playing url: ' + val); + console.debug('playing url: ' + val); // Convert to seconds var seconds = (options.playerStartPositionTicks || 0) / 10000000; @@ -608,7 +610,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa } else if (currentTrackEvents) { setTrackEventsSubtitleOffset(currentTrackEvents, offsetValue); } else { - console.log("No available track, cannot apply offset: ", offsetValue); + console.debug("No available track, cannot apply offset: ", offsetValue); } } }; @@ -727,22 +729,18 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa // https://msdn.microsoft.com/en-us/library/hh772507(v=vs.85).aspx var elemAudioTracks = elem.audioTracks || []; - console.log('found ' + elemAudioTracks.length + ' audio tracks'); + console.debug('found ' + elemAudioTracks.length + ' audio tracks'); for (i = 0, length = elemAudioTracks.length; i < length; i++) { if (audioIndex === i) { - console.log('setting audio track ' + i + ' to enabled'); + console.debug('setting audio track ' + i + ' to enabled'); elemAudioTracks[i].enabled = true; } else { - console.log('setting audio track ' + i + ' to disabled'); + console.debug('setting audio track ' + i + ' to disabled'); elemAudioTracks[i].enabled = false; } } - - setTimeout(function () { - elem.currentTime = elem.currentTime; - }, 100); }; self.stop = function (destroyPlayer) { @@ -911,7 +909,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa function onError() { var errorCode = this.error ? (this.error.code || 0) : 0; var errorMessage = this.error ? (this.error.message || '') : ''; - console.log('Media element error: ' + errorCode.toString() + ' ' + errorMessage); + console.error('media element error: ' + errorCode.toString() + ' ' + errorMessage); var type; @@ -1058,8 +1056,9 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa return i.DeliveryUrl; }), workerUrl: appRouter.baseUrl() + "/libraries/subtitles-octopus-worker.js", + legacyWorkerUrl: appRouter.baseUrl() + "/libraries/subtitles-octopus-worker-legacy.js", onError: function() { - htmlMediaHelper.onErrorInternal(self, 'mediadecodeerror') + htmlMediaHelper.onErrorInternal(self, 'mediadecodeerror'); } }; require(['JavascriptSubtitlesOctopus'], function(SubtitlesOctopus) { @@ -1115,9 +1114,10 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa function renderSsaAss(videoElement, track, item) { if (supportsCanvas() && supportsWebWorkers()) { + console.debug('rendering subtitles with SubtitlesOctopus'); renderWithSubtitlesOctopus(videoElement, track, item); } else { - console.log('rendering subtitles with libjass'); + console.debug('rendering subtitles with libjass'); renderWithLibjass(videoElement, track, item); } } @@ -1137,7 +1137,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa var videoElement = self._mediaElement; var width = videoElement.offsetWidth; var height = videoElement.offsetHeight; - console.log('videoElement resized: ' + width + 'x' + height); + console.debug('videoElement resized: ' + width + 'x' + height); renderer.resize(width, height, 0, 0); } } @@ -1254,7 +1254,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa trackElement.removeCue(trackElement.cues[0]); } } catch (e) { - console.log('Error removing cue from textTrack'); + console.error('error removing cue from textTrack'); } trackElement.mode = 'disabled'; @@ -1268,7 +1268,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa fetchSubtitles(track, item).then(function (data) { // show in ui - console.log('downloaded ' + data.TrackEvents.length + ' track events'); + console.debug('downloaded ' + data.TrackEvents.length + ' track events'); // add some cues to show the text // in safari, the cues need to be added before setting the track mode to showing data.TrackEvents.forEach(function (trackEvent) { @@ -1294,7 +1294,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa try { clock.seek(timeMs / 1000); } catch (err) { - console.log('Error in libjass: ' + err); + console.error('error in libjass: ' + err); } return; } @@ -1327,7 +1327,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa function setCurrentTrackElement(streamIndex) { - console.log('Setting new text track index to: ' + streamIndex); + console.debug('setting new text track index to: ' + streamIndex); var mediaStreamTextTracks = getMediaStreamTextTracks(self._currentPlayOptions.mediaSource); @@ -1348,38 +1348,6 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa } } - function updateTextStreamUrls(startPositionTicks) { - - if (!supportsTextTracks()) { - return; - } - - var allTracks = self._mediaElement.textTracks; // get list of tracks - var i; - var track; - - for (i = 0; i < allTracks.length; i++) { - - track = allTracks[i]; - - // This throws an error in IE, but is fine in chrome - // In IE it's not necessary anyway because changing the src seems to be enough - try { - while (track.cues.length) { - track.removeCue(track.cues[0]); - } - } catch (e) { - console.log('Error removing cue from textTrack'); - } - } - - var tracks = self._mediaElement.querySelectorAll('track'); - for (i = 0; i < tracks.length; i++) { - track = tracks[i]; - track.src = replaceQueryString(track.src, 'startPositionTicks', startPositionTicks); - } - } - function createMediaElement(options) { if (browser.tv || browser.iOS || browser.mobile) { @@ -1590,7 +1558,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa }; function onPictureInPictureError(err) { - console.log('Picture in picture error: ' + err.toString()); + console.error('Picture in picture error: ' + err.toString()); } HtmlVideoPlayer.prototype.setPictureInPictureEnabled = function (isEnabled) { @@ -1651,9 +1619,13 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa if (document.AirPlayEnabled) { if (video) { if (isEnabled) { - video.requestAirPlay().catch(onAirPlayError); + video.requestAirPlay().catch(function(err) { + console.error("Error requesting AirPlay", err) + }); } else { - document.exitAirPLay().catch(onAirPlayError); + document.exitAirPLay().catch(function(err) { + console.error("Error exiting AirPlay", err) + }); } } } else { diff --git a/src/components/humanedate.js b/src/components/humanedate.js index 85d3a6d3bf..26ce26d942 100644 --- a/src/components/humanedate.js +++ b/src/components/humanedate.js @@ -25,6 +25,7 @@ define(["datetime"], function (datetime) { if (seconds < 0) { seconds = Math.abs(seconds); } + // eslint-disable-next-line no-cond-assign for (; format = time_formats[i++];) { if (seconds < format[0]) { if (2 == format.length) { diff --git a/src/components/imagedownloader/imagedownloader.js b/src/components/imagedownloader/imagedownloader.js index f984ce22a5..ce53b5cf0d 100644 --- a/src/components/imagedownloader/imagedownloader.js +++ b/src/components/imagedownloader/imagedownloader.js @@ -117,7 +117,7 @@ define(['loading', 'apphost', 'dialogHelper', 'connectionManager', 'imageLoader' html += '
'; html += ''; - html += ''; + html += ''; html += '
'; } @@ -277,7 +277,7 @@ define(['loading', 'apphost', 'dialogHelper', 'connectionManager', 'imageLoader' if (enableFooterButtons) { html += '
'; - html += ''; + html += ''; html += '
'; } diff --git a/src/components/images/imageFetcher.js b/src/components/images/imageFetcher.js index 54d3ef7502..1e13cebc77 100644 --- a/src/components/images/imageFetcher.js +++ b/src/components/images/imageFetcher.js @@ -35,4 +35,4 @@ define(['dom'], function (dom) { loadImage: loadImage }; -}); \ No newline at end of file +}); diff --git a/src/components/images/imageLoader.js b/src/components/images/imageLoader.js index 80fcbbd3f4..764be06fd1 100644 --- a/src/components/images/imageLoader.js +++ b/src/components/images/imageLoader.js @@ -122,4 +122,4 @@ define(['lazyLoader', 'imageFetcher', 'layoutManager', 'browser', 'appSettings', self.getPrimaryImageAspectRatio = getPrimaryImageAspectRatio; return self; -}); \ No newline at end of file +}); diff --git a/src/components/imageuploader/imageuploader.js b/src/components/imageuploader/imageuploader.js index 198f540802..400646f669 100644 --- a/src/components/imageuploader/imageuploader.js +++ b/src/components/imageuploader/imageuploader.js @@ -47,7 +47,7 @@ define(['dialogHelper', 'connectionManager', 'dom', 'loading', 'scrollHelper', ' }; reader.onabort = function () { loading.hide(); - console.log('File read cancelled'); + console.debug('File read cancelled'); }; // Closure to capture the file information. diff --git a/src/components/indicators/indicators.js b/src/components/indicators/indicators.js index 4b9b0a8c69..e41ccb9775 100644 --- a/src/components/indicators/indicators.js +++ b/src/components/indicators/indicators.js @@ -62,7 +62,7 @@ define(['datetime', 'itemHelper', 'css!./indicators.css', 'material-icons'], fun startDate = datetime.parseISO8601Date(item.StartDate).getTime(); endDate = datetime.parseISO8601Date(item.EndDate).getTime(); } catch (err) { - console.log(err); + console.error(err); } var now = new Date().getTime(); @@ -174,7 +174,7 @@ define(['datetime', 'itemHelper', 'css!./indicators.css', 'material-icons'], fun return '
Unaired
'; } } catch (err) { - console.log(err); + console.error(err); } } return '
Missing
'; diff --git a/src/components/serverNotifications/gamepadtokey.js b/src/components/input/gamepadtokey.js similarity index 64% rename from src/components/serverNotifications/gamepadtokey.js rename to src/components/input/gamepadtokey.js index abf3ddb38b..5356bcbb45 100644 --- a/src/components/serverNotifications/gamepadtokey.js +++ b/src/components/input/gamepadtokey.js @@ -251,114 +251,150 @@ require(['apphost'], function (appHost) { } } + var inputLoopTimer; function runInputLoop() { // Get the latest gamepad state. - var gamepads; - if (navigator.getGamepads) { - gamepads = navigator.getGamepads(); - } else if (navigator.webkitGetGamepads) { - gamepads = navigator.webkitGetGamepads(); - } - gamepads = gamepads || []; - var i; - var j; - var len; - for (i = 0, len = gamepads.length; i < len; i++) { + var gamepads = navigator.getGamepads(); + for (var i = 0, len = gamepads.length; i < len; i++) { var gamepad = gamepads[i]; - if (gamepad) { - // Iterate through the axes - var axes = gamepad.axes; - var leftStickX = axes[0]; - var leftStickY = axes[1]; - if (leftStickX > _THUMB_STICK_THRESHOLD) { // Right - _ButtonPressedState.setleftThumbstickRight(true); - } else if (leftStickX < -_THUMB_STICK_THRESHOLD) { // Left - _ButtonPressedState.setleftThumbstickLeft(true); - } else if (leftStickY < -_THUMB_STICK_THRESHOLD) { // Up - _ButtonPressedState.setleftThumbstickUp(true); - } else if (leftStickY > _THUMB_STICK_THRESHOLD) { // Down - _ButtonPressedState.setleftThumbstickDown(true); - } else { - _ButtonPressedState.setleftThumbstickLeft(false); - _ButtonPressedState.setleftThumbstickRight(false); - _ButtonPressedState.setleftThumbstickUp(false); - _ButtonPressedState.setleftThumbstickDown(false); - } - // Iterate through the buttons to see if Left thumbstick, DPad, A and B are pressed. - var buttons = gamepad.buttons; - for (j = 0, len = buttons.length; j < len; j++) { - if (ProcessedButtons.indexOf(j) !== -1) { - - if (buttons[j].pressed) { - switch (j) { - case _GAMEPAD_DPAD_UP_BUTTON_INDEX: - _ButtonPressedState.setdPadUp(true); - break; - case _GAMEPAD_DPAD_DOWN_BUTTON_INDEX: - _ButtonPressedState.setdPadDown(true); - break; - case _GAMEPAD_DPAD_LEFT_BUTTON_INDEX: - _ButtonPressedState.setdPadLeft(true); - break; - case _GAMEPAD_DPAD_RIGHT_BUTTON_INDEX: - _ButtonPressedState.setdPadRight(true); - break; - case _GAMEPAD_A_BUTTON_INDEX: - _ButtonPressedState.setgamepadA(true); - break; - case _GAMEPAD_B_BUTTON_INDEX: - _ButtonPressedState.setgamepadB(true); - break; - default: - // No-op - break; - } - } else { - switch (j) { - case _GAMEPAD_DPAD_UP_BUTTON_INDEX: - if (_ButtonPressedState.getdPadUp()) { - _ButtonPressedState.setdPadUp(false); - } - break; - case _GAMEPAD_DPAD_DOWN_BUTTON_INDEX: - if (_ButtonPressedState.getdPadDown()) { - _ButtonPressedState.setdPadDown(false); - } - break; - case _GAMEPAD_DPAD_LEFT_BUTTON_INDEX: - if (_ButtonPressedState.getdPadLeft()) { - _ButtonPressedState.setdPadLeft(false); - } - break; - case _GAMEPAD_DPAD_RIGHT_BUTTON_INDEX: - if (_ButtonPressedState.getdPadRight()) { - _ButtonPressedState.setdPadRight(false); - } - break; - case _GAMEPAD_A_BUTTON_INDEX: - if (_ButtonPressedState.getgamepadA()) { - _ButtonPressedState.setgamepadA(false); - } - break; - case _GAMEPAD_B_BUTTON_INDEX: - if (_ButtonPressedState.getgamepadB()) { - _ButtonPressedState.setgamepadB(false); - } - break; - default: - // No-op - break; - } + if (!gamepad) { + continue; + } + // Iterate through the axes + var axes = gamepad.axes; + var leftStickX = axes[0]; + var leftStickY = axes[1]; + if (leftStickX > _THUMB_STICK_THRESHOLD) { // Right + _ButtonPressedState.setleftThumbstickRight(true); + } else if (leftStickX < -_THUMB_STICK_THRESHOLD) { // Left + _ButtonPressedState.setleftThumbstickLeft(true); + } else if (leftStickY < -_THUMB_STICK_THRESHOLD) { // Up + _ButtonPressedState.setleftThumbstickUp(true); + } else if (leftStickY > _THUMB_STICK_THRESHOLD) { // Down + _ButtonPressedState.setleftThumbstickDown(true); + } else { + _ButtonPressedState.setleftThumbstickLeft(false); + _ButtonPressedState.setleftThumbstickRight(false); + _ButtonPressedState.setleftThumbstickUp(false); + _ButtonPressedState.setleftThumbstickDown(false); + } + // Iterate through the buttons to see if Left thumbstick, DPad, A and B are pressed. + var buttons = gamepad.buttons; + for (var j = 0, len = buttons.length; j < len; j++) { + if (ProcessedButtons.indexOf(j) !== -1) { + if (buttons[j].pressed) { + switch (j) { + case _GAMEPAD_DPAD_UP_BUTTON_INDEX: + _ButtonPressedState.setdPadUp(true); + break; + case _GAMEPAD_DPAD_DOWN_BUTTON_INDEX: + _ButtonPressedState.setdPadDown(true); + break; + case _GAMEPAD_DPAD_LEFT_BUTTON_INDEX: + _ButtonPressedState.setdPadLeft(true); + break; + case _GAMEPAD_DPAD_RIGHT_BUTTON_INDEX: + _ButtonPressedState.setdPadRight(true); + break; + case _GAMEPAD_A_BUTTON_INDEX: + _ButtonPressedState.setgamepadA(true); + break; + case _GAMEPAD_B_BUTTON_INDEX: + _ButtonPressedState.setgamepadB(true); + break; + default: + // No-op + break; + } + } else { + switch (j) { + case _GAMEPAD_DPAD_UP_BUTTON_INDEX: + if (_ButtonPressedState.getdPadUp()) { + _ButtonPressedState.setdPadUp(false); + } + break; + case _GAMEPAD_DPAD_DOWN_BUTTON_INDEX: + if (_ButtonPressedState.getdPadDown()) { + _ButtonPressedState.setdPadDown(false); + } + break; + case _GAMEPAD_DPAD_LEFT_BUTTON_INDEX: + if (_ButtonPressedState.getdPadLeft()) { + _ButtonPressedState.setdPadLeft(false); + } + break; + case _GAMEPAD_DPAD_RIGHT_BUTTON_INDEX: + if (_ButtonPressedState.getdPadRight()) { + _ButtonPressedState.setdPadRight(false); + } + break; + case _GAMEPAD_A_BUTTON_INDEX: + if (_ButtonPressedState.getgamepadA()) { + _ButtonPressedState.setgamepadA(false); + } + break; + case _GAMEPAD_B_BUTTON_INDEX: + if (_ButtonPressedState.getgamepadB()) { + _ButtonPressedState.setgamepadB(false); + } + break; + default: + // No-op + break; } } } } } // Schedule the next one - requestAnimationFrame(runInputLoop); + inputLoopTimer = requestAnimationFrame(runInputLoop); } - runInputLoop(); + function startInputLoop() { + if (!inputLoopTimer) { + runInputLoop(); + } + } + + function stopInputLoop() { + cancelAnimationFrame(inputLoopTimer); + inputLoopTimer = undefined; + } + + function isGamepadConnected() { + var gamepads = navigator.getGamepads(); + for (var i = 0, len = gamepads.length; i < len; i++) { + var gamepad = gamepads[i]; + if (gamepad && gamepad.connected) { + return true; + } + } + return false; + } + + function onFocusOrGamepadAttach(e) { + if (isGamepadConnected() && document.hasFocus()) { + console.log("Gamepad connected! Starting input loop"); + startInputLoop(); + } + } + + function onFocusOrGamepadDetach(e) { + if (!isGamepadConnected() || !document.hasFocus()) { + console.log("Gamepad disconnected! No other gamepads are connected, stopping input loop"); + stopInputLoop(); + } else { + console.log("Gamepad disconnected! There are gamepads still connected."); + } + } + + // Event listeners for any change in gamepads' state. + window.addEventListener("gamepaddisconnected", onFocusOrGamepadDetach); + window.addEventListener("gamepadconnected", onFocusOrGamepadAttach); + window.addEventListener("blur", onFocusOrGamepadDetach); + window.addEventListener("focus", onFocusOrGamepadAttach); + + onFocusOrGamepadAttach(); // The gamepadInputEmulation is a string property that exists in JavaScript UWAs and in WebViews in UWAs. // It won't exist in Win8.1 style apps or browsers. @@ -369,4 +405,4 @@ require(['apphost'], function (appHost) { window.navigator.gamepadInputEmulation = "gamepad"; } -}); \ No newline at end of file +}); diff --git a/src/components/keyboardnavigation.js b/src/components/input/keyboardnavigation.js similarity index 84% rename from src/components/keyboardnavigation.js rename to src/components/input/keyboardnavigation.js index 4f3ed873d9..0359ee7430 100644 --- a/src/components/keyboardnavigation.js +++ b/src/components/input/keyboardnavigation.js @@ -1,8 +1,6 @@ define(["inputManager", "layoutManager"], function (inputManager, layoutManager) { "use strict"; - console.log("keyboardnavigation"); - /** * Key name mapping. */ @@ -45,7 +43,7 @@ define(["inputManager", "layoutManager"], function (inputManager, layoutManager) try { hasFieldKey = "key" in new KeyboardEvent("keydown"); } catch (e) { - console.log("error checking 'key' field"); + console.error("error checking 'key' field"); } if (!hasFieldKey) { @@ -142,12 +140,23 @@ define(["inputManager", "layoutManager"], function (inputManager, layoutManager) } if (capture) { - console.log("Disabling default event handling"); + console.debug("disabling default event handling"); e.preventDefault(); } }); } + // Gamepad initialisation. No script is required if no gamepads are present at init time, saving a bit of resources. + // Whenever the gamepad is connected, we hand all the control of the gamepad to gamepadtokey.js by removing the event handler + function attachGamepadScript(e) { + console.log("Gamepad connected! Attaching gamepadtokey.js script"); + window.removeEventListener("gamepadconnected", attachGamepadScript); + require(["components/input/gamepadtokey"]); + } + + // No need to check for gamepads manually at load time, the eventhandler will be fired for that + window.addEventListener("gamepadconnected", attachGamepadScript); + return { enable: enable, getKeyName: getKeyName, diff --git a/src/components/serverNotifications/mouseManager.js b/src/components/input/mouseManager.js similarity index 99% rename from src/components/serverNotifications/mouseManager.js rename to src/components/input/mouseManager.js index ffea3b01ff..78057c0bfe 100644 --- a/src/components/serverNotifications/mouseManager.js +++ b/src/components/input/mouseManager.js @@ -166,4 +166,4 @@ define(['inputManager', 'focusManager', 'browser', 'layoutManager', 'events', 'd events.on(layoutManager, 'modechange', initMouse); return self; -}); \ No newline at end of file +}); diff --git a/src/components/itemsrefresher.js b/src/components/itemsrefresher.js index 46956d2df5..6da74eef80 100644 --- a/src/components/itemsrefresher.js +++ b/src/components/itemsrefresher.js @@ -278,4 +278,4 @@ define(['playbackManager', 'serverNotifications', 'events'], function (playbackM }; return ItemsRefresher; -}); \ No newline at end of file +}); diff --git a/src/components/lazyloader/lazyloader-intersectionobserver.js b/src/components/lazyloader/lazyloader-intersectionobserver.js index 1935f65a30..5f83742601 100644 --- a/src/components/lazyloader/lazyloader-intersectionobserver.js +++ b/src/components/lazyloader/lazyloader-intersectionobserver.js @@ -100,4 +100,4 @@ define(['require', 'browser'], function (require, browser) { }; return LazyLoader; -}); \ No newline at end of file +}); diff --git a/src/components/lazyloader/lazyloader-scroll.js b/src/components/lazyloader/lazyloader-scroll.js index 318f6dbea0..d5120146ce 100644 --- a/src/components/lazyloader/lazyloader-scroll.js +++ b/src/components/lazyloader/lazyloader-scroll.js @@ -186,4 +186,4 @@ define(['visibleinviewport', 'dom', 'browser'], function (visibleinviewport, dom }; return LazyLoader; -}); \ No newline at end of file +}); diff --git a/src/components/libraryoptionseditor/libraryoptionseditor.js b/src/components/libraryoptionseditor/libraryoptionseditor.js index f9f63c9b51..193533bfc2 100644 --- a/src/components/libraryoptionseditor/libraryoptionseditor.js +++ b/src/components/libraryoptionseditor/libraryoptionseditor.js @@ -58,7 +58,7 @@ define(["globalize", "dom", "emby-checkbox", "emby-select", "emby-input"], funct for (var i = 0; i < plugins.length; i++) { var plugin = plugins[i]; html += '
'; - html += 'live_tv'; + html += ''; html += '
'; html += '

'; html += plugin.Name; @@ -463,7 +463,7 @@ define(["globalize", "dom", "emby-checkbox", "emby-select", "emby-input"], funct if (!typeOptions) { typeOptions = { - Type: type + Type: originalTypeOption.Type }; options.TypeOptions.push(typeOptions); } diff --git a/src/components/libraryoptionseditor/libraryoptionseditor.template.html b/src/components/libraryoptionseditor/libraryoptionseditor.template.html index ebfdacaa19..377488f44f 100644 --- a/src/components/libraryoptionseditor/libraryoptionseditor.template.html +++ b/src/components/libraryoptionseditor/libraryoptionseditor.template.html @@ -147,4 +147,4 @@
${SaveSubtitlesIntoMediaFoldersHelp}

-
\ No newline at end of file +
diff --git a/src/components/listview/listview.js b/src/components/listview/listview.js index 4ab317155d..b38d601e3b 100644 --- a/src/components/listview/listview.js +++ b/src/components/listview/listview.js @@ -269,7 +269,6 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan if (options.image !== false) { var imgUrl = options.imageSource === 'channel' ? getChannelImageUrl(item, downloadWidth) : getImageUrl(item, downloadWidth); - console.log(imgUrl); var imageClass = isLargeStyle ? 'listItemImage listItemImage-large' : 'listItemImage'; if (isLargeStyle && layoutManager.tv) { diff --git a/src/components/loading/loading.js b/src/components/loading/loading.js index 510f311217..d6c00347c7 100644 --- a/src/components/loading/loading.js +++ b/src/components/loading/loading.js @@ -81,4 +81,4 @@ define(['components/loading/loadingLegacy', 'browser', 'css!./loading'], functio } } }; -}); \ No newline at end of file +}); diff --git a/src/components/maintabsmanager.js b/src/components/maintabsmanager.js index 64e25b4870..2571470015 100644 --- a/src/components/maintabsmanager.js +++ b/src/components/maintabsmanager.js @@ -264,4 +264,4 @@ define(['dom', 'browser', 'events', 'emby-tabs', 'emby-button'], function (dom, getTabsElement: getTabsElement, selectedTabIndex: selectedTabIndex }; -}); \ No newline at end of file +}); diff --git a/src/components/mediainfo/mediainfo.js b/src/components/mediainfo/mediainfo.js index 3b25b58ffa..188ea9a07c 100644 --- a/src/components/mediainfo/mediainfo.js +++ b/src/components/mediainfo/mediainfo.js @@ -57,7 +57,7 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater miscInfo.push(text); } catch (e) { - console.log("Error parsing date: " + item.StartDate); + console.error("error parsing date: " + item.StartDate); } } @@ -143,7 +143,7 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater text = datetime.toLocaleDateString(date); miscInfo.push(text); } catch (e) { - console.log("Error parsing date: " + item.PremiereDate); + console.error("error parsing date: " + item.PremiereDate); } } } @@ -176,7 +176,7 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater miscInfo.push(text); } } catch (e) { - console.log("Error parsing date: " + item.StartDate); + console.error("error parsing date: " + item.StartDate); } } @@ -200,7 +200,7 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater } } catch (e) { - console.log("Error parsing date: " + item.EndDate); + console.error("error parsing date: " + item.EndDate); } } @@ -248,7 +248,7 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater text = globalize.translate('OriginalAirDateValue', datetime.toLocaleDateString(date)); miscInfo.push(text); } catch (e) { - console.log("Error parsing date: " + item.PremiereDate); + console.error("error parsing date: " + item.PremiereDate); } } else if (item.ProductionYear) { miscInfo.push(item.ProductionYear); @@ -267,7 +267,7 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater text = datetime.parseISO8601Date(item.PremiereDate).getFullYear(); miscInfo.push(text); } catch (e) { - console.log("Error parsing date: " + item.PremiereDate); + console.error("error parsing date: " + item.PremiereDate); } } } diff --git a/src/components/metadataeditor/metadataeditor.js b/src/components/metadataeditor/metadataeditor.js index 030fdc80ce..e8736258fa 100644 --- a/src/components/metadataeditor/metadataeditor.js +++ b/src/components/metadataeditor/metadataeditor.js @@ -477,7 +477,7 @@ define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loadi html += '
'; if (formatString) { - html += ''; + html += ''; } html += '
'; @@ -917,7 +917,7 @@ define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loadi for (var i = 0; i < items.length; i++) { html += '
'; - html += 'live_tv'; + html += ''; html += '
'; diff --git a/src/components/metadataeditor/personeditor.js b/src/components/metadataeditor/personeditor.js index 7883cfca1b..9fb6fdec6f 100644 --- a/src/components/metadataeditor/personeditor.js +++ b/src/components/metadataeditor/personeditor.js @@ -96,4 +96,4 @@ define(['dialogHelper', 'layoutManager', 'globalize', 'require', 'paper-icon-but return { show: show }; -}); \ No newline at end of file +}); diff --git a/src/components/multidownload.js b/src/components/multidownload.js index a1881b8db9..d11e52de14 100644 --- a/src/components/multidownload.js +++ b/src/components/multidownload.js @@ -63,4 +63,4 @@ define(['browser'], function (browser) { download(url); }); }; -}); \ No newline at end of file +}); diff --git a/src/components/nowplayingbar/nowplayingbar.js b/src/components/nowplayingbar/nowplayingbar.js index 9a96220e51..8da9b9c053 100644 --- a/src/components/nowplayingbar/nowplayingbar.js +++ b/src/components/nowplayingbar/nowplayingbar.js @@ -54,7 +54,7 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', html += '
'; - html += ''; + html += ''; html += '
'; html += ''; @@ -591,8 +591,7 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', } function onPlaybackStart(e, state) { - - //console.log('nowplaying event: ' + e.type); + console.debug('nowplaying event: ' + e.type); var player = this; @@ -637,7 +636,7 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', function onPlaybackStopped(e, state) { - //console.log('nowplaying event: ' + e.type); + console.debug('nowplaying event: ' + e.type); var player = this; if (player.isLocalPlayer) { @@ -663,7 +662,7 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', function onStateChanged(event, state) { - //console.log('nowplaying event: ' + e.type); + console.debug('nowplaying event: ' + event.type); var player = this; if (!state.NowPlayingItem || layoutManager.tv) { diff --git a/src/components/packagemanager.js b/src/components/packagemanager.js index 03ed1006c1..46f4704522 100644 --- a/src/components/packagemanager.js +++ b/src/components/packagemanager.js @@ -149,4 +149,4 @@ define(['appSettings', 'pluginManager'], function (appSettings, pluginManager) { }; return new PackageManager(); -}); \ No newline at end of file +}); diff --git a/src/components/photoplayer/plugin.js b/src/components/photoplayer/plugin.js index 6629fbfb0f..4ebdbbd6d2 100644 --- a/src/components/photoplayer/plugin.js +++ b/src/components/photoplayer/plugin.js @@ -43,4 +43,4 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa }; return PhotoPlayer; -}); \ No newline at end of file +}); diff --git a/src/components/playback/experimentalwarnings.js b/src/components/playback/experimentalwarnings.js index 17b1af0257..2d1ef53c19 100644 --- a/src/components/playback/experimentalwarnings.js +++ b/src/components/playback/experimentalwarnings.js @@ -94,4 +94,4 @@ define(['connectionManager', 'globalize', 'userSettings', 'apphost'], function ( }; return ExpirementalPlaybackWarnings; -}); \ No newline at end of file +}); diff --git a/src/components/playback/playaccessvalidation.js b/src/components/playback/playaccessvalidation.js index 35d8314fc1..46a6f7546c 100644 --- a/src/components/playback/playaccessvalidation.js +++ b/src/components/playback/playaccessvalidation.js @@ -47,4 +47,4 @@ define(['connectionManager', 'globalize'], function (connectionManager, globaliz }; return PlayAccessValidation; -}); \ No newline at end of file +}); diff --git a/src/components/playback/playbackmanager.js b/src/components/playback/playbackmanager.js index da04a2e13e..3a3bddd989 100644 --- a/src/components/playback/playbackmanager.js +++ b/src/components/playback/playbackmanager.js @@ -57,7 +57,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla addPlaylistToPlaybackReport(playbackManagerInstance, info, player, serverId); } - //console.log(method + '-' + JSON.stringify(info)); + console.debug(method + '-' + JSON.stringify(info)); var apiClient = connectionManager.getApiClient(serverId); apiClient[method](info); } @@ -1024,7 +1024,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla currentTargetInfo = targetInfo; if (targetInfo) { - console.log('Active player: ' + JSON.stringify(targetInfo)); + console.debug('Active player: ' + JSON.stringify(targetInfo)); } if (player && player.isLocalPlayer) { @@ -2828,7 +2828,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla if (newItemInfo) { - console.log('playing next track'); + console.debug('playing next track'); var newItemPlayOptions = newItemInfo.item.playOptions || getDefaultPlayOptions(); @@ -3118,7 +3118,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla // medianotsupported var errorType = error.type; - console.log('playbackmanager playback error type: ' + (errorType || '')); + console.debug('playbackmanager playback error type: ' + (errorType || '')); var streamInfo = error.streamInfo || getPlayerData(player).streamInfo; @@ -3401,7 +3401,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla function getLiveStreamMediaInfo(player, streamInfo, mediaSource, liveStreamId, serverId) { - console.log('getLiveStreamMediaInfo'); + console.debug('getLiveStreamMediaInfo'); streamInfo.lastMediaInfoQuery = new Date().getTime(); @@ -3961,7 +3961,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla }; PlaybackManager.prototype.sendCommand = function (cmd, player) { - console.log('MediaController received command: ' + cmd.Name); + console.debug('MediaController received command: ' + cmd.Name); switch (cmd.Name) { case 'SetRepeatMode': this.setRepeatMode(cmd.Arguments.RepeatMode, player); diff --git a/src/components/playback/playbackorientation.js b/src/components/playback/playbackorientation.js index 3253d8acdf..5b178dbf08 100644 --- a/src/components/playback/playbackorientation.js +++ b/src/components/playback/playbackorientation.js @@ -9,7 +9,7 @@ define(['playbackManager', 'layoutManager', 'events'], function (playbackManager function onOrientationChangeError(err) { orientationLocked = false; - console.log('error locking orientation: ' + err); + console.error('error locking orientation: ' + err); } events.on(playbackManager, 'playbackstart', function (e, player, state) { @@ -46,10 +46,10 @@ define(['playbackManager', 'layoutManager', 'events'], function (playbackManager try { unlockOrientation(); } catch (err) { - console.log('error unlocking orientation: ' + err); + console.error('error unlocking orientation: ' + err); } orientationLocked = false; } } }); -}); \ No newline at end of file +}); diff --git a/src/components/playback/playmethodhelper.js b/src/components/playback/playmethodhelper.js index 4e85f87093..75af04035c 100644 --- a/src/components/playback/playmethodhelper.js +++ b/src/components/playback/playmethodhelper.js @@ -21,4 +21,4 @@ define([], function () { return { getDisplayPlayMethod: getDisplayPlayMethod }; -}); \ No newline at end of file +}); diff --git a/src/components/playback/playqueuemanager.js b/src/components/playback/playqueuemanager.js index ed2076a814..429c4027f1 100644 --- a/src/components/playback/playqueuemanager.js +++ b/src/components/playback/playqueuemanager.js @@ -230,4 +230,4 @@ define([], function () { }; return PlayQueueManager; -}); \ No newline at end of file +}); diff --git a/src/components/playback/remotecontrolautoplay.js b/src/components/playback/remotecontrolautoplay.js index d8316b87ef..90a872cc6e 100644 --- a/src/components/playback/remotecontrolautoplay.js +++ b/src/components/playback/remotecontrolautoplay.js @@ -32,16 +32,16 @@ define(['events', 'playbackManager'], function (events, playbackManager) { } if (!oldPlayer.isLocalPlayer) { - console.log('Skipping remote control autoplay because oldPlayer is not a local player'); + console.debug('Skipping remote control autoplay because oldPlayer is not a local player'); return; } if (newPlayer.isLocalPlayer) { - console.log('Skipping remote control autoplay because newPlayer is a local player'); + console.debug('Skipping remote control autoplay because newPlayer is a local player'); return; } transferPlayback(oldPlayer, newPlayer); }); -}); \ No newline at end of file +}); diff --git a/src/components/playback/volumeosd.js b/src/components/playback/volumeosd.js index de20aaab15..5d2c90ddb7 100644 --- a/src/components/playback/volumeosd.js +++ b/src/components/playback/volumeosd.js @@ -11,7 +11,7 @@ define(['events', 'playbackManager', 'dom', 'browser', 'css!./iconosd', 'materia function getOsdElementHtml() { var html = ''; - html += ''; + html += ''; html += '
'; diff --git a/src/components/playbacksettings/playbacksettings.js b/src/components/playbacksettings/playbacksettings.js index 69915b18bf..d249b5b989 100644 --- a/src/components/playbacksettings/playbacksettings.js +++ b/src/components/playbacksettings/playbacksettings.js @@ -342,4 +342,4 @@ define(['require', 'browser', 'appSettings', 'apphost', 'focusManager', 'quality }; return PlaybackSettings; -}); \ No newline at end of file +}); diff --git a/src/components/playbacksettings/playbacksettings.template.html b/src/components/playbacksettings/playbacksettings.template.html index 06cfe3f3d6..0c8b726a40 100644 --- a/src/components/playbacksettings/playbacksettings.template.html +++ b/src/components/playbacksettings/playbacksettings.template.html @@ -86,4 +86,4 @@ - \ No newline at end of file + diff --git a/src/components/playmenu.js b/src/components/playmenu.js index 7225ff94e1..a410da6985 100644 --- a/src/components/playmenu.js +++ b/src/components/playmenu.js @@ -72,4 +72,4 @@ define(['actionsheet', 'datetime', 'playbackManager', 'globalize', 'appSettings' return { show: show }; -}); \ No newline at end of file +}); diff --git a/src/components/pluginManager.js b/src/components/pluginManager.js index ec65e63e65..2126d73b3c 100644 --- a/src/components/pluginManager.js +++ b/src/components/pluginManager.js @@ -27,7 +27,7 @@ define(['events'], function (events) { PluginManager.prototype.loadPlugin = function (url) { - console.log('Loading plugin: ' + url); + console.debug('Loading plugin: ' + url); var instance = this; return new Promise(function (resolve, reject) { @@ -146,4 +146,4 @@ define(['events'], function (events) { }; return new PluginManager(); -}); \ No newline at end of file +}); diff --git a/src/components/polyfills/focusPreventScroll.js b/src/components/polyfills/focusPreventScroll.js index 6511c0426c..6df9e9928c 100644 --- a/src/components/polyfills/focusPreventScroll.js +++ b/src/components/polyfills/focusPreventScroll.js @@ -12,6 +12,7 @@ if (HTMLElement.prototype.nativeFocus === undefined) { }, true); var opts = Object.defineProperty({}, "preventScroll", { + // eslint-disable-next-line getter-return get: function () { supportsPreventScrollOption = true; } @@ -19,7 +20,7 @@ if (HTMLElement.prototype.nativeFocus === undefined) { focusElem.focus(opts); } catch (e) { - console.log("error checking preventScroll support"); + console.error("error checking preventScroll support"); } if (!supportsPreventScrollOption) { diff --git a/src/components/polyfills/objectassign.js b/src/components/polyfills/objectassign.js index bf8d7118a5..85f55aa144 100644 --- a/src/components/polyfills/objectassign.js +++ b/src/components/polyfills/objectassign.js @@ -11,6 +11,7 @@ if (typeof Object.assign != 'function') { var source = arguments[index]; if (source !== undefined && source !== null) { for (var nextKey in source) { + // eslint-disable-next-line no-prototype-builtins if (source.hasOwnProperty(nextKey)) { output[nextKey] = source[nextKey]; } diff --git a/src/components/prompt/nativeprompt.js b/src/components/prompt/nativeprompt.js index b0634bd428..ba7f1a9a49 100644 --- a/src/components/prompt/nativeprompt.js +++ b/src/components/prompt/nativeprompt.js @@ -25,4 +25,4 @@ define([], function () { return Promise.reject(result); } }; -}); \ No newline at end of file +}); diff --git a/src/components/prompt/prompt.js b/src/components/prompt/prompt.js index 6e8e019c83..8f4f839eaa 100644 --- a/src/components/prompt/prompt.js +++ b/src/components/prompt/prompt.js @@ -101,4 +101,4 @@ define(['dialogHelper', 'layoutManager', 'scrollHelper', 'globalize', 'dom', 're }); }); }; -}); \ No newline at end of file +}); diff --git a/src/components/qualityoptions.js b/src/components/qualityoptions.js index e46a690e8a..5ad69cb790 100644 --- a/src/components/qualityoptions.js +++ b/src/components/qualityoptions.js @@ -160,4 +160,4 @@ define(['globalize'], function (globalize) { getVideoQualityOptions: getVideoQualityOptions, getAudioQualityOptions: getAudioQualityOptions }; -}); \ No newline at end of file +}); diff --git a/src/components/recordingcreator/recordingcreator.js b/src/components/recordingcreator/recordingcreator.js index 614d483b21..a51fac4305 100644 --- a/src/components/recordingcreator/recordingcreator.js +++ b/src/components/recordingcreator/recordingcreator.js @@ -202,4 +202,4 @@ define(['dialogHelper', 'globalize', 'layoutManager', 'mediaInfo', 'apphost', 'c return { show: showEditor }; -}); \ No newline at end of file +}); diff --git a/src/components/recordingcreator/recordingeditor.js b/src/components/recordingcreator/recordingeditor.js index 3a1d4ba943..86c731ad26 100644 --- a/src/components/recordingcreator/recordingeditor.js +++ b/src/components/recordingcreator/recordingeditor.js @@ -159,4 +159,4 @@ define(['dialogHelper', 'globalize', 'layoutManager', 'mediaInfo', 'apphost', 'c return { show: showEditor }; -}); \ No newline at end of file +}); diff --git a/src/components/recordingcreator/recordinghelper.js b/src/components/recordingcreator/recordinghelper.js index 4bfd316c73..a071cb2032 100644 --- a/src/components/recordingcreator/recordinghelper.js +++ b/src/components/recordingcreator/recordinghelper.js @@ -214,4 +214,4 @@ define(['globalize', 'loading', 'connectionManager'], function (globalize, loadi cancelTimerWithConfirmation: cancelTimerWithConfirmation, cancelSeriesTimerWithConfirmation: cancelSeriesTimerWithConfirmation }; -}); \ No newline at end of file +}); diff --git a/src/components/recordingcreator/seriesrecordingeditor.js b/src/components/recordingcreator/seriesrecordingeditor.js index 73a98cf5e7..62accd5b63 100644 --- a/src/components/recordingcreator/seriesrecordingeditor.js +++ b/src/components/recordingcreator/seriesrecordingeditor.js @@ -267,4 +267,4 @@ define(['dialogHelper', 'globalize', 'layoutManager', 'mediaInfo', 'apphost', 'c show: showEditor, embed: embed }; -}); \ No newline at end of file +}); diff --git a/src/components/remotecontrol/remotecontrol.js b/src/components/remotecontrol/remotecontrol.js index 11f14fdc8e..90115b3a82 100644 --- a/src/components/remotecontrol/remotecontrol.js +++ b/src/components/remotecontrol/remotecontrol.js @@ -1,4 +1,4 @@ -define(["browser", "datetime", "backdrop", "libraryBrowser", "listView", "imageLoader", "playbackManager", "nowPlayingHelper", "events", "connectionManager", "apphost", "globalize", "cardStyle", "emby-itemscontainer", "css!./remotecontrol.css", "emby-ratingbutton"], function (browser, datetime, backdrop, libraryBrowser, listView, imageLoader, playbackManager, nowPlayingHelper, events, connectionManager, appHost, globalize) { +define(["browser", "datetime", "backdrop", "libraryBrowser", "listView", "imageLoader", "playbackManager", "nowPlayingHelper", "events", "connectionManager", "apphost", "globalize", "layoutManager", "userSettings", "cardStyle", "emby-itemscontainer", "css!./remotecontrol.css", "emby-ratingbutton"], function (browser, datetime, backdrop, libraryBrowser, listView, imageLoader, playbackManager, nowPlayingHelper, events, connectionManager, appHost, globalize, layoutManager, userSettings) { "use strict"; function showAudioMenu(context, player, button, item) { @@ -127,7 +127,7 @@ define(["browser", "datetime", "backdrop", "libraryBrowser", "listView", "imageL maxHeight: 300 }) : null; - console.log("updateNowPlayingInfo"); + console.debug("updateNowPlayingInfo"); setImageUrl(context, url); if (item) { backdrop.setBackdrops([item]); @@ -228,6 +228,11 @@ define(["browser", "datetime", "backdrop", "libraryBrowser", "listView", "imageL buttonVisible(context.querySelector(".btnFastForward"), null != item); var positionSlider = context.querySelector(".nowPlayingPositionSlider"); + if (positionSlider && item && item.RunTimeTicks) { + positionSlider.setKeyboardSteps(userSettings.skipBackLength() * 1000000 / item.RunTimeTicks, + userSettings.skipForwardLength() * 1000000 / item.RunTimeTicks); + } + if (positionSlider && !positionSlider.dragging) { positionSlider.disabled = !playState.CanSeek; var isProgressClear = state.MediaSource && null == state.MediaSource.RunTimeTicks; @@ -266,7 +271,7 @@ define(["browser", "datetime", "backdrop", "libraryBrowser", "listView", "imageL toggleRepeatButton.innerHTML = "repeat"; toggleRepeatButton.classList.add("repeatButton-active"); } else if ("RepeatOne" == repeatMode) { - toggleRepeatButton.innerHTML = "repeat_one"; + toggleRepeatButton.innerHTML = ""; toggleRepeatButton.classList.add("repeatButton-active"); } else { toggleRepeatButton.innerHTML = "repeat"; @@ -392,7 +397,7 @@ define(["browser", "datetime", "backdrop", "libraryBrowser", "listView", "imageL } function onPlaybackStart(e, state) { - console.log("remotecontrol event: " + e.type); + console.debug("remotecontrol event: " + e.type); var player = this; onStateChanged.call(player, e, state); } @@ -420,7 +425,7 @@ define(["browser", "datetime", "backdrop", "libraryBrowser", "listView", "imageL } function onPlaybackStopped(e, state) { - console.log("remotecontrol event: " + e.type); + console.debug("remotecontrol event: " + e.type); var player = this; if (!state.NextMediaType) { @@ -693,6 +698,12 @@ define(["browser", "datetime", "backdrop", "libraryBrowser", "listView", "imageL context.querySelector(".sendMessageForm").addEventListener("submit", onMessageSubmit); context.querySelector(".typeTextForm").addEventListener("submit", onSendStringSubmit); events.on(playbackManager, "playerchange", onPlayerChange); + + if (layoutManager.tv) { + var positionSlider = context.querySelector(".nowPlayingPositionSlider"); + positionSlider.classList.add("focusable"); + positionSlider.enableKeyboardDragging(); + } } function onDialogClosed(e) { diff --git a/src/components/sanitizefilename.js b/src/components/sanitizefilename.js index d422a95533..f53ce613f6 100644 --- a/src/components/sanitizefilename.js +++ b/src/components/sanitizefilename.js @@ -4,6 +4,7 @@ define([], function () { 'use strict'; var illegalRe = /[\/\?<>\\:\*\|":]/g; + // eslint-disable-next-line no-control-regex var controlRe = /[\x00-\x1f\x80-\x9f]/g; var reservedRe = /^\.+$/; var windowsReservedRe = /^(con|prn|aux|nul|com[0-9]|lpt[0-9])(\..*)?$/i; @@ -92,4 +93,4 @@ define([], function () { return truncate(sanitized, 255); } }; -}); \ No newline at end of file +}); diff --git a/src/components/screensavermanager.js b/src/components/screensavermanager.js index 5b7613c98d..b9d7082850 100644 --- a/src/components/screensavermanager.js +++ b/src/components/screensavermanager.js @@ -53,7 +53,7 @@ define(["events", "playbackManager", "pluginManager", "inputManager", "connectio throw new Error("An existing screensaver is already active."); } - console.log("Showing screensaver " + screensaver.name); + console.debug("Showing screensaver " + screensaver.name); screensaver.show(); activeScreenSaver = screensaver; @@ -71,7 +71,7 @@ define(["events", "playbackManager", "pluginManager", "inputManager", "connectio function hide() { if (activeScreenSaver) { - console.log("Hiding screensaver"); + console.debug("Hiding screensaver"); activeScreenSaver.hide(); activeScreenSaver = null; } diff --git a/src/components/scrollManager.js b/src/components/scrollManager.js index 4ba696d744..5fc3729bac 100644 --- a/src/components/scrollManager.js +++ b/src/components/scrollManager.js @@ -33,6 +33,7 @@ define(["dom", "browser", "layoutManager"], function (dom, browser, layoutManage var elem = document.createElement("div"); var opts = Object.defineProperty({}, "behavior", { + // eslint-disable-next-line getter-return get: function () { supportsScrollToOptions = true; } @@ -40,7 +41,7 @@ define(["dom", "browser", "layoutManager"], function (dom, browser, layoutManage elem.scrollTo(opts); } catch (e) { - console.log("error checking ScrollToOptions support"); + console.error("error checking ScrollToOptions support"); } /** diff --git a/src/components/scroller.js b/src/components/scroller.js index 65f33b8e8d..8c67127eb3 100644 --- a/src/components/scroller.js +++ b/src/components/scroller.js @@ -392,7 +392,7 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc var currentStart = self._pos.cur; var currentEnd = currentStart + frameSize; - //console.log('offset:' + offset + ' currentStart:' + currentStart + ' currentEnd:' + currentEnd); + console.debug('offset:' + offset + ' currentStart:' + currentStart + ' currentEnd:' + currentEnd); var isVisible = offset >= currentStart && (offset + size) <= currentEnd; return { @@ -574,8 +574,9 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc * @return {Int} */ function normalizeWheelDelta(event) { - // wheelDelta needed only for IE8- - scrolling.curDelta = ((o.horizontal ? event.deltaY || event.deltaX : event.deltaY) || -event.wheelDelta); + // JELLYFIN MOD: Only use deltaX for horizontal scroll and remove IE8 support + scrolling.curDelta = o.horizontal ? event.deltaX : event.deltaY; + // END JELLYFIN MOD if (transform) { scrolling.curDelta /= event.deltaMode === 1 ? 3 : 100; @@ -928,4 +929,4 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc }; return scrollerFactory; -}); \ No newline at end of file +}); diff --git a/src/components/scrollhelper.js b/src/components/scrollhelper.js index 6280dc5062..1a36594026 100644 --- a/src/components/scrollhelper.js +++ b/src/components/scrollhelper.js @@ -134,4 +134,4 @@ define(['focusManager', 'dom', 'scrollStyles'], function (focusManager, dom) { toCenter: toCenter, toStart: toStart }; -}); \ No newline at end of file +}); diff --git a/src/components/search/searchfields.js b/src/components/search/searchfields.js index 912acfc41c..53ab187a81 100644 --- a/src/components/search/searchfields.js +++ b/src/components/search/searchfields.js @@ -121,4 +121,4 @@ define(['layoutManager', 'globalize', 'require', 'events', 'browser', 'alphaPick }; return SearchFields; -}); \ No newline at end of file +}); diff --git a/src/components/search/searchresults.template.html b/src/components/search/searchresults.template.html index a9fa232fbc..1deecaca6c 100644 --- a/src/components/search/searchresults.template.html +++ b/src/components/search/searchresults.template.html @@ -11,7 +11,7 @@

${Movies}

-
+
@@ -19,7 +19,7 @@

${Shows}

-
+
@@ -27,7 +27,7 @@

${Episodes}

-
+
@@ -35,7 +35,7 @@

${Sports}

-
+
@@ -43,7 +43,7 @@

${Kids}

-
+
@@ -51,7 +51,7 @@

${News}

-
+
@@ -59,7 +59,7 @@

${Programs}

-
+
@@ -67,7 +67,7 @@

${Videos}

-
+
@@ -75,7 +75,7 @@

${Playlists}

-
+
@@ -83,7 +83,7 @@

${Artists}

-
+
@@ -91,7 +91,7 @@

${Albums}

-
+
@@ -99,7 +99,7 @@

${Songs}

-
+
@@ -107,7 +107,7 @@

${HeaderPhotoAlbums}

-
+
@@ -115,7 +115,7 @@

${Photos}

-
+
@@ -123,7 +123,7 @@

${HeaderAudioBooks}

-
+
@@ -131,7 +131,7 @@

${Books}

-
+
@@ -139,7 +139,7 @@

${People}

-
+
-
\ No newline at end of file +
diff --git a/src/components/serverNotifications/serverNotifications.js b/src/components/serverNotifications.js similarity index 90% rename from src/components/serverNotifications/serverNotifications.js rename to src/components/serverNotifications.js index 1941881b7a..5554925272 100644 --- a/src/components/serverNotifications/serverNotifications.js +++ b/src/components/serverNotifications.js @@ -33,7 +33,7 @@ define(['connectionManager', 'playbackManager', 'events', 'inputManager', 'focus } function processGeneralCommand(cmd, apiClient) { - console.log('Received command: ' + cmd.Name); + console.debug('Received command: ' + cmd.Name); switch (cmd.Name) { case 'Select': inputManager.trigger('select'); @@ -133,7 +133,7 @@ define(['connectionManager', 'playbackManager', 'events', 'inputManager', 'focus focusManager.sendText(cmd.Arguments.String); break; default: - console.log('processGeneralCommand does not recognize: ' + cmd.Name); + console.debug('processGeneralCommand does not recognize: ' + cmd.Name); break; } @@ -191,36 +191,14 @@ define(['connectionManager', 'playbackManager', 'events', 'inputManager', 'focus events.trigger(serverNotifications, msg.MessageType, [apiClient, msg.Data]); } } - function bindEvents(apiClient) { events.off(apiClient, "message", onMessageReceived); events.on(apiClient, "message", onMessageReceived); } - function enableNativeGamepadKeyMapping() { - if (window.navigator && "string" == typeof window.navigator.gamepadInputEmulation) { - window.navigator.gamepadInputEmulation = "keyboard"; - return true; - } - - return false; - } - - function isGamepadSupported() { - return "ongamepadconnected" in window || navigator.getGamepads || navigator.webkitGetGamepads; - } - connectionManager.getApiClients().forEach(bindEvents); - events.on(connectionManager, 'apiclientcreated', function (e, newApiClient) { bindEvents(newApiClient); }); - - if (!enableNativeGamepadKeyMapping() && isGamepadSupported()) { - require(["components/serverNotifications/gamepadtokey"]); - } - - require(["components/serverNotifications/mouseManager"]); - return serverNotifications; }); diff --git a/src/components/serverRestartDialog.js b/src/components/serverRestartDialog.js index 4c20183b2a..ef012fe44a 100644 --- a/src/components/serverRestartDialog.js +++ b/src/components/serverRestartDialog.js @@ -155,4 +155,4 @@ define(['loading', 'events', 'dialogHelper', 'dom', 'layoutManager', 'scrollHelp }; return ServerRestartDialog; -}); \ No newline at end of file +}); diff --git a/src/components/serviceworker/notifications.js b/src/components/serviceworker/notifications.js index 9c5be840bf..33f54bb64d 100644 --- a/src/components/serviceworker/notifications.js +++ b/src/components/serviceworker/notifications.js @@ -1,3 +1,4 @@ +/* eslint-env serviceworker */ (function () { 'use strict'; @@ -41,4 +42,4 @@ event.waitUntil(executeAction(action, data, serverId)); }, false); -})(); \ No newline at end of file +})(); diff --git a/src/components/sessionplayer.js b/src/components/sessionplayer.js index adcaab2674..bbb22a9654 100644 --- a/src/components/sessionplayer.js +++ b/src/components/sessionplayer.js @@ -549,4 +549,4 @@ define(['playbackManager', 'events', 'serverNotifications', 'connectionManager'] }; return SessionPlayer; -}); \ No newline at end of file +}); diff --git a/src/components/shell.js b/src/components/shell.js index 534a57b027..f82f5eea3c 100644 --- a/src/components/shell.js +++ b/src/components/shell.js @@ -27,4 +27,4 @@ define([], function () { } } }; -}); \ No newline at end of file +}); diff --git a/src/components/shortcuts.js b/src/components/shortcuts.js index 9d2b1847e5..ab606ab1d2 100644 --- a/src/components/shortcuts.js +++ b/src/components/shortcuts.js @@ -425,4 +425,4 @@ define(['playbackManager', 'inputManager', 'connectionManager', 'appRouter', 'gl getShortcutAttributesHtml: getShortcutAttributesHtml }; -}); \ No newline at end of file +}); diff --git a/src/components/skinManager.js b/src/components/skinManager.js index b757aab3d6..b81e7c3a40 100644 --- a/src/components/skinManager.js +++ b/src/components/skinManager.js @@ -96,7 +96,7 @@ define(['apphost', 'userSettings', 'browser', 'events', 'pluginManager', 'backdr appHost.setThemeColor(color); } } catch (err) { - console.log('Error setting theme color: ' + err); + console.error('error setting theme color: ' + err); } } @@ -162,6 +162,7 @@ define(['apphost', 'userSettings', 'browser', 'events', 'pluginManager', 'backdr function playSound(path, volume) { lastSound = new Date().getTime(); require(['howler'], function (howler) { + /* globals Howl */ try { var sound = new Howl({ src: [path], @@ -170,7 +171,7 @@ define(['apphost', 'userSettings', 'browser', 'events', 'pluginManager', 'backdr sound.play(); currentSound = sound; } catch (err) { - console.log('Error playing sound: ' + err); + console.error('error playing sound: ' + err); } }); } diff --git a/src/components/slideshow/slideshow.js b/src/components/slideshow/slideshow.js index 115de54b25..40d87e9519 100644 --- a/src/components/slideshow/slideshow.js +++ b/src/components/slideshow/slideshow.js @@ -78,7 +78,7 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f try { appHost.setUserScalable(scalable); } catch (err) { - console.log('error in appHost.setUserScalable: ' + err); + console.error('error in appHost.setUserScalable: ' + err); } } @@ -198,6 +198,20 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f } } + function onAutoplayStart() { + var btnSlideshowPause = dlg.querySelector('.btnSlideshowPause i'); + if (btnSlideshowPause) { + btnSlideshowPause.innerHTML = "pause"; + } + } + + function onAutoplayStop() { + var btnSlideshowPause = dlg.querySelector('.btnSlideshowPause i'); + if (btnSlideshowPause) { + btnSlideshowPause.innerHTML = ""; + } + } + function loadSwiper(dlg) { if (currentOptions.slides) { @@ -225,6 +239,9 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f speed: 240 }); + swiperInstance.on('autoplayStart', onAutoplayStart); + swiperInstance.on('autoplayStop', onAutoplayStop); + if (layoutManager.mobile) { pause(); } else { @@ -336,23 +353,15 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f } function play() { - - var btnSlideshowPause = dlg.querySelector('.btnSlideshowPause i'); - if (btnSlideshowPause) { - btnSlideshowPause.innerHTML = "pause"; + if (swiperInstance.autoplay) { + swiperInstance.autoplay.start(); } - - swiperInstance.startAutoplay(); } function pause() { - - var btnSlideshowPause = dlg.querySelector('.btnSlideshowPause i'); - if (btnSlideshowPause) { - btnSlideshowPause.innerHTML = ""; + if (swiperInstance.autoplay) { + swiperInstance.autoplay.stop(); } - - swiperInstance.stopAutoplay(); } function playPause() { @@ -641,4 +650,4 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f } }; }; -}); \ No newline at end of file +}); diff --git a/src/components/sortmenu/sortmenu.template.html b/src/components/sortmenu/sortmenu.template.html index 3f523c2959..da7da98371 100644 --- a/src/components/sortmenu/sortmenu.template.html +++ b/src/components/sortmenu/sortmenu.template.html @@ -19,4 +19,4 @@
-
\ No newline at end of file +
diff --git a/src/components/subtitlesettings/subtitleappearancehelper.js b/src/components/subtitlesettings/subtitleappearancehelper.js index 8a40bd134b..fdc64f0dfa 100644 --- a/src/components/subtitlesettings/subtitleappearancehelper.js +++ b/src/components/subtitlesettings/subtitleappearancehelper.js @@ -156,4 +156,4 @@ define([], function () { getStyles: getStyles, applyStyles: applyStyles }; -}); \ No newline at end of file +}); diff --git a/src/components/subtitlesettings/subtitlesettings.js b/src/components/subtitlesettings/subtitlesettings.js index 669b26d271..69de536e4c 100644 --- a/src/components/subtitlesettings/subtitlesettings.js +++ b/src/components/subtitlesettings/subtitlesettings.js @@ -219,4 +219,4 @@ define(['require', 'globalize', 'appSettings', 'apphost', 'focusManager', 'loadi }; return SubtitleSettings; -}); \ No newline at end of file +}); diff --git a/src/components/subtitlesettings/subtitlesettings.template.html b/src/components/subtitlesettings/subtitlesettings.template.html index a6ec43d8fa..cc2788397f 100644 --- a/src/components/subtitlesettings/subtitlesettings.template.html +++ b/src/components/subtitlesettings/subtitlesettings.template.html @@ -91,4 +91,4 @@ - \ No newline at end of file + diff --git a/src/components/subtitlesync/subtitlesync.js b/src/components/subtitlesync/subtitlesync.js index 904c612317..07ce2cb7ec 100644 --- a/src/components/subtitlesync/subtitlesync.js +++ b/src/components/subtitlesync/subtitlesync.js @@ -130,7 +130,7 @@ define(['playbackManager', 'text!./subtitlesync.template.html', 'css!./subtitles SubtitleSync.prototype.toggle = function(action) { if (player && playbackManager.supportSubtitleOffset(player)) { - + /* eslint-disable no-fallthrough */ switch (action) { case undefined: // if showing subtitle sync is enabled @@ -157,7 +157,7 @@ define(['playbackManager', 'text!./subtitlesync.template.html', 'css!./subtitles subtitleSyncContainer.classList.add("hide"); break; } - + /* eslint-enable no-fallthrough */ } } diff --git a/src/components/subtitlesync/subtitlesync.template.html b/src/components/subtitlesync/subtitlesync.template.html index 2aa6b10450..999e4d0bb9 100644 --- a/src/components/subtitlesync/subtitlesync.template.html +++ b/src/components/subtitlesync/subtitlesync.template.html @@ -4,4 +4,4 @@
-
\ No newline at end of file +
diff --git a/src/components/tabbedview/tabbedview.js b/src/components/tabbedview/tabbedview.js index 33f1c6e6cc..a67e8e0fa1 100644 --- a/src/components/tabbedview/tabbedview.js +++ b/src/components/tabbedview/tabbedview.js @@ -120,4 +120,4 @@ define(['backdrop', 'mainTabsManager', 'layoutManager', 'emby-tabs'], function ( }; return TabbedView; -}); \ No newline at end of file +}); diff --git a/src/components/thememediaplayer.js b/src/components/thememediaplayer.js index a8298fad37..94012ba823 100644 --- a/src/components/thememediaplayer.js +++ b/src/components/thememediaplayer.js @@ -108,4 +108,4 @@ define(['playbackManager', 'userSettings', 'connectionManager'], function (playb // } //}); -}); \ No newline at end of file +}); diff --git a/src/components/toast/toast.js b/src/components/toast/toast.js index d8ac404764..22eb53396c 100644 --- a/src/components/toast/toast.js +++ b/src/components/toast/toast.js @@ -39,4 +39,4 @@ define(['css!./toast'], function () { }, 300); }; -}); \ No newline at end of file +}); diff --git a/src/components/touchhelper.js b/src/components/touchhelper.js index 0f6d34aace..97455fc969 100644 --- a/src/components/touchhelper.js +++ b/src/components/touchhelper.js @@ -168,4 +168,4 @@ define(['dom', 'events'], function (dom, events) { }; return TouchHelper; -}); \ No newline at end of file +}); diff --git a/src/components/tunerpicker.js b/src/components/tunerpicker.js index ec6087b890..4dd5ecd3de 100644 --- a/src/components/tunerpicker.js +++ b/src/components/tunerpicker.js @@ -1,4 +1,4 @@ -define(["dialogHelper", "dom", "layoutManager", "connectionManager", "globalize", "loading", "browser", "material-icons", "formDialogStyle", "emby-button", "emby-itemscontainer", "cardStyle"], function (dialogHelper, dom, layoutManager, connectionManager, globalize, loading, browser) { +define(["dialogHelper", "dom", "layoutManager", "connectionManager", "globalize", "loading", "browser", "focusManager", "scrollHelper", "material-icons", "formDialogStyle", "emby-button", "emby-itemscontainer", "cardStyle"], function (dialogHelper, dom, layoutManager, connectionManager, globalize, loading, browser, focusManager, scrollHelper) { "use strict"; var enableFocusTransform = !browser.slow && !browser.edge; @@ -152,14 +152,14 @@ define(["dialogHelper", "dom", "layoutManager", "connectionManager", "globalize" }); if (layoutManager.tv) { - centerFocus(dlg.querySelector(".formDialogContent"), false, true); + scrollHelper.centerFocus.on(dlg.querySelector(".formDialogContent"), false); } var apiClient = connectionManager.getApiClient(options.serverId); discoverDevices(dlg, apiClient); if (layoutManager.tv) { - centerFocus(dlg.querySelector(".formDialogContent"), false, false); + scrollHelper.centerFocus.off(dlg.querySelector(".formDialogContent"), false); } return dialogHelper.open(dlg).then(function () { diff --git a/src/components/tvproviders/schedulesdirect.template.html b/src/components/tvproviders/schedulesdirect.template.html index da593ef569..3cfba06fe1 100644 --- a/src/components/tvproviders/schedulesdirect.template.html +++ b/src/components/tvproviders/schedulesdirect.template.html @@ -70,4 +70,4 @@
-
\ No newline at end of file +
diff --git a/src/components/upnextdialog/upnextdialog.js b/src/components/upnextdialog/upnextdialog.js index 80e7d807bd..225859e0b3 100644 --- a/src/components/upnextdialog/upnextdialog.js +++ b/src/components/upnextdialog/upnextdialog.js @@ -131,7 +131,7 @@ define(['dom', 'playbackManager', 'connectionManager', 'events', 'mediaInfo', 'l var secondsRemaining = Math.max(Math.round(getTimeRemainingMs(instance) / 1000), 0); - console.log('up next seconds remaining: ' + secondsRemaining); + console.debug('up next seconds remaining: ' + secondsRemaining); var timeText = '' + globalize.translate('HeaderSecondsValue', secondsRemaining) + ''; @@ -332,4 +332,4 @@ define(['dom', 'playbackManager', 'connectionManager', 'events', 'mediaInfo', 'l }; return UpNextDialog; -}); \ No newline at end of file +}); diff --git a/src/components/userdatabuttons/emby-playstatebutton.js b/src/components/userdatabuttons/emby-playstatebutton.js index eaed128933..4c3e5b6b62 100644 --- a/src/components/userdatabuttons/emby-playstatebutton.js +++ b/src/components/userdatabuttons/emby-playstatebutton.js @@ -156,4 +156,4 @@ define(['connectionManager', 'serverNotifications', 'events', 'globalize', 'emby prototype: EmbyPlaystateButtonPrototype, extends: 'button' }); -}); \ No newline at end of file +}); diff --git a/src/components/viewsettings/viewsettings.template.html b/src/components/viewsettings/viewsettings.template.html index 07cbc35e9f..8aea2fac26 100644 --- a/src/components/viewsettings/viewsettings.template.html +++ b/src/components/viewsettings/viewsettings.template.html @@ -38,4 +38,4 @@
-
\ No newline at end of file +
diff --git a/src/components/visibleinviewport.js b/src/components/visibleinviewport.js index 3768740175..a48dbd3a1d 100644 --- a/src/components/visibleinviewport.js +++ b/src/components/visibleinviewport.js @@ -38,4 +38,4 @@ define(['dom'], function (dom) { } return visibleInViewport; -}); \ No newline at end of file +}); diff --git a/src/components/youtubeplayer/plugin.js b/src/components/youtubeplayer/plugin.js index a2478cd3f4..fd9c05292e 100644 --- a/src/components/youtubeplayer/plugin.js +++ b/src/components/youtubeplayer/plugin.js @@ -1,5 +1,6 @@ define(['require', 'events', 'browser', 'appRouter', 'loading'], function (require, events, browser, appRouter, loading) { "use strict"; + /* globals YT */ function zoomIn(elem, iterations) { var keyframes = [ @@ -405,4 +406,4 @@ define(['require', 'events', 'browser', 'appRouter', 'loading'], function (requi }; return YoutubePlayer; -}); \ No newline at end of file +}); diff --git a/src/controllers/dashboard/dashboard.js b/src/controllers/dashboard/dashboard.js index 1b7d123931..2530d7a9a1 100644 --- a/src/controllers/dashboard/dashboard.js +++ b/src/controllers/dashboard/dashboard.js @@ -741,21 +741,15 @@ define(["datetime", "events", "itemHelper", "serverNotifications", "dom", "globa }; return function (view, params) { function onRestartRequired(evt, apiClient) { - if (apiClient.serverId() === serverId) { - renderHasPendingRestart(view, apiClient, true); - } + console.debug('onRestartRequired not implemented', evt, apiClient); } function onServerShuttingDown(evt, apiClient) { - if (apiClient.serverId() === serverId) { - renderHasPendingRestart(view, apiClient, true); - } + console.debug('onServerShuttingDown not implemented', evt, apiClient); } function onServerRestarting(evt, apiClient) { - if (apiClient.serverId() === serverId) { - renderHasPendingRestart(view, apiClient, true); - } + console.debug('onServerRestarting not implemented', evt, apiClient); } function onPackageInstalling(evt, apiClient) { diff --git a/src/controllers/dashboard/general.js b/src/controllers/dashboard/general.js index 7eed352329..a434e46241 100644 --- a/src/controllers/dashboard/general.js +++ b/src/controllers/dashboard/general.js @@ -56,6 +56,12 @@ define(["jQuery", "loading", "fnchecked", "emby-checkbox", "emby-textarea", "emb } }); }); + }, function () { + require(["alert"], function (alert) { + alert(Globalize.translate("DefaultErrorMessage")); + }); + + Dashboard.processServerConfigurationUpdateResult(); }); }); return false; diff --git a/src/controllers/dashboard/logs.js b/src/controllers/dashboard/logs.js index f5866f344c..144e21fc92 100644 --- a/src/controllers/dashboard/logs.js +++ b/src/controllers/dashboard/logs.js @@ -30,4 +30,4 @@ define(["datetime", "loading", "apphost", "listViewStyle", "emby-button", "flexS }); }); } -}); \ No newline at end of file +}); diff --git a/src/controllers/dashboard/notifications/notifications.js b/src/controllers/dashboard/notifications/notifications.js index 466728210e..8f63753bf3 100644 --- a/src/controllers/dashboard/notifications/notifications.js +++ b/src/controllers/dashboard/notifications/notifications.js @@ -31,14 +31,14 @@ define(["loading", "libraryMenu", "globalize", "listViewStyle", "emby-button"], } itemHtml += ''; if (notification.Enabled) { - itemHtml += 'notifications_active'; + itemHtml += ''; } else { - itemHtml += 'notifications_off'; + itemHtml += ''; } itemHtml += '
'; itemHtml += '
' + notification.Name + "
"; itemHtml += "
"; - itemHtml += ''; + itemHtml += ''; itemHtml += "
"; return itemHtml; }).join(""); diff --git a/src/controllers/dashboard/plugins/add.js b/src/controllers/dashboard/plugins/add.js index 7930d6927b..72a7134fac 100644 --- a/src/controllers/dashboard/plugins/add.js +++ b/src/controllers/dashboard/plugins/add.js @@ -122,7 +122,7 @@ define(["jQuery", "loading", "libraryMenu", "globalize", "connectionManager", "e confirm(msg, globalize.translate("HeaderConfirmPluginInstallation")).then(function () { alertCallback(); }, function () { - console.log('plugin not installed'); + console.debug('plugin not installed'); }); }); } else { diff --git a/src/controllers/devices.js b/src/controllers/devices.js index 4ddb4d4d20..3fd2be983e 100644 --- a/src/controllers/devices.js +++ b/src/controllers/devices.js @@ -80,7 +80,7 @@ define(["loading", "dom", "libraryMenu", "globalize", "scripts/imagehelper", "hu deviceHtml += '
"; deviceHtml += "
"; } else { - deviceHtml += 'tablet_android'; + deviceHtml += ''; } deviceHtml += ""; diff --git a/src/controllers/dlnaprofiles.js b/src/controllers/dlnaprofiles.js index eae529c538..e1719ea597 100644 --- a/src/controllers/dlnaprofiles.js +++ b/src/controllers/dlnaprofiles.js @@ -32,7 +32,7 @@ define(["jQuery", "globalize", "loading", "libraryMenu", "listViewStyle", "emby- for (var i = 0, length = profiles.length; i < length; i++) { var profile = profiles[i]; html += '
'; - html += 'live_tv'; + html += ''; html += '
'; html += ""; html += "
" + profile.Name + "
"; diff --git a/src/controllers/encodingsettings.js b/src/controllers/encodingsettings.js index 24cf656d62..ff140ed539 100644 --- a/src/controllers/encodingsettings.js +++ b/src/controllers/encodingsettings.js @@ -15,6 +15,7 @@ define(["jQuery", "loading", "globalize", "dom", "libraryMenu"], function ($, lo page.querySelector("#selectEncoderPreset").value = config.EncoderPreset || ""; page.querySelector("#txtH264Crf").value = config.H264Crf || ""; page.querySelector("#chkEnableSubtitleExtraction").checked = config.EnableSubtitleExtraction || false; + page.querySelector("#chkEnableThrottling").checked = config.EnableThrottling || false; page.querySelector("#selectVideoDecoder").dispatchEvent(new CustomEvent("change", { bubbles: true })); @@ -58,6 +59,7 @@ define(["jQuery", "loading", "globalize", "dom", "libraryMenu"], function ($, lo config.EncoderPreset = form.querySelector("#selectEncoderPreset").value; config.H264Crf = parseInt(form.querySelector("#txtH264Crf").value || "0"); 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) { return c.checked; }), function (c) { @@ -66,6 +68,12 @@ define(["jQuery", "loading", "globalize", "dom", "libraryMenu"], function ($, lo config.EnableHardwareEncoding = form.querySelector("#chkHardwareEncoding").checked; ApiClient.updateNamedConfiguration("encoding", config).then(function () { updateEncoder(form); + }, function () { + require(["alert"], function (alert) { + alert(globalize.translate("DefaultErrorMessage")); + }); + + Dashboard.processServerConfigurationUpdateResult(); }); }); }; diff --git a/src/controllers/favorites.js b/src/controllers/favorites.js index a4f2af64dd..c06b0bd8fb 100644 --- a/src/controllers/favorites.js +++ b/src/controllers/favorites.js @@ -253,7 +253,7 @@ define(["appRouter", "cardBuilder", "dom", "globalize", "connectionManager", "ap } html += "
"; - html += '
'; + html += '
'; html += "
"; } diff --git a/src/controllers/itemdetailpage.js b/src/controllers/itemdetailpage.js index 990de87b60..e18311048c 100644 --- a/src/controllers/itemdetailpage.js +++ b/src/controllers/itemdetailpage.js @@ -1,4 +1,4 @@ -define(["loading", "appRouter", "layoutManager", "connectionManager", "cardBuilder", "datetime", "mediaInfo", "backdrop", "listView", "itemContextMenu", "itemHelper", "dom", "indicators", "apphost", "imageLoader", "libraryMenu", "globalize", "browser", "events", "scrollHelper", "playbackManager", "libraryBrowser", "scrollStyles", "emby-itemscontainer", "emby-checkbox", "emby-button", "emby-playstatebutton", "emby-ratingbutton", "emby-scroller", "emby-select"], function (loading, appRouter, layoutManager, connectionManager, cardBuilder, datetime, mediaInfo, backdrop, listView, itemContextMenu, itemHelper, dom, indicators, appHost, imageLoader, libraryMenu, globalize, browser, events, scrollHelper, playbackManager, libraryBrowser) { +define(["loading", "appRouter", "layoutManager", "connectionManager", "userSettings", "cardBuilder", "datetime", "mediaInfo", "backdrop", "listView", "itemContextMenu", "itemHelper", "dom", "indicators", "imageLoader", "libraryMenu", "globalize", "browser", "events", "playbackManager", "scrollStyles", "emby-itemscontainer", "emby-checkbox", "emby-button", "emby-playstatebutton", "emby-ratingbutton", "emby-scroller", "emby-select"], function (loading, appRouter, layoutManager, connectionManager, userSettings, cardBuilder, datetime, mediaInfo, backdrop, listView, itemContextMenu, itemHelper, dom, indicators, imageLoader, libraryMenu, globalize, browser, events, playbackManager) { "use strict"; function getPromise(apiClient, params) { @@ -60,8 +60,7 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "cardBuild return options; } - function getProgramScheduleHtml(items, options) { - options = options || {}; + function getProgramScheduleHtml(items) { var html = ""; html += '
'; html += listView.getListViewHtml({ @@ -445,7 +444,7 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "cardBuild } } - function renderBackdrop(page, item, apiClient) { + function renderBackdrop(item) { if (dom.getWindowSize().innerWidth >= 1000) { backdrop.setBackdrops([item]); } else { @@ -455,7 +454,6 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "cardBuild function renderDetailPageBackdrop(page, item, apiClient) { var imgUrl; - var screenWidth = screen.availWidth; var hasbackdrop = false; var itemBackdropElement = page.querySelector("#itemBackdrop"); var usePrimaryImage = item.MediaType === "Video" && item.Type !== "Movie" && item.Type !== "Trailer" || @@ -464,13 +462,17 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "cardBuild item.Type === "MusicArtist" || item.Type === "Person"; + if (!layoutManager.mobile && !userSettings.enableBackdrops()) { + return false; + } + if ("Program" === item.Type && item.ImageTags && item.ImageTags.Thumb) { imgUrl = apiClient.getScaledImageUrl(item.Id, { type: "Thumb", index: 0, tag: item.ImageTags.Thumb }); - itemBackdropElement.classList.remove("noBackdrop"); + page.classList.remove("noBackdrop"); imageLoader.lazyImage(itemBackdropElement, imgUrl, false); hasbackdrop = true; } else if (usePrimaryImage && item.ImageTags && item.ImageTags.Primary) { @@ -479,7 +481,7 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "cardBuild index: 0, tag: item.ImageTags.Primary }); - itemBackdropElement.classList.remove("noBackdrop"); + page.classList.remove("noBackdrop"); imageLoader.lazyImage(itemBackdropElement, imgUrl, false); hasbackdrop = true; } else if (item.BackdropImageTags && item.BackdropImageTags.length) { @@ -488,7 +490,7 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "cardBuild index: 0, tag: item.BackdropImageTags[0] }); - itemBackdropElement.classList.remove("noBackdrop"); + page.classList.remove("noBackdrop"); imageLoader.lazyImage(itemBackdropElement, imgUrl, false); hasbackdrop = true; } else if (item.ParentBackdropItemId && item.ParentBackdropImageTags && item.ParentBackdropImageTags.length) { @@ -497,7 +499,7 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "cardBuild index: 0, tag: item.ParentBackdropImageTags[0] }); - itemBackdropElement.classList.remove("noBackdrop"); + page.classList.remove("noBackdrop"); imageLoader.lazyImage(itemBackdropElement, imgUrl, false); hasbackdrop = true; } else if (item.ImageTags && item.ImageTags.Thumb) { @@ -506,15 +508,16 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "cardBuild index: 0, tag: item.ImageTags.Thumb }); - itemBackdropElement.classList.remove("noBackdrop"); + page.classList.remove("noBackdrop"); imageLoader.lazyImage(itemBackdropElement, imgUrl, false); hasbackdrop = true; } else { - itemBackdropElement.classList.add("noBackdrop"); itemBackdropElement.style.backgroundImage = ""; } if ("Person" === item.Type) { + // FIXME: This hides the backdrop on all persons to fix a margin issue. Ideally, a proper fix should be made. + page.classList.add('noBackdrop'); itemBackdropElement.classList.add("personBackdrop"); } else { itemBackdropElement.classList.remove("personBackdrop"); @@ -526,6 +529,7 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "cardBuild function reloadFromItem(instance, page, params, item, user) { var context = params.context; page.querySelector(".detailPagePrimaryContainer").classList.add("detailSticky"); + renderName(item, page.querySelector(".nameContainer"), false, context); var apiClient = connectionManager.getApiClient(item.ServerId); renderSeriesTimerEditor(page, item, apiClient, user); @@ -536,7 +540,7 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "cardBuild setInitialCollapsibleState(page, item, apiClient, context, user); renderDetails(page, item, apiClient, context); renderTrackSelections(page, instance, item); - renderBackdrop(page, item, apiClient); + renderBackdrop(item); renderDetailPageBackdrop(page, item, apiClient); var canPlay = reloadPlayButtons(page, item); @@ -647,7 +651,7 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "cardBuild function setTitle(item, apiClient) { var url = logoImageUrl(item, apiClient, {}); - if (url = null) { + if (url != null) { var pageTitle = document.querySelector(".pageTitle"); pageTitle.style.backgroundImage = "url('" + url + "')"; pageTitle.classList.add("pageTitleWithLogo"); @@ -663,7 +667,9 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "cardBuild }); var detailLogo = page.querySelector(".detailLogo"); - if (url) { + if (!layoutManager.mobile && !userSettings.enableBackdrops()) { + detailLogo.classList.add("hide"); + } else if (url) { detailLogo.classList.remove("hide"); detailLogo.classList.add("lazy"); detailLogo.setAttribute("data-src", url); @@ -817,7 +823,7 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "cardBuild if (editable) { html += ""; } else if (!editable && url === undefined) { - html += "
" + html += "
"; } var progressHtml = item.IsFolder || !item.UserData ? "" : indicators.getProgressBarHtml(item); @@ -873,7 +879,7 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "cardBuild elem.querySelector(".detailImageProgressContainer").innerHTML = indicators.getProgressBarHtml(item); } - function refreshImage(page, item, user) { + function refreshImage(page, item) { refreshDetailImageUserData(page.querySelector(".detailImageContainer"), item); } @@ -922,10 +928,10 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "cardBuild if ("Playlist" == item.Type) { page.querySelector("#childrenCollapsible").classList.remove("hide"); - renderPlaylistItems(page, item, user); + renderPlaylistItems(page, item); } else if ("Studio" == item.Type || "Person" == item.Type || "Genre" == item.Type || "MusicGenre" == item.Type || "MusicArtist" == item.Type) { page.querySelector("#childrenCollapsible").classList.remove("hide"); - renderItemsByName(page, item, user); + renderItemsByName(page, item); } else if (item.IsFolder) { if ("BoxSet" == item.Type) { page.querySelector("#childrenCollapsible").classList.add("hide"); @@ -937,7 +943,7 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "cardBuild } if ("Series" == item.Type) { - renderSeriesSchedule(page, item, user); + renderSeriesSchedule(page, item); renderNextUp(page, item, user); } else { page.querySelector(".nextUpSection").classList.add("hide"); @@ -952,7 +958,7 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "cardBuild page.querySelector("#specialsCollapsible").classList.add("hide"); } - renderCast(page, item, context, enableScrollX() ? null : 12); + renderCast(page, item); if (item.PartCount && item.PartCount > 1) { page.querySelector("#additionalPartsCollapsible").classList.remove("hide"); @@ -988,7 +994,7 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "cardBuild } } - function renderGenres(page, item, apiClient, context, isStatic) { + function renderGenres(page, item, context) { context = context || inferContext(item); var type; var genres = item.GenreItems || []; @@ -1022,7 +1028,7 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "cardBuild } } - function renderDirector(page, item, apiClient, context, isStatic) { + function renderDirector(page, item, context) { var directors = (item.People || []).filter(function (p) { return "Director" === p.Type; }); @@ -1050,8 +1056,8 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "cardBuild renderSimilarItems(page, item, context); renderMoreFromSeason(page, item, apiClient); renderMoreFromArtist(page, item, apiClient); - renderDirector(page, item, apiClient, context, isStatic); - renderGenres(page, item, apiClient, context, isStatic); + renderDirector(page, item, context); + renderGenres(page, item, context); renderChannelGuide(page, apiClient, item); var taglineElement = page.querySelector(".tagline"); @@ -1125,14 +1131,6 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "cardBuild return scrollX ? "overflowSquare" : "square"; } - function getThumbShape(scrollX) { - if (null == scrollX) { - scrollX = enableScrollX(); - } - - return scrollX ? "overflowBackdrop" : "backdrop"; - } - function renderMoreFromSeason(view, item, apiClient) { var section = view.querySelector(".moreFromSeasonSection"); @@ -1508,13 +1506,13 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "cardBuild } } - function renderItemsByName(page, item, user) { + function renderItemsByName(page, item) { require("scripts/itembynamedetailpage".split(","), function () { window.ItemsByName.renderItems(page, item); }); } - function renderPlaylistItems(page, item, user) { + function renderPlaylistItems(page, item) { require("scripts/playlistedit".split(","), function () { PlaylistViewer.render(page, item); }); @@ -1594,7 +1592,7 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "cardBuild } } - function renderSeriesSchedule(page, item, user) { + function renderSeriesSchedule(page, item) { var apiClient = connectionManager.getApiClient(item.ServerId); apiClient.getLiveTvPrograms({ UserId: apiClient.getCurrentUserId(), @@ -1661,7 +1659,7 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "cardBuild function canPlaySomeItemInCollection(items) { var i = 0; - for (length = items.length; i < length; i++) { + for (var length = items.length; i < length; i++) { if (playbackManager.canPlay(items[i])) { return true; } @@ -1844,7 +1842,7 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "cardBuild }); } - function renderCast(page, item, context, limit, isStatic) { + function renderCast(page, item) { var people = (item.People || []).filter(function (p) { return "Director" !== p.Type; }); @@ -1934,7 +1932,7 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "cardBuild playbackManager.play(playOptions); } - function playTrailer(page) { + function playTrailer() { playbackManager.playTrailers(currentItem); } @@ -1991,11 +1989,7 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "cardBuild } function onPlayTrailerClick() { - playTrailer(view); - } - - function onDownloadChange() { - reload(self, view, params); + playTrailer(); } function onDownloadClick() { @@ -2050,9 +2044,7 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "cardBuild if (userData) { currentItem.UserData = userData; reloadPlayButtons(view, currentItem); - apiClient.getCurrentUser().then(function (user) { - refreshImage(view, currentItem, user); - }); + refreshImage(view, currentItem); } } } @@ -2083,11 +2075,9 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "cardBuild }); view.addEventListener("click", function (e) { if (dom.parentWithClass(e.target, "moreScenes")) { - apiClient.getCurrentUser().then(function (user) { - renderScenes(view, currentItem); - }); + renderScenes(view, currentItem); } else if (dom.parentWithClass(e.target, "morePeople")) { - renderCast(view, currentItem, params.context); + renderCast(view, currentItem); } else if (dom.parentWithClass(e.target, "moreSpecials")) { apiClient.getCurrentUser().then(function (user) { renderSpecials(view, currentItem, user); diff --git a/src/controllers/librarydisplay.js b/src/controllers/librarydisplay.js index 10a0eb945b..55986a4b7d 100644 --- a/src/controllers/librarydisplay.js +++ b/src/controllers/librarydisplay.js @@ -68,4 +68,4 @@ define(["globalize", "loading", "libraryMenu", "emby-checkbox", "emby-button", " }); }); } -}); \ No newline at end of file +}); diff --git a/src/controllers/metadataimagespage.js b/src/controllers/metadataimagespage.js index 3a6656e4b6..a4932e9bb0 100644 --- a/src/controllers/metadataimagespage.js +++ b/src/controllers/metadataimagespage.js @@ -61,4 +61,4 @@ define(["jQuery", "dom", "loading", "libraryMenu", "listViewStyle"], function($, }).on("pageshow", "#metadataImagesConfigurationPage", function() { libraryMenu.setTabs("metadata", 2, getTabs), loading.show(), loadPage(this) }) -}); \ No newline at end of file +}); diff --git a/src/controllers/movies/moviesrecommended.js b/src/controllers/movies/moviesrecommended.js index 8b71844434..7e19af4b9f 100644 --- a/src/controllers/movies/moviesrecommended.js +++ b/src/controllers/movies/moviesrecommended.js @@ -203,7 +203,7 @@ define(["events", "layoutManager", "inputManager", "userSettings", "libraryMenu" function loadSuggestionsTab(view, params, tabContent) { var parentId = params.topParentId; var userId = ApiClient.getCurrentUserId(); - console.log("loadSuggestionsTab"); + console.debug("loadSuggestionsTab"); loadResume(tabContent, userId, parentId); loadLatest(tabContent, userId, parentId); loadSuggestions(tabContent, userId, parentId); diff --git a/src/controllers/music/musicrecommended.js b/src/controllers/music/musicrecommended.js index 556877aa1b..8b87dff265 100644 --- a/src/controllers/music/musicrecommended.js +++ b/src/controllers/music/musicrecommended.js @@ -155,7 +155,7 @@ define(["browser", "layoutManager", "userSettings", "inputManager", "loading", " } function loadSuggestionsTab(page, tabContent, parentId) { - console.log("loadSuggestionsTab"); + console.debug("loadSuggestionsTab"); loadLatest(tabContent, parentId); loadRecentlyPlayed(tabContent, parentId); loadFrequentlyPlayed(tabContent, parentId); diff --git a/src/controllers/playback/videoosd.js b/src/controllers/playback/videoosd.js index 27652958d0..c02c9b4171 100644 --- a/src/controllers/playback/videoosd.js +++ b/src/controllers/playback/videoosd.js @@ -575,7 +575,7 @@ define(["playbackManager", "dom", "inputManager", "datetime", "itemHelper", "med } function onPlaybackStart(e, state) { - console.log("nowplaying event: " + e.type); + console.debug("nowplaying event: " + e.type); var player = this; onStateChanged.call(player, e, state); resetUpNextDialog(); @@ -594,7 +594,7 @@ define(["playbackManager", "dom", "inputManager", "datetime", "itemHelper", "med function onPlaybackStopped(e, state) { currentRuntimeTicks = null; resetUpNextDialog(); - console.log("nowplaying event: " + e.type); + console.debug("nowplaying event: " + e.type); if ("Video" !== state.NextMediaType) { view.removeEventListener("viewbeforehide", onViewHideStopPlayback); @@ -725,14 +725,14 @@ define(["playbackManager", "dom", "inputManager", "datetime", "itemHelper", "med var endDate = datetime.parseISO8601Date(program.EndDate); if (new Date().getTime() >= endDate.getTime()) { - console.log("program info needs to be refreshed"); + console.debug("program info needs to be refreshed"); var state = playbackManager.getPlayerState(player); onStateChanged.call(player, { type: "init" }, state); } } catch (e) { - console.log("Error parsing date: " + program.EndDate); + console.error("error parsing date: " + program.EndDate); } } } @@ -1218,7 +1218,7 @@ define(["playbackManager", "dom", "inputManager", "datetime", "itemHelper", "med return null; } - let playPauseClickTimeout; + var playPauseClickTimeout; function onViewHideStopPlayback() { if (playbackManager.isPlayingVideo()) { require(['shell'], function (shell) { @@ -1388,7 +1388,7 @@ define(["playbackManager", "dom", "inputManager", "datetime", "itemHelper", "med clearTimeout(playPauseClickTimeout); playPauseClickTimeout = 0; } else { - playPauseClickTimeout = setTimeout(() => { + playPauseClickTimeout = setTimeout(function() { playbackManager.playPause(currentPlayer); showOsd(); playPauseClickTimeout = 0; diff --git a/src/controllers/shows/tvupcoming.js b/src/controllers/shows/tvupcoming.js index f85278195f..249d932d39 100644 --- a/src/controllers/shows/tvupcoming.js +++ b/src/controllers/shows/tvupcoming.js @@ -58,7 +58,7 @@ define(["layoutManager", "loading", "datetime", "libraryBrowser", "cardBuilder", day: "numeric" }); } catch (err) { - console.log('error parsing timestamp for upcoming tv shows'); + console.error('error parsing timestamp for upcoming tv shows'); } } diff --git a/src/controllers/streamingsettings.js b/src/controllers/streamingsettings.js index 6c85034458..14e5e028a8 100644 --- a/src/controllers/streamingsettings.js +++ b/src/controllers/streamingsettings.js @@ -13,6 +13,7 @@ define(["jQuery", "libraryMenu", "loading"], function ($, libraryMenu, loading) config.RemoteClientBitrateLimit = parseInt(1e6 * parseFloat($("#txtRemoteClientBitrateLimit", form).val() || "0")); ApiClient.updateServerConfiguration(config).then(Dashboard.processServerConfigurationUpdateResult); }); + return false; } @@ -30,24 +31,6 @@ define(["jQuery", "libraryMenu", "loading"], function ($, libraryMenu, loading) } $(document).on("pageinit", "#streamingSettingsPage", function () { - var page = this; - $("#btnSelectTranscodingTempPath", page).on("click.selectDirectory", function () { - require(["directorybrowser"], function (directoryBrowser) { - var picker = new directoryBrowser(); - picker.show({ - callback: function (path) { - if (path) { - $("#txtTranscodingTempPath", page).val(path); - } - - picker.close(); - }, - validateWriteable: true, - header: Globalize.translate("HeaderSelectTranscodingPath"), - instruction: Globalize.translate("HeaderSelectTranscodingPathHelp") - }); - }); - }); $(".streamingSettingsForm").off("submit", onSubmit).on("submit", onSubmit); }).on("pageshow", "#streamingSettingsPage", function () { loading.show(); diff --git a/src/controllers/wizard/user.js b/src/controllers/wizard/user.js index d29be37c13..270953b24e 100644 --- a/src/controllers/wizard/user.js +++ b/src/controllers/wizard/user.js @@ -10,7 +10,7 @@ define(["loading", "globalize", "dashboardcss", "emby-input", "emby-button", "em } function onUpdateUserComplete(result) { - console.log(result); + console.debug("user update complete: " + result); loading.hide(); nextWizardPage(); } diff --git a/src/elements/emby-checkbox/emby-checkbox.css b/src/elements/emby-checkbox/emby-checkbox.css index e694342571..42a9207560 100644 --- a/src/elements/emby-checkbox/emby-checkbox.css +++ b/src/elements/emby-checkbox/emby-checkbox.css @@ -68,7 +68,8 @@ color: #fff; } -.checkboxIcon-checked { +.checkboxIcon-checked, +.emby-checkbox-label .checkboxIcon-checked { display: none; } diff --git a/src/elements/emby-collapse/emby-collapse.js b/src/elements/emby-collapse/emby-collapse.js index 764e525a25..600af55516 100644 --- a/src/elements/emby-collapse/emby-collapse.js +++ b/src/elements/emby-collapse/emby-collapse.js @@ -97,4 +97,4 @@ define(['browser', 'css!./emby-collapse', 'registerElement', 'emby-button'], fun prototype: EmbyButtonPrototype, extends: 'div' }); -}); \ No newline at end of file +}); diff --git a/src/elements/emby-input/emby-input.js b/src/elements/emby-input/emby-input.js index 7d2ea63a0d..03ba2b93aa 100644 --- a/src/elements/emby-input/emby-input.js +++ b/src/elements/emby-input/emby-input.js @@ -123,4 +123,4 @@ define(['layoutManager', 'browser', 'dom', 'css!./emby-input', 'registerElement' prototype: EmbyInputPrototype, extends: 'input' }); -}); \ No newline at end of file +}); diff --git a/src/elements/emby-progressring/emby-progressring.js b/src/elements/emby-progressring/emby-progressring.js index 80c5458528..edc635947c 100644 --- a/src/elements/emby-progressring/emby-progressring.js +++ b/src/elements/emby-progressring/emby-progressring.js @@ -98,4 +98,4 @@ define(['require', 'css!./emby-progressring', 'registerElement'], function (requ }); return EmbyProgressRing; -}); \ No newline at end of file +}); diff --git a/src/elements/emby-progressring/emby-progressring.template.html b/src/elements/emby-progressring/emby-progressring.template.html index bebefe5f51..a1be620b33 100644 --- a/src/elements/emby-progressring/emby-progressring.template.html +++ b/src/elements/emby-progressring/emby-progressring.template.html @@ -20,4 +20,4 @@
-
\ No newline at end of file +
diff --git a/src/elements/emby-radio/emby-radio.js b/src/elements/emby-radio/emby-radio.js index 3c72f91521..9b91591050 100644 --- a/src/elements/emby-radio/emby-radio.js +++ b/src/elements/emby-radio/emby-radio.js @@ -45,4 +45,4 @@ define(['css!./emby-radio', 'registerElement'], function () { prototype: EmbyRadioPrototype, extends: 'input' }); -}); \ No newline at end of file +}); diff --git a/src/elements/emby-textarea/emby-textarea.js b/src/elements/emby-textarea/emby-textarea.js index c500db6e1f..e0ce77aa51 100644 --- a/src/elements/emby-textarea/emby-textarea.js +++ b/src/elements/emby-textarea/emby-textarea.js @@ -135,4 +135,4 @@ define(['layoutManager', 'browser', 'css!./emby-textarea', 'registerElement', 'e prototype: EmbyTextAreaPrototype, extends: 'textarea' }); -}); \ No newline at end of file +}); diff --git a/src/elements/emby-toggle/emby-toggle.js b/src/elements/emby-toggle/emby-toggle.js index 08597164b2..bd7eba3078 100644 --- a/src/elements/emby-toggle/emby-toggle.js +++ b/src/elements/emby-toggle/emby-toggle.js @@ -47,4 +47,4 @@ define(['css!./emby-toggle', 'registerElement'], function () { prototype: EmbyTogglePrototype, extends: 'input' }); -}); \ No newline at end of file +}); diff --git a/src/encodingsettings.html b/src/encodingsettings.html index 7d7c3a8c6a..bcdd86544e 100644 --- a/src/encodingsettings.html +++ b/src/encodingsettings.html @@ -144,6 +144,14 @@
${AllowOnTheFlySubtitleExtractionHelp}
+
+ +
${AllowFfmpegThrottlingHelp}
+
+
-
\ No newline at end of file +
diff --git a/src/itemdetails.html b/src/itemdetails.html index 100e3f968a..a1966afe08 100644 --- a/src/itemdetails.html +++ b/src/itemdetails.html @@ -1,5 +1,5 @@ -
-
+
+
@@ -31,7 +31,7 @@ @@ -94,7 +94,7 @@ @@ -182,21 +182,21 @@

-
+

-
+

${HeaderCastCrew}

-
+
@@ -218,14 +218,14 @@

${HeaderScenes}

-
+

${HeaderMoreLikeThis}

-
+
diff --git a/src/legacy/dashboard.js b/src/legacy/dashboard.js index 11ba3177b7..0268806f21 100644 --- a/src/legacy/dashboard.js +++ b/src/legacy/dashboard.js @@ -17,4 +17,4 @@ Dashboard.confirm = function(message, title, callback) { require(["loading"], function(loading) { loading.hide() }) -}; \ No newline at end of file +}; diff --git a/src/legacy/fnchecked.js b/src/legacy/fnchecked.js index 120f6e148a..4f24990f46 100644 --- a/src/legacy/fnchecked.js +++ b/src/legacy/fnchecked.js @@ -7,4 +7,4 @@ define(["jQuery"], function($) { }, $.fn.checkboxradio = function() { return this } -}); \ No newline at end of file +}); diff --git a/src/legacy/selectmenu.js b/src/legacy/selectmenu.js index bc211b9664..ba8c688511 100644 --- a/src/legacy/selectmenu.js +++ b/src/legacy/selectmenu.js @@ -3,4 +3,4 @@ define(["jQuery"], function($) { $.fn.selectmenu = function() { return this } -}); \ No newline at end of file +}); diff --git a/src/libraries/apiclient/apiclient.js b/src/libraries/apiclient/apiclient.js index 06d9cf0861..d848358c3e 100644 --- a/src/libraries/apiclient/apiclient.js +++ b/src/libraries/apiclient/apiclient.js @@ -233,4 +233,4 @@ define(["libraries/apiclient/apiclientcore", "localassetmanager"], function(ApiC } return ApiClient.prototype.getItemDownloadUrl.call(this, itemId) }, ApiClientEx -}); \ No newline at end of file +}); diff --git a/src/libraries/apiclient/apiclientcore.js b/src/libraries/apiclient/apiclientcore.js index b6c98ebbd9..ec1a329b13 100644 --- a/src/libraries/apiclient/apiclientcore.js +++ b/src/libraries/apiclient/apiclientcore.js @@ -59,8 +59,23 @@ define(["events", "appStorage"], function(events, appStorage) { } function ApiClient(serverAddress, appName, appVersion, deviceName, deviceId, devicePixelRatio) { - if (!serverAddress) throw new Error("Must supply a serverAddress"); - console.log("ApiClient serverAddress: " + serverAddress), console.log("ApiClient appName: " + appName), console.log("ApiClient appVersion: " + appVersion), console.log("ApiClient deviceName: " + deviceName), console.log("ApiClient deviceId: " + deviceId), this._serverInfo = {}, this._serverAddress = serverAddress, this._deviceId = deviceId, this._deviceName = deviceName, this._appName = appName, this._appVersion = appVersion, this._devicePixelRatio = devicePixelRatio + if (!serverAddress) { + throw new Error("Must supply a serverAddress"); + } + + console.debug("ApiClient serverAddress: " + serverAddress); + console.debug("ApiClient appName: " + appName); + console.debug("ApiClient appVersion: " + appVersion); + console.debug("ApiClient deviceName: " + deviceName); + console.debug("ApiClient deviceId: " + deviceId); + + this._serverInfo = {}; + this._serverAddress = serverAddress; + this._deviceId = deviceId; + this._deviceName = deviceName; + this._appName = appName; + this._appVersion = appVersion; + this._devicePixelRatio = devicePixelRatio; } function setSavedEndpointInfo(instance, info) { @@ -68,13 +83,14 @@ define(["events", "appStorage"], function(events, appStorage) { } function getTryConnectPromise(instance, url, state, resolve, reject) { - console.log("getTryConnectPromise " + url), fetchWithTimeout(instance.getUrl("system/info/public", null, url), { + console.debug("getTryConnectPromise " + url); + fetchWithTimeout(instance.getUrl("system/info/public", null, url), { method: "GET", accept: "application/json" }, 15e3).then(function() { - state.resolved || (state.resolved = !0, console.log("Reconnect succeeded to " + url), instance.serverAddress(url), resolve()) + state.resolved || (state.resolved = !0, console.debug("Reconnect succeeded to " + url), instance.serverAddress(url), resolve()) }, function() { - state.resolved || (console.log("Reconnect failed to " + url), ++state.rejects >= state.numAddresses && reject()) + state.resolved || (console.error("Reconnect failed to " + url), ++state.rejects >= state.numAddresses && reject()) }) } @@ -91,7 +107,7 @@ define(["events", "appStorage"], function(events, appStorage) { }), addressesStrings.push(addresses[addresses.length - 1].url)), serverInfo.RemoteAddress && -1 === addressesStrings.indexOf(serverInfo.RemoteAddress) && (addresses.push({ url: serverInfo.RemoteAddress, timeout: 200 - }), addressesStrings.push(addresses[addresses.length - 1].url)), console.log("tryReconnect: " + addressesStrings.join("|")), new Promise(function(resolve, reject) { + }), addressesStrings.push(addresses[addresses.length - 1].url)), console.debug("tryReconnect: " + addressesStrings.join("|")), new Promise(function(resolve, reject) { var state = {}; state.numAddresses = addresses.length, state.rejects = 0, addresses.map(function(url) { setTimeout(function() { @@ -103,7 +119,7 @@ define(["events", "appStorage"], function(events, appStorage) { function tryReconnect(instance, retryCount) { return retryCount = retryCount || 0, retryCount >= 20 ? Promise.reject() : tryReconnectInternal(instance).catch(function(err) { - return console.log("error in tryReconnectInternal: " + (err || "")), new Promise(function(resolve, reject) { + return console.error("error in tryReconnectInternal: " + (err || "")), new Promise(function(resolve, reject) { setTimeout(function() { tryReconnect(instance, retryCount + 1).then(resolve, reject) }, 500) @@ -139,7 +155,7 @@ define(["events", "appStorage"], function(events, appStorage) { function onWebSocketOpen() { var instance = this; - console.log("web socket connection opened"), events.trigger(instance, "websocketopen") + console.debug("web socket connection opened"), events.trigger(instance, "websocketopen") } function onWebSocketError() { @@ -149,7 +165,12 @@ define(["events", "appStorage"], function(events, appStorage) { function setSocketOnClose(apiClient, socket) { socket.onclose = function() { - console.log("web socket closed"), apiClient._webSocket === socket && (console.log("nulling out web socket"), apiClient._webSocket = null), setTimeout(function() { + console.debug("web socket closed"); + if (apiClient._webSocket === socket) { + console.debug("nulling out web socket"); + apiClient._webSocket = null; + } + setTimeout(function() { events.trigger(apiClient, "websocketclose") }, 0) } @@ -244,24 +265,24 @@ define(["events", "appStorage"], function(events, appStorage) { var lowered = url.toLowerCase(); return "/" !== name.charAt(0) && (url += "/"), url += name, params && (params = paramsToString(params)) && (url += "?" + params), url }, ApiClient.prototype.fetchWithFailover = function(request, enableReconnection) { - console.log("Requesting " + request.url), request.timeout = 3e4; + console.debug("Requesting " + request.url), request.timeout = 3e4; var instance = this; return getFetchPromise(request).then(function(response) { return instance.lastFetch = (new Date).getTime(), response.status < 400 ? "json" === request.dataType || "application/json" === request.headers.accept ? response.json() : "text" === request.dataType || 0 === (response.headers.get("Content-Type") || "").toLowerCase().indexOf("text/") ? response.text() : response : (onFetchFail(instance, request.url, response), Promise.reject(response)) }, function(error) { - if (error ? console.log("Request failed to " + request.url + " " + (error.status || "") + " " + error.toString()) : console.log("Request timed out to " + request.url), error && error.status || !enableReconnection) throw console.log("Reporting request failure"), onFetchFail(instance, request.url, {}), error; - console.log("Attempting reconnection"); + if (error ? console.error("Request failed to " + request.url + " " + (error.status || "") + " " + error.toString()) : console.error("Request timed out to " + request.url), error && error.status || !enableReconnection) throw console.error("Reporting request failure"), onFetchFail(instance, request.url, {}), error; + console.debug("Attempting reconnection"); var previousServerAddress = instance.serverAddress(); return tryReconnect(instance).then(function() { - return console.log("Reconnect succeesed"), request.url = request.url.replace(previousServerAddress, instance.serverAddress()), instance.fetchWithFailover(request, !1) + return console.debug("Reconnect succeesed"), request.url = request.url.replace(previousServerAddress, instance.serverAddress()), instance.fetchWithFailover(request, !1) }, function(innerError) { - throw console.log("Reconnect failed"), onFetchFail(instance, request.url, {}), innerError + throw console.error("Reconnect failed"), onFetchFail(instance, request.url, {}), innerError }) }) }, ApiClient.prototype.fetch = function(request, includeAuthorization) { if (!request) throw new Error("Request cannot be null"); if (request.headers = request.headers || {}, !1 !== includeAuthorization && this.setRequestHeaders(request.headers), !1 === this.enableAutomaticNetworking || "GET" !== request.type) { - console.log("Requesting url without automatic networking: " + request.url); + console.debug("Requesting url without automatic networking: " + request.url); var instance = this; return getFetchPromise(request).then(function(response) { return instance.lastFetch = (new Date).getTime(), response.status < 400 ? "json" === request.dataType || "application/json" === request.headers.accept ? response.json() : "text" === request.dataType || 0 === (response.headers.get("Content-Type") || "").toLowerCase().indexOf("text/") ? response.text() : response : (onFetchFail(instance, request.url, response), Promise.reject(response)) @@ -340,7 +361,7 @@ define(["events", "appStorage"], function(events, appStorage) { if (!this.isWebSocketOpenOrConnecting() && this.isWebSocketSupported()) try { this.openWebSocket() } catch (err) { - console.log("Error opening web socket: " + err) + console.error("error opening web socket: " + err) } }; var messageIdsReceived = {}; @@ -348,14 +369,14 @@ define(["events", "appStorage"], function(events, appStorage) { var accessToken = this.accessToken(); if (!accessToken) throw new Error("Cannot open web socket without access token."); var url = this.getUrl("socket"); - url = replaceAll(url, "emby/socket", "embywebsocket"), url = replaceAll(url, "https:", "wss:"), url = replaceAll(url, "http:", "ws:"), url += "?api_key=" + accessToken, url += "&deviceId=" + this.deviceId(), console.log("opening web socket with url: " + url); + url = replaceAll(url, "emby/socket", "embywebsocket"), url = replaceAll(url, "https:", "wss:"), url = replaceAll(url, "http:", "ws:"), url += "?api_key=" + accessToken, url += "&deviceId=" + this.deviceId(), console.debug("opening web socket with url: " + url); var webSocket = new WebSocket(url); webSocket.onmessage = onWebSocketMessage.bind(this), webSocket.onopen = onWebSocketOpen.bind(this), webSocket.onerror = onWebSocketError.bind(this), setSocketOnClose(this, webSocket), this._webSocket = webSocket }, ApiClient.prototype.closeWebSocket = function() { var socket = this._webSocket; socket && socket.readyState === WebSocket.OPEN && socket.close() }, ApiClient.prototype.sendWebSocketMessage = function(name, data) { - console.log("Sending web socket message: " + name); + console.debug("Sending web socket message: " + name); var msg = { MessageType: name }; @@ -387,7 +408,7 @@ define(["events", "appStorage"], function(events, appStorage) { }, ApiClient.prototype.updateServerInfo = function(server, serverUrl) { if (null == server) throw new Error("server cannot be null"); if (this.serverInfo(server), !serverUrl) throw new Error("serverUrl cannot be null. serverInfo: " + JSON.stringify(server)); - console.log("Setting server address to " + serverUrl), this.serverAddress(serverUrl) + console.debug("Setting server address to " + serverUrl), this.serverAddress(serverUrl) }, ApiClient.prototype.isWebSocketSupported = function() { try { return null != WebSocket diff --git a/src/libraries/apiclient/appStorage.js b/src/libraries/apiclient/appStorage.js index 6083bb4953..dacf38822f 100644 --- a/src/libraries/apiclient/appStorage.js +++ b/src/libraries/apiclient/appStorage.js @@ -2,7 +2,7 @@ define([], function() { "use strict"; function onCachePutFail(e) { - console.log(e); + console.error("cannot put to a cache: " + e); } function updateCache(instance) { @@ -45,9 +45,9 @@ define([], function() { self.caches.open("embydata").then(onCacheOpened.bind(this)); } } catch (err) { - console.log("Error opening cache: " + err); + console.error("error opening cache: " + err); } } return new MyStore; -}); \ No newline at end of file +}); diff --git a/src/libraries/apiclient/connectionmanager.js b/src/libraries/apiclient/connectionmanager.js index 7e7d578cba..a8e389bd03 100644 --- a/src/libraries/apiclient/connectionmanager.js +++ b/src/libraries/apiclient/connectionmanager.js @@ -95,18 +95,18 @@ define(["events", "apiclient", "appStorage"], function (events, apiClientFactory } function fetchWithTimeout(url, options, timeoutMs) { - console.log("fetchWithTimeout: timeoutMs: " + timeoutMs + ", url: " + url); + console.debug("fetchWithTimeout: timeoutMs: " + timeoutMs + ", url: " + url); return new Promise(function (resolve, reject) { var timeout = setTimeout(reject, timeoutMs); options = options || {}; options.credentials = "same-origin"; fetch(url, options).then(function (response) { clearTimeout(timeout); - console.log("fetchWithTimeout: succeeded connecting to url: " + url); + console.debug("fetchWithTimeout: succeeded connecting to url: " + url); resolve(response); }, function (error) { clearTimeout(timeout); - console.log("fetchWithTimeout: timed out connecting to url: " + url); + console.error("fetchWithTimeout: timed out connecting to url: " + url); reject(); }); }); @@ -118,9 +118,9 @@ define(["events", "apiclient", "appStorage"], function (events, apiClientFactory } request.headers = request.headers || {}; - console.log("ConnectionManager requesting url: " + request.url); + console.debug("ConnectionManager requesting url: " + request.url); return getFetchPromise(request).then(function (response) { - console.log("ConnectionManager response status: " + response.status + ", url: " + request.url); + console.debug("ConnectionManager response status: " + response.status + ", url: " + request.url); if (response.status < 400) { if ("json" === request.dataType || "application/json" === request.headers.accept) { @@ -132,7 +132,7 @@ define(["events", "apiclient", "appStorage"], function (events, apiClientFactory return Promise.reject(response); }, function (err) { - console.log("ConnectionManager request failed to url: " + request.url); + console.error("ConnectionManager request failed to url: " + request.url); throw err; }); } @@ -227,7 +227,7 @@ define(["events", "apiclient", "appStorage"], function (events, apiClientFactory apiClient.enableAutomaticBitrateDetection = options.enableAutomaticBitrateDetection; if (false !== options.enableWebSocket) { - console.log("calling apiClient.ensureWebSocket"); + console.debug("calling apiClient.ensureWebSocket"); apiClient.ensureWebSocket(); } } @@ -333,7 +333,7 @@ define(["events", "apiclient", "appStorage"], function (events, apiClientFactory } function getTryConnectPromise(url, connectionMode, state, resolve, reject) { - console.log("getTryConnectPromise " + url); + console.debug("getTryConnectPromise " + url); ajax({ url: getEmbyServerUrl(url, "system/info/public"), timeout: defaultTimeout, @@ -342,7 +342,7 @@ define(["events", "apiclient", "appStorage"], function (events, apiClientFactory }).then(function (result) { if (!state.resolved) { state.resolved = true; - console.log("Reconnect succeeded to " + url); + console.debug("Reconnect succeeded to " + url); resolve({ url: url, connectionMode: connectionMode, @@ -351,7 +351,7 @@ define(["events", "apiclient", "appStorage"], function (events, apiClientFactory } }, function () { if (!state.resolved) { - console.log("Reconnect failed to " + url); + console.error("Reconnect failed to " + url); if (++state.rejects >= state.numAddresses) { reject(); @@ -391,7 +391,7 @@ define(["events", "apiclient", "appStorage"], function (events, apiClientFactory addressesStrings.push(addresses[addresses.length - 1].url); } - console.log("tryReconnect: " + addressesStrings.join("|")); + console.debug("tryReconnect: " + addressesStrings.join("|")); return new Promise(function (resolve, reject) { var state = {}; state.numAddresses = addresses.length; @@ -458,7 +458,7 @@ define(["events", "apiclient", "appStorage"], function (events, apiClientFactory } } - console.log("Begin ConnectionManager constructor"); + console.debug("Begin ConnectionManager constructor"); var self = this; this._apiClients = []; self._minServerVersion = "3.2.33"; @@ -530,7 +530,7 @@ define(["events", "apiclient", "appStorage"], function (events, apiClientFactory }; self.clearData = function () { - console.log("connection manager clearing data"); + console.debug("connection manager clearing data"); var credentials = credentialProvider.credentials(); credentials.Servers = []; credentialProvider.credentials(credentials); @@ -550,7 +550,7 @@ define(["events", "apiclient", "appStorage"], function (events, apiClientFactory events.trigger(self, "apiclientcreated", [apiClient]); } - console.log("returning instance from getOrAddApiClient"); + console.debug("returning instance from getOrAddApiClient"); return apiClient; }; @@ -592,7 +592,7 @@ define(["events", "apiclient", "appStorage"], function (events, apiClientFactory }; self.logout = function () { - console.log("begin connectionManager loguot"); + console.debug("begin connectionManager loguot"); var promises = []; for (var i = 0, length = self._apiClients.length; i < length; i++) { @@ -628,7 +628,7 @@ define(["events", "apiclient", "appStorage"], function (events, apiClientFactory }; self.getAvailableServers = function () { - console.log("Begin getAvailableServers"); + console.debug("begin getAvailableServers"); var credentials = credentialProvider.credentials(); return Promise.all([findServers()]).then(function (responses) { var foundServers = responses[0]; @@ -644,7 +644,7 @@ define(["events", "apiclient", "appStorage"], function (events, apiClientFactory }; self.connectToServers = function (servers, options) { - console.log("Begin connectToServers, with " + servers.length + " servers"); + console.debug("begin connectToServers, with " + servers.length + " servers"); var firstServer = servers.length ? servers[0] : null; if (firstServer) { @@ -653,7 +653,7 @@ define(["events", "apiclient", "appStorage"], function (events, apiClientFactory result.State = "ServerSelection"; } - console.log("resolving connectToServers with result.State: " + result.State); + console.debug("resolving connectToServers with result.State: " + result.State); return result; }); } @@ -665,7 +665,7 @@ define(["events", "apiclient", "appStorage"], function (events, apiClientFactory }; self.connectToServer = function (server, options) { - console.log("begin connectToServer"); + console.debug("begin connectToServer"); return new Promise(function (resolve, reject) { options = options || {}; tryReconnect(server).then(function (result) { @@ -674,14 +674,14 @@ define(["events", "apiclient", "appStorage"], function (events, apiClientFactory result = result.data; if (1 === compareVersions(self.minServerVersion(), result.Version)) { - console.log("minServerVersion requirement not met. Server version: " + result.Version); + console.debug("minServerVersion requirement not met. Server version: " + result.Version); resolve({ State: "ServerUpdateNeeded", Servers: [server] }); } else { if (server.Id && result.Id !== server.Id) { - console.log("http request succeeded, but found a different server Id than what was expected"); + console.debug("http request succeeded, but found a different server Id than what was expected"); resolveFailure(self, resolve); } else { onSuccessfulConnection(server, result, connectionMode, serverUrl, options, resolve); @@ -695,7 +695,7 @@ define(["events", "apiclient", "appStorage"], function (events, apiClientFactory self.connectToAddress = function (address, options) { function onFail() { - console.log("connectToAddress " + address + " failed"); + console.error("connectToAddress " + address + " failed"); return Promise.resolve({ State: "Unavailable", }); @@ -741,7 +741,7 @@ define(["events", "apiclient", "appStorage"], function (events, apiClientFactory }; ConnectionManager.prototype.connect = function (options) { - console.log("Begin connect"); + console.debug("begin connect"); var instance = this; return instance.getAvailableServers().then(function (servers) { return instance.connectToServers(servers, options); diff --git a/src/libraries/apiclient/credentialprovider.js b/src/libraries/apiclient/credentialprovider.js index 471f2b5ef1..4ae809cace 100644 --- a/src/libraries/apiclient/credentialprovider.js +++ b/src/libraries/apiclient/credentialprovider.js @@ -4,7 +4,7 @@ define(["events", "appStorage"], function(events, appStorage) { function ensure(instance, data) { if (!instance._credentials) { var json = appStorage.getItem(instance.key) || "{}"; - console.log("credentials initialized with: " + json), instance._credentials = JSON.parse(json), instance._credentials.Servers = instance._credentials.Servers || [] + console.debug("credentials initialized with: " + json), instance._credentials = JSON.parse(json), instance._credentials.Servers = instance._credentials.Servers || [] } } @@ -26,4 +26,4 @@ define(["events", "appStorage"], function(events, appStorage) { })[0]; return existing ? (existing.DateLastAccessed = Math.max(existing.DateLastAccessed || 0, server.DateLastAccessed || 0), existing.UserLinkType = server.UserLinkType, server.AccessToken && (existing.AccessToken = server.AccessToken, existing.UserId = server.UserId), server.ExchangeToken && (existing.ExchangeToken = server.ExchangeToken), server.RemoteAddress && (existing.RemoteAddress = server.RemoteAddress), server.ManualAddress && (existing.ManualAddress = server.ManualAddress), server.LocalAddress && (existing.LocalAddress = server.LocalAddress), server.Name && (existing.Name = server.Name), null != server.LastConnectionMode && (existing.LastConnectionMode = server.LastConnectionMode), server.ConnectServerId && (existing.ConnectServerId = server.ConnectServerId), existing) : (list.push(server), server) }, Credentials -}); \ No newline at end of file +}); diff --git a/src/libraries/apiclient/events.js b/src/libraries/apiclient/events.js index 6204dc4d4f..c109ee9c48 100644 --- a/src/libraries/apiclient/events.js +++ b/src/libraries/apiclient/events.js @@ -27,4 +27,4 @@ define([], function() { }) } } -}); \ No newline at end of file +}); diff --git a/src/libraries/apiclient/localassetmanager.js b/src/libraries/apiclient/localassetmanager.js index fbe74aae51..6fb1d4722d 100644 --- a/src/libraries/apiclient/localassetmanager.js +++ b/src/libraries/apiclient/localassetmanager.js @@ -2,7 +2,7 @@ define(["filerepository", "itemrepository", "useractionrepository", "transferman "use strict"; function getLocalItem(serverId, itemId) { - return console.log("[lcoalassetmanager] Begin getLocalItem"), itemrepository.get(serverId, itemId) + return console.debug("localassetmanager: begin getLocalItem"), itemrepository.get(serverId, itemId) } function recordUserAction(action) { @@ -25,7 +25,7 @@ define(["filerepository", "itemrepository", "useractionrepository", "transferman } function getServerItems(serverId) { - return console.log("[localassetmanager] Begin getServerItems"), itemrepository.getAll(serverId) + return console.debug("localassetmanager: begin getServerItems"), itemrepository.getAll(serverId) } function getItemsFromIds(serverId, ids) { diff --git a/src/libraries/apiclient/package.json b/src/libraries/apiclient/package.json index 0069cfc6bf..67f9d49756 100644 --- a/src/libraries/apiclient/package.json +++ b/src/libraries/apiclient/package.json @@ -1,3 +1,3 @@ { "main": "apiclient.js" -} \ No newline at end of file +} diff --git a/src/libraries/apiclient/sync/filerepository.js b/src/libraries/apiclient/sync/filerepository.js index 198967469d..5b7088af31 100644 --- a/src/libraries/apiclient/sync/filerepository.js +++ b/src/libraries/apiclient/sync/filerepository.js @@ -42,4 +42,4 @@ define([], function() { getItemFileSize: getItemFileSize, getImageUrl: getImageUrl } -}); \ No newline at end of file +}); diff --git a/src/libraries/apiclient/sync/itemrepository.js b/src/libraries/apiclient/sync/itemrepository.js index 5330d5d1a2..db1f962876 100644 --- a/src/libraries/apiclient/sync/itemrepository.js +++ b/src/libraries/apiclient/sync/itemrepository.js @@ -120,4 +120,4 @@ define([], function() { getAll: getAll, getServerItemTypes: getServerItemTypes } -}); \ No newline at end of file +}); diff --git a/src/libraries/apiclient/sync/localsync.js b/src/libraries/apiclient/sync/localsync.js index cea244de08..14e9ff9c0f 100644 --- a/src/libraries/apiclient/sync/localsync.js +++ b/src/libraries/apiclient/sync/localsync.js @@ -3,7 +3,7 @@ define(["connectionManager"], function(connectionManager) { var isSyncing; return { sync: function(options) { - return console.log("localSync.sync starting..."), isSyncing ? Promise.resolve() : (isSyncing = !0, new Promise(function(resolve, reject) { + return console.debug("localSync.sync starting..."), isSyncing ? Promise.resolve() : (isSyncing = !0, new Promise(function(resolve, reject) { require(["multiserversync", "appSettings"], function(MultiServerSync, appSettings) { options = options || {}, options.cameraUploadServers = appSettings.cameraUploadServers(), (new MultiServerSync).sync(connectionManager, options).then(function() { isSyncing = null, resolve() @@ -14,4 +14,4 @@ define(["connectionManager"], function(connectionManager) { })) } } -}); \ No newline at end of file +}); diff --git a/src/libraries/apiclient/sync/mediasync.js b/src/libraries/apiclient/sync/mediasync.js index 24220561ad..e6d9e781f3 100644 --- a/src/libraries/apiclient/sync/mediasync.js +++ b/src/libraries/apiclient/sync/mediasync.js @@ -2,9 +2,9 @@ define(["localassetmanager"], function(localassetmanager) { "use strict"; function processDownloadStatus(apiClient, serverInfo, options) { - return console.log("[mediasync] Begin processDownloadStatus"), localassetmanager.resyncTransfers().then(function() { + return console.debug("mediasync: begin processDownloadStatus"), localassetmanager.resyncTransfers().then(function() { return localassetmanager.getServerItems(serverInfo.Id).then(function(items) { - console.log("[mediasync] Begin processDownloadStatus getServerItems completed"); + console.debug("mediasync: begin processDownloadStatus getServerItems completed"); var p = Promise.resolve(), cnt = 0; return items.filter(function(item) { @@ -14,7 +14,9 @@ define(["localassetmanager"], function(localassetmanager) { return reportTransfer(apiClient, item) }), cnt++ }), p.then(function() { - return console.log("[mediasync] Exit processDownloadStatus. Items reported: " + cnt.toString()), Promise.resolve() + console.debug("mediasync: exit processDownloadStatus"); + console.debug("items reported: " + cnt.toString()); + return Promise.resolve(); }) }) }) @@ -23,39 +25,39 @@ define(["localassetmanager"], function(localassetmanager) { function reportTransfer(apiClient, item) { return localassetmanager.getItemFileSize(item.LocalPath).then(function(size) { return size > 0 ? apiClient.reportSyncJobItemTransferred(item.SyncJobItemId).then(function() { - return item.SyncStatus = "synced", console.log("[mediasync] reportSyncJobItemTransferred called for " + item.LocalPath), localassetmanager.addOrUpdateLocalItem(item) + return item.SyncStatus = "synced", console.debug("mediasync: reportSyncJobItemTransferred called for " + item.LocalPath), localassetmanager.addOrUpdateLocalItem(item) }, function(error) { - return console.error("[mediasync] Mediasync error on reportSyncJobItemTransferred", error), item.SyncStatus = "error", localassetmanager.addOrUpdateLocalItem(item) + return console.error("mediasync: mediasync error on reportSyncJobItemTransferred", error), item.SyncStatus = "error", localassetmanager.addOrUpdateLocalItem(item) }) : localassetmanager.isDownloadFileInQueue(item.LocalPath).then(function(result) { - return result ? Promise.resolve() : (console.log("[mediasync] reportTransfer: Size is 0 and download no longer in queue. Deleting item."), localassetmanager.removeLocalItem(item).then(function() { - return console.log("[mediasync] reportTransfer: Item deleted."), Promise.resolve() + return result ? Promise.resolve() : (console.debug("mediasync: reportTransfer: Size is 0 and download no longer in queue. Deleting item."), localassetmanager.removeLocalItem(item).then(function() { + return console.debug("mediasync: reportTransfer: Item deleted."), Promise.resolve() }, function(err2) { - return console.log("[mediasync] reportTransfer: Failed to delete item.", err2), Promise.resolve() + return console.debug("mediasync: reportTransfer: Failed to delete item.", err2), Promise.resolve() })) }) }, function(error) { - return console.error("[mediasync] reportTransfer: error on getItemFileSize. Deleting item.", error), localassetmanager.removeLocalItem(item).then(function() { - return console.log("[mediasync] reportTransfer: Item deleted."), Promise.resolve() + return console.error("mediasync: reportTransfer: error on getItemFileSize. Deleting item.", error), localassetmanager.removeLocalItem(item).then(function() { + return console.debug("mediasync: reportTransfer: Item deleted."), Promise.resolve() }, function(err2) { - return console.log("[mediasync] reportTransfer: Failed to delete item.", err2), Promise.resolve() + return console.error("mediasync: reportTransfer: Failed to delete item.", err2), Promise.resolve() }) }) } function reportOfflineActions(apiClient, serverInfo) { - return console.log("[mediasync] Begin reportOfflineActions"), localassetmanager.getUserActions(serverInfo.Id).then(function(actions) { + return console.debug("mediasync: begin reportOfflineActions"), localassetmanager.getUserActions(serverInfo.Id).then(function(actions) { return actions.length ? apiClient.reportOfflineActions(actions).then(function() { return localassetmanager.deleteUserActions(actions).then(function() { - return console.log("[mediasync] Exit reportOfflineActions (actions reported and deleted.)"), Promise.resolve() + return console.debug("mediasync: exit reportOfflineActions (actions reported and deleted.)"), Promise.resolve() }) }, function(err) { - return console.error("[mediasync] error on apiClient.reportOfflineActions: " + err.toString()), localassetmanager.deleteUserActions(actions) - }) : (console.log("[mediasync] Exit reportOfflineActions (no actions)"), Promise.resolve()) + return console.error("mediasync: error on apiClient.reportOfflineActions: " + err.toString()), localassetmanager.deleteUserActions(actions) + }) : (console.debug("mediasync: exit reportOfflineActions (no actions)"), Promise.resolve()) }) } function syncData(apiClient, serverInfo) { - return console.log("[mediasync] Begin syncData"), localassetmanager.getServerItems(serverInfo.Id).then(function(items) { + return console.debug("mediasync: begin syncData"), localassetmanager.getServerItems(serverInfo.Id).then(function(items) { var completedItems = items.filter(function(item) { return item && ("synced" === item.SyncStatus || "error" === item.SyncStatus) }), @@ -67,16 +69,16 @@ define(["localassetmanager"], function(localassetmanager) { }; return apiClient.syncData(request).then(function(result) { return afterSyncData(apiClient, serverInfo, result).then(function() { - return console.log("[mediasync] Exit syncData"), Promise.resolve() + return console.debug("mediasync: exit syncData"), Promise.resolve() }, function(err) { - return console.error("[mediasync] Error in syncData: " + err.toString()), Promise.resolve() + return console.error("mediasync: error in syncData: " + err.toString()), Promise.resolve() }) }) }) } function afterSyncData(apiClient, serverInfo, syncDataResult) { - console.log("[mediasync] Begin afterSyncData"); + console.debug("mediasync: begin afterSyncData"); var p = Promise.resolve(); return syncDataResult.ItemIdsToRemove && syncDataResult.ItemIdsToRemove.length > 0 && syncDataResult.ItemIdsToRemove.forEach(function(itemId) { p = p.then(function() { @@ -85,25 +87,25 @@ define(["localassetmanager"], function(localassetmanager) { }), p = p.then(function() { return removeObsoleteContainerItems(serverInfo.Id) }), p.then(function() { - return console.log("[mediasync] Exit afterSyncData"), Promise.resolve() + return console.debug("mediasync: exit afterSyncData"), Promise.resolve() }) } function removeObsoleteContainerItems(serverId) { - return console.log("[mediasync] Begin removeObsoleteContainerItems"), localassetmanager.removeObsoleteContainerItems(serverId) + return console.debug("mediasync: begin removeObsoleteContainerItems"), localassetmanager.removeObsoleteContainerItems(serverId) } function removeLocalItem(itemId, serverId) { - return console.log("[mediasync] Begin removeLocalItem"), localassetmanager.getLocalItem(serverId, itemId).then(function(item) { + return console.debug("mediasync: begin removeLocalItem"), localassetmanager.getLocalItem(serverId, itemId).then(function(item) { return item ? localassetmanager.removeLocalItem(item) : Promise.resolve() }, function(err2) { - return console.error("[mediasync] removeLocalItem: Failed: ", err2), Promise.resolve() + return console.error("mediasync: removeLocalItem: Failed: ", err2), Promise.resolve() }) } function getNewMedia(apiClient, downloadCount) { - return console.log("[mediasync] Begin getNewMedia"), apiClient.getReadySyncItems(apiClient.deviceId()).then(function(jobItems) { - console.log("[mediasync] getReadySyncItems returned " + jobItems.length + " items"); + return console.debug("mediasync: begin getNewMedia"), apiClient.getReadySyncItems(apiClient.deviceId()).then(function(jobItems) { + console.debug("mediasync: getReadySyncItems returned " + jobItems.length + " items"); var p = Promise.resolve(), currentCount = downloadCount; return jobItems.forEach(function(jobItem) { @@ -111,15 +113,15 @@ define(["localassetmanager"], function(localassetmanager) { return getNewItem(jobItem, apiClient) })) }), p.then(function() { - return console.log("[mediasync] Exit getNewMedia"), Promise.resolve() + return console.debug("mediasync: exit getNewMedia"), Promise.resolve() }) }, function(err) { - return console.error("[mediasync] getReadySyncItems: Failed: ", err), Promise.resolve() + return console.error("mediasync: getReadySyncItems: Failed: ", err), Promise.resolve() }) } function afterMediaDownloaded(apiClient, jobItem, localItem) { - return console.log("[mediasync] Begin afterMediaDownloaded"), getImages(apiClient, jobItem, localItem).then(function() { + return console.debug("mediasync: begin afterMediaDownloaded"), getImages(apiClient, jobItem, localItem).then(function() { var libraryItem = jobItem.Item; return downloadParentItems(apiClient, jobItem, libraryItem).then(function() { return getSubtitles(apiClient, jobItem, localItem) @@ -128,21 +130,21 @@ define(["localassetmanager"], function(localassetmanager) { } function createLocalItem(libraryItem, jobItem) { - console.log("[localassetmanager] Begin createLocalItem"); + console.debug("localassetmanager: begin createLocalItem"); var item = { Item: libraryItem, ItemId: libraryItem.Id, ServerId: libraryItem.ServerId, Id: libraryItem.Id }; - return jobItem && (item.SyncJobItemId = jobItem.SyncJobItemId), console.log("[localassetmanager] End createLocalItem"), item + return jobItem && (item.SyncJobItemId = jobItem.SyncJobItemId), console.debug("localassetmanager: end createLocalItem"), item } function getNewItem(jobItem, apiClient) { - console.log("[mediasync] Begin getNewItem"); + console.debug("mediasync: begin getNewItem"); var libraryItem = jobItem.Item; return localassetmanager.getLocalItem(libraryItem.ServerId, libraryItem.Id).then(function(existingItem) { - if (existingItem && ("queued" === existingItem.SyncStatus || "transferring" === existingItem.SyncStatus || "synced" === existingItem.SyncStatus) && (console.log("[mediasync] getNewItem: getLocalItem found existing item"), localassetmanager.enableBackgroundCompletion())) return Promise.resolve(); + if (existingItem && ("queued" === existingItem.SyncStatus || "transferring" === existingItem.SyncStatus || "synced" === existingItem.SyncStatus) && (console.debug("mediasync: getNewItem: getLocalItem found existing item"), localassetmanager.enableBackgroundCompletion())) return Promise.resolve(); libraryItem.CanDelete = !1, libraryItem.CanDownload = !1, libraryItem.SupportsSync = !1, libraryItem.People = [], libraryItem.Chapters = [], libraryItem.Studios = [], libraryItem.SpecialFeatureCount = null, libraryItem.LocalTrailerCount = null, libraryItem.RemoteTrailers = []; var localItem = createLocalItem(libraryItem, jobItem); return localItem.SyncStatus = "queued", downloadMedia(apiClient, jobItem, localItem) @@ -169,7 +171,7 @@ define(["localassetmanager"], function(localassetmanager) { return localassetmanager.addOrUpdateLocalItem(localItem).then(function() { return Promise.resolve(localItem) }, function(err) { - return console.error("[mediasync] downloadItem failed: " + err.toString()), Promise.resolve(null) + return console.error("mediasync: downloadItem failed: " + err.toString()), Promise.resolve(null) }) }) } @@ -183,12 +185,12 @@ define(["localassetmanager"], function(localassetmanager) { } function downloadMedia(apiClient, jobItem, localItem) { - console.log("[mediasync] downloadMedia: start."); + console.debug("mediasync: downloadMedia: start."); var url = apiClient.getUrl("Sync/JobItems/" + jobItem.SyncJobItemId + "/File", { api_key: apiClient.accessToken() }); return ensureLocalPathParts(localItem, jobItem), localassetmanager.downloadFile(url, localItem).then(function(result) { - console.log("[mediasync] downloadMedia-downloadFile returned path: " + result.path); + console.debug("mediasync: downloadMedia-downloadFile returned path: " + result.path); var localPath = result.path, libraryItem = localItem.Item; if (localPath && libraryItem.MediaSources) @@ -200,18 +202,18 @@ define(["localassetmanager"], function(localassetmanager) { return afterMediaDownloaded(apiClient, jobItem, localItem).then(function() { return result.isComplete ? (localItem.SyncStatus = "synced", reportTransfer(apiClient, localItem)) : Promise.resolve() }, function(err) { - return console.log("[mediasync] downloadMedia: afterMediaDownloaded failed: " + err), Promise.reject(err) + return console.debug("mediasync: downloadMedia: afterMediaDownloaded failed: " + err), Promise.reject(err) }) }, function(err) { - return console.log("[mediasync] downloadMedia: addOrUpdateLocalItem failed: " + err), Promise.reject(err) + return console.debug("mediasync: downloadMedia: addOrUpdateLocalItem failed: " + err), Promise.reject(err) }) }, function(err) { - return console.log("[mediasync] downloadMedia: localassetmanager.downloadFile failed: " + err), Promise.reject(err) + return console.debug("mediasync: downloadMedia: localassetmanager.downloadFile failed: " + err), Promise.reject(err) }) } function getImages(apiClient, jobItem, localItem) { - console.log("[mediasync] Begin getImages"); + console.debug("mediasync: begin getImages"); var p = Promise.resolve(), libraryItem = localItem.Item, serverId = libraryItem.ServerId, @@ -249,15 +251,15 @@ define(["localassetmanager"], function(localassetmanager) { })), libraryItem.ParentPrimaryImageItemId && libraryItem.ParentPrimaryImageTag && (p = p.then(function() { return downloadImage(localItem, apiClient, serverId, libraryItem.ParentPrimaryImageItemId, libraryItem.ParentPrimaryImageTag, "Primary") })), p.then(function() { - return console.log("[mediasync] Finished getImages"), localassetmanager.addOrUpdateLocalItem(localItem) + return console.debug("mediasync: finished getImages"), localassetmanager.addOrUpdateLocalItem(localItem) }, function(err) { - return console.log("[mediasync] Error getImages: " + err.toString()), Promise.resolve() + return console.error("mediasync: error getImages: " + err.toString()), Promise.resolve() }) } function downloadImage(localItem, apiClient, serverId, itemId, imageTag, imageType, index) { return index = index || 0, localassetmanager.hasImage(serverId, itemId, imageType, index).then(function(hasImage) { - if (hasImage) return console.log("[mediasync] downloadImage - skip existing: " + itemId + " " + imageType + "_" + index.toString()), Promise.resolve(); + if (hasImage) return console.debug("mediasync: downloadImage - skip existing: " + itemId + " " + imageType + "_" + index.toString()), Promise.resolve(); var maxWidth = 400; "backdrop" === imageType && (maxWidth = null); var imageUrl = apiClient.getScaledImageUrl(itemId, { @@ -266,18 +268,18 @@ define(["localassetmanager"], function(localassetmanager) { maxWidth: maxWidth, api_key: apiClient.accessToken() }); - return console.log("[mediasync] downloadImage " + itemId + " " + imageType + "_" + index.toString()), localassetmanager.downloadImage(localItem, imageUrl, serverId, itemId, imageType, index).then(function(result) { + return console.debug("mediasync: downloadImage " + itemId + " " + imageType + "_" + index.toString()), localassetmanager.downloadImage(localItem, imageUrl, serverId, itemId, imageType, index).then(function(result) { return Promise.resolve(result) }, function(err) { - return console.log("[mediasync] Error downloadImage: " + err.toString()), Promise.resolve() + return console.error("mediasync: error downloadImage: " + err.toString()), Promise.resolve() }) }, function(err) { - return console.log("[mediasync] Error downloadImage: " + err.toString()), Promise.resolve() + return console.error("mediasync: error downloadImage: " + err.toString()), Promise.resolve() }) } function getSubtitles(apiClient, jobItem, localItem) { - if (console.log("[mediasync] Begin getSubtitles"), !jobItem.Item.MediaSources.length) return console.log("[mediasync] Cannot download subtitles because video has no media source info."), Promise.resolve(); + if (console.debug("mediasync: begin getSubtitles"), !jobItem.Item.MediaSources.length) return console.debug("mediasync: cannot download subtitles because video has no media source info."), Promise.resolve(); var files = jobItem.AdditionalFiles.filter(function(f) { return "Subtitles" === f.Type }), @@ -288,16 +290,16 @@ define(["localassetmanager"], function(localassetmanager) { return getItemSubtitle(file, apiClient, jobItem, localItem, mediaSource) }) }), p.then(function() { - return console.log("[mediasync] Exit getSubtitles"), Promise.resolve() + return console.debug("mediasync: exit getSubtitles"), Promise.resolve() }) } function getItemSubtitle(file, apiClient, jobItem, localItem, mediaSource) { - console.log("[mediasync] Begin getItemSubtitle"); + console.debug("mediasync: begin getItemSubtitle"); var subtitleStream = mediaSource.MediaStreams.filter(function(m) { return "Subtitle" === m.Type && m.Index === file.Index })[0]; - if (!subtitleStream) return console.log("[mediasync] Cannot download subtitles because matching stream info was not found."), Promise.resolve(); + if (!subtitleStream) return console.debug("mediasync: cannot download subtitles because matching stream info was not found."), Promise.resolve(); var url = apiClient.getUrl("Sync/JobItems/" + jobItem.SyncJobItemId + "/AdditionalFiles", { Name: file.Name, api_key: apiClient.accessToken() @@ -311,7 +313,7 @@ define(["localassetmanager"], function(localassetmanager) { } function checkLocalFileExistence(apiClient, serverInfo, options) { - return options.checkFileExistence ? (console.log("[mediasync] Begin checkLocalFileExistence"), localassetmanager.getServerItems(serverInfo.Id).then(function(items) { + return options.checkFileExistence ? (console.debug("mediasync: begin checkLocalFileExistence"), localassetmanager.getServerItems(serverInfo.Id).then(function(items) { var completedItems = items.filter(function(item) { return item && ("synced" === item.SyncStatus || "error" === item.SyncStatus) }), @@ -332,13 +334,13 @@ define(["localassetmanager"], function(localassetmanager) { return function() { var self = this; "string" == typeof webWorkerBaseUrl && -1 !== webWorkerBaseUrl.indexOf("ms-appx://") ? self.sync = function(apiClient, serverInfo, options) { - return console.log("[mediasync]************************************* Start sync"), checkLocalFileExistence(apiClient, serverInfo, options).then(function() { + return console.debug("mediasync: start sync"), checkLocalFileExistence(apiClient, serverInfo, options).then(function() { return processDownloadStatus(apiClient, serverInfo, options).then(function() { return localassetmanager.getDownloadItemCount().then(function(downloadCount) { return !0 === options.syncCheckProgressOnly && downloadCount > 2 ? Promise.resolve() : reportOfflineActions(apiClient, serverInfo).then(function() { return getNewMedia(apiClient, downloadCount).then(function() { return syncData(apiClient, serverInfo).then(function() { - return console.log("[mediasync]************************************* Exit sync"), Promise.resolve() + return console.debug("mediasync: Exit sync"), Promise.resolve() }) }) }) @@ -348,7 +350,7 @@ define(["localassetmanager"], function(localassetmanager) { console.error(err.toString()) }) } : self.sync = function(apiClient, serverInfo, options) { - return console.log("[mediasync]************************************* Start sync"), checkLocalFileExistence(apiClient, serverInfo, options).then(function() { + return console.debug("mediasync: Start sync"), checkLocalFileExistence(apiClient, serverInfo, options).then(function() { return syncData(apiClient, serverInfo).then(function() { return processDownloadStatus(apiClient, serverInfo, options).then(function() { return localassetmanager.getDownloadItemCount().then(function(downloadCount) { @@ -365,4 +367,4 @@ define(["localassetmanager"], function(localassetmanager) { }) } } -}); \ No newline at end of file +}); diff --git a/src/libraries/apiclient/sync/multiserversync.js b/src/libraries/apiclient/sync/multiserversync.js index 0654b5615d..ff01a5ad1d 100644 --- a/src/libraries/apiclient/sync/multiserversync.js +++ b/src/libraries/apiclient/sync/multiserversync.js @@ -3,20 +3,20 @@ define(["serversync"], function(ServerSync) { function syncNext(connectionManager, servers, index, options, resolve, reject) { var length = servers.length; - if (index >= length) return console.log("MultiServerSync.sync complete"), void resolve(); + if (index >= length) return console.debug("MultiServerSync.sync complete"), void resolve(); var server = servers[index]; - console.log("Creating ServerSync to server: " + server.Id), (new ServerSync).sync(connectionManager, server, options).then(function() { - console.log("ServerSync succeeded to server: " + server.Id), syncNext(connectionManager, servers, index + 1, options, resolve, reject) + console.debug("Creating ServerSync to server: " + server.Id), (new ServerSync).sync(connectionManager, server, options).then(function() { + console.debug("ServerSync succeeded to server: " + server.Id), syncNext(connectionManager, servers, index + 1, options, resolve, reject) }, function(err) { - console.log("ServerSync failed to server: " + server.Id + ". " + err), syncNext(connectionManager, servers, index + 1, options, resolve, reject) + console.error("ServerSync failed to server: " + server.Id + ". " + err), syncNext(connectionManager, servers, index + 1, options, resolve, reject) }) } function MultiServerSync() {} return MultiServerSync.prototype.sync = function(connectionManager, options) { - return console.log("MultiServerSync.sync starting..."), new Promise(function(resolve, reject) { + return console.debug("MultiServerSync.sync starting..."), new Promise(function(resolve, reject) { var servers = connectionManager.getSavedServers(); syncNext(connectionManager, servers, 0, options, resolve, reject) }) }, MultiServerSync -}); \ No newline at end of file +}); diff --git a/src/libraries/apiclient/sync/serversync.js b/src/libraries/apiclient/sync/serversync.js index 34a1b11e8e..887b829cee 100644 --- a/src/libraries/apiclient/sync/serversync.js +++ b/src/libraries/apiclient/sync/serversync.js @@ -2,11 +2,11 @@ define([], function() { "use strict"; function performSync(connectionManager, server, options) { - console.log("ServerSync.performSync to server: " + server.Id), options = options || {}; + console.debug("ServerSync.performSync to server: " + server.Id), options = options || {}; var cameraUploadServers = options.cameraUploadServers || []; - console.log("ServerSync cameraUploadServers: " + JSON.stringify(cameraUploadServers)); + console.debug("ServerSync cameraUploadServers: " + JSON.stringify(cameraUploadServers)); var uploadPhotos = -1 !== cameraUploadServers.indexOf(server.Id); - return console.log("ServerSync uploadPhotos: " + uploadPhotos), (uploadPhotos ? uploadContent(connectionManager, server, options) : Promise.resolve()).then(function() { + return console.debug("ServerSync uploadPhotos: " + uploadPhotos), (uploadPhotos ? uploadContent(connectionManager, server, options) : Promise.resolve()).then(function() { return syncMedia(connectionManager, server, options) }) } @@ -26,7 +26,7 @@ define([], function() { function ServerSync() {} return ServerSync.prototype.sync = function(connectionManager, server, options) { - if (!server.AccessToken && !server.ExchangeToken) return console.log("Skipping sync to server " + server.Id + " because there is no saved authentication information."), Promise.resolve(); + if (!server.AccessToken && !server.ExchangeToken) return console.debug("Skipping sync to server " + server.Id + " because there is no saved authentication information."), Promise.resolve(); var connectionOptions = { updateDateLastAccessed: !1, enableWebSocket: !1, @@ -34,9 +34,9 @@ define([], function() { enableAutomaticBitrateDetection: !1 }; return connectionManager.connectToServer(server, connectionOptions).then(function(result) { - return "SignedIn" === result.State ? performSync(connectionManager, server, options) : (console.log("Unable to connect to server id: " + server.Id), Promise.reject()) + return "SignedIn" === result.State ? performSync(connectionManager, server, options) : (console.error("Unable to connect to server id: " + server.Id), Promise.reject()) }, function(err) { - throw console.log("Unable to connect to server id: " + server.Id), err + throw console.error("Unable to connect to server id: " + server.Id), err }) }, ServerSync -}); \ No newline at end of file +}); diff --git a/src/libraries/apiclient/sync/transfermanager.js b/src/libraries/apiclient/sync/transfermanager.js index 162a6a1226..d9889fffbd 100644 --- a/src/libraries/apiclient/sync/transfermanager.js +++ b/src/libraries/apiclient/sync/transfermanager.js @@ -27,4 +27,4 @@ define([], function() { resyncTransfers: resyncTransfers, getDownloadItemCount: getDownloadItemCount } -}); \ No newline at end of file +}); diff --git a/src/libraries/apiclient/sync/useractionrepository.js b/src/libraries/apiclient/sync/useractionrepository.js index 8612b05bea..7b33ba1c35 100644 --- a/src/libraries/apiclient/sync/useractionrepository.js +++ b/src/libraries/apiclient/sync/useractionrepository.js @@ -105,4 +105,4 @@ define([], function() { getAll: getAll, getByServerId: getByServerId } -}); \ No newline at end of file +}); diff --git a/src/libraries/pagejs/page.js b/src/libraries/pagejs/page.js index ce96fd185e..be5c8aee97 100644 --- a/src/libraries/pagejs/page.js +++ b/src/libraries/pagejs/page.js @@ -1074,4 +1074,4 @@ define([], function () { return page; -}); \ No newline at end of file +}); diff --git a/src/libraries/query-string/index.js b/src/libraries/query-string/index.js index 515b745bf3..cc63f52b80 100644 --- a/src/libraries/query-string/index.js +++ b/src/libraries/query-string/index.js @@ -15,4 +15,4 @@ window.queryString = {}, window.queryString.extract = function(maybeUrl) { return encodeURIComponent(key) + "=" + encodeURIComponent(val2) }).join("&") : encodeURIComponent(key) + "=" + encodeURIComponent(val) }).join("&") : "" -}; \ No newline at end of file +}; diff --git a/src/libraries/query-string/test.js b/src/libraries/query-string/test.js index 4e16ad17c1..072a33fb1d 100644 --- a/src/libraries/query-string/test.js +++ b/src/libraries/query-string/test.js @@ -80,4 +80,4 @@ describe(".parse()", function() { qs.extract(void 0) }, TypeError) }) -}); \ No newline at end of file +}); diff --git a/src/library.html b/src/library.html index 7e313c1708..398613f9e6 100644 --- a/src/library.html +++ b/src/library.html @@ -12,4 +12,4 @@
-
\ No newline at end of file +
diff --git a/src/livetvsettings.html b/src/livetvsettings.html index d853063ab0..1b1557889e 100644 --- a/src/livetvsettings.html +++ b/src/livetvsettings.html @@ -99,4 +99,4 @@
-
\ No newline at end of file +
diff --git a/src/log.html b/src/log.html index dd98b0d333..5943f5dc08 100644 --- a/src/log.html +++ b/src/log.html @@ -5,4 +5,4 @@
-
\ No newline at end of file +
diff --git a/src/metadataimages.html b/src/metadataimages.html index 8250572011..8ad129256c 100644 --- a/src/metadataimages.html +++ b/src/metadataimages.html @@ -22,4 +22,4 @@
-
\ No newline at end of file +
diff --git a/src/metadatanfo.html b/src/metadatanfo.html index 7263952b42..4005c74f67 100644 --- a/src/metadatanfo.html +++ b/src/metadatanfo.html @@ -46,4 +46,4 @@
-
\ No newline at end of file +
diff --git a/src/mypreferencesdisplay.html b/src/mypreferencesdisplay.html index 799681f061..bee49754af 100644 --- a/src/mypreferencesdisplay.html +++ b/src/mypreferencesdisplay.html @@ -1,4 +1,4 @@
-
\ No newline at end of file +
diff --git a/src/mypreferenceshome.html b/src/mypreferenceshome.html index f45a6478bf..79c5ccc4bd 100644 --- a/src/mypreferenceshome.html +++ b/src/mypreferenceshome.html @@ -1,4 +1,4 @@
-
\ No newline at end of file +
diff --git a/src/mypreferencesmenu.html b/src/mypreferencesmenu.html index f7948a0789..41fcd1b75c 100644 --- a/src/mypreferencesmenu.html +++ b/src/mypreferencesmenu.html @@ -32,7 +32,7 @@ \ No newline at end of file +
diff --git a/src/nowplaying.html b/src/nowplaying.html index 690aa2f5fe..59b6a4b789 100644 --- a/src/nowplaying.html +++ b/src/nowplaying.html @@ -12,7 +12,7 @@
-
+
@@ -63,7 +63,7 @@
@@ -87,10 +87,10 @@

diff --git a/src/playbackconfiguration.html b/src/playbackconfiguration.html index 81a42231e4..9deeeebbcd 100644 --- a/src/playbackconfiguration.html +++ b/src/playbackconfiguration.html @@ -27,4 +27,4 @@
-
\ No newline at end of file +
diff --git a/src/robots.txt b/src/robots.txt index 77470cb39f..1f53798bb4 100644 --- a/src/robots.txt +++ b/src/robots.txt @@ -1,2 +1,2 @@ User-agent: * -Disallow: / \ No newline at end of file +Disallow: / diff --git a/src/scripts/apploader.js b/src/scripts/apploader.js index 4b5d2e8eec..e8a63217a8 100644 --- a/src/scripts/apploader.js +++ b/src/scripts/apploader.js @@ -19,11 +19,23 @@ document.head.appendChild(script); } - injectScriptElement( - self.Promise ? "./libraries/alameda.js" : "./libraries/require.js", - function() { - // onload of require library - injectScriptElement("./scripts/site.js"); - } - ); + function loadSite() { + injectScriptElement( + "./libraries/alameda.js", + function() { + // onload of require library + injectScriptElement("./scripts/site.js"); + } + ); + } + + if (!self.Promise) { + // Load Promise polyfill if they are not natively supported + injectScriptElement( + "./libraries/npo.js", + loadSite + ); + } else { + loadSite(); + } })(); diff --git a/src/scripts/autobackdrops.js b/src/scripts/autobackdrops.js index 73042f83ce..09f89fad6f 100644 --- a/src/scripts/autobackdrops.js +++ b/src/scripts/autobackdrops.js @@ -10,7 +10,7 @@ define(["backdrop", "userSettings", "libraryMenu"], function (backdrop, userSett var data = cache[key]; if (data) { - console.log("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); } diff --git a/src/scripts/browser.js b/src/scripts/browser.js index 66c3051c8c..791ac7411b 100644 --- a/src/scripts/browser.js +++ b/src/scripts/browser.js @@ -311,4 +311,4 @@ define([], function () { browser.chromecast = browser.chrome && userAgent.toLowerCase().indexOf('crkey') !== -1; return browser; -}); \ No newline at end of file +}); diff --git a/src/scripts/browserdeviceprofile.js b/src/scripts/browserdeviceprofile.js index 9d91a691d0..b45bdc59bf 100644 --- a/src/scripts/browserdeviceprofile.js +++ b/src/scripts/browserdeviceprofile.js @@ -92,7 +92,7 @@ define(['browser'], function (browser) { return true; } - if (!!videoTestElement.canPlayType) { + if (videoTestElement.canPlayType) { return videoTestElement.canPlayType('application/x-mpegurl; codecs="avc1.42E01E, ac-3"').replace(/no/, '') || videoTestElement.canPlayType('application/vnd.apple.mpegURL; codecs="avc1.42E01E, ac-3"').replace(/no/, ''); } @@ -302,9 +302,9 @@ define(['browser'], function (browser) { try { var isTizenUhd = webapis.productinfo.isUdPanelSupported(); isTizenFhd = !isTizenUhd; - console.log("isTizenFhd = " + isTizenFhd); + console.debug("isTizenFhd = " + isTizenFhd); } catch (error) { - console.log("isUdPanelSupported() error code = " + error.code); + console.error("isUdPanelSupported() error code = " + error.code); } } @@ -761,7 +761,7 @@ define(['browser'], function (browser) { videoTestElement.canPlayType('video/mp4; codecs="avc1.6e0033"').replace(/no/, '')) { // These tests are passing in safari, but playback is failing - if (!browser.safari && !browser.iOS && !browser.web0s && !browser.edge) { + if (!browser.safari && !browser.iOS && !browser.web0s && !browser.edge && !browser.mobile) { h264Profiles += '|high 10'; } } diff --git a/src/scripts/datetime.js b/src/scripts/datetime.js index a7ee1d946a..8a7666844c 100644 --- a/src/scripts/datetime.js +++ b/src/scripts/datetime.js @@ -279,4 +279,4 @@ define(['globalize'], function (globalize) { return toLocaleTimeStringSupportsLocales; } }; -}); \ No newline at end of file +}); diff --git a/src/scripts/editorsidebar.js b/src/scripts/editorsidebar.js index 1a9b9775ef..b7cb4b5c57 100644 --- a/src/scripts/editorsidebar.js +++ b/src/scripts/editorsidebar.js @@ -49,7 +49,7 @@ define(["datetime", "jQuery", "material-icons"], function (datetime, $) { } else if (item.MediaType === "Audio") { htmlName += 'audiotrack'; } else if (item.Type === "TvChannel") { - htmlName += 'live_tv'; + htmlName += ''; } else if (item.MediaType === "Photo") { htmlName += 'photo'; } else if (item.MediaType === "Book") { diff --git a/src/scripts/globalize.js b/src/scripts/globalize.js index aa3a2ef0f9..69bb3aee21 100644 --- a/src/scripts/globalize.js +++ b/src/scripts/globalize.js @@ -38,7 +38,7 @@ define(['connectionManager', 'userSettings', 'events'], function (connectionMana try { culture = userSettings.language(); } catch (err) { - console.log('no language set in user settings'); + console.error('no language set in user settings'); } culture = culture || getDefaultLanguage(); @@ -48,7 +48,7 @@ define(['connectionManager', 'userSettings', 'events'], function (connectionMana try { dateTimeCulture = userSettings.dateTimeLocale(); } catch (err) { - console.log('no date format set in user settings'); + console.error('no date format set in user settings'); } if (dateTimeCulture) { diff --git a/src/scripts/librarybrowser.js b/src/scripts/librarybrowser.js index 4aab16b2e3..bd8980aed2 100644 --- a/src/scripts/librarybrowser.js +++ b/src/scripts/librarybrowser.js @@ -92,7 +92,7 @@ define(["userSettings"], function (userSettings) { if (showControls) { html += ''; - html += ''; + html += ''; } if (options.addLayoutButton) { diff --git a/src/scripts/librarymenu.js b/src/scripts/librarymenu.js index 0abcf697b1..001c75787d 100644 --- a/src/scripts/librarymenu.js +++ b/src/scripts/librarymenu.js @@ -12,6 +12,7 @@ define(["dom", "layoutManager", "inputManager", "connectionManager", "events", " html += "
"; html += '
'; html += ''; + html += ''; html += ''; html += ''; html += ''; @@ -27,6 +28,7 @@ define(["dom", "layoutManager", "inputManager", "connectionManager", "events", " headerHomeButton = skinHeader.querySelector(".headerHomeButton"); headerUserButton = skinHeader.querySelector(".headerUserButton"); headerCastButton = skinHeader.querySelector(".headerCastButton"); + headerAudioPlayerButton = skinHeader.querySelector(".headerAudioPlayerButton"); headerSearchButton = skinHeader.querySelector(".headerSearchButton"); lazyLoadViewMenuBarImages(); @@ -116,6 +118,10 @@ define(["dom", "layoutManager", "inputManager", "connectionManager", "events", " Dashboard.navigate("home.html"); } + function showAudioPlayer() { + return appRouter.showNowPlaying(); + } + function bindMenuEvents() { mainDrawerButton = document.querySelector(".mainDrawerButton"); @@ -140,9 +146,27 @@ define(["dom", "layoutManager", "inputManager", "connectionManager", "events", " headerCastButton.addEventListener("click", onCastButtonClicked); } + headerAudioPlayerButton.addEventListener("click", showAudioPlayer); + if (layoutManager.mobile) { initHeadRoom(skinHeader); } + events.on(playbackManager, 'playbackstart', onPlaybackStart); + events.on(playbackManager, 'playbackstop', onPlaybackStop); + } + + function onPlaybackStart(e) { + if (playbackManager.isPlayingAudio() && layoutManager.tv) { + headerAudioPlayerButton.classList.remove("hide"); + } else { + headerAudioPlayerButton.classList.add("hide"); + } + } + + function onPlaybackStop(e, stopInfo) { + if (stopInfo.nextMediaType != 'Audio') { + headerAudioPlayerButton.classList.add("hide"); + } } function onCastButtonClicked() { @@ -205,7 +229,7 @@ define(["dom", "layoutManager", "inputManager", "connectionManager", "events", " html += globalize.translate("HeaderAdmin"); html += ""; html += 'dashboard' + globalize.translate("TabDashboard") + ""; - html += 'mode_edit' + globalize.translate("Metadata") + ""; + html += '' + globalize.translate("Metadata") + ""; html += "
"; } @@ -219,7 +243,7 @@ define(["dom", "layoutManager", "inputManager", "connectionManager", "events", " html += 'wifi' + globalize.translate("ButtonSelectServer") + ""; } - html += 'exit_to_app' + globalize.translate("ButtonSignOut") + ""; + html += '' + globalize.translate("ButtonSignOut") + ""; html += "
"; } @@ -763,6 +787,7 @@ define(["dom", "layoutManager", "inputManager", "connectionManager", "events", " var currentUser; var headerCastButton; var headerSearchButton; + var headerAudioPlayerButton; var enableLibraryNavDrawer = !layoutManager.tv; var skinHeader = document.querySelector(".skinHeader"); var requiresUserRefresh = true; diff --git a/src/scripts/livetvcomponents.js b/src/scripts/livetvcomponents.js index 4215de4cbe..61ffc66fb4 100644 --- a/src/scripts/livetvcomponents.js +++ b/src/scripts/livetvcomponents.js @@ -34,7 +34,7 @@ define(["layoutManager", "datetime", "cardBuilder", "apphost"], function (layout day: "numeric" }); } catch (err) { - console.log("Error parsing premiereDate:" + item.StartDate + "; error: " + err); + console.error("error parsing premiereDate:" + item.StartDate + "; error: " + err); } } diff --git a/src/scripts/routes.js b/src/scripts/routes.js index b726aaf872..9c3db58a7f 100644 --- a/src/scripts/routes.js +++ b/src/scripts/routes.js @@ -16,12 +16,12 @@ define([ function defineRoute(newRoute) { var path = newRoute.path; - console.log("defining route: " + path); + console.debug("defining route: " + path); newRoute.dictionary = "core"; Emby.Page.addRoute(path, newRoute); } - console.log("defining core routes"); + console.debug("defining core routes"); defineRoute({ path: "/addplugin.html", diff --git a/src/scripts/site.js b/src/scripts/site.js index 0cf65158d5..fc18ae9504 100644 --- a/src/scripts/site.js +++ b/src/scripts/site.js @@ -286,10 +286,10 @@ var AppInfo = {}; bindConnectionManagerEvents(connectionManager, events, userSettings); if (!AppInfo.isNativeApp) { - console.log("loading ApiClient singleton"); + console.debug("loading ApiClient singleton"); return require(["apiclient"], function (apiClientFactory) { - console.log("creating ApiClient singleton"); + console.debug("creating ApiClient singleton"); var apiClient = new apiClientFactory(Dashboard.serverAddress(), apphost.appName(), apphost.appVersion(), apphost.deviceName(), apphost.deviceId(), window.devicePixelRatio); @@ -301,7 +301,7 @@ var AppInfo = {}; window.ApiClient = apiClient; localApiClient = apiClient; - console.log("loaded ApiClient singleton"); + console.debug("loaded ApiClient singleton"); }); } @@ -335,7 +335,7 @@ var AppInfo = {}; try { playbackManager.onAppClose(); } catch (err) { - console.log("error in onAppClose: " + err); + console.error("error in onAppClose: " + err); } }); return playbackManager; @@ -393,7 +393,7 @@ var AppInfo = {}; } function onRequireJsError(requireType, requireModules) { - console.log("RequireJS error: " + (requireType || "unknown") + ". Failed modules: " + (requireModules || []).join(",")); + console.error("RequireJS error: " + (requireType || "unknown") + ". Failed modules: " + (requireModules || []).join(",")); } function defineResizeObserver() { @@ -481,7 +481,7 @@ var AppInfo = {}; Promise.all(promises).then(function () { createConnectionManager().then(function () { - console.log("initAfterDependencies promises resolved"); + console.debug("initAfterDependencies promises resolved"); require(["globalize", "browser"], function (globalize, browser) { window.Globalize = globalize; @@ -492,6 +492,7 @@ var AppInfo = {}; require(["keyboardnavigation"], function(keyboardnavigation) { keyboardnavigation.enable(); }); + require(["mouseManager"]); require(["focusPreventScroll"]); require(["autoFocuser"], function(autoFocuser) { autoFocuser.enable(); @@ -525,10 +526,10 @@ var AppInfo = {}; document.title = Globalize.translateDocument(document.title, "core"); if (browser.tv && !browser.android) { - console.log("Using system fonts with explicit sizes"); + console.debug("using system fonts with explicit sizes"); require(["systemFontsSizedCss"]); } else { - console.log("Using default fonts"); + console.debug("using default fonts"); require(["systemFontsCss"]); } @@ -540,7 +541,7 @@ var AppInfo = {}; } function loadPlugins(appHost, browser, shell) { - console.log("Loading installed plugins"); + console.debug("loading installed plugins"); var list = [ "components/playback/playaccessvalidation", "components/playback/experimentalwarnings", @@ -582,13 +583,13 @@ var AppInfo = {}; } function onAppReady(browser) { - console.log("Begin onAppReady"); + console.debug("begin onAppReady"); // ensure that appHost is loaded in this point require(['apphost', 'appRouter'], function (appHost, appRouter) { window.Emby = {}; - console.log("onAppReady - loading dependencies"); + console.debug("onAppReady: loading dependencies"); if (browser.iOS) { require(['css!assets/css/ios.css']); } @@ -659,7 +660,7 @@ var AppInfo = {}; try { navigator.serviceWorker.register("serviceworker.js"); } catch (err) { - console.log("Error registering serviceWorker: " + err); + console.error("error registering serviceWorker: " + err); } } } @@ -671,11 +672,7 @@ var AppInfo = {}; AppInfo.isNativeApp = true; } - if (!window.Promise || browser.web0s) { - require(["native-promise-only"], init); - } else { - init(); - } + init(); } var localApiClient; @@ -908,9 +905,10 @@ var AppInfo = {}; define("htmlMediaHelper", [componentsPath + "/htmlMediaHelper"], returnFirstDependency); define("viewContainer", [componentsPath + "/viewContainer"], returnFirstDependency); define("dialogHelper", [componentsPath + "/dialogHelper/dialogHelper"], returnFirstDependency); - define("serverNotifications", [componentsPath + "/serverNotifications/serverNotifications"], returnFirstDependency); + define("serverNotifications", [componentsPath + "/serverNotifications"], returnFirstDependency); define("skinManager", [componentsPath + "/skinManager"], returnFirstDependency); - define("keyboardnavigation", [componentsPath + "/keyboardnavigation"], returnFirstDependency); + define("keyboardnavigation", [componentsPath + "/input/keyboardnavigation"], returnFirstDependency); + define("mouseManager", [componentsPath + "/input/mouseManager"], returnFirstDependency); define("scrollManager", [componentsPath + "/scrollManager"], returnFirstDependency); define("autoFocuser", [componentsPath + "/autoFocuser"], returnFirstDependency); define("connectionManager", [], function () { @@ -989,10 +987,6 @@ var AppInfo = {}; Dashboard.navigate("mypreferencesmenu.html"); }; - appRouter.showNowPlaying = function () { - Dashboard.navigate("nowplaying.html"); - }; - appRouter.setTitle = function (title) { LibraryMenu.setTitle(title); }; diff --git a/src/scripts/userpassword.js b/src/scripts/userpassword.js deleted file mode 100644 index 52e06e6cec..0000000000 --- a/src/scripts/userpassword.js +++ /dev/null @@ -1,30 +0,0 @@ -define(["jQuery", "loading", "libraryMenu"], function ($, loading, libraryMenu) { - "use strict"; - - function loadUser(page, user) { - libraryMenu.setTitle(user.Name); - - if ("Guest" == user.ConnectLinkType) { - $(".connectMessage", page).show(); - } else { - $(".connectMessage", page).hide(); - } - - loading.hide(); - } - - function loadData(page) { - loading.show(); - var userId = getParameterByName("userId"); - ApiClient.getUser(userId).then(function (user) { - loadUser(page, user); - }); - } - - $(document).on("pageinit", "#userPasswordPage", function () { - $(".adminUpdatePasswordForm").off("submit", UpdatePasswordPage.onSubmit).on("submit", UpdatePasswordPage.onSubmit); - $(".adminLocalAccessForm").off("submit", UpdatePasswordPage.onLocalAccessSubmit).on("submit", UpdatePasswordPage.onLocalAccessSubmit); - }).on("pagebeforeshow", "#userPasswordPage", function () { - loadData(this); - }); -}); diff --git a/src/selectserver.html b/src/selectserver.html index dd52467bfe..2c84525174 100644 --- a/src/selectserver.html +++ b/src/selectserver.html @@ -3,7 +3,7 @@

${HeaderSelectServer}

-
+
diff --git a/src/serviceworker.js b/src/serviceworker.js index 4d9e12ee6a..c43d1f4b4e 100644 --- a/src/serviceworker.js +++ b/src/serviceworker.js @@ -1 +1,2 @@ -importScripts("components/serviceworker/notifications.js"); \ No newline at end of file +/* eslint-env serviceworker */ +importScripts("components/serviceworker/notifications.js"); diff --git a/src/strings/cs.json b/src/strings/cs.json index 346215407f..23f4d624eb 100644 --- a/src/strings/cs.json +++ b/src/strings/cs.json @@ -554,7 +554,7 @@ "LabelH264Crf": "H264 kódování CRF:", "LabelEncoderPreset": "Přednastavení H264 kódování:", "LabelHardwareAccelerationType": "Hardwarová akcelerace:", - "LabelHardwareAccelerationTypeHelp": "Toto je experimentální funkce dostupná pouze v podporovaných systémech.", + "LabelHardwareAccelerationTypeHelp": "Hardwarová akcelerace vyžaduje další konfiguraci.", "LabelHomeScreenSectionValue": "Sekce domovské obrazovky {0}:", "LabelHttpsPort": "Lokální HTTPS port:", "LabelHttpsPortHelp": "Číslo portu TCP, ke kterému by se měl připojit HTTPS server Jellyfin.", @@ -1567,5 +1567,8 @@ "EnableFastImageFadeIn": "Rychlé zmizení obrazu", "LabelPlayerDimensions": "Zobrazené rozlišení:", "LabelDroppedFrames": "Vynechané snímky:", - "LabelCorruptedFrames": "Poškozené snímky:" + "LabelCorruptedFrames": "Poškozené snímky:", + "OptionForceRemoteSourceTranscoding": "Vynutit transkódování vzdálených zdrojů médií (jako např. živá TV)", + "NoCreatedLibraries": "Zdá se, že jste dosud nevytvořili žádnou knihovnu. {0}Chtěli byste nějakou vytvořit nyní?{1}", + "AskAdminToCreateLibrary": "Požádejte administrátora o vytvoření knihovny." } diff --git a/src/strings/de.json b/src/strings/de.json index ac5b84ae76..1c5b4243b3 100644 --- a/src/strings/de.json +++ b/src/strings/de.json @@ -260,7 +260,7 @@ "EncoderPresetHelp": "Wähle einen schnelleren Wert um die Performance zu verbessern oder einen langsameren Wert um die Qualität zu verbessern.", "HDPrograms": "HD Programme", "HandledByProxy": "Verwaltet vom Reverse Proxy", - "HardwareAccelerationWarning": "Das Aktivieren der Hardwarebeschleunigung kann auf einigen Systemen zu Instabilität führen. Stellen Sie sicher, dass Ihr Betriebssystem sowie Ihre Grafikkarten-Treiber auf dem aktuellsten Stand sind. Wenn Sie nach der Aktivierung Probleme mit der Wiedergabe von Videos haben, müssen Sie diese Einstellung zurück auf \"Auto\" stellen.", + "HardwareAccelerationWarning": "Das Aktivieren der Hardwarebeschleunigung kann auf einigen Systemen zu Instabilität führen. Stellen Sie sicher, dass Ihr Betriebssystem sowie Ihre Grafikkarten-Treiber auf dem aktuellsten Stand sind. Wenn Sie nach der Aktivierung Probleme mit der Wiedergabe von Videos haben, müssen Sie diese Einstellung zurück auf \"Keine\" stellen.", "HeaderAccessSchedule": "Zugangsplan", "HeaderAccessScheduleHelp": "Erstelle einen Zugangsplan, um den Zugriff auf bestimmte Zeiten zu limitieren.", "HeaderActiveDevices": "Aktive Geräte", @@ -593,7 +593,7 @@ "LabelGroupMoviesIntoCollectionsHelp": "Wenn Filmlisten angezeigt werden, dann werden Filme, die zu einer Collection gehören, als ein gruppiertes Element angezeigt.", "LabelEncoderPreset": "H264 Encoding Voreinstellung:", "LabelHardwareAccelerationType": "Hardware Beschleunigung:", - "LabelHardwareAccelerationTypeHelp": "Dies ist eine experimentelle Funktion und nur auf unterstützten Systemen verfügbar.", + "LabelHardwareAccelerationTypeHelp": "Hardwarebeschleunigung benötigt zusätzliche Konfiguration.", "LabelHomeNetworkQuality": "Heimnetzwerkqualität:", "LabelHomeScreenSectionValue": "Startseitenbereich {0}:", "LabelHttpsPort": "Lokale HTTPS-Portnummer:", @@ -1486,5 +1486,7 @@ "LabelPlayerDimensions": "Playerabmessungen:", "LabelDroppedFrames": "Verlorene Frames:", "LabelCorruptedFrames": "Fehlerhafte Frames:", - "OptionForceRemoteSourceTranscoding": "Transkodieren von externen Medienquellen erzwingen (z.B. LiveTV)" + "OptionForceRemoteSourceTranscoding": "Transkodieren von externen Medienquellen erzwingen (z.B. LiveTV)", + "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}" } diff --git a/src/strings/en-us.json b/src/strings/en-us.json index d7e404eba6..72894707db 100644 --- a/src/strings/en-us.json +++ b/src/strings/en-us.json @@ -24,6 +24,8 @@ "AllowMediaConversionHelp": "Grant or deny access to the convert media feature.", "AllowOnTheFlySubtitleExtraction": "Allow subtitle extraction on the fly", "AllowOnTheFlySubtitleExtractionHelp": "Embedded subtitles can be extracted from videos and delivered to clients in plain text in order to help prevent video transcoding. On some systems this can take a long time and cause video playback to stall during the extraction process. Disable this to have embedded subtitles burned in with video transcoding when they are not natively supported by the client device.", + "AllowFfmpegThrottling": "Throttle Transcodes", + "AllowFfmpegThrottlingHelp": "When a transcode or remux gets far enough ahead from the current playback position, pause the process so it will consume less resources. This is most useful when watching without seeking often. Turn this off if you experience playback issues.", "AllowRemoteAccess": "Allow remote connections to this Jellyfin Server.", "AllowRemoteAccessHelp": "If unchecked, all remote connections will be blocked.", "AllowedRemoteAddressesHelp": "Comma separated list of IP addresses or IP/netmask entries for networks that will be allowed to connect remotely. If left blank, all remote addresses will be allowed.", @@ -282,7 +284,7 @@ "EncoderPresetHelp": "Choose a faster value to improve performance, or a slower value to improve quality.", "HDPrograms": "HD programs", "HandledByProxy": "Handled by reverse proxy", - "HardwareAccelerationWarning": "Enabling hardware acceleration may cause instability in some environments. Ensure that your operating system and video drivers are fully up to date. If you have difficulty playing video after enabling this, you'll need to change the setting back to Auto.", + "HardwareAccelerationWarning": "Enabling hardware acceleration may cause instability in some environments. Ensure that your operating system and video drivers are fully up to date. If you have difficulty playing video after enabling this, you'll need to change the setting back to None.", "HeaderAccessSchedule": "Access Schedule", "HeaderAccessScheduleHelp": "Create an access schedule to limit access to certain hours.", "HeaderActiveDevices": "Active Devices", diff --git a/src/strings/es_DO.json b/src/strings/es_DO.json index 70f9f52d46..7c42778a1c 100644 --- a/src/strings/es_DO.json +++ b/src/strings/es_DO.json @@ -2,5 +2,15 @@ "Add": "Añadir", "Actor": "Actor", "AccessRestrictedTryAgainLater": "El acceso está restringido actualmente. Inténtelo de nuevo más tarde.", - "Absolute": "Absoluto" + "Absolute": "Absoluto", + "HeaderAlbumArtists": "Artistas del Álbum", + "HeaderContinueWatching": "Continuar Viendo", + "Genres": "Géneros", + "Folders": "Carpetas", + "Favorites": "Favoritos", + "Collections": "Colecciones", + "Books": "Libros", + "Albums": "Álbumes", + "Artists": "Artistas", + "Channels": "Canales" } diff --git a/src/strings/he.json b/src/strings/he.json index e94a916b02..d2e7263177 100644 --- a/src/strings/he.json +++ b/src/strings/he.json @@ -66,7 +66,7 @@ "Edit": "ערוך", "EditImages": "ערוך תמונות", "EditSubtitles": "ערוך כתוביות", - "EnableColorCodedBackgrounds": "אפשר רקע בצבע מקודד", + "EnableColorCodedBackgrounds": "רקע בצבע מקודד", "Ended": "הסתיים", "EndsAtValue": "מסתיים ב {0}", "Favorite": "מועדף", @@ -550,5 +550,47 @@ "AllowOnTheFlySubtitleExtraction": "אפשר חילוץ כתוביות בזמן אמת", "AllowHWTranscodingHelp": "אפשר למלקט לקודד הזרמות בזמן אמת. זה עשוי לעזור בהפחתת הקידוד שנעשה ע\"י השרת.", "AllComplexFormats": "כל הפורמטים המורכבים (ASS, SSA, VOBSUB, PGS, SUB\\IDX וכדומה)", - "AddItemToCollectionHelp": "הוסף פריטים לאוספים ע\"י חיפושם ושימוש בלחצן ימני או הקשה על התפריט כדי להוסיף אותם לאוסף." + "AddItemToCollectionHelp": "הוסף פריטים לאוספים ע\"י חיפושם ושימוש בלחצן ימני או הקשה על התפריט כדי להוסיף אותם לאוסף.", + "Songs": "שירים", + "Shows": "סדרות", + "DownloadsValue": "{0} הורדות", + "DisplayMissingEpisodesWithinSeasons": "הצג פרקים חסרים בתוך העונות", + "DisplayInMyMedia": "הצג בעמוד הבית", + "Disconnect": "התנתק", + "DirectorsValue": "במאים: {0}", + "DirectorValue": "במאי: {0}", + "Descending": "סדר יורד", + "Default": "ברירת מחדל", + "DeathDateValue": "נפטר: {0}", + "DatePlayed": "תאריך ניגון", + "DateAdded": "תאריך הוספה", + "CriticRating": "דירוג מבקרים", + "ContinueWatching": "המשך לצפות", + "ButtonUninstall": "הסר התקנה", + "ButtonTrailer": "קדימון", + "ButtonSubtitles": "כתוביות", + "ButtonSplit": "פיצול", + "ButtonStop": "עצור", + "ButtonSettings": "הגדרות", + "ButtonSend": "שלח", + "ButtonSelectView": "בחר תצוגה", + "ButtonSelectServer": "בחר שרת", + "ButtonRename": "שנה שם", + "ButtonPause": "השהה", + "ButtonParentalControl": "בקרת הורים", + "ButtonNetwork": "רשת", + "ButtonMore": "עוד", + "ButtonLearnMore": "למד עוד", + "ButtonInfo": "מידע", + "ButtonHome": "בית", + "ButtonHelp": "עזרה", + "ButtonFullscreen": "מסך מלא", + "ButtonEditImages": "ערוך תמונות", + "ButtonConnect": "התחבר", + "ButtonAddServer": "הוסף שרת", + "ButtonAddMediaLibrary": "הוסף ספריית מדיה", + "ButtonAddImage": "הוסף תמונה", + "AskAdminToCreateLibrary": "בקש ממנהל ליצור ספרייה.", + "Ascending": "סדר עולה", + "Photos": "תמונות" } diff --git a/src/strings/hu.json b/src/strings/hu.json index 541323e90a..f7a1700810 100644 --- a/src/strings/hu.json +++ b/src/strings/hu.json @@ -267,7 +267,7 @@ "LabelGroupMoviesIntoCollections": "Filmek csoportosítása gyűjteményekbe", "LabelEncoderPreset": "H264 enkóder beállítások:", "LabelHardwareAccelerationType": "Hardveres gyorsítás:", - "LabelHardwareAccelerationTypeHelp": "Ez egy kísérleti szolgáltatás, amely csak a támogatott rendszereken érhető el.", + "LabelHardwareAccelerationTypeHelp": "A hardveres gyorsítás további konfigurálást igényel.", "LabelHomeScreenSectionValue": "{0}. kezdőképernyő blokk:", "LabelImageType": "Kép típusa:", "LabelKodiMetadataDateFormat": "Megjelenési dátum formátuma:", @@ -602,7 +602,7 @@ "Backdrops": "Háttér", "Banner": "Banner", "BirthLocation": "Születési hely", - "Box": "Box", + "Box": "Doboz", "AlwaysPlaySubtitlesHelp": "A nyelvi beállításoknak megfelelő feliratok az audió nyelvétől függetlenül kerülnek betöltésre.", "Artists": "Előadók", "Blacklist": "Feketelista", @@ -659,7 +659,7 @@ "DirectPlaying": "Közvetlen lejátszás", "DirectStreamHelp1": "Az adathordozó kompatibilis a készülékkel a felbontás és a médiatípus (H.264, AC3, stb.) tekintetében, de nem kompatibilis a fájltárolóban (.mkv, .avi, .wmv, stb.). A videófelvétel újra csomagolásra kerül, mielőtt azt a készülékre továbbítaná.", "DirectStreamHelp2": "A fájl közvetlen közvetítése (Direct Streaming) nagyon kevés feldolgozási erőforrást használ, ennek ellenére a videó nem veszít a minőségéből.", - "DirectStreaming": "Direct streaming", + "DirectStreaming": "Közvetlen streaming", "Disabled": "Tiltva", "Disc": "Lemez", "Disconnect": "Szétkapcsol", @@ -702,7 +702,7 @@ "EncoderPresetHelp": "Válassz egy gyorsabb értéket a teljesítmény javítása érdekében, vagy egy lassabb értéket a minőség javítása érdekében.", "HDPrograms": "HD programok", "HandledByProxy": "Reverse proxy segítségével kezelhető", - "HardwareAccelerationWarning": "A hardveres gyorsítás engedélyezése bizonyos környezetekben instabilitást okozhat. Győződj meg róla, hogy az operációs rendszer és a videó-illesztőprogramok teljesen naprakészek. Ha a beállítás után problémába ütközik a videólejátszás, akkor vissza kell állítani a beállítást Auto-ra.", + "HardwareAccelerationWarning": "A hardveres gyorsítás engedélyezése bizonyos környezetekben instabilitást okozhat. Győződj meg róla, hogy az operációs rendszer és a videó-illesztőprogramok teljesen naprakészek. Ha a beállítás után problémába ütközik a videólejátszás, akkor vissza kell állítani a beállítást Nincs-re.", "HeaderAccessSchedule": "Hozzáférési Ütemezés", "HeaderAccessScheduleHelp": "Hozz létre hozzáférési ütemezést, hogy korlátozd a hozzáférést bizonyos időben.", "HeaderActiveRecordings": "Aktív Felvételek", @@ -748,7 +748,7 @@ "HeaderIdentificationCriteriaHelp": "Adj meg legalább egy azonosítási kritériumot.", "HeaderIdentificationHeader": "Azonosító fejléc", "HeaderImageOptions": "Képbeállítások", - "HeaderInstantMix": "Instant Mix", + "HeaderInstantMix": "Azonnali keverés", "HeaderItems": "Elemek", "HeaderKeepRecording": "Felvétel készítése", "HeaderKodiMetadataHelp": "Az Nfo metaadatok engedélyezéséhez vagy letiltásához szerkeszd a könyvtárat a Jellyfin Médiatár beállításaiban és keresd meg a metaadat letöltő részt.", @@ -816,11 +816,11 @@ "HeaderXmlDocumentAttribute": "XML dokumentum attribútum", "HeaderXmlDocumentAttributes": "XML dokumentum attribútumok", "HeaderXmlSettings": "XML beállítások", - "Hide": "Elrejt", + "Hide": "Elrejtés", "Horizontal": "Vízszintes", "HttpsRequiresCert": "A biztonságos kapcsolatok engedélyezéséhez megbízható SSL-tanúsítványt kell használni, mint például a Let's Encrypt. Kérlek add meg a tanúsítványt, vagy tiltsd le a biztonságos kapcsolatokat.", "ImportMissingEpisodesHelp": "Ha engedélyezve van, a hiányzó epizódokra vonatkozó információk a Jellyfin adatbázisába kerülnek importálásra és megjelenítésre kerülnek az évadokban és sorozatokban. Ez jelentősen hosszabb könyvtárvizsgálatot okozhat.", - "InstantMix": "Instant mix", + "InstantMix": "Azonnali keverés", "ItemCount": "{0} elem", "Items": "Elemek", "Kids": "Gyerekek", @@ -1440,5 +1440,36 @@ "LabelCorruptedFrames": "Sérült képkockák:", "HeaderKeepSeries": "Sorozat megtartása", "ErrorGettingTvLineups": "Hiba történt a TV kínálat letöltése során. Kérjük ellenőrizd a megadott információkat és próbáld újra.", - "LabelTranscodes": "Átkódolások:" + "LabelTranscodes": "Átkódolások:", + "AskAdminToCreateLibrary": "Kérj meg egy adminisztrátort könyvtár létrehozására.", + "LabelXDlnaDoc": "X-DLNA doc:", + "LabelXDlnaCap": "X-DLNA cap:", + "MapChannels": "Csatornák feltérképezése", + "PasswordResetProviderHelp": "Válassz egy jelszó-visszaállítási szolgáltatót, amelyet akkor kell használni, amikor a felhasználó jelszó-visszaállítást kér", + "OptionResElement": "res elem", + "OptionReportByteRangeSeekingWhenTranscodingHelp": "Erre olyan készülékek esetében van szükség, amelyek időigénye nem nagyon jó.", + "OptionPlainVideoItemsHelp": "Ha engedélyezve van, akkor az összes videót a DIDL-ben \"object.item.videoItem\" -ként ábrázolja, nem pedig egy specifikusabb típusként, például \"object.item.videoItem.movie\" .", + "OptionPlainStorageFoldersHelp": "Ha engedélyezve van, akkor az összes mappa a DIDL-ben \"object.container.storageFolder\" lesz, nem pedig egy specifikusabb típusként, például \"object.container.person.musicArtist\".", + "OptionHlsSegmentedSubtitles": "HLS szegmentált feliratok", + "OptionEquals": "Egyenlő", + "OptionForceRemoteSourceTranscoding": "A távoli médiaforrások (például az élő TV) átkódolásának kényszerítése", + "NoCreatedLibraries": "Úgy tűnik még nem hoztál létre egy könyvtárat sem. {0}Szeretnél létrehozni egyet most?{1}", + "MessageDirectoryPickerBSDInstruction": "A BSD esetében valószínűleg konfigurálni kell a FreeNAS Jailben lévő tárolót, hogy a Jellyfin hozzáférhest kapjon.", + "LabelXDlnaDocHelp": "Meghatározza az X_DLNADOC elem tartalmát az urn: schemas-dlna-org: device-1-0 névtérben.", + "LabelXDlnaCapHelp": "Meghatározza az X_DLNACAP elem tartalmát az urn: schemas-dlna-org: eszköz-1-0 névtérben.", + "LabelVaapiDeviceHelp": "Ez a render csomópont, amelyet a hardveres gyorsításhoz használunk.", + "LabelTriggerType": "Trigger típusa:", + "LabelTranscodingProgress": "Átkódolás folyamatban:", + "LabelTranscodingFramerate": "Átkódolás framerate:", + "LabelTranscodePath": "Átkódolási útvonal:", + "LabelSonyAggregationFlagsHelp": "Meghatározza az aggregationFlags elem tartalmát az urn: schemas-sonycom: av névtérben.", + "LabelPostProcessorArguments": "Utófeldolgozási parancssori paraméterek:", + "LabelPlayerDimensions": "Lejátszó méretei:", + "LabelParentNumber": "Szülő száma:", + "LabelMetadataReadersHelp": "Rangsorold az előnyben részesített metaadat forrásokat. Az a forrás kerül sorsolásra, amelyben először találunk információt.", + "LabelLineup": "Felhozatal:", + "LabelBaseUrlHelp": "Ide hozzáadhatsz egy egyéni alkönyvtárat, hogy a szerverhez egyedibb URL-címről férj hozzá.", + "ErrorPleaseSelectLineup": "Kérjük, válassz ki egy felhozatalt, és próbáld újra. Ha nem állnak rendelkezésre felsorolások, akkor ellenőrizd, hogy helyes-e felhasználóneved, jelszavad és irányítószámod.", + "ErrorAddingListingsToSchedulesDirect": "Hiba történt a felhozatal hozzáadása közben a Schedules Direct fiókhoz. A Schedules Direct csak korlátozott számú fiók hozzáadását támogatja. Lehetséges, hogy be kell jelentkezned a Schedules Direct weboldalán és eltávolítani néhány más listát a fiókodról mielőtt továbblépsz.", + "DeviceAccessHelp": "Ez csak azokra az eszközökre alkalmazható, amelyek egyedileg vannak azonosítva és nem gátolják meg a böngészőből való elérést. A felhasználói eszközök kiszűrése meg fogja akadályozni az új eszközök használatát addig, amíg itt nem engedélyezed őket." } diff --git a/src/strings/id.json b/src/strings/id.json index 81d82159fd..1a6113ecd6 100644 --- a/src/strings/id.json +++ b/src/strings/id.json @@ -200,5 +200,7 @@ "Sync": "Sinkron", "Shows": "Tayangan", "Photos": "Foto", - "Movies": "Film" + "Movies": "Film", + "Alerts": "Peringatan", + "AddedOnValue": "Ditambahkan {0}" } diff --git a/src/strings/is-is.json b/src/strings/is-is.json index 36eba8ff7a..70fc891193 100644 --- a/src/strings/is-is.json +++ b/src/strings/is-is.json @@ -232,24 +232,66 @@ "ButtonResetPassword": "Endurstilla lykilorð", "ButtonOpen": "Opna", "Songs": "Lög", - "ButtonProfile": "", - "ButtonPreviousTrack": "", - "ButtonPause": "", - "ButtonRemove": "", - "ButtonResume": "", - "ButtonQuickStartGuide": "", - "ConfirmDeleteImage": "", - "ButtonRename": "", + "ButtonProfile": "Prófíll", + "ButtonPreviousTrack": "Fyrra lag", + "ButtonPause": "Pása", + "ButtonRemove": "Fjarlægja", + "ButtonResume": "Halda áfram", + "ButtonQuickStartGuide": "Byrjunar leiðarvísir", + "ConfirmDeleteImage": "Eyða mynd?", + "ButtonRename": "Endurnefna", "Sync": "Samstilla", "Never": "", "News": "", - "ButtonRevoke": "", - "ButtonRepeat": "", + "ButtonRevoke": "Afturkalla", + "ButtonRepeat": "Endurtaka", "MusicArtist": "", "MusicAlbum": "", "No": "", - "Monday": "", + "Monday": "Mánudagur", "Name": "", "Mute": "", - "MusicVideo": "" + "MusicVideo": "", + "ButtonRefresh": "Endurhlaða", + "ButtonParentalControl": "Foreldraeftirlit", + "ButtonOff": "Af", + "ButtonNextTrack": "Næsta lag", + "ButtonNetwork": "Net", + "ButtonMore": "Meira", + "ButtonManualLogin": "Handvirkt Auðkenni", + "ButtonLibraryAccess": "Aðgangur að safni", + "ButtonLearnMore": "Læra meira", + "ButtonInfo": "Upplýsingar", + "ButtonHome": "Heim", + "ButtonHelp": "Hjálp", + "ButtonGuide": "Sjónvarpsvísir", + "ButtonGotIt": "Skilið", + "ButtonFullscreen": "Fylla upp í skjá", + "ButtonForgotPassword": "Gleymt Lykilorð", + "ButtonFilter": "Sía", + "ButtonEditOtherUserPreferences": "Breyta stillingum notanda, mynd og persónulegum stillingum.", + "ButtonEditImages": "Breyta myndum", + "ButtonEdit": "Breyta", + "ButtonDownload": "Sækja", + "ButtonDown": "Niður", + "ButtonDeleteImage": "Eyða Mynd", + "ButtonDelete": "Eyða", + "ButtonConnect": "Tengjast", + "ButtonChangeServer": "Skipta um þjón", + "ButtonBack": "Til baka", + "ButtonAudioTracks": "Hljóðspor", + "BookLibraryHelp": "Hljóð og texta bækur eru stuttar. Lesið {0}book naming guide{1}.", + "Backdrops": "Bakgrunnar", + "Backdrop": "Bakgrunnur", + "AuthProviderHelp": "Veljið vottunaraðila til þess að sannvotta lykilorð notanta.", + "AskAdminToCreateLibrary": "Biðjið stjórnanda að gera nýtt gagnasafn.", + "MoreFromValue": "Meira frá {0}", + "AlwaysPlaySubtitlesHelp": "Allir textar sem samsvara við túngumáli valið verða alltaf hlaðnir óháð hljóðmáls túngumáli.", + "AllowedRemoteAddressesHelp": "Kommu aðskilinn listi yfir ip tölur eða ip-númeramát fyrir net sem mega fjartengjas. Ef þetta er autt eru allar fjartengingar leyfðar.", + "AllowHWTranscodingHelp": "Leyfa viðtæki að umbreyta straumi í rauntíma.Þetta getur minnkað álag á þjón.", + "ValueSpecialEpisodeName": "Sérstakt - {0}", + "Shows": "Þættir", + "Playlists": "Spilunarlisti", + "ButtonScanAllLibraries": "Skanna Öll Gagnasöfn", + "AllLibraries": "Öll gagnasöfn" } diff --git a/src/strings/kk.json b/src/strings/kk.json index ebb3d22b95..73ea163b2e 100644 --- a/src/strings/kk.json +++ b/src/strings/kk.json @@ -637,7 +637,7 @@ "LabelH264Crf": "H264 kodtaý CRF máni:", "LabelEncoderPreset": "H264 kodtaý daıyndamasy:", "LabelHardwareAccelerationType": "Apparatyq jedeldetý:", - "LabelHardwareAccelerationTypeHelp": "Bul tájirıbelik múmkindik tek qoldaý kórsetiletin júıelerde qoljetimdi.", + "LabelHardwareAccelerationTypeHelp": "Apparattyq jedeldetý úshin qosymsha konfıgýrasýa qajet.", "LabelHomeNetworkQuality": "Úılik jeli sapasy:", "LabelHomeScreenSectionValue": "Basqy bet {0}-bólim:", "LabelHttpsPort": "Jergilikti HTTPS-port nómiri:", @@ -1485,5 +1485,21 @@ "FetchingData": "Qosymsha derekterdi shyǵaryp alý", "ButtonAddImage": "Sýret ústeý", "MusicLibraryHelp": "{0}Mýzyka ataý nusqaýlyǵyn{1} qarap shyǵý.", - "HeaderFavoritePeople": "Tańdaýly adamdar" + "HeaderFavoritePeople": "Tańdaýly adamdar", + "NoCreatedLibraries": "Eshqandaı tasyǵyshhanany jasamaǵanyńyz sıaqty. {0}Qazir bireýin jasaısyz ba?{1}", + "SelectAdminUsername": "Ákimshi tirkelgisi úshin paıdalanýshy atyn tańdańyz.", + "OptionRandom": "Kezdeısoq", + "OptionForceRemoteSourceTranscoding": "Alystaǵy tasyǵyshderekter kózin qaıta kodtaýdy májbúrleý (efırlik TD sıaqty)", + "MessageConfirmAppExit": "Shyǵýdy qalaısyz ba?", + "LabelVideoResolution": "Beıne ajyratymdylyǵy:", + "LabelStreamType": "Aǵyn túri:", + "EnableFastImageFadeInHelp": "Júktelgen sýretter úshin shapshan kórsetilýin qosý", + "EnableFastImageFadeIn": "Sýrettiń shapshan kórsetilýi", + "LabelPlayerDimensions": "Oınatqysh ólshemderi:", + "LabelDroppedFrames": "Ótkizilgen kadrlar:", + "LabelCorruptedFrames": "Búlingen kadrlar:", + "HeaderNavigation": "Sharlaý", + "CopyStreamURLError": "URL kóshirgende qate oryn aldy.", + "ButtonSplit": "Bólý", + "AskAdminToCreateLibrary": "Tasýǵyshanany jasaý úshin ákimshiden suraý." } diff --git a/src/strings/ko.json b/src/strings/ko.json index 8e2e438d89..9cfacb6c34 100644 --- a/src/strings/ko.json +++ b/src/strings/ko.json @@ -94,7 +94,7 @@ "DeleteMedia": "미디어 제거", "DeleteUser": "사용자 제거", "DeleteUserConfirmation": "이 사용자를 제거하겠습니까?", - "DeviceAccessHelp": "이것은 고유하게 식별할 수 있고 브라우저 접근을 방해하지 않는 장치에만 적용됩니다. 사용자 장치 접근을 필터링하면 여기에서 승인될 때까지 새 장치를 사용할 수 없게 됩니다.", + "DeviceAccessHelp": "이것은 고유하게 식별할 수 있는 장치에만 적용되므로 브라우저를 통한 접근은 차단할 수 없습니다. 사용자 장치 접근을 필터링하면 이곳에서 승인될 때까지 새 장치를 사용할 수 없게 됩니다.", "Director": "감독", "Dislike": "싫어요", "Download": "다운로드", @@ -1285,5 +1285,15 @@ "Identify": "식별자", "HeaderMoreLikeThis": "비슷한 작품", "DirectorsValue": "감독: {0}", - "ButtonSplit": "나누기" + "ButtonSplit": "나누기", + "HeaderContainerProfileHelp": "컨테이너 프로파일은 사용자의 디바이스에서 재생 가능한 파일 형식을 나타냅니다. 다이렉트 플레이가 설정된 경우에도 디바이스에서 지원되지 않는 형식이라면 트랜스코딩이 적용됩니다.", + "HeaderCodecProfileHelp": "코덱 프로파일은 사용자의 디바이스에서 재생 가능한 코덱을 가리킵니다. 다이렉트 플레이가 설정된 경우에도 디바이스에서 지원되지 않는 코덱이라면 트랜스코딩이 적용됩니다.", + "HeaderAppearsOn": "표시", + "HandledByProxy": "리버스 프록시로 처리", + "Features": "기능", + "ErrorPleaseSelectLineup": "라인업을 선택하고 다시 시도하십시오. 이용 가능한 라인업이 없으면 계정, 비밀번호, 우편번호가 정확한지 확인하십시오.", + "ErrorAddingListingsToSchedulesDirect": "Schedules Direct 계정에 라인업을 추가하는 중에 오류가 발생했습니다. Schedules Direct는 계정 당 제한된 수의 라인업만이 허용됩니다. 계속하려면 Schedules Direct 웹사이트에 로그인하여 다른 항목을 삭제해야 할 수 있습니다.", + "CopyStreamURLError": "URL을 복사하는 중에 오류가 발생했습니다.", + "ColorTransfer": "컬러 변환", + "AskAdminToCreateLibrary": "라이브러리를 생성하려면 관리자에게 문의하십시오." } diff --git a/src/strings/ms.json b/src/strings/ms.json index 9f959b9574..c377e52af1 100644 --- a/src/strings/ms.json +++ b/src/strings/ms.json @@ -35,14 +35,14 @@ "AllowOnTheFlySubtitleExtractionHelp": "Sarikata-sarikata yang sedia ada dapat diekstrak dari video-video dan dihantar ke aplikasi Jellyfin dalam teks biasa. Ini untuk menghindari video daripada transkoding. Pada sistem-sistem lain, ia dapat mengambil masa panjang dan menyebabkan video main balik terhenti semasa proses pengekstrakan. Ciri ini dapat dimatikan supaya sarikata yang sedia ada akan dibakar bersama video transkoding, jika ianya tidak disokong secara asal oleh peranti klien.", "AllowRemoteAccess": "Membenarkan persambungan jauh ke pelayan Jellyfin ini.", "AllowRemoteAccessHelp": "Jika tidak disemak, semua persambungan jauh akan disekat.", - "AllowHWTranscodingHelp": "Jika diaktifkan, penala dibolehkan untuk transkod strim dengan serta-merta. Ini dapat bantu mengurangkan transkoding yang diperlukan dari pelayan Jellyfin.", + "AllowHWTranscodingHelp": "Benarkan penala untuk transkod strim serta-merta. Ini mungkin dapat bantu kurangkan kadar transkod yang diperlukan dari pelayan.", "AlwaysPlaySubtitles": "Sentiasa main sarikata", "AlwaysPlaySubtitlesHelp": "Sarikata sepadan dengan bahasa yang dipilih akan masih dimuatkan tanpa mengira bahasa audio.", "AnyLanguage": "Mana-mana bahasa", "Anytime": "Pada bila masa saja", "AroundTime": "Sekitar {0}", "Art": "Seni", - "Artists": "Artis-artis", + "Artists": "Artis", "AsManyAsPossible": "Sebanyak mungkin", "Ascending": "Susunan menaik", "AspectRatio": "Nisbah aspek", diff --git a/src/strings/pt-br.json b/src/strings/pt-br.json index 8f9a9b022b..1ea78320d5 100644 --- a/src/strings/pt-br.json +++ b/src/strings/pt-br.json @@ -1451,5 +1451,18 @@ "MusicLibraryHelp": "Verifique o {0}guia de nomes de músicas{1}.", "ButtonAddImage": "Adicionar Imagem", "HeaderFavoritePeople": "Pessoas Favoritas", - "OptionRandom": "Aleatório" + "OptionRandom": "Aleatório", + "SelectAdminUsername": "Por favor selecione um nome de usuário para a conta de administrador.", + "OptionForceRemoteSourceTranscoding": "Forçar transcodificação em fontes de mídia remotas (como LiveTV)", + "NoCreatedLibraries": "Parece que você ainda não criou nenhuma biblioteca. {0}Gostaria de criar uma agora?{1}", + "MessageConfirmAppExit": "Você quer sair?", + "LabelVideoResolution": "Resolução de vídeo:", + "LabelStreamType": "Tipo de stream:", + "EnableFastImageFadeIn": "Fade-in rápido da imagem", + "LabelPlayerDimensions": "Dimensões do player:", + "LabelCorruptedFrames": "Quadros corrompidos:", + "HeaderNavigation": "Navegação", + "CopyStreamURLError": "Houve um erro ao copiar a URL.", + "ButtonSplit": "Dividir", + "AskAdminToCreateLibrary": "Peça a um administrador para criar uma biblioteca." } diff --git a/src/strings/pt-pt.json b/src/strings/pt-pt.json index 2cf5193bd7..089345ad55 100644 --- a/src/strings/pt-pt.json +++ b/src/strings/pt-pt.json @@ -351,7 +351,7 @@ "LabelGroupMoviesIntoCollections": "Agrupar filmes em coleções", "LabelGroupMoviesIntoCollectionsHelp": "Ao mostrar listas de filmes, filmes que pertençam a uma coleção serão mostrados como um único item agrupado.", "LabelHardwareAccelerationType": "Aceleração por hardware:", - "LabelHardwareAccelerationTypeHelp": "Esta funcionalidade é experimental e está disponível apenas em sistemas suportados.", + "LabelHardwareAccelerationTypeHelp": "Aceleração via Hardware requer configurações adicionais.", "LabelHttpsPort": "Número do porto HTTPS local:", "LabelHttpsPortHelp": "Número do porto TCP em que o servidor HTTPS do Jellyfin ficará à escuta.", "LabelIconMaxHeight": "Altura máxima do ícone:", @@ -1442,5 +1442,9 @@ "EnableStreamLooping": "Auto-cíclico de streams ao vivo", "Down": "Baixo", "CopyStreamURLError": "Ocorreu um erro a copiar o URL.", - "ButtonSplit": "Dividir" + "ButtonSplit": "Dividir", + "NoCreatedLibraries": "Oh Não! Parece que você ainda não criou nenhuma biblioteca por enquanto. {0} Gostaria de criar uma biblioteca agora? {1}", + "AskAdminToCreateLibrary": "Pergunte a um administrador para criar uma biblioteca.", + "LabelVideoResolution": "Resolução de vídeo:", + "LabelPlayerDimensions": "Dimensões de leitor:" } diff --git a/src/strings/ro.json b/src/strings/ro.json index b8e87e0d36..3880d14d10 100644 --- a/src/strings/ro.json +++ b/src/strings/ro.json @@ -809,7 +809,7 @@ "LabelHttpsPort": "Portul local HTTPS:", "LabelHomeScreenSectionValue": "Secțiunea ecranului de pornire {0}:", "LabelHomeNetworkQuality": "Calitatea pe rețeaua de domiciliu:", - "LabelHardwareAccelerationTypeHelp": "Aceasta este o caracteristică experimentală disponibilă doar pe sistemele acceptate.", + "LabelHardwareAccelerationTypeHelp": "Accelerarea hardware necesită configurare suplimentară.", "LabelHardwareAccelerationType": "Accelerare hardware:", "LabelEncoderPreset": "H264 encoding presetat:", "LabelH264Crf": "CRF codare H264:", @@ -1463,5 +1463,7 @@ "LabelPlayerDimensions": "Dimensiunile soft redare:", "LabelDroppedFrames": "Cadre abandonate:", "LabelCorruptedFrames": "Cadre corupte:", - "OptionForceRemoteSourceTranscoding": "Forțați transcodarea surselor media distante (cum ar fi LiveTV)" + "OptionForceRemoteSourceTranscoding": "Forțați transcodarea surselor media distante (cum ar fi LiveTV)", + "NoCreatedLibraries": "Se pare că nu ați creat încă biblioteci. {0} Doriți să creați una acum? {1}", + "AskAdminToCreateLibrary": "Cereți unui administrator să creeze o bibliotecă." } diff --git a/src/strings/ru.json b/src/strings/ru.json index b90aaa90b4..5ef7fb3024 100644 --- a/src/strings/ru.json +++ b/src/strings/ru.json @@ -622,7 +622,7 @@ "LabelH264Crf": "Значение CRF H264-кодирования:", "LabelEncoderPreset": "Предустановка H264-кодирования:", "LabelHardwareAccelerationType": "Аппаратное ускорение:", - "LabelHardwareAccelerationTypeHelp": "Это экспериментальная функция, имеющаяся только на поддерживаемых системах.", + "LabelHardwareAccelerationTypeHelp": "Аппаратное ускорение требует дополнительной конфигурации.", "LabelHomeNetworkQuality": "Качество в домашней сети:", "LabelHomeScreenSectionValue": "Главная страница - раздел {0}:", "LabelHttpsPort": "Номер локального HTTPS-порта:", @@ -1458,10 +1458,13 @@ "HeaderNavigation": "Навигация", "LabelVideoResolution": "Разрешение видео:", "LabelStreamType": "Тип потока:", - "EnableFastImageFadeInHelp": "Включить быстрое гашение анимации для загруженных рисунков", - "EnableFastImageFadeIn": "Быстрое гашение рисунка", + "EnableFastImageFadeInHelp": "Включить быстрое появление анимации для загруженных рисунков", + "EnableFastImageFadeIn": "Быстрое появление рисунка", "LabelPlayerDimensions": "Размерности проигрывателя:", "LabelDroppedFrames": "Пропущенные кадры:", "LabelCorruptedFrames": "Испорченные кадры:", - "CopyStreamURLError": "Произошла ошибка при копировании URL." + "CopyStreamURLError": "Произошла ошибка при копировании URL.", + "OptionForceRemoteSourceTranscoding": "Принудительное перекодирование удалённых источников медиаданных (например, эфирное ТВ)", + "NoCreatedLibraries": "Похоже, вы еще не создали ни одной медиатеки. {0}Желаете создать её сейчас?{1}", + "AskAdminToCreateLibrary": "Запрашивать администратора для создания медиатеки." } diff --git a/src/strings/sk.json b/src/strings/sk.json index a6fce31503..56bbaf04cf 100644 --- a/src/strings/sk.json +++ b/src/strings/sk.json @@ -1143,7 +1143,7 @@ "HeaderApp": "Appka", "HeaderApiKeysHelp": "Externé aplikácie musia mať vlastný API kľúč, aby mohli komunikovať s Jellyfin Serverom. Kľúče sú vydávané pomocou prihlásenia sa cez Jellyfin účet alebo manuálnym priradením kľúča aplikácií.", "HeaderAdditionalParts": "Dodatočné časti", - "HardwareAccelerationWarning": "Povolenie hardvérovej akcelerácie môže spôsobiť nestabilitu v niektorých podmienkach. Uistite sa, že váš operačný systém a grafické ovládače sú plne aktualizované. Pokiaľ máte po zapnutí problémy s prehrávaním videa, budete musieť zmeniť nastavenie späť na Auto.", + "HardwareAccelerationWarning": "Povolenie hardvérovej akcelerácie môže spôsobiť nestabilitu v niektorých podmienkach. Uistite sa, že váš operačný systém a grafické ovládače sú plne aktualizované. Pokiaľ máte po zapnutí problémy s prehrávaním videa, budete musieť zmeniť nastavenie späť na Žiadne.", "AddItemToCollectionHelp": "Pridať položku do kolekcie jej vyhľadaním a použitím pravého tlačítka myši alebo kliknutím na tlačidlo ponuky a pridať do kolekcie.", "HandledByProxy": "Spracované pomocou reverznej proxy", "EncoderPresetHelp": "Vyberte hodnotu faster pre zlepšenie výkonu alebo hodnotu slower pre zlepšenie kvality.", @@ -1465,5 +1465,7 @@ "LabelDroppedFrames": "Vynechané snímky:", "LabelCorruptedFrames": "Poškodené snímky:", "CopyStreamURLError": "Pri kopírovaní URL nastala chyba.", - "OptionForceRemoteSourceTranscoding": "Vynútiť transkódovanie vzdialených mediálnych zdrojov (ako napr. živá TV)" + "OptionForceRemoteSourceTranscoding": "Vynútiť transkódovanie vzdialených mediálnych zdrojov (ako napr. živá TV)", + "NoCreatedLibraries": "Vyzerá to tak, že ste zatiaľ nevytvorili žiadnu knižnicu. {0}Chceli by ste nejakú vytvoriť teraz?{1}", + "AskAdminToCreateLibrary": "Pokiaľ chcete vytvoriť knižnicu, musíte sa spýtať administrátora." } diff --git a/src/strings/sv.json b/src/strings/sv.json index 17556a0f6d..524a644f8b 100644 --- a/src/strings/sv.json +++ b/src/strings/sv.json @@ -1,14 +1,14 @@ { - "AccessRestrictedTryAgainLater": "Åtkomst är begränsad. Försök igen senare.", + "AccessRestrictedTryAgainLater": "För närvarande är åtkomst begränsad. Försök igen senare.", "Actor": "Skådespelare", "Add": "Lägg till", - "AddItemToCollectionHelp": "Lägg till objekt till samlingar genom att först söka efter dom och sen högerklicka eller tappa upp menyn för att lägga till dom.", + "AddItemToCollectionHelp": "Lägg till objekt till samlingar genom att först söka efter dem och sen högerklicka eller tappa upp menyn för att lägga till dem.", "AddToCollection": "Lägg till samling", "AddToPlayQueue": "Lägg till i spelkö", "AddToPlaylist": "Lägg till i spellista", "AddedOnValue": "Tillagd {0}", "AdditionalNotificationServices": "Sök efter fler meddelandetillägg i tilläggskatalogen.", - "AirDate": "Sändningstid", + "AirDate": "Sändningsdatum", "Aired": "Sändes", "Albums": "Album", "All": "Alla", @@ -17,7 +17,7 @@ "AllEpisodes": "Alla avsnitt", "AllLanguages": "Alla språk", "AllLibraries": "Alla bibliotek", - "AllowHWTranscodingHelp": "Aktivera för att låta TV-mottagaren omkoda strömmar. Det kan minska behovet av omkodning på Jellyfin Server.", + "AllowHWTranscodingHelp": "Tillåt TV-mottagaren att omkoda strömmar. Det kan minska behovet av omkodning på Jellyfin Servern.", "AllowOnTheFlySubtitleExtraction": "Tillåt undertextsextrahering under uppspelning", "AllowOnTheFlySubtitleExtractionHelp": "Inbäddade undertexter kan extraheras ur videor och skickas till klienter i textformat för att förhindra omkodning. I vissa system kan detta ta en lång tid och stoppa videouppspelningen under extraheringsprocessen. Avaktivera detta för att bränna in inbäddade undertexter genom omkodning när de inte stöds av klienten.", "AllowRemoteAccess": "Tillåt fjärranslutningar till denna Jellyfin-server.", @@ -40,13 +40,13 @@ "BirthDateValue": "Född: {0}", "BirthLocation": "Födelseort", "BirthPlaceValue": "Födelseort:{0}", - "BookLibraryHelp": "Ljud- och textböcker stöds. Läs {0}Jellyfins boknamngivningsguide{1}.", + "BookLibraryHelp": "Ljud- och textböcker stöds. Läs {0}boknamngivningsguide{1}.", "Books": "Böcker", "Box": "Omslag", "BoxRear": "Omslag (baksida)", "Browse": "Bläddra", "BrowsePluginCatalogMessage": "Besök katalogen för att se tillgängliga tillägg.", - "BurnSubtitlesHelp": "Avgör ifall servern ska \"bränna in\" undertexterna under videokonverteringen, beroende på undertextsformatet. Att undvika inbränning av undertexter kommer att förbättra prestandan på servern. Välj Automatisk för att bränna bild-baserade formats (ex. VOBSUB, PGS, SUB/IDX, etc.) men också vissa ASS/SSA undertexter.", + "BurnSubtitlesHelp": "Avgör ifall servern ska \"bränna in\" undertexterna under videokonverteringen, beroende på undertextsformatet. Att undvika inbränning av undertexter kommer att förbättra prestandan på servern. Välj Automatisk för att bränna bild-baserade formats (ex. VOBSUB, PGS, SUB/IDX, etc.) och vissa ASS/SSA undertexter.", "ButtonAdd": "Lägg till", "ButtonAddMediaLibrary": "Lägg till mediabibliotek", "ButtonAddScheduledTaskTrigger": "Lägg till utlösare", @@ -69,25 +69,25 @@ "ButtonEditImages": "Ändra bilder", "ButtonEditOtherUserPreferences": "Ändra den här användarens profil, bild och personliga inställningar.", "ButtonFilter": "Filtrera", - "ButtonForgotPassword": "Glömt lösenord", + "ButtonForgotPassword": "Glömt Lösenord", "ButtonFullscreen": "Fullskärm", "ButtonGotIt": "Ok", "ButtonHelp": "Hjälp", "ButtonHome": "Hem", "ButtonLearnMore": "Läs mer", "ButtonLibraryAccess": "Biblioteksåtkomst", - "ButtonManualLogin": "Manuell inloggning:", + "ButtonManualLogin": "Manuell inloggning", "ButtonMore": "Mer", "ButtonNetwork": "Nätverk", "ButtonNew": "Nytillkommet", - "ButtonNextTrack": "Nästa spår:", + "ButtonNextTrack": "Nästa spår", "ButtonOff": "Av", "ButtonOk": "OK", "ButtonOpen": "Öppna", "ButtonParentalControl": "Föräldralås", "ButtonPause": "Paus", "ButtonPlay": "Spela upp", - "ButtonPreviousTrack": "Föregående spår:", + "ButtonPreviousTrack": "Föregående spår", "ButtonProfile": "Profil", "ButtonQuickStartGuide": "Snabbstartguide", "ButtonRefresh": "Uppdatera", @@ -179,14 +179,14 @@ "Down": "Ner", "Download": "Ladda ned", "DownloadsValue": "Nedladdningar: {0}", - "DrmChannelsNotImported": "Kanaler med DRM kommer inte att importeras", - "DropShadow": "Visa skugga", + "DrmChannelsNotImported": "Kanaler med DRM kommer inte att importeras.", + "DropShadow": "Visa Skugga", "EasyPasswordHelp": "Din enkla pin-kod används för att logga in offline på klienter som stödjer det, och kan också användas för enkel inloggning från ditt nätverk.", "Edit": "Ändra", "EditImages": "Ändra bilder", "EditMetadata": "Redigera metadata", "EditSubtitles": "Ändra undertexter", - "EnableBackdrops": "Aktivera fondbilder", + "EnableBackdrops": "Fondbilder", "EnableBackdropsHelp": "Visar fondbilder i bakgrunden av vissa sidor vid bläddring i biblioteket.", "EnableCinemaMode": "Bioläge", "EnableColorCodedBackgrounds": "Färgkodade bakgrundsbilder", @@ -198,9 +198,9 @@ "EnableNextVideoInfoOverlayHelp": "Vid slutet av en video, visa information om nästföljande video i spellistan.", "EnablePhotos": "Visa foton", "EnablePhotosHelp": "Bilder kommer upptäckas och visas tillsammans med andra mediefiler.", - "EnableThemeSongs": "Aktivera ledmotiv", + "EnableThemeSongs": "Signaturmelodi", "EnableThemeSongsHelp": "Spela ledmotiv i bakgrunden vid bläddring i biblioteket.", - "EnableThemeVideos": "Aktivera tema-videos", + "EnableThemeVideos": "Tema-videor", "EnableThemeVideosHelp": "Spela tema-videos i bakgrunden vid bläddring i biblioteket.", "Ended": "Avslutad", "EndsAtValue": "Slutar vid: {0}", @@ -208,13 +208,13 @@ "ErrorAddingMediaPathToVirtualFolder": "Det gick inte att lägga till sökvägen. Kontrollera att sökvägen är korrekt och att Jellyfin Server har rättigheter till sökvägen.", "ErrorAddingTunerDevice": "Det gick inte att lågga till den här TV-mottagaren. Säkerställ att den går att nå och försök igen.", "ErrorDeletingItem": "Det gick inte att ta bort det här objektet från Jellyfin-servern. Kontrollera att Jellyfin-servern har skrivrättigheter till media-mappen och försök igen.", - "ErrorGettingTvLineups": "Ett fel uppstod vid nedladdningen utav tv-sortimentet. Se till så att uppgifterna stämmer och försök igen.", + "ErrorGettingTvLineups": "Ett fel uppstod vid nedladdningen utav TV-sortimentet. Se till så att uppgifterna stämmer och försök igen.", "ErrorMessageStartHourGreaterThanEnd": "Sluttiden måste vara senare än starttiden.", "ErrorPleaseSelectLineup": "Välj en lineup och försök igen. Om inga lineups finns tillgängliga, kolla så att användarnamn, lösenord och postnummer stämmer.", "ErrorSavingTvProvider": "Ett fel uppstod när TV-tjänsten skulle sparas. Se till att den går att nå och försök igen senare.", "EveryNDays": "Var {0}:e dag", "ExitFullscreen": "Avsluta fullskärm", - "ExtraLarge": "Extra stor", + "ExtraLarge": "Extra Stor", "ExtractChapterImagesHelp": "Att extrahera kapitelrutor möjliggör för klienter att visa grafiska menyer för kapitelval. Aktiviteten kan vara långsam, resurs-intensiv och kan kräva flera gigabyte i utrymme. Aktiviteten körs när nya videofiler upptäcks, och är även schemalagd under nattetid. Schemat går att konfigurera under schemalagda aktiviteter. Det är inte rekommenderat att köra den här aktiviteten vid tider med hög belastning.", "FFmpegSavePathNotFound": "Det gick inte att hitta FFmpeg med den angivna sökvägen. FFprobe måste även finnas i samma mapp. Dessa komponenter inkluderas normalt i samma nedladdning. Var god undersök sökvägen och försök igen.", "Favorite": "Favorit", @@ -229,7 +229,7 @@ "FolderTypeMovies": "Filmer", "FolderTypeMusic": "Musik", "FolderTypeMusicVideos": "Musikvideor", - "FolderTypeTvShows": "Serier", + "FolderTypeTvShows": "TV Serier", "FolderTypeUnset": "Blandat Innehåll", "Folders": "Mappar", "Friday": "Fredag", @@ -287,7 +287,7 @@ "HeaderContainerProfile": "Behållareprofil", "HeaderContainerProfileHelp": "Behållareprofiler bestämmer begränsningarna hos en enhet när den spelar upp olika filformat. Om en begränsning är aktuell kommer innehållet att kodas om, även om formatet i sig är inställt för direkt avspelning.", "HeaderContinueListening": "Fortsätt lyssna på", - "HeaderContinueWatching": "Fortsätt kolla på", + "HeaderContinueWatching": "Fortsätt kolla", "HeaderCustomDlnaProfiles": "Anpassade profiler", "HeaderDateIssued": "Utgivningsdatum", "HeaderDefaultRecordingSettings": "Standard inspelningsinställningar", @@ -320,9 +320,9 @@ "HeaderFrequentlyPlayed": "Ofta spelade", "HeaderGenres": "Genrer", "HeaderGuideProviders": "Källor för programguide", - "HeaderHttpHeaders": "Http-rubriker", + "HeaderHttpHeaders": "HTTP headers", "HeaderIdentification": "Identifiering", - "HeaderIdentificationCriteriaHelp": "Var god skriv in minst ett identifieringskriterium", + "HeaderIdentificationCriteriaHelp": "Skriv in minst ett kriterie för identifiering.", "HeaderIdentificationHeader": "ID-rubrik", "HeaderIdentifyItemHelp": "Ange ett eller flera sökkriterier. Ta bort kriterier för att få fler träffar.", "HeaderImageSettings": "Bildinställningar", @@ -331,7 +331,7 @@ "HeaderItems": "Objekt", "HeaderKeepRecording": "Fortsätt spela in", "HeaderKeepSeries": "Behåll serie", - "HeaderKodiMetadataHelp": "Jellyfin har stöd för Nfo-metadatafiler. För att aktivera eller inaktivera Nfo-metadata, använd Metadata-fliken för att konfigurera Nfo-stöd för dina mediatyper.", + "HeaderKodiMetadataHelp": "Jellyfin har stöd för NFO-metadatafiler. För att aktivera eller inaktivera NFO-metadata, använd Metadata-fliken för att konfigurera NFO-stöd för dina mediatyper.", "HeaderLatestEpisodes": "Senaste avsnitten", "HeaderLatestMedia": "Nytillkommet", "HeaderLatestMovies": "Nytillkomna filmer", @@ -350,7 +350,7 @@ "HeaderMetadataSettings": "Metadatainställningar", "HeaderMoreLikeThis": "Mer som denna", "HeaderMovies": "Filmer", - "HeaderMusicQuality": "Musikkvalitet:", + "HeaderMusicQuality": "Musikkvalitet", "HeaderMusicVideos": "Musikvideor", "HeaderMyDevice": "Min enhet", "HeaderMyMedia": "Min Media", @@ -358,7 +358,7 @@ "HeaderNewApiKey": "Ny API-nyckel", "HeaderNewDevices": "Nya enheter", "HeaderNextEpisodePlayingInValue": "Nästa avsnitt börjar om {0}", - "HeaderNextUp": "Nästa på tur", + "HeaderNextUp": "Nästa", "HeaderNextVideoPlayingInValue": "Nästa video börjar om {0}", "HeaderOnNow": "Visas nu", "HeaderOtherItems": "Övriga objekt", @@ -375,7 +375,7 @@ "HeaderPlaybackError": "Uppspelningsfel", "HeaderPleaseSignIn": "Var god logga in", "HeaderPluginInstallation": "Installation av tillägg", - "HeaderPreferredMetadataLanguage": "Önskat språk för metadata:", + "HeaderPreferredMetadataLanguage": "Önskat språk för metadata", "HeaderProfile": "Profil", "HeaderProfileInformation": "Profilinformation", "HeaderProfileServerSettingsHelp": "Dessa inställningar kontrollerar hur Jellyfin Server presenterar sig för enheten.", @@ -404,7 +404,7 @@ "HeaderSelectTranscodingPath": "Välj plats för mellanlagring vid omkodning", "HeaderSelectTranscodingPathHelp": "Bläddra fram till eller ange plats för omkodarens mellanlagring. Katalogen måste vara tillgänglig för skrivning.", "HeaderSendMessage": "Skicka meddelande", - "HeaderSeries": "Serie:", + "HeaderSeries": "Serier", "HeaderSeriesOptions": "Seriealternativ", "HeaderSeriesStatus": "Seriestatus", "HeaderServerSettings": "Serverinställningar", @@ -479,7 +479,7 @@ "LabelAllowServerAutoRestart": "Tillåt att servern startas om automatiskt efter uppdateringar", "LabelAllowServerAutoRestartHelp": "Servern startas om endast då inga användare är inloggade.", "LabelAppName": "Appens namn", - "LabelAppNameExample": "Exempel: Sickbeard, NzbDrone", + "LabelAppNameExample": "Exempel: Sickbeard, Sonarr", "LabelArtists": "Artister:", "LabelArtistsHelp": "Separera med vid flera ;", "LabelAudio": "Ljud:", @@ -506,8 +506,8 @@ "LabelCriticRating": "Kritikerbetyg:", "LabelCurrentPassword": "Nuvarande lösenord:", "LabelCustomCertificatePath": "Sökväg för anpassat SSL-certifikat:", - "LabelCustomCertificatePathHelp": "Lägg upp ditt eget SSL-certifkat i .pfx-format", - "LabelCustomCss": "Egen css:", + "LabelCustomCertificatePathHelp": "Lägg upp ditt eget SSL-certifkat i .pfx-format.", + "LabelCustomCss": "Egen CSS:", "LabelCustomCssHelp": "Applicera din egen css till webbgränssnittet.", "LabelCustomDeviceDisplayName": "Visningsnamn:", "LabelCustomDeviceDisplayNameHelp": "Ange ett anpassat enhetsnamn. Lämna blankt för att använda det namn enheten själv rapporterar.", @@ -523,7 +523,7 @@ "LabelDefaultUser": "Förvald användare:", "LabelDefaultUserHelp": "Anger vilket användarbibliotek som skall visas på anslutna enheter. Denna inställning kan ändras på enhetsbasis med hjälp av en enhetsprofiler.", "LabelDeviceDescription": "Enhetsbeskrivning", - "LabelDidlMode": "Didl-läge:", + "LabelDidlMode": "DIDL-läge:", "LabelDiscNumber": "Skivnummer:", "LabelDisplayLanguage": "Visningsspråk:", "LabelDisplayLanguageHelp": "Att översätta Jellyfin är ett pågående projekt.", @@ -532,7 +532,7 @@ "LabelDisplayName": "Visningsnamn:", "LabelDisplayOrder": "Visningsordning:", "LabelDisplaySpecialsWithinSeasons": "Visa specialavsnitt i de säsonger de sändes i", - "LabelDownMixAudioScale": "Höj nivån vid nedmixning av ljud", + "LabelDownMixAudioScale": "Höj nivån vid nedmixning av ljud:", "LabelDownMixAudioScaleHelp": "Höj nivån vid nedmixning. Sätt värdet till 1 för att behålla den ursprungliga nivån.", "LabelDownloadLanguages": "Språk att hämta:", "LabelDropImageHere": "Släpp en bild här, eller klicka för att bläddra.", @@ -550,12 +550,12 @@ "LabelEnableDlnaDebugLogging": "Aktivera DLNA felsökningsloggning", "LabelEnableDlnaDebugLoggingHelp": "Detta resulterar i mycket stora loggfiler och rekommenderas bara vid felsökning.", "LabelEnableDlnaPlayTo": "Använd DLNA spela-upp-på", - "LabelEnableDlnaPlayToHelp": "Jellyfin kan hitta enheter på ditt nätverk och ge dig möjlighet att fjärrstyra dem.", + "LabelEnableDlnaPlayToHelp": "Hitta enheter på ditt nätverk och ge dig möjlighet att fjärrstyra dem.", "LabelEnableDlnaServer": "Aktivera DLNA-server", - "LabelEnableDlnaServerHelp": "Tillåt att UPnP-enheter på ditt nätverk kan se och spela upp innehåll från din Jellyfin Server.", + "LabelEnableDlnaServerHelp": "Tillåt att UPnP-enheter på ditt nätverk kan se och spela upp innehåll.", "LabelEnableHardwareDecodingFor": "Aktivera hårdvaruomkodning för:", "LabelEnableRealtimeMonitor": "Aktivera bevakning av mappar i realtid", - "LabelEnableRealtimeMonitorHelp": "Förändringar upptäcks omedelbart (i filsystem som stödjer detta)", + "LabelEnableRealtimeMonitorHelp": "Förändringar upptäcks omedelbart (i filsystem som stödjer detta).", "LabelEnableSingleImageInDidlLimit": "Begränsa till en inbäddad bild", "LabelEnableSingleImageInDidlLimitHelp": "Visa enheter kommer inte renderas ordentligt om flera bilder bäddas in i Didl.", "LabelEndDate": "Slutdatum:", @@ -565,11 +565,11 @@ "LabelExtractChaptersDuringLibraryScan": "Extrahera kapitelbildrutor vid genomsökning av biblioteket", "LabelExtractChaptersDuringLibraryScanHelp": "Om aktiverat extraheras kapitelbildrutor när videor importeras vid genomsökning av biblioteket. Om avaktiverat kommer extrahering att ske vid schemalagd kapitelbildrutebehandling, för att snabba upp den regelbundna genomsökningen av biblioteket.", "LabelFailed": "Misslyckades", - "LabelFileOrUrl": "Fil eller url:", + "LabelFileOrUrl": "Fil eller URL:", "LabelFinish": "Klart", "LabelFont": "Typsnitt:", "LabelForgotPasswordUsernameHelp": "Skriv ditt användarnamn, om du kommer ihåg det.", - "LabelFriendlyName": "Visningsnamn", + "LabelFriendlyName": "Visningsnamn:", "LabelServerNameHelp": "Det här namnet används för att identifiera servern, om det lämnas tomt kommer datorns namn att användas.", "LabelGroupMoviesIntoCollections": "Gruppera filmer i samlingsboxar", "LabelGroupMoviesIntoCollectionsHelp": "I filmlistor visas filmer som ingår i en samlingsbox som ett enda objekt.", @@ -579,7 +579,7 @@ "LabelHardwareAccelerationTypeHelp": "Endast tillgängligt på hårdvara med stöd.", "LabelHomeNetworkQuality": "Hemnätverkskvalitet:", "LabelHomeScreenSectionValue": "Hemskärmsdel {0}:", - "LabelHttpsPort": "Lokalt portnummer för https:", + "LabelHttpsPort": "Lokalt portnummer för HTTPS:", "LabelHttpsPortHelp": "Den lokala tcp-port som Jellyfin Server ska lyssna på https.", "LabelIconMaxHeight": "Maxhöjd på ikoner:", "LabelIconMaxHeightHelp": "Högsta upplösning hos ikoner som visas via upnp:icon.", @@ -607,25 +607,25 @@ "LabelLanNetworks": "LAN nätverk:", "LabelLanguage": "Språk:", "LabelLineup": "Uppsättning:", - "LabelLocalHttpServerPortNumber": "Lokalt portnummer för http:", + "LabelLocalHttpServerPortNumber": "Lokalt portnummer för HTTP:", "LabelLocalHttpServerPortNumberHelp": "Den lokala tcp-port som Jellyfin Server ska lyssna på http.", "LabelLockItemToPreventChanges": "Lås det här objektet för att förhindra ändringar", "LabelLoginDisclaimer": "Ansvarsbegränsning vid inloggning:", "LabelLoginDisclaimerHelp": "Detta visas längst ned på inloggningssidan.", "LabelLogs": "Loggfiler:", - "LabelManufacturer": "Tillverkare", + "LabelManufacturer": "Tillverkare:", "LabelManufacturerUrl": "Tillverkarens webaddress", "LabelMatchType": "Matchningstyp:", "LabelMaxBackdropsPerItem": "Högsta antal fondbilder per objekt:", "LabelMaxChromecastBitrate": "Strömningskvalitet för Chromecast:", - "LabelMaxParentalRating": "Högsta tillåtna åldersgräns", - "LabelMaxResumePercentage": "Högsta gräns för återupptagande (%)", - "LabelMaxResumePercentageHelp": "Objekt betraktas som färdigspelade om uppspelningen stoppas efter denna tidpunkt", + "LabelMaxParentalRating": "Högsta tillåtna åldersgräns:", + "LabelMaxResumePercentage": "Högsta gräns för återupptagande i procent:", + "LabelMaxResumePercentageHelp": "Objekt betraktas som färdigspelade om uppspelningen stoppas efter denna tidpunkt.", "LabelMaxScreenshotsPerItem": "Högsta antal skärmdumpar per objekt:", "LabelMaxStreamingBitrate": "Maximal strömningskvalite:", "LabelMaxStreamingBitrateHelp": "Ange högsta bithastighet för strömning.", - "LabelMessageText": "Meddelandetext", - "LabelMessageTitle": "Meddelandetitel", + "LabelMessageText": "Meddelandetext:", + "LabelMessageTitle": "Meddelandetitel:", "LabelMetadataDownloadLanguage": "Önskat språk:", "LabelMetadataDownloadersHelp": "Aktivera och rangordna dina hämtare baserat på prioritet. Lägre prioriterade hämtare används endast för att fylla i saknad information.", "LabelMetadataPath": "Plats för metadata:", @@ -636,10 +636,10 @@ "LabelMetadataSaversHelp": "Välj de filformat du vill använda för att spara dina metadata.", "LabelMethod": "Metod:", "LabelMinBackdropDownloadWidth": "Hämta enbart fondbilder bredare än:", - "LabelMinResumeDuration": "Minsta tid för återupptagande (s)", - "LabelMinResumeDurationHelp": "Objekt med speltid kortare än så här kan ej återupptas", - "LabelMinResumePercentage": "Lägsta gräns för återupptagande (%)", - "LabelMinResumePercentageHelp": "Objekt betraktas som ej spelade om uppspelningen stoppas före denna tidpunkt", + "LabelMinResumeDuration": "Minsta tid för återupptagande:", + "LabelMinResumeDurationHelp": "Objekt med speltid kortare än så här kan ej återupptas.", + "LabelMinResumePercentage": "Lägsta gräns för återupptagande i procent:", + "LabelMinResumePercentageHelp": "Objekt betraktas som ej spelade om uppspelningen stoppas före denna tidpunkt.", "LabelMinScreenshotDownloadWidth": "Hämta enbart skärmdumpar bredare än:", "LabelModelDescription": "Modellbeskrivning", "LabelModelName": "Modellnamn", @@ -648,10 +648,10 @@ "LabelMonitorUsers": "Övervaka aktivitet från:", "LabelMovieCategories": "Filmkategorier:", "LabelMoviePrefix": "Film prefix:", - "LabelMoviePrefixHelp": "Om ett prefix har lagts till filmertitlarna, skriv in det här så att Jellyfin kan hantera dessa korrekt.", + "LabelMoviePrefixHelp": "Om ett prefix har lagts till filmertitlarna, skriv in det här så att servern kan hantera dessa korrekt.", "LabelMovieRecordingPath": "Inspelningssökväg för film (valfri):", "LabelMusicStreamingTranscodingBitrate": "Bithastighet vid omkodning av musik:", - "LabelMusicStreamingTranscodingBitrateHelp": "Ange högsta bithastighet vid strömning av musik", + "LabelMusicStreamingTranscodingBitrateHelp": "Ange högsta bithastighet vid strömning av musik.", "LabelName": "Namn:", "LabelNewName": "Nytt namn:", "LabelNewPassword": "Nytt lösenord:", @@ -660,7 +660,7 @@ "LabelNext": "Nästa", "LabelNotificationEnabled": "Aktivera denna meddelandetyp", "LabelNumber": "Nr:", - "LabelNumberOfGuideDays": "Antal dagars tablå att hämta", + "LabelNumberOfGuideDays": "Antal dagars tablå att hämta:", "LabelNumberOfGuideDaysHelp": "Hämtning av en längre periods tablå ger möjlighet att boka inspelningar och se program längre fram i tiden, men ger längre nedladdningstid. \"Auto\" väljer baserat på antalet kanaler.", "LabelOptionalNetworkPath": "(Valfri) Delad nätverksmapp:", "LabelOptionalNetworkPathHelp": "Om denna mappen delas på ditt nätverk, kan den delade sökvägen tillåta Jellyfin-appar på andra enheter att streama mediafiler direkt.", @@ -691,10 +691,10 @@ "LabelProtocol": "Protokoll:", "LabelProtocolInfo": "Protokollinfo:", "LabelProtocolInfoHelp": "Värde att använda vid svar på GetProtocolInfo-begäran från enheter.", - "LabelPublicHttpPort": "Publikt portnummer för http:", - "LabelPublicHttpPortHelp": "Det publika portnumret som ska mappas till den lokala porten för http.", - "LabelPublicHttpsPort": "Publikt portnummer för https:", - "LabelPublicHttpsPortHelp": "Det publika portnumret som ska mappas till den lokala porten för https.", + "LabelPublicHttpPort": "Publikt portnummer för HTTP:", + "LabelPublicHttpPortHelp": "Det publika portnumret som ska mappas till den lokala porten för HTTP.", + "LabelPublicHttpsPort": "Publikt portnummer för HTTPS:", + "LabelPublicHttpsPortHelp": "Det publika portnumret som ska mappas till den lokala porten för HTTPS.", "LabelReadHowYouCanContribute": "Se hur du kan hjälpa till.", "LabelReasonForTranscoding": "Orsak för omkodning:", "LabelRecord": "Spela in:", @@ -707,7 +707,7 @@ "LabelRuntimeMinutes": "Speltid (min):", "LabelSaveLocalMetadata": "Spara grafik till mediamapparna", "LabelSaveLocalMetadataHelp": "Om grafik sparas tillsammans med media är de enkelt åtkomliga för redigering.", - "LabelScheduledTaskLastRan": "Senast körd {0}, tog {1}", + "LabelScheduledTaskLastRan": "Senast körd {0}, tog {1}.", "LabelScreensaver": "Skärmsläckare:", "LabelSeasonNumber": "Säsongsnummer:", "LabelSelectFolderGroups": "Gruppera automatiskt innehåll från dessa mappar i vyer, t ex Filmer, Musik eller TV:", @@ -718,19 +718,19 @@ "LabelSerialNumber": "Serienummer", "LabelSeriesRecordingPath": "Inspelningssökväg för TV-serier (valfri):", "LabelServerHost": "Värd:", - "LabelServerHostHelp": "192.168.1.100 eller https://min.server.com", - "LabelSimultaneousConnectionLimit": "Begränsning för samtidiga strömmar", + "LabelServerHostHelp": "192.168.1.100:8096 eller https://min.server.com", + "LabelSimultaneousConnectionLimit": "Begränsning för samtidiga strömmar:", "LabelSkin": "Skal:", "LabelSkipBackLength": "'Hoppa bakåt'-längd:", "LabelSkipForwardLength": "'Hoppa framåt'-längd:", - "LabelSkipIfAudioTrackPresent": "Hoppa över om det förvalda ljudspårets språk är samma som det hämtade.", + "LabelSkipIfAudioTrackPresent": "Hoppa över om det förvalda ljudspårets språk är samma som det hämtade", "LabelSkipIfAudioTrackPresentHelp": "Bocka ur denna för att ge undertexter åt alla videor oavsett ljudspårets språk.", "LabelSkipIfGraphicalSubsPresent": "Hoppa över om videofilen redan innehåller inbäddade undertexter", "LabelSkipIfGraphicalSubsPresentHelp": "Att även ha externa undertexter resulterar i en effektivare uppspelning och minskar risken för omkodning.", "LabelSonyAggregationFlags": "\"Aggregation flags\" för Sony:", "LabelSonyAggregationFlagsHelp": "Anger innehållet i elementet aggregationFlags i namnutrymmet urn:schemas-sonycom:av.", "LabelSortBy": "Sortera efter:", - "LabelSortOrder": "Sortering", + "LabelSortOrder": "Sortering:", "LabelSortTitle": "Sorteringstitel:", "LabelSoundEffects": "Ljudeffekter:", "LabelSource": "Källa:", @@ -745,7 +745,7 @@ "LabelSubtitles": "Undertexter:", "LabelSupportedMediaTypes": "Mediaformat som stöds:", "LabelTVHomeScreen": "Hemskärm i TV-läge:", - "LabelTag": "Etikett", + "LabelTag": "Etikett:", "LabelTagline": "Slogan:", "LabelTextBackgroundColor": "Bakgrundsfärg för text:", "LabelTextColor": "Textfärg:", @@ -754,10 +754,10 @@ "LabelTime": "Tid:", "LabelTimeLimitHours": "Tidsbegränsning (timmar):", "LabelTitle": "Titel:", - "LabelTrackNumber": "Spår nr", + "LabelTrackNumber": "Spår nr:", "LabelTranscodingAudioCodec": "Ljudkodning:", "LabelTranscodingContainer": "Behållare:", - "LabelTranscodingTempPathHelp": "Denna mapp innehåller tillfälliga filer som används vid omkodning. Ange en plats för dessa, eller lämna blankt för att använda förvald plats.", + "LabelTranscodingTempPathHelp": "Ange en egen sökväg där omkodningar skall sparas för klienter. Lämna blankt för att använda förvald plats.", "LabelTranscodingThreadCount": "Trådar för omkodning:", "LabelTranscodingThreadCountHelp": "Välj maximala antalet trådar som ska användas vid omkodning. Att minska antalet trådar sänker cpu-belastningan men ökar även risken att omkodning inte kan ske snabbt nog för felfri uppspelning.", "LabelTranscodingVideoCodec": "Videokodning:", @@ -799,7 +799,7 @@ "MarkUnplayed": "Markera som ospelad", "MaxParentalRatingHelp": "Innehåll med högre gräns visas ej för den här användaren.", "MediaInfoAnamorphic": "Anamorfisk", - "MediaInfoAspectRatio": "Bildförhållande:", + "MediaInfoAspectRatio": "Bildförhållande", "MediaInfoBitDepth": "Färgdjup", "MediaInfoBitrate": "Bithastighet", "MediaInfoChannels": "Kanaler", @@ -832,7 +832,7 @@ "MessageConfirmRemoveMediaLocation": "Är du säker på att du vill ta bort den här platsen?", "MessageConfirmRestart": "Är du säker på att du vill starta om Jellyfin server?", "MessageConfirmRevokeApiKey": "Är du säker på att du vill återkalla den här api-nyckeln? Applikationens koppling till Jellyfin Server kommer avslutas abrupt.", - "MessageConfirmShutdown": "Är du säker på att du vill stänga av Jellyfin server?", + "MessageConfirmShutdown": "Är du säker på att du vill stänga av servern?", "MessageContactAdminToResetPassword": "Vänligen kontakta din systemadministratör för att återställa ditt lösenord.", "MessageCreateAccountAt": "Skapa ett konto på {0}", "MessageDeleteTaskTrigger": "Vill du ta bort denna aktivitetsutlösare?", @@ -856,27 +856,27 @@ "MessageNoTrailersFound": "Hittade inga trailers. Installera Trailer-kanalen och öka biokänslan genom att lägga till ett bibliotek av trailers.", "MessageNothingHere": "Ingenting här.", "MessagePasswordResetForUsers": "Lösenord har tagots bort från följande användare. För att logga in, använd ett blankt lösenord.", - "MessagePlayAccessRestricted": "Uppspelning av detta innehållet är för närvarande begränsat. Kontakta din Jellyfin Server administratör för mer information.", + "MessagePlayAccessRestricted": "Uppspelning av detta innehållet är för närvarande begränsat. Kontakta din server administratör för mer information.", "MessagePleaseEnsureInternetMetadata": "Var god se till att hämtning av metadata via Internet är aktiverad.", "MessagePleaseWait": "Vänligen vänta. Detta kan ta ett tag.", "MessagePluginConfigurationRequiresLocalAccess": "Logga in på din din lokala Jellyfin Server för att konfigurera det här tillägget.", "MessagePluginInstallDisclaimer": "Tillägg skapade av Jellyfin-användare är ett bra sätt att förbättra din Jellyfin-upplevelse med ytterligare funktionalitet. Observera att detta kan påverka din Jellyfin-server så som längre tidsåtgång för biblioteksskanningar, ytterligare bakgrundsprocesser och minskad systemstabilitet.", "MessageReenableUser": "Se nedan för att aktivera igen", "MessageSettingsSaved": "Inställningarna har sparats.", - "MessageTheFollowingLocationWillBeRemovedFromLibrary": "Följande mediaplatser kommer att tas bort från ditt Jellyfin bibliotek:", + "MessageTheFollowingLocationWillBeRemovedFromLibrary": "Följande mediaplatser kommer att tas bort från ditt bibliotek:", "MessageUnableToConnectToServer": "Vi kunde inte upprätta anslutning till vald server just nu. Försäkra dig om att den är påslagen och försök igen.", "MessageUnsetContentHelp": "Innehåll kommer visas som enkla mappar. För bästa resultat, använd en metadata-hanterare för att ställa in typ av innehåll för undermapparna.", "MessageYouHaveVersionInstalled": "Version {0} är installerad.", "MetadataManager": "Metadata-hanteraren", "MinutesAfter": "minuter efter", "MinutesBefore": "minuter före", - "Mobile": "Mobil / Platta", + "Mobile": "Mobil", "Monday": "Måndag", "MoreFromValue": "Mer från {0}", "MoreUsersCanBeAddedLater": "Flera användare kan skapas senare i Kontrollpanelen.", "MoveLeft": "Vänster", "MoveRight": "Höger", - "MovieLibraryHelp": "Läs om {0}Jellyfins namngivningsguide för filmer{1}.", + "MovieLibraryHelp": "Läs om {0} namngivningsguide för filmer{1}.", "Movies": "Filmer", "Mute": "Tyst", "MySubtitles": "Mina undertexter", @@ -902,7 +902,7 @@ "OneChannel": "En kanal", "OnlyForcedSubtitles": "Endast tvingande undertexter", "OnlyForcedSubtitlesHelp": "Endast undertexter markerade som tvingande kommer att laddas.", - "OnlyImageFormats": "Endast image-format (VOBSUB, PGS, SUB/IDX, etc.)", + "OnlyImageFormats": "Endast image-format (VOBSUB, PGS, SUB, etc)", "OptionAdminUsers": "Administratörer", "OptionAlbumArtist": "Albumartist", "OptionAllUsers": "Alla användare", @@ -919,7 +919,7 @@ "OptionAllowRemoteSharedDevicesHelp": "DLNA-enheter betraktas som delade tills en användare börjar kontrollera den.", "OptionAllowSyncTranscoding": "Tillåt nedladdning som kräver omkodning", "OptionAllowUserToManageServer": "Tillåt denna användare att administrera servern", - "OptionAllowVideoPlaybackRemuxing": "Tillåt videouppspelning som kräver konvertering utan omkodning.", + "OptionAllowVideoPlaybackRemuxing": "Tillåt videouppspelning som kräver konvertering utan omkodning", "OptionAllowVideoPlaybackTranscoding": "Tillåt videouppspelning som kräver omkodning", "OptionAscending": "Stigande", "OptionAutomaticallyGroupSeries": "Slå ihop serier automatiskt som ligger utspritt under flera kataloger", @@ -936,7 +936,7 @@ "OptionCriticRating": "Kritikerbetyg", "OptionCustomUsers": "Anpassad", "OptionDaily": "Dagligen", - "OptionDateAdded": "Inlagd den", + "OptionDateAdded": "Tillagd den", "OptionDateAddedFileTime": "Använd datum då filen skapades", "OptionDateAddedImportTime": "Använd datum för inläsning i biblioteket", "OptionDatePlayed": "Senast visad", @@ -945,7 +945,7 @@ "OptionDisableUserHelp": "Spärrade användare tillåts ej kontakta servern. Eventuella pågående anslutningar avbryts omedelbart.", "OptionDislikes": "Ogillar", "OptionDisplayFolderView": "Visa en mappvy för att visa enkla mediamappar", - "OptionDisplayFolderViewHelp": "Vid aktivering kommer Jellyfinappar att visa en Mappkategori intill ditt mediabibliotek. Detta är användbart om du har enkla mappvyer.", + "OptionDisplayFolderViewHelp": "Visa mappar jämsides med dina andra media bibliotek. Detta kan vara bra om du vill ha en enkel mapp visning.", "OptionDownloadArtImage": "Grafik", "OptionDownloadBackImage": "Baksida", "OptionDownloadBannerImage": "Banderoll", @@ -975,14 +975,14 @@ "OptionExtractChapterImage": "Aktivera extrahering av kapitelbilder", "OptionFavorite": "Favoriter", "OptionFriday": "Fredag", - "OptionHasSpecialFeatures": "Extramaterial:", + "OptionHasSpecialFeatures": "Extramaterial", "OptionHasSubtitles": "Undertexter", "OptionHasThemeSong": "Ledmotiv", "OptionHasThemeVideo": "Temavideo", "OptionHideUser": "Visa inte den här användaren på inloggningssidorna", "OptionHideUserFromLoginHelp": "Användbart för privata konton eller gömda administratörskonton. Användaren beöver logga in manuellt genom att skriva sitt användarnamn och lösenord.", "OptionHlsSegmentedSubtitles": "HLS-segmenterade undertexter", - "OptionHomeVideos": "Hemvideos & foton", + "OptionHomeVideos": "Foton", "OptionIgnoreTranscodeByteRangeRequests": "Ignorera begäran om \"byte range\" vid omkodning", "OptionIgnoreTranscodeByteRangeRequestsHelp": "Om aktiverad kommer begäran att uppfyllas, men \"byte range\"-rubriken ignoreras.", "OptionImdbRating": "Betyg på IMDB", @@ -1082,7 +1082,7 @@ "Record": "Spela in", "RecordSeries": "Spela in serie", "RecordingCancelled": "Inspelning avbruten.", - "RecordingScheduled": "Inspelning schemalagd", + "RecordingScheduled": "Inspelning schemalagd.", "Recordings": "Inspelningar", "Refresh": "Uppdatera", "RefreshDialogHelp": "Metadata uppdateras baserat på inställningar och internettjänster som har aktiverats under Jellyfin servers kontrollpanel.", @@ -1182,7 +1182,7 @@ "TabMusicVideos": "Musikvideor", "TabMyPlugins": "Mina tillägg", "TabNetworks": "TV-bolag", - "TabNfoSettings": "nfo-inställingar", + "TabNfoSettings": "NFO-inställingar", "TabNotifications": "Meddelanden", "TabOther": "Övrigt", "TabParentalControl": "Föräldralås", @@ -1195,7 +1195,7 @@ "TabProfiles": "Profiler", "TabRecordings": "Inspelningar", "TabResponses": "Svar", - "TabResumeSettings": "Återuppta-inställningar", + "TabResumeSettings": "Återuppta", "TabScheduledTasks": "Schemalagda aktiviteter", "TabSeries": "Serie", "TabSettings": "Inställningar", @@ -1209,7 +1209,7 @@ "Tags": "Etiketter", "TagsValue": "Etiketter: {0}", "TellUsAboutYourself": "Berätta om dig själv", - "ThemeSongs": "Vinjetter", + "ThemeSongs": "Signaturmelodier", "ThemeVideos": "Temavideos", "TheseSettingsAffectSubtitlesOnThisDevice": "Dessa inställningar påverkar undertexter på den här enheten", "ThisWizardWillGuideYou": "Den här guiden hjälper dig att göra de första inställningarna. För att börja var vänlig välj önskat språk.", @@ -1221,7 +1221,7 @@ "TrackCount": "{0} spår", "Transcoding": "Omkodning", "Tuesday": "Tisdag", - "TvLibraryHelp": "Läs om {0}Jellyfins namngivningsguide för TV-serier{1}.", + "TvLibraryHelp": "Läs om {0} namngivningsguide för TV-serier{1}.", "UninstallPluginConfirmation": "Är du säker på att du vill avinstallera {0}?", "UninstallPluginHeader": "Avinstallera tillägg", "Unmute": "Muting av", @@ -1257,13 +1257,13 @@ "Watched": "Sedd", "Wednesday": "Onsdag", "WelcomeToProject": "Välkommen till Jellyfin!", - "WizardCompleted": "Det är allt vi behöver veta just nu. Jellyfin Server har börjat samla information om ditt mediabibliotek. Kolla in några av våra appar och klicka sedan på Avsluta för att se kontrollpanelen.", + "WizardCompleted": "Det är allt vi behöver veta just nu. Jellyfin har börjat samla information om ditt mediabibliotek. Kolla in några av våra appar och klicka sedan på Avsluta för att se kontrollpanelen.", "Writer": "Manusförfattare", - "XmlDocumentAttributeListHelp": "Dessa attribut tillämpas på rotelementet i alla xml-svar.", + "XmlDocumentAttributeListHelp": "Dessa attribut tillämpas på rotelementet i alla XML-svar.", "XmlTvKidsCategoriesHelp": "Program med dessa kategorier kommer visas som program för barn. Separerade med '|'.", "XmlTvMovieCategoriesHelp": "Program med dessa kategorier kommer visas som filmer. Separerade med '|'.", "XmlTvNewsCategoriesHelp": "Program med dessa kategorier kommer visas som nyhetsprogram. Separerade med '|'.", - "XmlTvPathHelp": "En sökväg till en xml-fil för tv. Jellyfin kommer läsa in den här filen och regelbundet leta efter uppdateringar. Du är själv ansvarig för att skapa och uppdatera filen.", + "XmlTvPathHelp": "En sökväg till en XML-fil för tv. Jellyfin kommer läsa in den här filen och regelbundet leta efter uppdateringar. Du är själv ansvarig för att skapa och uppdatera filen.", "XmlTvSportsCategoriesHelp": "Program med dessa kategorier kommer visas som sportprogram. Separerade med '|'.", "Yes": "Ja", "Yesterday": "Igår", @@ -1276,8 +1276,8 @@ "GenreValue": "Genre: {0}", "General": "Allmänt", "FastForward": "Snabbspola", - "Extras": "Mer", - "ErrorAddingXmlTvFile": "Det uppstod ett problem vid läsningen av XmlTV filen. Kontrollera att filen är tillgänglig och försök igen.", + "Extras": "Extramaterial", + "ErrorAddingXmlTvFile": "Det uppstod ett problem vid läsningen av XMLTV filen. Kontrollera att filen är tillgänglig och försök igen.", "ErrorAddingListingsToSchedulesDirect": "Det uppstod ett problem när din lista skulle läggas till på ditt Schedules Direct konto. Schedules Direct tillåter bara ett begränsat antal listor per konto. Du kanske behöver logga in på Schedules Direct hemsidan och ta bort andras listningar från ditt konto innan du fortsätter.", "EnableStreamLoopingHelp": "Aktivera enbart detta om direktsändningen enbart innehåller några sekunders data och behöver bli kontinuerligt uppdaterad. Att aktivera denna funktion i onödan kan skapa problem.", "EnableStreamLooping": "Loopa direktsändningar", @@ -1294,12 +1294,12 @@ "ButtonGuide": "Guide", "Blacklist": "Svartlista", "Auto": "Automatisk", - "AuthProviderHelp": "Välj en autentiseringsleverantör för att autentisera denna användares lösenord.", + "AuthProviderHelp": "Välj en autentiserings leverantör som ska användas för att autentisera denna användarens lösenord.", "Ascending": "Stigande", "AllowedRemoteAddressesHelp": "Kommaavgränsad lista av IP-adresser eller IP/nätmask poster för nätverk som kommer bli tillåtna att ansluta avlägset. Om fältet lämnas tomt så kommer alla avlägsna adresser tillåtas.", "AllowMediaConversionHelp": "Tillåt eller neka tillgång till media konvertings funktionen.", "AllowMediaConversion": "Tillåt media konvertering", - "Alerts": "Notiser", + "Alerts": "Alarm", "HeaderMedia": "Media", "HeaderHome": "Hem", "HeaderFavoriteVideos": "Favoritvideor", @@ -1313,12 +1313,12 @@ "CopyStreamURLSuccess": "URL har kopierats.", "CopyStreamURL": "Kopiera Stream URL", "FetchingData": "Hämtar ytterligare data", - "HeaderFetcherSettings": "Hämtarinställningar", - "ButtonAddImage": "Lägg till bild", + "HeaderFetcherSettings": "Hämtar inställningar", + "ButtonAddImage": "Lägg till Bild", "HeaderStopRecording": "Stoppa inspelning", - "HeaderImageOptions": "Bildinställningar", - "Absolute": "Absolut", - "HeaderFavoritePeople": "Favoritpersoner", + "HeaderImageOptions": "Bildalternativ", + "Absolute": "komplett", + "HeaderFavoritePeople": "Favoritmänniskor", "HeaderRestartingServer": "Startar om server", "HeaderStatus": "Status", "LabelPostProcessor": "Program för efterbehandling:", @@ -1327,17 +1327,144 @@ "LabelMetadata": "Metadata:", "LabelFormat": "Format:", "LabelFolder": "Mapp:", - "LabelBaseUrl": "Grund URL:", + "LabelBaseUrl": "Bas-RL:", "LabelAuthProvider": "Autentiseringsleverantör:", "LabelAudioCodec": "Ljudkodek:", "LabelAudioChannels": "Ljudkanaler:", "LabelAllowedRemoteAddressesMode": "Fjärr-IP-adressfilterläge:", "LabelAllowedRemoteAddresses": "Fjärr-IP-adressfilter:", "HttpsRequiresCert": "För att aktivera säkra anslutningar måste du tillhandahålla ett pålitligt SSL-certifikat, till exempel \"Let's Encrypt\". Vänligen ange ett certifikat eller inaktivera säkra anslutningar.", - "HeaderTypeImageFetchers": "{0} Bildhämtare", + "HeaderTypeImageFetchers": "Bildhämtare", "HeaderLiveTvTunerSetup": "Ställ in Live-TV-mottagare", "ButtonSplit": "Dela upp", "LabelCache": "Cache:", "LabelAlbum": "Album:", - "HeaderVideos": "Videor" + "HeaderVideos": "Videor", + "LabelBitrate": "Bithastighet:", + "LabelStreamType": "Stream typ:", + "LabelStatus": "Status:", + "LabelSize": "Storlek:", + "LabelServerName": "Server namn:", + "LabelSecureConnectionsMode": "Säker uppkopplings läge:", + "EnableFastImageFadeInHelp": "Aktivera snabbare fade-in animationer för laddade bilder", + "EnableFastImageFadeIn": "Snabb bild fade-in", + "LabelPostProcessorArgumentsHelp": "Använd {path} som sökväg till inspelade filen.", + "LabelPostProcessorArguments": "Post-processor kommandoradsargument:", + "LabelDroppedFrames": "Tappade ramar:", + "LabelAudioSampleRate": "Ljudprovfrekvens:", + "LabelAudioBitrate": "Ljudbithastighet:", + "LabelAudioBitDepth": "Ljudbitdjup:", + "LabelPlayMethod": "Spelmetod:", + "LabelPlayerDimensions": "Spelare dimensioner:", + "LabelPasswordResetProvider": "Lösenords Återställning Leverantör:", + "LabelBaseUrlHelp": "Du kan lägga till en egen underkategori här för att få tillgång till servern från en mer unik URL.", + "LabelCorruptedFrames": "Skadade ramar:", + "HeaderParentalRatings": "Föräldrabetyg", + "HeaderNavigation": "Navigering", + "HeaderBranding": "Märke", + "CopyStreamURLError": "Det vart ett fel vid kopiering av URL.", + "AskAdminToCreateLibrary": "Fråga en administratör för att skapa ett bibliotek.", + "Whitelist": "Vitlista", + "VideoRange": "Video räckvidd", + "ValueOneAlbum": "1 album", + "ValueMinutes": "{0} min", + "ValueContainer": "Behållare: {0}", + "UserAgentHelp": "Stöd en egen user-agent HTTP rubrik.", + "Uniform": "Enhetlig", + "Trailers": "Trailers", + "TabTrailers": "Trailers", + "TabServer": "Server", + "TabNetworking": "Nätverk", + "TabMetadata": "Metadata", + "TabInfo": "Info", + "TabAccess": "Tillgång", + "TV": "TV", + "SubtitleOffset": "Undertext justering", + "Smart": "Smart", + "Smaller": "Mindre", + "ShowAdvancedSettings": "Visa avancerade inställningar", + "SeriesDisplayOrderHelp": "Ordna avsnitt via sändnings datum, DVD ordning, eller absolut numrering.", + "SelectAdminUsername": "Vänligen välj ett användarnamn för admin kontot.", + "SaveSubtitlesIntoMediaFoldersHelp": "Spara undertexter vid video filer kommer göra det mer enklare att hantera.", + "Rewind": "Spola tillbaka", + "RequiredForAllRemoteConnections": "Krävs för alla fjärr kopplingar", + "RecordingPathChangeMessage": "Ändring av din inspelnings mapp kommer inte migrera existerande inspelningar från gamla platsen till den nya. Du behöver flytta dom manuellt om så önskas.", + "PreferredNotRequired": "Föredragen, men inte krävande", + "PlaybackData": "Uppspelnings Data", + "PasswordResetProviderHelp": "Välj en Lösenords Återställnings Provider att använda när denna användare begär att återställa lösenordet", + "OptionThumbCard": "Miniatyr kort", + "OptionThumb": "Miniatyr", + "OptionSaveMetadataAsHiddenHelp": "Ändring av detta kommer att tilldelas till ny metadata som sparas. Existerande metadata filer kommer att uppdateras nästa gång dom sparas av Jellyfin Server.", + "OptionResElement": "res element", + "OptionRegex": "Regex", + "OptionRandom": "Slumpmässig", + "OptionProtocolHttp": "HTTP", + "OptionProfileVideo": "Video", + "OptionPosterCard": "Omslags kort", + "OptionPoster": "Omslag", + "OptionMax": "Max", + "OptionLoginAttemptsBeforeLockoutHelp": "Ett värde av noll menas att använda standard av tre försök för normala användare och fem för administratörer. -1 kommer att stänga av denna funktion.", + "OptionLoginAttemptsBeforeLockout": "Avgör hur många felaktiga inloggnings försök som kan utföras innan kontot låses.", + "OptionList": "List", + "OptionIsSD": "SD", + "OptionIsHD": "HD", + "OptionHasTrailer": "Trailer", + "OptionCaptionInfoExSamsung": "CaptionInfoEx (Samsung)", + "OptionBlockTrailers": "Trailers", + "OptionBanner": "Banner", + "OptionAutomatic": "Auto", + "OptionAuto": "Auto", + "OptionArtist": "Artist", + "OptionForceRemoteSourceTranscoding": "Tvinga omkodning på fjärr media källor (som LiveTV)", + "OptionAlbum": "Album", + "Option3D": "3D", + "Normal": "Normal", + "NoCreatedLibraries": "Ser ut som du inte har skapat några bibliotek än. {0}Vill du skapa ett nu?{1}", + "NextUp": "Nästa på tur", + "MusicVideo": "Musik Video", + "MusicLibraryHelp": "Granska {0}musik döpnings guiden{1}.", + "MusicArtist": "Musik Artist", + "MusicAlbum": "Musik Album", + "MoreMediaInfo": "Media Info", + "MetadataSettingChangeHelp": "Ändring av metadata inställningar kommer att ske på nytt innehåll som är tillagt framledes. För att uppdatera existerat innehåll, öppna detalj skärmen och tryck på uppdatera knappen, eller utför bulk uppdateringar med metadata hanteraren.", + "Metadata": "Metadata", + "MessageNoServersAvailable": "Inga servrar har hittats med automatiska server sökningen.", + "MessageNoCollectionsAvailable": "Samlingar tillåter dig att njuta av personlig gruppering av Filmer, Serier och Albums. Tryck på + knapen för att skapa samlingar.", + "MessageImageTypeNotSelected": "Vänligen välj en bild typ från rullningslisten.", + "MessageImageFileTypeAllowed": "Endast JPEG och PNG filer stöds.", + "MessageConfirmAppExit": "Vill du avsluta?", + "MediaInfoStreamTypeVideo": "Video", + "MediaInfoStreamTypeSubtitle": "Undertext", + "MediaInfoStreamTypeEmbeddedImage": "Inbäddad Bild", + "MediaInfoStreamTypeData": "Data", + "MediaInfoStreamTypeAudio": "Ljud", + "MediaInfoSoftware": "Mjukvara", + "MediaInfoLayout": "Design", + "MediaInfoContainer": "Behållare", + "ManageLibrary": "Hantera bibliotek", + "Live": "Live", + "LeaveBlankToNotSetAPassword": "Du kan lämna detta fält tomt för att inte ange lösenord.", + "LaunchWebAppOnStartupHelp": "Öppna webb klient i din standard webbläsare när servern startas. Detta kommer inte ske när du använder starta om servern funktionen.", + "LaunchWebAppOnStartup": "Starta webb gränssnitt när servern startas", + "LanNetworksHelp": "Kommatecken separerad lista på IP adresser eller IP/nätmask inlägg för nätverk som anses vara på lokala nätverket för att tvinga fram bandbredd begränsningar. Om angett, alla andra IP adresser kommer att anses vara på ett externt nätverk och kommer tilldelas till det externa bandbredd begränsningarna. Om lämnat tomt, endast serverns subnet anses vara på det lokala nätverket.", + "LabelXDlnaDoc": "X-DLNA doc:", + "LabelXDlnaCap": "X-DLNA cap:", + "LabelWeb": "Webb:", + "LabelVideoResolution": "Video upplösning:", + "LabelVideoCodec": "Video codec:", + "LabelVideoBitrate": "Video bitrate:", + "LabelVideo": "Video:", + "DashboardArchitecture": "Arkitektur: {0}", + "DashboardOperatingSystem": "Operativsystem: {0}", + "DashboardServerName": "Server: {0}", + "DashboardVersionNumber": "Version: {0}", + "LabelVersion": "Version:", + "LabelUserLoginAttemptsBeforeLockout": "Felaktiga inloggnings försök innan användare blir utelåst:", + "LabelUserAgent": "Användar agent:", + "LabelTypeText": "Text", + "LabelTypeMetadataDownloaders": "{0} metadata nerladdare:", + "LabelTranscodingProgress": "Omkodning progress:", + "LabelTranscodingFramerate": "Omkodning framerate:", + "LabelTranscodes": "Omkodningar:", + "LabelTranscodePath": "Omkodning sökväg:" } diff --git a/src/strings/vi.json b/src/strings/vi.json index 9cb4b48495..e32272bdaf 100644 --- a/src/strings/vi.json +++ b/src/strings/vi.json @@ -118,5 +118,123 @@ "UninstallPluginHeader": "Gỡ bỏ Plugin", "AccessRestrictedTryAgainLater": "Truy cập hiện đang hạn chế. Hãy thử lại sau.", "AddToCollection": "Thêm vào bộ sưu tập", - "Actor": "Diễn viên" + "Actor": "Diễn viên", + "ButtonRevoke": "Thu hồi", + "ButtonResume": "Tiếp tục", + "ButtonRestart": "Khởi động lại", + "ButtonResetEasyPassword": "Đặt lại mã pin nhanh", + "ButtonRepeat": "Lặp lại", + "ButtonRename": "Đổi tên", + "ButtonRefreshGuideData": "Làm mới dữ liệu hướng dẫn", + "ButtonRefresh": "Làm mới", + "ButtonQuickStartGuide": "Hướng dẫn nhanh", + "ButtonProfile": "Hồ sơ", + "ButtonPreviousTrack": "Bài trước", + "ButtonPlay": "Chơi", + "ButtonPause": "Tạm dừng", + "ButtonParentalControl": "Kiểm soát của cha mẹ", + "ButtonOpen": "Mở", + "ButtonOff": "Tắt", + "ButtonNextTrack": "Tiếp theo", + "ButtonNetwork": "Mạng", + "ButtonMore": "Thêm", + "ButtonManualLogin": "Đăng nhập thủ công", + "ButtonLibraryAccess": "Truy cập thư viện", + "ButtonLearnMore": "Tìm hiểu thêm", + "ButtonInfo": "Thông tin", + "ButtonHome": "Trang chủ", + "ButtonHelp": "Giúp đỡ", + "ButtonGuide": "Hướng dẫn", + "ButtonGotIt": "Hiểu rồi", + "ButtonFullscreen": "Toàn màn hình", + "ButtonForgotPassword": "Quên mật khẩu", + "ButtonFilter": "Lọc", + "ButtonEditOtherUserPreferences": "Chỉnh sửa hồ sơ, hình ảnh và sở thích cá nhân.", + "ButtonEditImages": "Sửa hình ảnh", + "ButtonEdit": "Sửa", + "ButtonDownload": "Tải", + "ButtonDown": "Xuống", + "ButtonDelete": "Xoá", + "ButtonConnect": "Kết nối", + "ButtonChangeServer": "Đổi máy chủ", + "ButtonBack": "Lùi", + "ButtonAudioTracks": "Track âm thanh", + "ButtonArrowUp": "Lên", + "ButtonArrowRight": "Phải", + "ButtonArrowLeft": "Trái", + "ButtonArrowDown": "Xuống", + "ButtonAddServer": "Thêm máy chủ", + "ButtonAddScheduledTaskTrigger": "Thêm kích hoạt", + "ButtonAddMediaLibrary": "Thêm thư viện Media", + "ButtonAddImage": "Thêm hình ảnh", + "BurnSubtitlesHelp": "Xác định xem máy chủ có ghi phụ đề khi chuyển đổi video hay không tùy thuộc vào định dạng phụ đề. Tránh ghi trong phụ đề sẽ cải thiện hiệu suất máy chủ. Chọn Tự động để ghi hình ảnh dựa trên các định dạng (VOBSUB, PGS, SUB / IDX, v.v.) và phụ đề ASS/SSA nhất định.", + "Browse": "Duyệt", + "BoxRear": "Hộp (mặt sau)", + "Books": "Sách", + "BookLibraryHelp": "Âm thanh và sách văn bản được hỗ trợ. Xem lại {0}hướng dẫn đặt tên sách{1}.", + "Blacklist": "Danh sách đen", + "BirthPlaceValue": "Nơi sinh: {0}", + "BirthLocation": "Nơi sinh", + "BirthDateValue": "Sinh năm: {0}", + "Backdrops": "Phông nền", + "Backdrop": "Phông nền", + "AutoBasedOnLanguageSetting": "Tự động (dựa trên cài đặt ngôn ngữ)", + "Auto": "Tự động", + "AuthProviderHelp": "Chọn Nhà cung cấp xác thực sẽ được sử dụng để xác thực mật khẩu người dùng này.", + "Audio": "Âm thanh", + "AttributeNew": "Tạo mới", + "AspectRatio": "Tỷ lệ khung hình", + "AskAdminToCreateLibrary": "Yêu cầu quản trị viên tạo thư viện.", + "Ascending": "Tăng dần", + "AsManyAsPossible": "Càng nhiều càng tốt", + "Artists": "Nghệ Sĩ", + "AroundTime": "Xunh quanh {0}", + "Anytime": "Bất cứ lúc nào", + "AnyLanguage": "Bất kỳ ngôn ngữ", + "AlwaysPlaySubtitlesHelp": "Phụ đề phù hợp với sở thích ngôn ngữ sẽ được tải bất kể ngôn ngữ âm thanh.", + "AlwaysPlaySubtitles": "Luôn hiển thị phụ đề", + "AllowedRemoteAddressesHelp": "Danh sách địa chỉ IP được phân tách bằng dấu phẩy hoặc các mục IP/netmask cho các mạng sẽ được phép kết nối từ xa. Nếu để trống, tất cả các địa chỉ sẽ được cho phép.", + "AllowRemoteAccessHelp": "Nếu không được chọn, tất cả các kết nối từ xa sẽ bị chặn.", + "AllowRemoteAccess": "Cho phép kết nối từ xa đến Máy chủ Jellyfin.", + "AllowOnTheFlySubtitleExtractionHelp": "Phụ đề nhúng có thể được trích xuất từ video và dùng như văn bản thuần túy để giúp ngăn chặn chuyển mã video. Trên một số hệ thống, việc này có thể mất nhiều thời gian và khiến quá trình phát video bị đình trệ trong quá trình trích xuất. Vô hiệu hóa điều này để có phụ đề nhúng được ghi trong chuyển mã video khi chúng không được thiết bị khách hỗ trợ.", + "AllowOnTheFlySubtitleExtraction": "Cho phép trích xuất phụ đề trực tiếp", + "AllowMediaConversionHelp": "Cấp hoặc từ chối truy cập vào tính năng chuyển đổi media.", + "AllowMediaConversion": "Cho phép chuyển đổi media", + "AllowHWTranscodingHelp": "Cho phép bộ chỉnh chuyển mã stream khi đang chơi. Điều này có thể giúp giảm tải của máy chủ khi chuyển mã.", + "AllLibraries": "Tất cả các thư viện", + "AllLanguages": "Tất cả các ngôn ngữ", + "AllEpisodes": "Tất cả các tập phim", + "AllComplexFormats": "Tất cả các định dạng phức tạp (ASS, SSA, VOBSUB, PGS, SUB / IDX, v.v.)", + "AllChannels": "Tất cả các kênh", + "Alerts": "Cảnh Báo", + "Albums": "Albums", + "Aired": "Đã phát sóng", + "AirDate": "Ngày phát sóng", + "AdditionalNotificationServices": "Duyệt qua danh mục plugin để cài đặt các dịch vụ thông báo bổ sung.", + "AddedOnValue": "Đã thêm {0}", + "AddToPlaylist": "Thêm vào danh sách phát", + "AddToPlayQueue": "Thêm vào hàng đợi", + "AddItemToCollectionHelp": "Thêm các mục vào bộ sưu tập bằng cách tìm kiếm và nhấp chuột phải hoặc nhấn vào menu để thêm chúng vào bộ sưu tập.", + "Absolute": "Tuyệt Đối", + "ButtonSend": "Gửi", + "ButtonSelectView": "Chọn chế độ xem", + "ButtonSelectServer": "Chọn máy chủ", + "ButtonScanAllLibraries": "Quét tất cả các thư viện", + "ButtonOk": "Đồng Ý", + "ButtonShuffle": "Xáo trộn", + "Categories": "Phân loại", + "CancelRecording": "Ngưng ghi hình", + "ButtonWebsite": "Trang web", + "ButtonViewWebsite": "Xem trang web", + "ButtonUp": "Lên", + "ButtonUninstall": "Gỡ cài đặt", + "ButtonTrailer": "Tóm tắt", + "ButtonSubtitles": "Phụ đề", + "ButtonSubmit": "Đăng", + "ButtonSplit": "Tách", + "ButtonStop": "Ngưng", + "ButtonStart": "Bắt đầu", + "ButtonSignIn": "Đăng nhập", + "ButtonShutdown": "Tắt", + "ButtonSettings": "Cài đặt" } diff --git a/src/strings/zh-cn.json b/src/strings/zh-cn.json index 4274d4efd7..b71d9408c1 100644 --- a/src/strings/zh-cn.json +++ b/src/strings/zh-cn.json @@ -247,7 +247,7 @@ "EncoderPresetHelp": "选择一个更快的值以提升性能,或者选择一个更慢的值以提升质量。", "HDPrograms": "高清节目", "HandledByProxy": "由反向代理处理", - "HardwareAccelerationWarning": "启动硬件加速可能在某些环境下导致系统不稳定。请确认你的操作系统和视频驱动程序是最新的。如果你在开启此项后播放视频产生困难,那么你需要将此选项设置回”自动“。", + "HardwareAccelerationWarning": "启动硬件加速可能在某些环境下导致系统不稳定。请确认你的操作系统和显卡驱动程序是最新的。如果你在开启此项后播放视频时遇到困难,那么你需要将此选项设置回“没有”。", "HeaderAccessSchedule": "访问计划", "HeaderAccessScheduleHelp": "创建一个访问计划以限制可访问的时间段。", "HeaderActiveDevices": "活动的设备", @@ -706,7 +706,7 @@ "LabelPublicHttpsPort": "公开 HTTPS 端口号:", "LabelPublicHttpsPortHelp": "映射到本地 HTTPS 端口的公开端口号。", "LabelReadHowYouCanContribute": "学习如何构建。", - "LabelReasonForTranscoding": "转码的原因:", + "LabelReasonForTranscoding": "转码原因:", "LabelRecord": "录制:", "LabelRecordingPath": "默认录制路径:", "LabelRecordingPathHelp": "指定一个默认位置用于存储转码文件。如果该位置留空,服务器的程序数据文件夹将被使用。", @@ -1448,7 +1448,7 @@ "LabelFolder": "文件夹:", "LabelBitrate": "比特率:", "LabelAudioSampleRate": "采样率:", - "LabelAudioCodec": "编码:", + "LabelAudioCodec": "音频编码:", "LabelAudioChannels": "声道:", "LabelAudioBitrate": "比特率:", "LabelAudioBitDepth": "采样位宽:", @@ -1469,5 +1469,7 @@ "MessageConfirmAppExit": "你要退出吗?", "EnableFastImageFadeIn": "快速图片淡入", "EnableFastImageFadeInHelp": "为已加载的图片启用更快的图片淡入动画", - "OptionForceRemoteSourceTranscoding": "强制远程转码(像电视直播一样)" + "OptionForceRemoteSourceTranscoding": "强制远程转码(像电视直播一样)", + "NoCreatedLibraries": "看上去您还未创建任何资料库。{0} 您想现在创建一个吗? {1}", + "AskAdminToCreateLibrary": "请联系管理员以创建一个新的资料库。" } diff --git a/src/themes/appletv/theme.css b/src/themes/appletv/theme.css index ccc6eaaabe..5ca517bea5 100644 --- a/src/themes/appletv/theme.css +++ b/src/themes/appletv/theme.css @@ -112,7 +112,7 @@ html { .inputLabelFocused, .selectLabelFocused, .textareaLabelFocused { - color: green; + color: #00a4dc; } .checkboxOutline { diff --git a/src/themes/dark/theme.css b/src/themes/dark/theme.css index 4d4b0a91be..41af2c32d3 100644 --- a/src/themes/dark/theme.css +++ b/src/themes/dark/theme.css @@ -201,6 +201,10 @@ html { } .detailSticky { + background: rgba(32, 32, 32, 0.8); +} + +.noBackdrop .detailSticky { background: #202020; } diff --git a/src/themes/light/theme.css b/src/themes/light/theme.css index cedc8bfb8b..d84a1c3b67 100644 --- a/src/themes/light/theme.css +++ b/src/themes/light/theme.css @@ -105,7 +105,7 @@ html { .inputLabelFocused, .selectLabelFocused, .textareaLabelFocused { - color: green; + color: #00a4dc; } .checkboxOutline { diff --git a/src/videoosd.html b/src/videoosd.html index ac3570c670..c200360c05 100644 --- a/src/videoosd.html +++ b/src/videoosd.html @@ -76,7 +76,7 @@
diff --git a/src/wizardlibrary.html b/src/wizardlibrary.html index 660b508f22..4fad656581 100644 --- a/src/wizardlibrary.html +++ b/src/wizardlibrary.html @@ -16,7 +16,7 @@
diff --git a/src/wizardremoteaccess.html b/src/wizardremoteaccess.html index 8a830d6244..c7ddfb7e84 100644 --- a/src/wizardremoteaccess.html +++ b/src/wizardremoteaccess.html @@ -26,7 +26,7 @@
diff --git a/src/wizardsettings.html b/src/wizardsettings.html index 5850167c54..f753919478 100644 --- a/src/wizardsettings.html +++ b/src/wizardsettings.html @@ -21,7 +21,7 @@
diff --git a/src/wizardstart.html b/src/wizardstart.html index 5dd6f7e1b8..a47fcad090 100644 --- a/src/wizardstart.html +++ b/src/wizardstart.html @@ -20,7 +20,7 @@
diff --git a/src/wizarduser.html b/src/wizarduser.html index 9f54d7ca67..90f492b0fe 100644 --- a/src/wizarduser.html +++ b/src/wizarduser.html @@ -27,7 +27,7 @@
diff --git a/webpack.common.js b/webpack.common.js index 5e0f885267..bff1f5f4ea 100644 --- a/webpack.common.js +++ b/webpack.common.js @@ -5,10 +5,13 @@ const CopyPlugin = require("copy-webpack-plugin"); const Assets = [ "alameda/alameda.js", - "requirejs/require.js", + "native-promise-only/npo.js", "libass-wasm/dist/subtitles-octopus-worker.js", "libass-wasm/dist/subtitles-octopus-worker.data", - "libass-wasm/dist/subtitles-octopus-worker.wasm" + "libass-wasm/dist/subtitles-octopus-worker.wasm", + "libass-wasm/dist/subtitles-octopus-worker-legacy.js", + "libass-wasm/dist/subtitles-octopus-worker-legacy.data", + "libass-wasm/dist/subtitles-octopus-worker-legacy.js.mem" ]; module.exports = { diff --git a/yarn.lock b/yarn.lock index 7187bd1774..f156002c6d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3683,10 +3683,9 @@ levn@^0.3.0, levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" -libass-wasm@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/libass-wasm/-/libass-wasm-2.1.1.tgz#f12f4fdb9579dd422dcbc348bc3bd61097f4d07d" - integrity sha512-d45bHQ7tFVsLW3QstQDrDog2m+0D6Cja4GTrkGi70R9A5+aeLunPSUz3G4CVB+sKffNgiWjK4QI5NZLHQKZ9oQ== +"libass-wasm@https://github.com/jellyfin/JavascriptSubtitlesOctopus": + version "3.0.2" + resolved "https://github.com/jellyfin/JavascriptSubtitlesOctopus#7f331237026db75af2441717a4132d2398e96735" libjass@^0.11.0: version "0.11.0" @@ -5415,11 +5414,6 @@ require-main-filename@^2.0.0: resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== -requirejs@^2.3.5: - version "2.3.6" - resolved "https://registry.yarnpkg.com/requirejs/-/requirejs-2.3.6.tgz#e5093d9601c2829251258c0b9445d4d19fa9e7c9" - integrity sha512-ipEzlWQe6RK3jkzikgCupiTbTvm4S0/CAU5GlgptkN5SO6F3u0UD0K18wy6ErDqiCyP4J4YYe1HuAShvsxePLg== - requires-port@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" @@ -5639,11 +5633,6 @@ serialize-javascript@^2.1.2: resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-2.1.2.tgz#ecec53b0e0317bdc95ef76ab7074b7384785fa61" integrity sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ== -serialize-javascript@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-2.1.2.tgz#ecec53b0e0317bdc95ef76ab7074b7384785fa61" - integrity sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ== - serve-index@^1.9.1: version "1.9.1" resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239"