From 3604ebd637b13dc25c87b2a6f2ffbbad63021732 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 9 Feb 2020 21:48:13 -0500 Subject: [PATCH] update strings --- .../alphanumericshortcuts.js | 25 +- cardbuilder/card.css | 865 --------- cardbuilder/cardbuilder.js | 1636 ----------------- cardbuilder/chaptercardbuilder.js | 95 - cardbuilder/peoplecardbuilder.js | 23 - cardbuilder/roundcard.css | 3 - images/imagehelper.js | 124 -- images/style.css | 3 - itemcontextmenu.js | 2 +- lazyloader/lazyloader-intersectionobserver.js | 108 -- lazyloader/lazyloader-scroll.js | 197 -- listview/listview.css | 270 --- listview/listview.js | 557 ------ multiselect/multiselect.css | 31 +- multiselect/multiselect.js | 193 +- playback/playbackmanager.js | 2 +- shortcuts.js | 76 +- strings/hu.json | 490 ++--- sync/syncjobeditor.js | 1 + sync/syncjoblist.js | 2 + 20 files changed, 394 insertions(+), 4309 deletions(-) delete mode 100644 cardbuilder/card.css delete mode 100644 cardbuilder/cardbuilder.js delete mode 100644 cardbuilder/chaptercardbuilder.js delete mode 100644 cardbuilder/peoplecardbuilder.js delete mode 100644 cardbuilder/roundcard.css delete mode 100644 images/imagehelper.js delete mode 100644 images/style.css delete mode 100644 lazyloader/lazyloader-intersectionobserver.js delete mode 100644 lazyloader/lazyloader-scroll.js delete mode 100644 listview/listview.css delete mode 100644 listview/listview.js diff --git a/alphanumericshortcuts/alphanumericshortcuts.js b/alphanumericshortcuts/alphanumericshortcuts.js index c4e22794..b2760879 100644 --- a/alphanumericshortcuts/alphanumericshortcuts.js +++ b/alphanumericshortcuts/alphanumericshortcuts.js @@ -26,7 +26,7 @@ if (chr.length === 1) { currentDisplayTextContainer = this.options.itemsContainer; - onAlphanumericKeyPress(e, chr); + onAlphanumericKeyPress(this, e, chr); } } } @@ -53,12 +53,12 @@ alpanumericShortcutTimeout = null; } } - function resetAlphaNumericShortcutTimeout() { + function resetAlphaNumericShortcutTimeout(instance) { clearAlphaNumericShortcutTimeout(); - alpanumericShortcutTimeout = setTimeout(onAlphanumericShortcutTimeout, 2000); + alpanumericShortcutTimeout = setTimeout(onAlphanumericShortcutTimeout.bind(instance), 2000); } - function onAlphanumericKeyPress(e, chr) { + function onAlphanumericKeyPress(instance, e, chr) { if (currentDisplayText.length >= 3) { return; } @@ -66,10 +66,13 @@ currentDisplayText += chr; inputDisplayElement.innerHTML = currentDisplayText; inputDisplayElement.classList.remove('hide'); - resetAlphaNumericShortcutTimeout(); + resetAlphaNumericShortcutTimeout(instance); } function onAlphanumericShortcutTimeout() { + + var instance = this; + var value = currentDisplayText; var container = currentDisplayTextContainer; @@ -78,12 +81,16 @@ inputDisplayElement.innerHTML = ''; inputDisplayElement.classList.add('hide'); clearAlphaNumericShortcutTimeout(); - selectByShortcutValue(container, value); + selectByShortcutValue(instance, container, value); } - function selectByShortcutValue(container, value) { + function selectByShortcutValue(instance, container, value) { - value = value.toUpperCase(); + if (instance.onAlphaNumericValueEntered) { + if (instance.onAlphaNumericValueEntered(value)) { + return; + } + } var focusElem; if (value === '#') { @@ -92,7 +99,7 @@ } if (!focusElem) { - focusElem = container.querySelector('*[data-prefix^=\'' + value + '\']'); + focusElem = container.querySelector('*[data-prefix^=\'' + value.toUpperCase() + '\']'); } if (focusElem) { diff --git a/cardbuilder/card.css b/cardbuilder/card.css deleted file mode 100644 index b76f4b38..00000000 --- a/cardbuilder/card.css +++ /dev/null @@ -1,865 +0,0 @@ -button::-moz-focus-inner { - padding: 0; - border: 0; -} - -button { - -webkit-border-fit: border !important; -} - -.card { - border: 0; - font-size: inherit !important; - font-family: inherit !important; - text-transform: none; - background-color: transparent !important; - background: none !important; - margin: 0; - padding: 0; - display: block; - color: inherit !important; - -webkit-tap-highlight-color: rgba(0,0,0,0); - outline: none !important; - cursor: pointer; - contain: layout style; - flex-shrink: 0; - font-weight: inherit !important; -} - -.card-nofocustransform { - contain: layout style paint; -} - -.itemsContainer { - display: flex; -} - -.vertical-list { - display: flex; - flex-direction: column; - flex-wrap: nowrap; -} - -.vertical-wrap { - display: flex; - flex-direction: row; - flex-wrap: wrap; -} - - .vertical-wrap.centered { - justify-content: center; - } - -.cardPadder-backdrop, .cardPadder-smallBackdrop { - padding-bottom: 56.25%; - contain: strict; -} - -.cardPadder-square { - padding-bottom: 100%; - contain: strict; -} - -.cardPadder-portrait, .cardPadder-overflowPortrait { - padding-bottom: 150%; - contain: strict; -} - -.cardPadder-fourThree { - padding-bottom: 75%; - contain: strict; -} - -.cardPadder-banner { - padding-bottom: 18.5%; - contain: strict; -} - -.cardScalable { - position: relative; - contain: layout style; -} - -.cardBox { - padding: 0 !important; - margin: .4em; - transition: none; - border: 0 solid transparent; - /* These both are needed in case cardBox is a button */ - -webkit-tap-highlight-color: rgba(0,0,0,0); - outline: none !important; - contain: layout style; -} - -@media (min-width: 50em) { - - .cardBox { - margin: .8em; - } -} - -.cardBox-withfocuscontent-large { - margin: .3em; -} - -.card-focuscontent-large { - border: .5em solid transparent; - border-radius: .25em; -} - -.cardBox-focustransform { - will-change: transform; - transition: transform 200ms ease-in-out; -} - -.card:focus > .cardBox-focustransform { - transform: scale(1.18, 1.18); -} - -.cardBox-bottompadded { - margin-bottom: 1.86em !important; -} - -/*.scrollX .cardBox-bottompadded { - margin-bottom: 1.6em !important; -}*/ - -.card:focus { - position: relative !important; - z-index: 10 !important; -} - -@media (pointer: coarse) { - .cardBox-touchzoom { - transition: transform 100ms ease-in-out; - transition-delay: 80ms; - } - - .card:active > .cardBox-touchzoom { - transform: scale(.94); - } -} - -.btnCardOptions { - position: absolute; - bottom: .25em; - right: 0; - margin: 0 !important; - z-index: 1; -} - -@media not all and (pointer: coarse) { - .btnCardOptions { - display: none; - } -} - -.mediaSourceIndicator { - display: flex; - position: absolute; - align-items: center; - justify-content: center; - top: .3em; - left: .3em; - text-align: center; - vertical-align: middle; - width: 1.6em; - height: 1.6em; - border-radius: 50%; - color: #fff; - background: rgb(51, 136, 204); -} - -.cardImageContainer { - background-size: contain; - background-repeat: no-repeat; - background-position: center center; - display: -webkit-flex; - display: flex; - align-items: center; - justify-content: center; - position: relative; - background-clip: content-box !important; - color: inherit; - /* This is only needed for scalable cards */ - height: 100%; - contain: strict; - border-radius: .3em; -} - -.chapterCardImageContainer { - background-color: #000; - border-radius: 0; -} - -.cardContent { - overflow: hidden; - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - /* Needed in case this is a button */ - display: block; - /* Needed in case this is a button */ - margin: 0 !important; - /* Needed in safari */ - height: 100%; - -webkit-tap-highlight-color: rgba(0,0,0,0); - outline: none !important; - contain: strict; -} - -.cardContent-button { - border: 0 !important; - padding: 0 !important; - cursor: pointer; - color: inherit; - width: 100%; - vertical-align: middle; - font-family: inherit; - font-size: inherit; -} - -.paddedImage { - background-size: auto 70%; -} - -.grayscaleImage { - -webkit-filter: grayscale(100%); - filter: grayscale(100%); -} - -.visualCardBox .cardContent { - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; -} - -.cardImageContainer { - display: flex; -} - -.cardImage { - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - background-size: contain; - background-repeat: no-repeat; - background-position: center bottom; -} - -.cardImage-img { - max-height: 100%; - max-width: 100%; - /* This is simply for lazy image purposes, to ensure the image is visible sooner when scrolling */ - min-height: 70%; - min-width: 70%; - margin: auto; -} - -.coveredImage-img { - width: 100%; - height: 100%; -} - -.coveredImage-noscale-img { - max-height: none; - max-width: none; -} - -.coveredImage { - background-size: 100% 100%; - background-position: center center; -} - -.coveredImage-noScale { - background-size: cover; -} - -.cardFooter { - padding: .3em .3em .5em .3em; - position: relative; -} - -.visualCardBox { - box-shadow: 0 0.06933em 0.06933em 0 rgba(0,0,0,0.14), 0 0.13866em 0.06933em -0.06933em rgba(0,0,0,0.12), 0 0.06933em 0.208em 0 rgba(0,0,0,0.2); - border-radius: .3em; -} - -.innerCardFooter { - background: rgba(0,0,0,.7); - position: absolute; - bottom: 0; - left: 0; - text-align: left; - overflow: hidden; - max-width: 100%; - color: #fff; -} - -.innerCardFooterClear { - background-color: transparent; -} - -.fullInnerCardFooter { - right: 0; -} - -.cardText { - padding: 0 .5em; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - text-align: left; -} - -.cardTextCentered { - text-align: center; - padding: 0 .25em; -} - -.cardText-secondary { - font-size: 88%; -} - -.cardText-first { - padding-top: .1em; -} - -.innerCardFooter > .cardText { - padding: .3em .5em; -} - -.cardFooter-withlogo { - padding-left: 4em; - position: relative; -} - -.cardFooterLogo { - position: absolute; - top: 0; - bottom: 0; - left: 0; - width: 4.5em; - background-size: 70% auto; - background-repeat: no-repeat; - background-position: center center; -} - -@media (pointer: coarse) { - .cardText-rightmargin { - margin-right: 2em; - text-align: left; - } -} - -.cardDefaultText { - white-space: normal; - text-align: center; -} - -.textActionButton { - border: 0 !important; - background: transparent; - border: 0 !important; - padding: 0 !important; - cursor: pointer; - -webkit-tap-highlight-color: rgba(0,0,0,0); - outline: none !important; - color: inherit; - vertical-align: middle; - font-family: inherit; - font-size: inherit; - /*display: flex; - align-items: center; - justify-content: center;*/ -} - -.cardTextActionButton { - width: 100%; - overflow: hidden; - text-overflow: ellipsis; - text-align: inherit; -} - -@media(hover: hover) and (pointer: fine) { - .textActionButton:hover { - text-decoration: underline; - } -} - -.cardImageIcon { - font-size: 4em !important; - color: inherit; -} - -.cardIndicators { - right: .225em; - top: .225em; - position: absolute; - display: flex; - align-items: center; - contain: layout style; -} - -.cardProgramAttributeIndicators { - top: 0; - left: 0; - position: absolute; - display: flex; - text-transform: uppercase; - font-size: 92%; -} - -.programAttributeIndicator { - padding: .18em .5em; - color: #fff; - font-weight: 500; -} - -.cardOverlayButton { - color: rgba(255, 255, 255, .76) !important; - margin: 0; - z-index: 1; - padding: .75em; - font-size: 88%; -} - -.cardOverlayButton-br { - position: absolute; - bottom: 0; - right: 0; -} - -.cardOverlayButtonIcon { - background-color: rgba(0,0,0,.7) !important; - border-radius: 100em; - width: 1.5em !important; - height: 1.5em !important; - justify-content: center; - align-items: center; - display: flex; - font-size: 1.66956521739130434em !important; -} - -.cardOverlayButton-centered { - bottom: initial; - right: initial; - position: static; - position: absolute; - display: flex; - font-size: 112%; - margin: -1.3em 0 0 -1.3em; - width: 2.6em; - height: 2.6em; - top: 50%; - left: 50%; - background-color: rgba(0,0,0,.5) !important; - border: .06em solid rgba(255,255,255,.6); - padding: .38em !important; - color: rgba(255, 255, 255, .76); - transition: transform 200ms ease-in-out; -} - -@media(hover: hover) and (pointer: fine) { - .cardOverlayButton-centered:hover { - transform: scale(1.2, 1.2); - } -} - -.bannerCard { - width: 100%; -} - -.backdropCard { - width: 33.333333333333333333333333333333%; -} - -.smallBackdropCard { - width: 33.333333333333333333333333333333%; -} - -/* Portrait orientation */ -@media all and (orientation: portrait) { - - .smallBackdropCard { - width: 50%; - } -} - -.fourThreeCard { - width: 50%; -} - -.squareCard { - width: 33.333333333333333333333333333333%; -} - -.portraitCard { - width: 25%; -} - -@media (min-width: 31.25em) { - - .fourThreeCard { - width: 33.333333333333333333333333333333%; - } -} - -@media (min-width: 36em) { - - .squareCard, .portraitCard { - width: 25%; - } - - .smallBackdropCard { - width: 33.333333333333333333333333333333%; - } -} - -@media (min-width: 40em) { - - .portraitCard { - width: 20%; - } -} - -@media (min-width: 43.75em) { - .fourThreeCard { - width: 25%; - } -} - -@media (min-width: 50em) { - - .bannerCard { - width: 50%; - } - - .smallBackdropCard { - width: 25%; - } - - .squareCard, .portraitCard { - width: 20%; - } -} - -@media (min-width: 62.5em) { - - .backdropCard { - width: 25%; - } - - .smallBackdropCard { - width: 20%; - } - - .fourThreeCard { - width: 20%; - } -} - -@media (min-width: 66em) { - - .squareCard, .portraitCard { - width: 16.666666666666666666666666666667%; - } -} - -@media (min-width: 75em) { - - .bannerCard { - width: 33.333333333333333333333333333333%; - } - - .smallBackdropCard { - width: 16.666666666666666666666666666667%; - } -} - -@media (min-width: 82.5em) { - - .squareCard, .portraitCard { - width: 14.285714285714285714285714285714%; - } -} - -@media (min-width: 87.5em) { - - .smallBackdropCard { - width: 14.285714285714285714285714285714%; - } -} - -@media (min-width: 95em) { - - .backdropCard { - width: 20%; - } -} - -@media (min-width: 100em) { - - .squareCard, .portraitCard { - width: 12.5%; - } - - .smallBackdropCard { - width: 12.5%; - } - - .fourThreeCard { - width: 16.666666666666666666666666666667%; - } -} - -@media (min-width: 115em) { - - .squareCard, .portraitCard { - width: 11.111111111111111111111111111111%; - } -} - -@media (min-width: 120em) { - - .backdropCard { - width: 16.666666666666666666666666666667%; - } -} - -@media (min-width: 131.25em) { - - .bannerCard { - width: 25%; - } - - .squareCard, .portraitCard { - width: 10%; - } - - .fourThreeCard { - width: 14.285714285714285714285714285714%; - } -} - -/* Portrait orientation */ -@media all and (orientation: portrait) { - - .squareCard { - width: 50%; - } - - .portraitCard { - width: 33.333333333333333333333333333333%; - } - - .backdropCard { - width: 100%; - } -} - -@media all and (orientation: portrait) and (min-width: 25em) { - - .backdropCard { - width: 50%; - } -} - -@media all and (orientation: portrait) and (min-width: 31.25em) { - - .squareCard, .portraitCard { - width: 33.333333333333333333333333333333%; - } -} - -@media all and (orientation: portrait) and (max-width: 35em) { - - .scrollX > .backdropCard { - width: 75%; - } -} - -@media all and (orientation: portrait) and (min-width: 40em) { - .squareCard, .portraitCard { - width: 25%; - } -} - -@media all and (orientation: portrait) and (min-width: 52em) { - .backdropCard { - width: 33.333333333333333333333333333333%; - } -} - -@media all and (orientation: portrait) and (min-width: 55em) { - - .squareCard, .portraitCard { - width: 20%; - } -} - -@media all and (orientation: portrait) and (min-width: 70em) { - - .squareCard, .portraitCard { - width: 16.666666666666666666666666666667%; - } -} - -@media all and (orientation: portrait) and (min-width: 75em) { - - .backdropCard { - width: 25%; - } -} - -@media all and (orientation: portrait) and (min-width: 82.5em) { - - .squareCard, .portraitCard { - width: 14.285714285714285714285714285714%; - } -} - -@media all and (orientation: portrait) and (min-width: 100em) { - - .squareCard, .portraitCard { - width: 12.5%; - } -} - -@media all and (orientation: portrait) and (min-width: 115em) { - - .squareCard, .portraitCard { - width: 11.111111111111111111111111111111%; - } -} - -@media all and (orientation: portrait) and (min-width: 131.25em) { - - .squareCard, .portraitCard { - width: 10%; - } -} - -@media all and (orientation: portrait) and (min-width: 95em) { - - .backdropCard { - width: 20%; - } -} - -@media all and (orientation: portrait) and (min-width: 120em) { - - .backdropCard { - width: 16.666666666666666666666666666667%; - } -} - -.itemsContainer-tv > .smallBackdropCard { - width: 20%; -} - -.itemsContainer-tv > .backdropCard { - width: 25%; -} - -.itemsContainer-tv > .fourThreeCard { - width: 20%; -} - -.itemsContainer-tv > .bannerCard { - width: 50%; -} - -.itemsContainer-tv > .squareCard { - width: 16.666666666666666666666666666667%; -} - -.itemsContainer-tv > .portraitCard { - width: 16.666666666666666666666666666667%; -} - -.cardOverlayContainer { - background: radial-gradient(farthest-corner at 50% 50%,rgba(30,30,30,.5) 50%,#2c2c2c 100%); - opacity: 0; - transition: opacity .2s; - position: absolute; - top: 0; - left: 0; - bottom: 0; - right: 0; - user-select: none; -} - -.chkCardSelectContainer { - font-size: 76%; - width: auto !important; - margin: .25em 0 0 .25em !important; - display: flex !important; - height: auto !important; -} - -.chkCardSelect + span:before { - border-color: rgba(255,255,255,.8) !important; -} - -@media(hover: hover) and (pointer: fine) { - .card-hoverable:hover .cardOverlayContainer { - opacity: 1; - } -} - -.cardOverlayButton-hover { - opacity: 0; - transition: opacity .2s; - background: transparent; - color: #fff !important; - padding: .5em; -} - -.cardOverlayButtonIcon-hover { - background: transparent !important; -} - -@media(hover: hover) and (pointer: fine) { - .card-hoverable:hover .cardOverlayButton-hover { - opacity: 1; - } -} - -.cardOverlayFab-primary { - font-size: 130%; - padding: 0; - width: 3em; - height: 3em; - margin-top: -1.5em; - margin-left: -1.5em; - position: absolute; - top: 50%; - left: 50%; -} - - .cardOverlayFab-primary i { - border: .07em solid rgba(255,255,255,.9); - color: #fff; - } - -@media(min-width: 48em) and (max-width: 70em) { - .skinBody-withFullDrawer .card { - min-width: 20vw; - } -} - -@media(min-width: 70em) and (max-width: 80em) { - .skinBody-withFullDrawer .card { - min-width: 16.666666666666666666666666666667vw; - } -} - -@media(min-width: 80em) and (max-width: 90em) { - .skinBody-withFullDrawer .card { - min-width: 14.285714285714285714285714285714vw; - } -} diff --git a/cardbuilder/cardbuilder.js b/cardbuilder/cardbuilder.js deleted file mode 100644 index 4a2e8289..00000000 --- a/cardbuilder/cardbuilder.js +++ /dev/null @@ -1,1636 +0,0 @@ -define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusManager', 'indicators', 'globalize', 'layoutManager', 'apphost', 'dom', 'browser', 'playbackManager', 'itemShortcuts', 'humanedate', 'css!./card', 'paper-icon-button-light', 'programStyles', 'embyProgressBarStyle', 'emby-checkbox', 'emby-playstatebutton', 'emby-ratingbutton'], - function (datetime, imageLoader, connectionManager, itemHelper, focusManager, indicators, globalize, layoutManager, appHost, dom, browser, playbackManager, itemShortcuts, humanedate) { - 'use strict'; - - var devicePixelRatio = window.devicePixelRatio || 1; - var enableFocusTransfrom = !browser.tv && !browser.xboxOne && !browser.ps4 && !browser.edge && !browser.msie; - var supportsNativeLazyLoading = 'loading' in HTMLImageElement.prototype; - - function getCardsHtml(items, options) { - - if (arguments.length === 1) { - - options = arguments[0]; - items = options.items; - } - - return buildCardsHtmlInternal(items, options); - } - - var cachedWidths = {}; - function getImageWidth(shape, cardClass, screenWidth) { - - var key = shape + screenWidth; - - var width = cachedWidths[key]; - if (width) { - return width; - } - - var div = document.createElement('div'); - div.className = 'itemsContainer'; - if (layoutManager.tv) { - div.classList.add('itemsContainer-tv'); - } - div.style.visibility = 'hidden'; - div.innerHTML = '
'; - - var parent = document.body; - parent.appendChild(div); - - width = cachedWidths[key] = div.querySelector('.cardScalable').offsetWidth; - parent.removeChild(div); - - return width; - } - - function isResizable(windowWidth) { - - var screen = window.screen; - if (screen) { - var screenWidth = screen.availWidth; - - if ((screenWidth - windowWidth) > 20) { - return true; - } - } - - return false; - } - - function getDefaultShape(items, requestedShape) { - - var firstItem = items[0]; - - if (firstItem) { - switch (firstItem.Type) { - - case 'Movie': - case 'SeriesTimer': - return 'portrait'; - case 'Episode': - case 'Program': - case 'Video': - return 'backdrop'; - default: - break; - } - } - - return 'square'; - } - - function setCardData(items, options) { - - var shape = options.shape || "auto"; - - var primaryImageAspectRatio = imageLoader.getPrimaryImageAspectRatio(items, options); - - if (shape === 'auto' || shape === 'autohome' || shape === 'autooverflow' || shape === 'autoVertical') { - - var requestedShape = shape; - shape = null; - - if (primaryImageAspectRatio) { - - if (primaryImageAspectRatio >= 3) { - shape = 'banner'; - } else if (primaryImageAspectRatio >= 1.4) { - shape = 'backdrop'; - } else if (primaryImageAspectRatio > 1.2) { - shape = 'fourThree'; - } else if (primaryImageAspectRatio > 0.71) { - shape = 'square'; - } else { - shape = 'portrait'; - } - } - - if (!shape) { - shape = options.defaultShape || getDefaultShape(items, requestedShape); - } - } - - if (options.preferThumb === 'auto') { - options.preferThumb = shape === 'backdrop'; - } - - options.uiAspect = getDesiredAspect(shape); - options.primaryImageAspectRatio = primaryImageAspectRatio; - - if (!options.width && options.widths) { - options.width = options.widths[shape]; - } - - if (options.rows && typeof (options.rows) !== 'number') { - options.rows = options.rows[shape]; - } - - if (!options.width) { - var screenWidth = dom.getWindowSize().innerWidth; - - var cardClass = 'card ' + shape + 'Card'; - - if (options.cardClass) { - cardClass += ' ' + options.cardClass; - } - - options.width = getImageWidth(shape, cardClass, screenWidth); - - if (isResizable(screenWidth)) { - var roundTo = 50; - options.width = Math.round(options.width / roundTo) * roundTo; - } - } - - var className = 'card'; - - if (shape) { - className += ' ' + shape + 'Card'; - } - - if (options.cardClass) { - className += " " + options.cardClass; - } - - var isLayoutTv = layoutManager.tv; - - if (!isLayoutTv) { - className += ' card-hoverable'; - } - - var isSingleClickElement = isLayoutTv || options.hoverMenu === false; - - if (!enableFocusTransfrom || !isLayoutTv) { - className += ' card-nofocustransform'; - } - - var tagName; - if (isSingleClickElement) { - tagName = 'button'; - className += " itemAction"; - } else { - tagName = 'div'; - } - - var innerHTML = '
'; - - options.templateInnerHTML = innerHTML; - options.tagName = tagName; - options.shape = shape; - options.className = className; - options.isSingleClickElement = isSingleClickElement; - } - - function buildCardsHtmlInternal(items, options) { - - setCardData(items, options); - - var html = ''; - var itemsInRow = 0; - var hasOpenRow; - - var rows = options.rows; - - for (var i = 0, length = items.length; i < length; i++) { - - var item = items[i]; - - if (rows && itemsInRow === 0) { - - if (hasOpenRow) { - html += ''; - hasOpenRow = false; - } - - html += '
'; - hasOpenRow = true; - } - - html += getCardHtml(item, options); - - itemsInRow++; - - if (rows && itemsInRow >= rows) { - html += '
'; - hasOpenRow = false; - itemsInRow = 0; - } - } - - if (hasOpenRow) { - html += ''; - } - - return html; - } - - function getDesiredAspect(shape) { - - if (shape) { - shape = shape.toLowerCase(); - if (shape.indexOf('portrait') !== -1) { - return (2 / 3); - } - if (shape.indexOf('backdrop') !== -1) { - return (16 / 9); - } - if (shape.indexOf('square') !== -1) { - return 1; - } - if (shape.indexOf('fourthree') !== -1) { - return (4 / 3); - } - if (shape.indexOf('banner') !== -1) { - return (1000 / 185); - } - } - return null; - } - - function getCardImageUrl(item, apiClient, options, shape) { - - var uiAspect = options.uiAspect; - - if (item.ImageUrl) { - return { - imgUrl: item.ImageUrl - }; - } - - var imageItem; - if (options.showCurrentProgramImage) { - imageItem = item.CurrentProgram || item; - } - else { - imageItem = item.ProgramInfo || item; - } - - item = imageItem; - - var width = options.width; - var height = null; - var primaryImageAspectRatio = item.PrimaryImageAspectRatio; - var forceName = false; - var imgUrl = null; - var coverImage = false; - - // .24 as opposed to .2 looks nice for nintendo 64 - var coverImageTolerance = 0.28; - - var imageTags = item.ImageTags; - - if (options.preferThumb && imageTags && imageTags.Thumb) { - - imgUrl = apiClient.getScaledImageUrl(item.Id, { - type: "Thumb", - maxWidth: width, - tag: imageTags.Thumb - }); - - } else if ((options.preferBanner || shape === 'banner') && imageTags && imageTags.Banner) { - - imgUrl = apiClient.getScaledImageUrl(item.Id, { - type: "Banner", - maxWidth: width, - tag: imageTags.Banner - }); - - } else if (options.preferDisc && imageTags && imageTags.Disc) { - - imgUrl = apiClient.getScaledImageUrl(item.Id, { - type: "Disc", - maxWidth: width, - tag: imageTags.Disc - }); - - } else if (options.preferLogo && imageTags && imageTags.Logo) { - - imgUrl = apiClient.getScaledImageUrl(item.Id, { - type: "Logo", - maxWidth: width, - tag: imageTags.Logo - }); - - } else if (options.preferLogo && item.ParentLogoImageTag && item.ParentLogoItemId) { - - imgUrl = apiClient.getScaledImageUrl(item.ParentLogoItemId, { - type: "Logo", - maxWidth: width, - tag: item.ParentLogoImageTag - }); - - } else if (options.preferThumb && item.ParentThumbItemId && options.inheritThumb !== false && item.MediaType !== 'Photo') { - - imgUrl = apiClient.getScaledImageUrl(item.ParentThumbItemId, { - type: "Thumb", - maxWidth: width, - tag: item.ParentThumbImageTag - }); - - } else if (options.preferThumb && item.BackdropImageTags && item.BackdropImageTags.length) { - - imgUrl = apiClient.getScaledImageUrl(item.Id, { - type: "Backdrop", - maxWidth: width, - tag: item.BackdropImageTags[0] - }); - - forceName = true; - - } else if (options.preferThumb && item.ParentBackdropImageTags && item.ParentBackdropImageTags.length && options.inheritThumb !== false && item.Type === 'Episode') { - - imgUrl = apiClient.getScaledImageUrl(item.ParentBackdropItemId, { - type: "Backdrop", - maxWidth: width, - tag: item.ParentBackdropImageTags[0] - }); - - if (options.preferThumb && options.showTitle !== false) { - forceName = true; - } - - } else if (imageTags && imageTags.Primary) { - - height = width && primaryImageAspectRatio ? Math.round(width / primaryImageAspectRatio) : null; - - imgUrl = apiClient.getScaledImageUrl(item.Id, { - type: "Primary", - maxHeight: height, - maxWidth: width, - tag: imageTags.Primary - }); - - if (options.preferThumb && options.showTitle !== false) { - forceName = true; - } - - if (primaryImageAspectRatio) { - if (uiAspect) { - coverImage = (Math.abs(primaryImageAspectRatio - uiAspect) / uiAspect) <= coverImageTolerance; - } - } - - } else if (item.ImageTag && item.Type === 'Plugin') { - - imgUrl = apiClient.getUrl('Plugins/' + item.Id + '/Thumb', { - maxHeight: height, - maxWidth: width, - tag: item.ImageTag - }); - - if (primaryImageAspectRatio) { - if (uiAspect) { - coverImage = (Math.abs(primaryImageAspectRatio - uiAspect) / uiAspect) <= coverImageTolerance; - } - } - - } else if (item.PrimaryImageTag) { - - height = width && primaryImageAspectRatio ? Math.round(width / primaryImageAspectRatio) : null; - - if (item.Type === 'User') { - - imgUrl = apiClient.getUserImageUrl(item.Id, { - maxHeight: height, - maxWidth: width, - tag: item.PrimaryImageTag, - type: "Primary" - }); - - } else { - imgUrl = apiClient.getScaledImageUrl(item.PrimaryImageItemId || item.Id || item.ItemId, { - type: "Primary", - maxHeight: height, - maxWidth: width, - tag: item.PrimaryImageTag - }); - - if (options.preferThumb && options.showTitle !== false) { - forceName = true; - } - } - - if (primaryImageAspectRatio) { - if (uiAspect) { - coverImage = (Math.abs(primaryImageAspectRatio - uiAspect) / uiAspect) <= coverImageTolerance; - } - } - } - else if (item.ParentThumbItemId && options.inheritThumb !== false && uiAspect && uiAspect >= 1.4 && item.MediaType !== 'Photo') { - - imgUrl = apiClient.getScaledImageUrl(item.ParentThumbItemId, { - type: "Thumb", - maxWidth: width, - tag: item.ParentThumbImageTag - }); - - } else if (item.ParentPrimaryImageTag) { - - imgUrl = apiClient.getScaledImageUrl(item.ParentPrimaryImageItemId, { - type: "Primary", - maxWidth: width, - tag: item.ParentPrimaryImageTag - }); - } - else if (item.SeriesPrimaryImageTag) { - - imgUrl = apiClient.getScaledImageUrl(item.SeriesId, { - type: "Primary", - maxWidth: width, - tag: item.SeriesPrimaryImageTag - }); - } - else if (item.AlbumId && item.AlbumPrimaryImageTag) { - - width = primaryImageAspectRatio ? Math.round(height * primaryImageAspectRatio) : null; - - imgUrl = apiClient.getScaledImageUrl(item.AlbumId, { - type: "Primary", - maxHeight: height, - maxWidth: width, - tag: item.AlbumPrimaryImageTag - }); - - if (primaryImageAspectRatio) { - if (uiAspect) { - coverImage = (Math.abs(primaryImageAspectRatio - uiAspect) / uiAspect) <= coverImageTolerance; - } - } - } - else if (item.Type === 'Season' && imageTags && imageTags.Thumb) { - - imgUrl = apiClient.getScaledImageUrl(item.Id, { - type: "Thumb", - maxWidth: width, - tag: imageTags.Thumb - }); - - } - else if (item.BackdropImageTags && item.BackdropImageTags.length) { - - imgUrl = apiClient.getScaledImageUrl(item.Id, { - type: "Backdrop", - maxWidth: width, - tag: item.BackdropImageTags[0] - }); - - } else if (imageTags && imageTags.Thumb) { - - imgUrl = apiClient.getScaledImageUrl(item.Id, { - type: "Thumb", - maxWidth: width, - tag: imageTags.Thumb - }); - - } else if (item.ParentThumbItemId && options.inheritThumb !== false) { - - imgUrl = apiClient.getScaledImageUrl(item.ParentThumbItemId, { - type: "Thumb", - maxWidth: width, - tag: item.ParentThumbImageTag - }); - - } else if (item.ParentBackdropImageTags && item.ParentBackdropImageTags.length && options.inheritThumb !== false) { - - imgUrl = apiClient.getScaledImageUrl(item.ParentBackdropItemId, { - type: "Backdrop", - maxWidth: width, - tag: item.ParentBackdropImageTags[0] - }); - - } else if (item.PrimaryImageItemId) { - - // VirtualFolder - imgUrl = apiClient.getScaledImageUrl(item.PrimaryImageItemId, { - type: "Primary", - maxHeight: height, - maxWidth: width - }); - - } - - return { - imgUrl: imgUrl, - forceName: forceName, - coverImage: coverImage - }; - } - - function getRandomInt(min, max) { - return Math.floor(Math.random() * (max - min + 1)) + min; - } - - var numRandomColors = 5; - function getDefaultColorIndex(str) { - - if (str) { - var charIndex = Math.floor(str.length / 2); - var character = String(str.substr(charIndex, 1).charCodeAt()); - var sum = 0; - for (var i = 0; i < character.length; i++) { - sum += parseInt(character.charAt(i)); - } - var index = String(sum).substr(-1); - - return (index % numRandomColors) + 1; - } else { - return getRandomInt(1, numRandomColors); - } - } - - function getCardTextLines(lines, cssClass, forceLines, isOuterFooter, cardLayout, addRightMargin, maxLines) { - - var html = ''; - - var valid = 0; - var i, length; - var currentCssClass = cssClass; - - for (i = 0, length = lines.length; i < length; i++) { - - currentCssClass = cssClass; - var text = lines[i]; - - if (valid > 0 && isOuterFooter) { - currentCssClass += ' cardText-secondary'; - } else if (valid === 0 && isOuterFooter) { - currentCssClass += ' cardText-first'; - } - - if (addRightMargin) { - currentCssClass += ' cardText-rightmargin'; - } - - if (text) { - html += '
'; - html += text; - html += "
"; - valid++; - - if (maxLines && valid >= maxLines) { - break; - } - } - } - - if (forceLines) { - - length = maxLines || Math.min(lines.length, maxLines || lines.length); - - while (valid < length) { - - currentCssClass = cssClass; - if (valid > 0 && isOuterFooter) { - currentCssClass += ' cardText-secondary'; - } - - html += '
 
'; - valid++; - } - } - - return html; - } - - function isUsingLiveTvNaming(itemType) { - - return itemType === 'Program' || itemType === 'Timer' || itemType === 'Recording'; - } - - function getAirTimeText(item, showAirDateTime, showAirEndTime) { - - var airTimeText = ''; - if (item.StartDate) { - - try { - var date = datetime.parseISO8601Date(item.StartDate); - - if (showAirDateTime) { - airTimeText += datetime.toLocaleDateString(date, { weekday: 'short', month: 'short', day: 'numeric' }) + ' '; - } - - airTimeText += datetime.getDisplayTime(date); - - if (item.EndDate && showAirEndTime) { - date = datetime.parseISO8601Date(item.EndDate); - airTimeText += ' – ' + datetime.getDisplayTime(date); - } - } - catch (e) { - console.log("Error parsing date: " + item.StartDate); - } - } - - return airTimeText; - } - - function getCardFooterText(item, options, showTitle, forceName, overlayText, imgUrl, footerClass, progressHtml, logoUrl, isOuterFooter) { - - var itemType = item.Type; - - var html = ''; - - if (logoUrl) { - html += ''; - } - - var showOtherText = isOuterFooter ? !overlayText : overlayText; - - if (isOuterFooter && options.cardLayout && !layoutManager.tv && options.cardFooterAside !== false) { - - // Checking item.Id for Type == AddServer - if (item.Type !== 'Program' && item.Id) { - html += ''; - } - } - - var cssClass = options.centerText ? "cardText cardTextCentered" : "cardText"; - - var lines = []; - var parentTitleUnderneath = itemType === 'MusicAlbum' || itemType === 'Audio' || itemType === 'MusicVideo' || itemType === 'Game'; - var titleAdded; - - var serverId = item.ServerId || options.serverId; - - if (showOtherText) { - if ((options.showParentTitle || options.showParentTitleOrTitle || (forceName && options.seriesNameInPlaceHolderName)) && !parentTitleUnderneath) { - - if (isOuterFooter && itemType === 'Episode' && item.SeriesName) { - - if (item.SeriesId) { - lines.push(getTextActionButton(options, { - Id: item.SeriesId, - ServerId: serverId, - Name: item.SeriesName, - Type: 'Series', - IsFolder: true - })); - } else { - lines.push(dom.htmlEncode(item.SeriesName)); - } - } - else { - - if (isUsingLiveTvNaming(itemType)) { - - lines.push(dom.htmlEncode(item.Name)); - - if (!item.EpisodeTitle) { - titleAdded = true; - } - - } else { - var parentTitle = item.SeriesName || item.Series || item.Album || item.AlbumArtist || item.GameSystem || ""; - - if (parentTitle || showTitle) { - lines.push(dom.htmlEncode(parentTitle)); - } - } - } - } - } - - var showMediaTitle = (showTitle && !titleAdded) || (options.showParentTitleOrTitle && !lines.length); - if (!showMediaTitle && !titleAdded && (showTitle || (forceName && !options.seriesNameInPlaceHolderName))) { - showMediaTitle = true; - } - - if (showMediaTitle) { - - var name = options.showTitle === 'auto' && !item.IsFolder && item.MediaType === 'Photo' ? '' : itemHelper.getDisplayName(item, { - includeParentInfo: options.includeParentInfoInTitle - }); - - if (overlayText) { - lines.push(dom.htmlEncode(name)); - } else { - lines.push(getTextActionButton(options, item, name, serverId, options.parentId, true)); - } - } - - if (showOtherText) { - if (options.showParentTitle && parentTitleUnderneath) { - - if (isOuterFooter && item.AlbumArtists && item.AlbumArtists.length && itemType === 'MusicAlbum') { - item.AlbumArtists[0].Type = 'MusicArtist'; - item.AlbumArtists[0].IsFolder = true; - lines.push(getTextActionButton(options, item.AlbumArtists[0], null, serverId)); - } else if (isOuterFooter && item.ArtistItems && item.ArtistItems.length) { - item.ArtistItems[0].Type = 'MusicArtist'; - item.ArtistItems[0].IsFolder = true; - lines.push(getTextActionButton(options, item.ArtistItems[0], null, serverId)); - } else if (isOuterFooter && item.AlbumArtists && item.AlbumArtists.length) { - item.AlbumArtists[0].Type = 'MusicArtist'; - item.AlbumArtists[0].IsFolder = true; - lines.push(getTextActionButton(options, item.AlbumArtists[0], null, serverId)); - } else if (isOuterFooter && item.GameSystem && item.GameSystemId) { - lines.push(getTextActionButton(options, { - Id: item.GameSystemId, - ServerId: serverId, - Name: item.GameSystem, - Type: 'GameSystem', - IsFolder: true - })); - } else { - lines.push(dom.htmlEncode(isUsingLiveTvNaming(itemType) ? item.Name : (item.SeriesName || item.Series || item.Album || item.AlbumArtist || item.GameSystem || ""))); - } - } - - if (options.textLines) { - var additionalLines = options.textLines(item); - for (var i = 0, length = additionalLines.length; i < length; i++) { - lines.push(additionalLines[i]); - } - } - - if (options.showYear) { - - if (itemType === 'Series') { - if (item.Status === "Continuing") { - - lines.push(globalize.translate('SeriesYearToPresent', item.ProductionYear || '')); - - } else { - - var endYear = item.EndDate ? datetime.parseISO8601Date(item.EndDate).getFullYear() : null; - - if (endYear && item.ProductionYear && endYear !== item.ProductionYear) { - lines.push(item.ProductionYear + ' – ' + endYear); - } else { - lines.push(item.ProductionYear || ''); - } - } - } else { - lines.push(item.ProductionYear || ''); - } - } - - if (options.showRuntime) { - - if (item.RunTimeTicks) { - - lines.push(datetime.getDisplayRunningTime(item.RunTimeTicks)); - } else { - lines.push(''); - } - } - - if (options.showAirTime) { - - lines.push(getAirTimeText(item, options.showAirDateTime, options.showAirEndTime) || ''); - } - - if (options.showChannelName) { - - if (item.ChannelId) { - - lines.push(getTextActionButton(options, { - - Id: item.ChannelId, - ServerId: serverId, - Name: item.ChannelName, - Type: 'TvChannel', - MediaType: item.MediaType, - IsFolder: false - - }, item.ChannelName)); - } else { - lines.push(item.ChannelName || ' '); - } - } - - if (options.showCurrentProgramParentTitle && itemType === 'TvChannel') { - - if (item.CurrentProgram) { - lines.push(item.CurrentProgram.Name || ''); - } else { - lines.push(''); - } - } - - if (options.showCurrentProgramTitle && itemType === 'TvChannel') { - - if (item.CurrentProgram) { - lines.push(item.CurrentProgram.EpisodeTitle || ''); - } else { - lines.push(''); - } - } - - if (options.showCurrentProgramTime && itemType === 'TvChannel') { - - if (item.CurrentProgram) { - lines.push(getAirTimeText(item.CurrentProgram, false, true) || ''); - } else { - lines.push(''); - } - } - - if (options.showSeriesTimerTime) { - if (item.RecordAnyTime) { - - lines.push(globalize.translate('Anytime')); - } else { - lines.push(datetime.getDisplayTime(item.StartDate)); - } - } - - if (options.showSeriesTimerChannel) { - if (item.RecordAnyChannel) { - lines.push(globalize.translate('AllChannels')); - } - else { - lines.push(item.ChannelName || globalize.translate('OneChannel')); - } - } - - if (options.showPersonRoleOrType) { - if (item.Role) { - lines.push(globalize.translate('ActorAsRole', item.Role)); - } - else if (itemType) { - lines.push(globalize.translate('' + itemType)); - } else { - lines.push(''); - } - } - - if (options.showChapterTime) { - lines.push(datetime.getDisplayRunningTime(item.StartPositionTicks)); - } - - if (options.showUserLastSeen) { - - if (item.Policy.IsDisabled) { - lines.push(globalize.translate('Disabled')); - } else { - lines.push(item.LastActivityDate ? humanedate(item.LastActivityDate) : ''); - } - } - - if (options.showContentType) { - - if (!item.Id) { - // AddVirtualFolder - lines.push(''); - } else { - lines.push(itemHelper.getContentTypeName(item.CollectionType)); - } - } - - if (options.showLibraryFolders) { - if (!item.Locations) { - - lines.push(''); - - } else if (item.Locations.length === 1) { - lines.push(item.Locations[0]); - } - else { - lines.push(globalize.translate('NumLocationsValue', item.Locations.length)); - } - } - - if (options.showDeviceAppInfo) { - lines.push(item.AppName + ' ' + item.AppVersion); - } - - if (options.showVersion) { - lines.push(item.Version || ''); - } - - if (options.showDeviceUserInfo) { - var deviceHtml = ''; - if (item.LastUserName) { - if (item.LastUserId) { - - deviceHtml += getTextActionButton(options, { - Id: item.LastUserId, - Name: item.LastUserName, - ServerId: serverId, - Type: 'User' - }, item.LastUserName + ', ' + humanedate(item.DateLastActivity), null, null); - - } else if (item.LastUserName) { - deviceHtml += item.LastUserName + ', ' + humanedate(item.DateLastActivity); - } - } - lines.push(deviceHtml); - } - } - - if ((showTitle || !imgUrl) && forceName && overlayText && lines.length === 1) { - lines = []; - } - - var addRightTextMargin = isOuterFooter && options.cardLayout && options.cardFooterAside !== false && !layoutManager.tv; - - html += getCardTextLines(lines, cssClass, !overlayText, isOuterFooter, options.cardLayout, addRightTextMargin, options.lines); - - if (progressHtml) { - html += progressHtml; - } - - if (html) { - - if (!isOuterFooter || logoUrl || options.cardLayout) { - html = '
' + html; - - //cardFooter - html += "
"; - } - } - - return html; - } - - function getTextActionButton(options, item, text, serverId, parentId, isSameItemAsCard) { - - if (!text) { - text = itemHelper.getDisplayName(item); - } - - if (layoutManager.tv) { - return dom.htmlEncode(text); - } - - if (options.textLinks === false) { - return dom.htmlEncode(text); - } - - text = dom.htmlEncode(text); - - var dataAttributes; - - if (isSameItemAsCard) { - dataAttributes = ''; - } - else { - dataAttributes = itemShortcuts.getShortcutAttributesHtml(item, { - serverId: serverId, - parentId: parentId - }); - } - - var html = ''; - - return html; - } - - var refreshIndicatorLoaded; - function requireRefreshIndicator() { - - if (!refreshIndicatorLoaded) { - refreshIndicatorLoaded = true; - require(['emby-itemrefreshindicator']); - } - } - - function getDefaultBackgroundClass(str) { - return 'defaultCardBackground defaultCardBackground' + getDefaultColorIndex(str); - } - - function getCardHtml(item, options) { - - var itemType = item.Type; - var action = options.action || 'link'; - - if (!item.Id) { - // AddServer - action = 'link'; - } - else if (item.IsFolder && action === 'play') { - // If this hard-coding is ever removed make sure to test nested photo albums - action = 'link'; - } - else if (item.MediaType === 'Photo') { - action = 'playallfromhere'; - } - - var shape = options.shape; - - var isSingleClickElement = options.isSingleClickElement; - - var serverId = item.ServerId || options.serverId; - var apiClient = serverId ? connectionManager.getApiClient(serverId) : null; - - var imgInfo = getCardImageUrl(item, apiClient, options, shape); - var imgUrl = imgInfo.imgUrl; - - var forceName = imgInfo.forceName; - - var overlayText = options.overlayText; - - if (forceName && !options.cardLayout) { - - if (overlayText == null) { - overlayText = true; - } - } - - var showTitle = options.showTitle === 'auto' ? true : (options.showTitle || (overlayText && (itemType === 'PhotoAlbum' || itemType === 'Folder'))); - - var cardImageContainerClass = 'cardImageContainer'; - var coveredImage = options.coverImage || imgInfo.coverImage; - - if (coveredImage) { - cardImageContainerClass += ' coveredImage'; - - if (item.MediaType === 'Photo' || itemType === 'PhotoAlbum' || itemType === 'Folder' || itemType === 'Program' || itemType === 'Recording' || itemType === 'TvChannel') { - cardImageContainerClass += ' coveredImage-noScale'; - } - } - - if (item.Policy && item.Policy.IsDisabled) { - cardImageContainerClass += ' grayscaleImage'; - } - - if (options.paddedImage) { - cardImageContainerClass += ' paddedImage'; - } - - if (options.defaultBackground) { - cardImageContainerClass += ' defaultCardBackground defaultCardBackground0'; - } - else if (!imgUrl) { - cardImageContainerClass += ' ' + getDefaultBackgroundClass(item.Name); - } - - var cardBoxClass = options.cardLayout ? 'cardBox visualCardBox' : 'cardBox'; - - var isLayoutTv = layoutManager.tv; - if (isLayoutTv) { - - if (enableFocusTransfrom) { - cardBoxClass += ' cardBox-focustransform cardBox-withfocuscontent'; - } else { - cardBoxClass += ' cardBox-withfocuscontent-large'; - } - - if (options.cardLayout) { - cardBoxClass += ' card-focuscontent'; - - if (!enableFocusTransfrom) { - cardBoxClass += ' card-focuscontent-large'; - } - } - } - - if (isSingleClickElement) { - - } else { - - if (!options.centerPlayButton) { - cardBoxClass += ' cardBox-touchzoom'; - } - } - - var playlistItemId = options.playlistItemId; - if (playlistItemId && playlistItemId === item.PlaylistItemId) { - cardBoxClass += ' activePlaylistCardBox'; - } - - var footerCssClass; - var progressHtml = indicators.getProgressBarHtml(item); - - var innerCardFooter = ''; - - var footerOverlayed = false; - - var logoUrl; - var logoHeight = 40; - - if (options.showChannelLogo && item.ChannelPrimaryImageTag) { - logoUrl = apiClient.getScaledImageUrl(item.ChannelId, { - type: "Primary", - height: logoHeight, - tag: item.ChannelPrimaryImageTag - }); - } - else if (options.showLogo && item.ParentLogoImageTag) { - logoUrl = apiClient.getScaledImageUrl(item.ParentLogoItemId, { - type: "Logo", - height: logoHeight, - tag: item.ParentLogoImageTag - }); - } - - if (overlayText) { - - logoUrl = null; - - footerCssClass = progressHtml ? 'innerCardFooter fullInnerCardFooter' : 'innerCardFooter'; - innerCardFooter += getCardFooterText(item, options, showTitle, forceName, overlayText, imgUrl, footerCssClass, progressHtml, logoUrl, false); - footerOverlayed = true; - } - else if (progressHtml) { - innerCardFooter += '
'; - innerCardFooter += progressHtml; - innerCardFooter += '
'; - - progressHtml = ''; - } - - var outerCardFooter = ''; - if (!overlayText && !footerOverlayed) { - footerCssClass = options.cardLayout ? 'cardFooter' : 'cardFooter cardFooter-transparent'; - - if (logoUrl) { - footerCssClass += ' cardFooter-withlogo'; - } - - if (!options.cardLayout) { - logoUrl = null; - } - - outerCardFooter = getCardFooterText(item, options, showTitle, forceName, overlayText, imgUrl, footerCssClass, progressHtml, logoUrl, true); - } - - if (outerCardFooter && !options.cardLayout /*&& options.allowBottomPadding !== false*/) { - cardBoxClass += ' cardBox-bottompadded'; - } - - // cardBox can be it's own separate element if an outer footer is ever needed - var cardImageContainerOpen; - var cardImageContainerClose = ''; - var cardScalableClose = ''; - - var cardContentClass = 'cardContent'; - if (!options.cardLayout) { - cardContentClass += ' cardContent-shadow'; - } - - if (imgUrl) { - - if (options.lazy !== 2) { - cardContentClass += ' lazy'; - } - } - - if (isSingleClickElement) { - - // Don't use the IMG tag with safari because it puts a white border around it - cardImageContainerOpen = imgUrl ? ('
') : ('
'); - - cardImageContainerClose = '
'; - } else { - - // Don't use the IMG tag with safari because it puts a white border around it - cardImageContainerOpen = imgUrl ? (''; - } - - var cardScalableClass = 'cardScalable'; - - if (isSingleClickElement && !options.cardLayout) { - - cardScalableClass += ' card-focuscontent'; - - if (!enableFocusTransfrom) { - cardScalableClass += ' card-focuscontent-large'; - } - } - - cardImageContainerOpen = '
' + cardImageContainerOpen; - - cardImageContainerOpen += indicators.getTypeIndicator(item); - - var indicatorsHtml = ''; - - if (options.missingIndicator !== false) { - indicatorsHtml += indicators.getMissingIndicator(item); - } - - indicatorsHtml += indicators.getSyncIndicator(item); - indicatorsHtml += indicators.getTimerIndicator(item); - - indicatorsHtml += indicators.getPlayedIndicatorHtml(item); - - if (itemType === 'CollectionFolder' || item.CollectionType) { - var refreshClass = item.RefreshProgress ? '' : ' class="hide"'; - indicatorsHtml += '
'; - requireRefreshIndicator(); - } - else if (itemType === 'User' && item.ConnectLinkType) { - - indicatorsHtml += '
cloud
'; - } - - if (indicatorsHtml) { - cardImageContainerOpen += '
' + indicatorsHtml + '
'; - } - - //if (itemType === 'Program' || itemType === 'Timer') { - // cardImageContainerOpen += getProgramIndicators(item); - //} - - if (!imgUrl) { - cardImageContainerOpen += getCardDefaultText(item, options); - } - - var tagName = options.tagName; - - var additionalCardContent = ''; - - if (layoutManager.desktop && options.hoverMenu !== false) { - additionalCardContent += getHoverMenuHtml(item, action, options); - } - - if (options.cardParts) { - - var attributes = itemShortcuts.getShortcutAttributes(item, options); - - if (options.isSingleClickElement) { - attributes.push({ name: 'data-action', value: action }); - } - - return { - attributes: attributes, - html: cardImageContainerOpen + innerCardFooter + cardImageContainerClose + additionalCardContent + cardScalableClose + outerCardFooter + '
' - }; - } - - var dataAttributes = itemShortcuts.getShortcutAttributesHtml(item, options); - - if (options.isSingleClickElement) { - dataAttributes += ' data-action="' + action + '"'; - } - - return '<' + tagName + dataAttributes + ' class="' + options.className + '">' + cardImageContainerOpen + innerCardFooter + cardImageContainerClose + additionalCardContent + cardScalableClose + outerCardFooter + '
'; - } - - function getItemParts(item, options) { - - options.cardParts = true; - return getCardHtml(item, options); - } - - function getHoverMenuHtml(item, action, options) { - - var html = ''; - var hasContent = false; - - html += '
'; - - var btnCssClass = 'cardOverlayButton cardOverlayButton-hover itemAction'; - - var serverId = item.ServerId || options.serverId; - var itemType = item.Type; - var itemId = item.Id; - - if (options.multiSelect !== false) { - hasContent = true; - html += ''; - } - - if (playbackManager.canPlay(item) && options.hoverPlayButton !== false) { - - hasContent = true; - - var playButtonAction = item.IsFolder ? 'resume' : (options.playAction || 'play'); - html += ''; - } - - html += '
'; - - //if (itemHelper.canEdit({ Policy: { IsAdministrator: true } }, item)) { - - // html += ''; - //} - - var userData = item.UserData || {}; - - if (options.playedButton !== false && itemHelper.canMarkPlayed(item)) { - - hasContent = true; - - html += ''; - } - - if (options.ratingButton !== false && itemHelper.canRate(item)) { - - var likes = userData.Likes == null ? '' : userData.Likes; - - hasContent = true; - - html += ''; - } - - // Checking item.Id for Type == AddServer - if (options.moreButton !== false && item.Type !== 'Program' && item.Id) { - hasContent = true; - - html += ''; - } - - if (!hasContent) { - return ''; - } - - html += '
'; - html += '
'; - - return html; - } - - var defaultIconsByItemType = { - MusicAlbum: '', - MusicArtist: '', - Person: '', - Channel: '', - Device: 'devices', - User: '', - Server: '', - SelectServer: '', - ManualLogin: '', - Downloads: 'folder', - ForgotPassword: '', - AddServer: '', - AddVirtualFolder: '' - }; - - var defaultIconsByCollectionType = { - movies: '', - music: '', - homevideos: '', - photos: '', - livetv: '', - tvshows: '', - games: '', - trailers: '', - musicvideos: '', - books: '', - channels: '', - playlists: '' - }; - - function getDefaultIcon(item, defaultIcon) { - - var icon; - - var collectionType = item.CollectionType; - if (collectionType) { - icon = defaultIconsByCollectionType[collectionType]; - if (icon) { - return icon; - } - } - - var itemType = item.Type; - if (itemType) { - icon = defaultIconsByItemType[itemType]; - if (icon) { - return icon; - } - } - - if (defaultIcon === false) { - return null; - } - - if (typeof defaultIcon === 'string') { - return defaultIcon; - } - - return ""; - } - - function getCardDefaultText(item, options) { - - var icon = getDefaultIcon(item, options.defaultCardImageIcon || false); - - if (icon) { - return '' + icon + ''; - } - - var defaultName = isUsingLiveTvNaming(item.Type) ? item.Name : itemHelper.getDisplayName(item); - return '
' + defaultName + '
'; - } - - function buildCards(items, options) { - - // Abort if the container has been disposed - var itemsContainer = options.itemsContainer; - if (!document.body.contains(itemsContainer)) { - return; - } - - var parentContainer = options.parentContainer; - if (parentContainer) { - if (items.length) { - parentContainer.classList.remove('hide'); - } else { - parentContainer.classList.add('hide'); - return; - } - } - - var html = buildCardsHtmlInternal(items, options); - - if (html) { - - if (itemsContainer.cardBuilderHtml !== html) { - itemsContainer.innerHTML = html; - - if (items.length < 50) { - itemsContainer.cardBuilderHtml = html; - } else { - itemsContainer.cardBuilderHtml = null; - } - } - - imageLoader.lazyChildren(itemsContainer); - } else { - - itemsContainer.innerHTML = html; - itemsContainer.cardBuilderHtml = null; - } - - if (options.autoFocus) { - focusManager.autoFocus(itemsContainer); - } - } - - function ensureIndicators(card, indicatorsElem) { - - if (indicatorsElem) { - return indicatorsElem; - } - - indicatorsElem = card.querySelector('.cardIndicators'); - - if (!indicatorsElem) { - - var cardImageContainer = card.querySelector('.cardImageContainer'); - indicatorsElem = document.createElement('div'); - indicatorsElem.classList.add('cardIndicators'); - cardImageContainer.appendChild(indicatorsElem); - } - - return indicatorsElem; - } - - function updateUserData(card, userData) { - - var type = card.getAttribute('data-type'); - - if (type === 'MusicArtist' || type === 'MusicAlbum' || type === 'Audio') { - return; - } - - // avoid updating chapter cards with watched marks - if (card.getAttribute('data-startpositionticks')) { - return; - } - - var enableCountIndicator = type === 'Series' || type === 'BoxSet' || type === 'Season'; - var indicatorsElem = null; - var playedIndicator = null; - var countIndicator = null; - var itemProgressBar = null; - - if (userData.Played) { - - playedIndicator = card.querySelector('.playedIndicator'); - - if (!playedIndicator) { - - playedIndicator = document.createElement('div'); - playedIndicator.classList.add('playedIndicator'); - playedIndicator.classList.add('indicator'); - indicatorsElem = ensureIndicators(card, indicatorsElem); - indicatorsElem.appendChild(playedIndicator); - } - playedIndicator.innerHTML = ''; - } else { - - playedIndicator = card.querySelector('.playedIndicator'); - if (playedIndicator) { - - playedIndicator.parentNode.removeChild(playedIndicator); - } - } - if (userData.UnplayedItemCount) { - countIndicator = card.querySelector('.countIndicator'); - - if (!countIndicator) { - - countIndicator = document.createElement('div'); - countIndicator.classList.add('countIndicator'); - indicatorsElem = ensureIndicators(card, indicatorsElem); - indicatorsElem.appendChild(countIndicator); - } - countIndicator.innerHTML = userData.UnplayedItemCount; - } else if (enableCountIndicator) { - - countIndicator = card.querySelector('.countIndicator'); - if (countIndicator) { - - countIndicator.parentNode.removeChild(countIndicator); - } - } - - var progressHtml = indicators.getProgressBarHtml({ - Type: type, - UserData: userData, - MediaType: 'Video' - }); - - if (progressHtml) { - - itemProgressBar = card.querySelector('.itemProgressBar'); - - if (!itemProgressBar) { - itemProgressBar = document.createElement('div'); - itemProgressBar.classList.add('itemProgressBar'); - - var innerCardFooter = card.querySelector('.innerCardFooter'); - if (!innerCardFooter) { - innerCardFooter = document.createElement('div'); - innerCardFooter.classList.add('innerCardFooter'); - var cardImageContainer = card.querySelector('.cardImageContainer'); - cardImageContainer.appendChild(innerCardFooter); - } - innerCardFooter.appendChild(itemProgressBar); - } - - itemProgressBar.innerHTML = progressHtml; - } - else { - - itemProgressBar = card.querySelector('.itemProgressBar'); - if (itemProgressBar) { - itemProgressBar.parentNode.removeChild(itemProgressBar); - } - } - } - - function onUserDataChanged(userData, scope) { - - var cards = (scope || document.body).querySelectorAll('.card[data-id="' + userData.ItemId + '"]'); - - for (var i = 0, length = cards.length; i < length; i++) { - updateUserData(cards[i], userData); - } - } - - function onTimerCreated(programId, newTimerId, itemsContainer) { - - var cells = itemsContainer.querySelectorAll('.card[data-id="' + programId + '"]'); - - for (var i = 0, length = cells.length; i < length; i++) { - var cell = cells[i]; - var icon = cell.querySelector('.timerIndicator'); - if (!icon) { - var indicatorsElem = ensureIndicators(cell); - indicatorsElem.insertAdjacentHTML('beforeend', ''); - } - cell.setAttribute('data-timerid', newTimerId); - } - } - - function onTimerCancelled(id, itemsContainer) { - - var cells = itemsContainer.querySelectorAll('.card[data-timerid="' + id + '"]'); - - for (var i = 0, length = cells.length; i < length; i++) { - var cell = cells[i]; - var icon = cell.querySelector('.timerIndicator'); - if (icon) { - icon.parentNode.removeChild(icon); - } - cell.removeAttribute('data-timerid'); - } - } - - function onSeriesTimerCancelled(id, itemsContainer) { - - var cells = itemsContainer.querySelectorAll('.card[data-seriestimerid="' + id + '"]'); - - for (var i = 0, length = cells.length; i < length; i++) { - var cell = cells[i]; - var icon = cell.querySelector('.timerIndicator'); - if (icon) { - icon.parentNode.removeChild(icon); - } - cell.removeAttribute('data-seriestimerid'); - } - } - - return { - setCardData: setCardData, - getCardsHtml: getCardsHtml, - getCardHtml: getCardHtml, - getItemParts: getItemParts, - buildCards: buildCards, - onUserDataChanged: onUserDataChanged, - onTimerCreated: onTimerCreated, - onTimerCancelled: onTimerCancelled, - onSeriesTimerCancelled: onSeriesTimerCancelled, - getDefaultIcon: getDefaultIcon - }; - }); \ No newline at end of file diff --git a/cardbuilder/chaptercardbuilder.js b/cardbuilder/chaptercardbuilder.js deleted file mode 100644 index 65a56694..00000000 --- a/cardbuilder/chaptercardbuilder.js +++ /dev/null @@ -1,95 +0,0 @@ -define(['datetime', 'imageLoader', 'connectionManager', 'layoutManager', 'browser', 'cardBuilder'], function (datetime, imageLoader, connectionManager, layoutManager, browser, cardBuilder) { - 'use strict'; - - function setChapterProperties(item, chapter, index, options, apiClient) { - - chapter.ImageUrl = getImgUrl(item, chapter, index, options.width || 400, apiClient); - - chapter.Id = item.Id; - chapter.Type = item.Type; - chapter.ServerId = item.ServerId; - chapter.MediaType = item.MediaType; - } - - function getImgUrl(item, chapter, index, maxWidth, apiClient) { - - if (chapter.ImageTag) { - - return apiClient.getScaledImageUrl(item.Id, { - - maxWidth: maxWidth, - tag: chapter.ImageTag, - type: "Chapter", - index: index - }); - } - - return null; - } - - function buildChapterCards(item, chapters, options) { - - var parentContainer = options.parentContainer; - - if (parentContainer) { - // Abort if the container has been disposed - if (!document.body.contains(parentContainer)) { - return; - } - - if (chapters.length) { - parentContainer.classList.remove('hide'); - } else { - parentContainer.classList.add('hide'); - return; - } - } - - var apiClient = connectionManager.getApiClient(item); - - var mediaStreams = ((item.MediaSources || [])[0] || {}).MediaStreams || []; - var videoStream = mediaStreams.filter(function (i) { - return i.Type === 'Video'; - })[0] || {}; - - var aspect = null; - - if (videoStream.Width && videoStream.Height) { - - aspect = videoStream.Width / videoStream.Height; - } - - for (var i = 0, length = chapters.length; i < length; i++) { - - chapters[i].PrimaryImageAspectRatio = aspect; - - setChapterProperties(item, chapters[i], i, options, apiClient); - } - - var itemsContainer = options.itemsContainer; - - itemsContainer.innerHTML = cardBuilder.getCardsHtml(chapters, { - - shape: 'autooverflow', - centerText: true, - overlayText: false, - showTitle: true, - showChapterTime: true, - multiSelect: false, - overlayMoreButton: false, - playedButton: false, - ratingButton: false, - moreButton: false, - centerPlayButton: true, - action: 'play', - enableUserData: false - }); - - imageLoader.lazyChildren(itemsContainer); - } - - return { - buildChapterCards: buildChapterCards - }; - -}); \ No newline at end of file diff --git a/cardbuilder/peoplecardbuilder.js b/cardbuilder/peoplecardbuilder.js deleted file mode 100644 index c76bb004..00000000 --- a/cardbuilder/peoplecardbuilder.js +++ /dev/null @@ -1,23 +0,0 @@ -define(['cardBuilder'], function (cardBuilder) { - 'use strict'; - - function buildPeopleCards(items, options) { - - options = Object.assign(options || {}, { - cardLayout: false, - centerText: true, - showTitle: true, - cardFooterAside: false, - showPersonRoleOrType: true, - cardClass: 'personCard', - defaultCardImageIcon: '', - multiSelect: false - }); - cardBuilder.buildCards(items, options); - } - - return { - buildPeopleCards: buildPeopleCards - }; - -}); \ No newline at end of file diff --git a/cardbuilder/roundcard.css b/cardbuilder/roundcard.css deleted file mode 100644 index 46ac72c4..00000000 --- a/cardbuilder/roundcard.css +++ /dev/null @@ -1,3 +0,0 @@ -.cardImageContainer-round, .cardImage-round { - border-radius: 1000px; -} \ No newline at end of file diff --git a/images/imagehelper.js b/images/imagehelper.js deleted file mode 100644 index af4dbf3b..00000000 --- a/images/imagehelper.js +++ /dev/null @@ -1,124 +0,0 @@ -define(['lazyLoader', 'layoutManager', 'browser', 'appSettings', 'require'], function (lazyLoader, layoutManager, browser, appSettings, require) { - 'use strict'; - - var supportsNativeLazyLoading = 'loading' in HTMLImageElement.prototype; - - if (!supportsNativeLazyLoading) { - require(['css!./style']); - } - - var self = {}; - - function fillImage(elem, source) { - - if (!source && supportsNativeLazyLoading) { - return; - } - - if (elem.tagName === "IMG") { - - elem.setAttribute("src", source || elem.getAttribute('data-src')); - elem.removeAttribute("data-src"); - return; - } - - if (source) { - elem.style.backgroundImage = "url('" + source + "')"; - } - - elem.classList.remove('lazy'); - } - - function lazyChildren(elem) { - - if (!supportsNativeLazyLoading) { - lazyLoader.lazyChildren(elem, fillImage); - } - } - - function getPrimaryImageAspectRatio(items, options) { - - var values = []; - - for (var i = 0, length = items.length; i < length; i++) { - - var item = items[i]; - var imageItem; - if (options && options.showCurrentProgramImage) { - imageItem = item.CurrentProgram || item; - } - else { - imageItem = item.ProgramInfo || item; - } - - var ratio = imageItem.PrimaryImageAspectRatio || 0; - - if (!ratio) { - continue; - } - - values[values.length] = ratio; - } - - if (!values.length) { - return null; - } - - // Use the median - values.sort(function (a, b) { return a - b; }); - - var half = Math.floor(values.length / 2); - - var result; - - if (values.length % 2) { - result = values[half]; - } - else { - result = (values[half - 1] + values[half]) / 2.0; - } - - // If really close to 2:3 (poster image), just return 2:3 - var aspect2x3 = 2 / 3; - if (Math.abs(aspect2x3 - result) <= 0.1666667) { - return aspect2x3; - } - - // If really close to 16:9 (episode image), just return 16:9 - var aspect16x9 = 16 / 9; - if (Math.abs(aspect16x9 - result) <= 0.222222) { - return aspect16x9; - } - - var aspectFourThree = 4 / 3; - if (Math.abs(aspectFourThree - result) <= 0.2) { - return aspectFourThree; - } - - // If really close to 1 (square image), just return 1 - if (Math.abs(1 - result) <= 0.1666667) { - return 1; - } - - return result; - } - - function fillImages(elems) { - - if (supportsNativeLazyLoading) { - return; - } - - for (var i = 0, length = elems.length; i < length; i++) { - var elem = elems[0]; - fillImage(elem); - } - } - - self.fillImages = fillImages; - self.lazyImage = fillImage; - self.lazyChildren = lazyChildren; - self.getPrimaryImageAspectRatio = getPrimaryImageAspectRatio; - - return self; -}); \ No newline at end of file diff --git a/images/style.css b/images/style.css deleted file mode 100644 index e20f1444..00000000 --- a/images/style.css +++ /dev/null @@ -1,3 +0,0 @@ -.lazy { - background-image: none !important; -} diff --git a/itemcontextmenu.js b/itemcontextmenu.js index 80925397..74110002 100644 --- a/itemcontextmenu.js +++ b/itemcontextmenu.js @@ -750,7 +750,7 @@ define(['dom', 'userSettings', 'apphost', 'globalize', 'connectionManager', 'ite function showMultiSelect(apiClient, item, options) { var itemsContainer = dom.parentWithClass(options.positionTo, 'itemsContainer'); - itemsContainer.showMultiSelect(options.positionTo); + itemsContainer.showMultiSelect(options.positionTo, true); } function deleteTimer(apiClient, item) { diff --git a/lazyloader/lazyloader-intersectionobserver.js b/lazyloader/lazyloader-intersectionobserver.js deleted file mode 100644 index 96df8162..00000000 --- a/lazyloader/lazyloader-intersectionobserver.js +++ /dev/null @@ -1,108 +0,0 @@ -define(['browser'], function (browser) { - 'use strict'; - - function LazyLoader(options) { - - this.options = options; - } - - LazyLoader.prototype.createObserver = function () { - - var observerOptions = {}; - var options = this.options; - var loadedCount = 0; - var callback = options.callback; - - if (!browser.edge) { - // this is causing it to not work at all - observerOptions.rootMargin = "50%"; - } - - var observerId = 'obs' + Date.now(); - - var self = this; - var observer = new IntersectionObserver(function (entries) { - for (var j = 0, length2 = entries.length; j < length2; j++) { - var entry = entries[j]; - - var isIntersecting = entry.isIntersecting; - - if (isIntersecting == null) { - isIntersecting = entry.intersectionRatio > 0; - } - - if (isIntersecting) { - - // Stop watching and load the image - var target = entry.target; - - observer.unobserve(target); - - if (!target[observerId]) { - target[observerId] = 1; - callback(target); - loadedCount++; - - if (loadedCount >= self.elementCount) { - self.destroyObserver(); - } - } - } - } - }, - observerOptions - ); - - this.observer = observer; - }; - - LazyLoader.prototype.addElements = function (elements) { - - var observer = this.observer; - - if (!observer) { - this.createObserver(); - observer = this.observer; - } - - this.elementCount = (this.elementCount || 0) + elements.length; - - for (var i = 0, length = elements.length; i < length; i++) { - observer.observe(elements[i]); - } - }; - - LazyLoader.prototype.destroyObserver = function (elements) { - - var observer = this.observer; - - if (observer) { - observer.disconnect(); - this.observer = null; - } - }; - - LazyLoader.prototype.destroy = function (elements) { - - this.destroyObserver(); - this.options = null; - }; - - function unveilElements(elements, root, callback) { - - if (!elements.length) { - return; - } - var lazyLoader = new LazyLoader({ - callback: callback - }); - lazyLoader.addElements(elements); - } - - LazyLoader.lazyChildren = function (elem, callback) { - - unveilElements(elem.getElementsByClassName('lazy'), elem, callback); - }; - - return LazyLoader; -}); \ No newline at end of file diff --git a/lazyloader/lazyloader-scroll.js b/lazyloader/lazyloader-scroll.js deleted file mode 100644 index e679af45..00000000 --- a/lazyloader/lazyloader-scroll.js +++ /dev/null @@ -1,197 +0,0 @@ -define(['visibleinviewport', 'dom', 'browser'], function (visibleinviewport, dom, browser) { - 'use strict'; - - var thresholdX; - var thresholdY; - - var requestIdleCallback = window.requestIdleCallback || function (fn) { - fn(); - }; - - function resetThresholds() { - - var threshold = 0.3; - - thresholdX = screen.availWidth * threshold; - thresholdY = screen.availHeight * threshold; - } - - function resetThresholdsOnTimer() { - - setTimeout(resetThresholds, 500); - } - - if (browser.iOS) { - dom.addEventListener(window, "orientationchange", resetThresholdsOnTimer, { passive: true }); - dom.addEventListener(window, 'resize', resetThresholdsOnTimer, { passive: true }); - } else { - dom.addEventListener(window, "orientationchange", resetThresholds, { passive: true }); - dom.addEventListener(window, 'resize', resetThresholds, { passive: true }); - } - resetThresholds(); - - function isVisible(elem) { - return visibleinviewport(elem, true, thresholdX, thresholdY); - } - - var wheelEvent = (document.implementation.hasFeature('Event.wheel', '3.0') ? 'wheel' : 'mousewheel'); - var self = {}; - - function cancelAll(tokens) { - for (var i = 0, length = tokens.length; i < length; i++) { - - tokens[i] = true; - } - } - - var enableTimeoutHack = browser.edge || browser.safari; - - function unveilElementsInternal(instance, callback) { - - var unveiledElements = []; - var cancellationTokens = []; - var loadedCount = 0; - - function unveilInternal(tokenIndex) { - - var anyFound = false; - var out = false; - - var elements = instance.elements; - // TODO: This out construct assumes left to right, top to bottom - - for (var i = 0, length = elements.length; i < length; i++) { - - if (cancellationTokens[tokenIndex]) { - return; - } - if (unveiledElements[i]) { - continue; - } - var elem = elements[i]; - if (!out && isVisible(elem)) { - anyFound = true; - unveiledElements[i] = true; - callback(elem); - loadedCount++; - } else { - - if (anyFound) { - out = true; - } - } - } - - if (loadedCount >= elements.length) { - dom.removeEventListener(document, 'focus', unveil, { - capture: true, - passive: true - }); - dom.removeEventListener(document, 'scroll', unveil, { - capture: true, - passive: true - }); - dom.removeEventListener(document, wheelEvent, unveil, { - capture: true, - passive: true - }); - dom.removeEventListener(window, 'resize', unveil, { - capture: true, - passive: true - }); - } - } - - function unveil() { - - cancelAll(cancellationTokens); - - var index = cancellationTokens.length; - cancellationTokens.length++; - - setTimeout(function () { - unveilInternal(index); - }, 1); - } - - dom.addEventListener(document, 'focus', unveil, { - capture: true, - passive: true - }); - dom.addEventListener(document, 'scroll', unveil, { - capture: true, - passive: true - }); - dom.addEventListener(document, wheelEvent, unveil, { - capture: true, - passive: true - }); - dom.addEventListener(window, 'resize', unveil, { - capture: true, - passive: true - }); - - unveil(); - - // This is helping resolve issues with initial visibility in both edge and safari - // 0 is fine for safari, but needed 100 for edge - if (enableTimeoutHack) { - setTimeout(unveil, 100); - } - } - - function LazyLoader(options) { - - this.options = options; - } - - LazyLoader.prototype.createObserver = function () { - - unveilElementsInternal(this, this.options.callback); - this.observer = 1; - }; - - LazyLoader.prototype.addElements = function (elements) { - - this.elements = this.elements || []; - - for (var i = 0, length = elements.length; i < length; i++) { - this.elements.push(elements[i]); - } - - var observer = this.observer; - - if (!observer) { - this.createObserver(); - } - - }; - - LazyLoader.prototype.destroyObserver = function (elements) { - - }; - - LazyLoader.prototype.destroy = function (elements) { - - this.destroyObserver(); - this.options = null; - }; - - function unveilElements(elements, root, callback) { - - if (!elements.length) { - return; - } - var lazyLoader = new LazyLoader({ - callback: callback - }); - lazyLoader.addElements(elements); - } - - LazyLoader.lazyChildren = function (elem, callback) { - - unveilElements(elem.getElementsByClassName('lazy'), elem, callback); - }; - - return LazyLoader; -}); \ No newline at end of file diff --git a/listview/listview.css b/listview/listview.css deleted file mode 100644 index 1363b768..00000000 --- a/listview/listview.css +++ /dev/null @@ -1,270 +0,0 @@ -.listItem { - background: transparent; - border: 0; - outline: none !important; - color: inherit; - vertical-align: middle; - font-family: inherit; - font-size: inherit; - margin: 0; - display: flex; - align-items: center; - text-align: left; - padding: .25em 0; - cursor: pointer; - overflow: hidden; - flex-shrink: 0; -} - -@media (pointer: coarse) { - .listItem-touchzoom-transition { - transition: transform 100ms ease-in-out; - transition-delay: 80ms; - } - - .listItem-touchzoom:active { - transform: scale(.94); - } -} - -.listItem-largeImage{ - padding: 1em 0; -} - -.listItem-withContentWrapper { - flex-direction: column; - align-items: flex-start; -} - -.listItem[data-action=none] { - cursor: default; -} - -.listItem-content { - display: flex; - align-items: center; - width: 100%; -} - -.listItem-button { - width: 100%; - line-height: inherit; -} - -.listItem-indexnumberleft { - margin-right: 1em; - margin-left: .5em; -} - -.listItem-border { - border-bottom-width: .08em; - border-bottom-style: solid; -} - -.listItemImageContainer, .listItemIcon, .listItemAside { - flex-shrink: 0; -} - -.listItemButton { - margin: 0; - flex-shrink: 0; - contain: layout style; -} - -@media (pointer: coarse) { - .listItemContextMenuButton { - display: none; - } -} - -.listItemBody { - flex-grow: 1; - padding: .35em .75em; - overflow: hidden; - text-overflow: ellipsis; - flex-direction: column; - vertical-align: middle; - justify-content: center; -} - -.listItemBody-noleftpadding { - padding-left: 0 !important; -} - -.listItemBodyText { - margin: 0; - overflow: hidden; - text-overflow: ellipsis; -} - -.listItemBodyText-nowrap { - white-space: nowrap; -} - -.listItemImageContainer { - width: 3.26em; - position: relative; - display: flex; - align-items: center; -} - -.listItemImage { - border-radius: .3em; - max-width: 100%; -} - -.listItemImageContainer-large { - width: 20vw; - margin-right: .35em; -} - -.listItemImageButton { - margin: 0; - color: rgba(255, 255, 255, .6); - font-size: 1.5em; - background: transparent; - transition: transform 200ms ease-in-out; - display: flex; - position: absolute; - top: 50%; - left: 50%; - margin-left: -2em; - margin-top: -2em; -} - -@media(hover: hover) and (pointer: fine) { - .listItemImageButton:hover { - transform: scale(1.2, 1.2); - } -} - -.listItemImageButton-icon { - background: rgba(0,0,0,.4); - border: .08em solid currentColor; - border-radius: 100em; - display: flex; - justify-content: center; - align-items: center; - padding: .21em; -} - -@media all and (max-width: 64em) { - - .listItemImageContainer-large { - width: 33.75vw; - } - - .listItemImageButton { - font-size: 1.02em !important; - } -} - -.listItemImageContainer-large-tv { - width: 30vw !important; -} - -.listItemIcon { - width: 1em !important; - height: 1em !important; - font-size: 143%; - padding: 0 .25em; -} - - .listItemIcon:not(.listItemIcon-transparent) { - background-color: #52B54B; - color: #fff; - padding: .5em; - border-radius: 100em; - margin: 0 .2em 0 .75em; - } - -.listViewDragHandle { - touch-action: none; - padding: 1em; -} - -.listItemProgressBar { - position: absolute!important; - bottom: 0; - left: 0; - right: 0; -} - -.listItem:focus { - border-radius: .2em; -} - - .listItem:focus .secondary { - color: inherit !important; - } - -.listItem-focusscale { - transition: transform .2s ease-out; -} - - .listItem-focusscale:focus { - transform: scale(1.025, 1.025); - } - -.paperList { - margin: .5em auto; -} - -.paperList-clear { - background-color: transparent !important; -} - -.listItemMediaInfo { - /* Don't display if flex not supported */ - display: none; - align-items: center; - margin-right: 1em; - flex-shrink: 0; -} - -.listGroupHeader-first { - margin-top: 0; -} - -.listItemIndicators { - right: .324em; - top: .324em; - position: absolute; - display: flex; - align-items: center; -} - -.listItem, .listItemBody, .listItemMediaInfo { - display: flex; - contain: layout style; -} - -.listItem-bottomoverview { - font-size: 88%; - margin-top: .2em; -} - -@media not all and (min-width: 50em) { - - .listItem-overview { - display: none !important; - } -} - -@media all and (min-width: 50em) { - - .listItem-bottomoverview { - display: none !important; - } -} - -.listItemCheckboxContainer { - width: auto !important; -} - -@media all and (max-width: 75em) { - - .listViewUserDataButtons { - display: none !important; - } -} \ No newline at end of file diff --git a/listview/listview.js b/listview/listview.js deleted file mode 100644 index ae12a94b..00000000 --- a/listview/listview.js +++ /dev/null @@ -1,557 +0,0 @@ -define(['dom', 'itemShortcuts', 'itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutManager', 'globalize', 'datetime', 'apphost', 'css!./listview', 'emby-ratingbutton', 'emby-playstatebutton', 'embyProgressBarStyle'], function (dom, itemShortcuts, itemHelper, mediaInfo, indicators, connectionManager, layoutManager, globalize, datetime, appHost) { - 'use strict'; - - var supportsNativeLazyLoading = 'loading' in HTMLImageElement.prototype; - - function getIndex(item, options) { - - if (options.index === 'disc') { - - var parentIndexNumber = item.ParentIndexNumber; - - if (parentIndexNumber === 1) { - return ''; - } - - return parentIndexNumber == null ? '' : globalize.translate('ValueDiscNumber', parentIndexNumber); - } - - return ''; - } - - function getImageUrl(item, width) { - - var apiClient = connectionManager.getApiClient(item); - - var options = { - width: width, - type: "Primary" - }; - - if (item.ImageTags && item.ImageTags.Primary) { - - options.tag = item.ImageTags.Primary; - return apiClient.getScaledImageUrl(item.Id, options); - } - - if (item.AlbumId && item.AlbumPrimaryImageTag) { - - options.tag = item.AlbumPrimaryImageTag; - return apiClient.getScaledImageUrl(item.AlbumId, options); - } - - else if (item.SeriesId && item.SeriesPrimaryImageTag) { - - options.tag = item.SeriesPrimaryImageTag; - return apiClient.getScaledImageUrl(item.SeriesId, options); - - } - else if (item.ParentPrimaryImageTag) { - - options.tag = item.ParentPrimaryImageTag; - return apiClient.getScaledImageUrl(item.ParentPrimaryImageItemId, options); - } - - return null; - } - - function getChannelImageUrl(item, width) { - - var apiClient = connectionManager.getApiClient(item); - - var options = { - width: width, - type: "Primary" - }; - - if (item.ChannelId && item.ChannelPrimaryImageTag) { - - options.tag = item.ChannelPrimaryImageTag; - return apiClient.getScaledImageUrl(item.ChannelId, options); - } - - return null; - } - - function getTextLinesHtml(textlines, isLargeStyle) { - - var html = ''; - var isFirst = true; - - for (var i = 0, length = textlines.length; i < length; i++) { - - var text = textlines[i]; - - if (!text) { - continue; - } - - if (isFirst) { - if (isLargeStyle) { - html += '

'; - } else { - html += '
'; - } - } else { - html += '
'; - } - html += dom.htmlEncode(text); - if (isFirst && isLargeStyle) { - html += '

'; - } else { - html += '
'; - } - - isFirst = false; - } - - return html; - } - - function getRightButtonsHtml(options) { - - var html = ''; - - for (var i = 0, length = options.rightButtons.length; i < length; i++) { - - var button = options.rightButtons[i]; - - html += ''; - } - - return html; - } - - function getId(item) { - return item.Id; - } - - function getListItemHtml(item, options) { - - var enableOverview = options.enableOverview; - var enableSideMediaInfo = options.enableSideMediaInfo != null ? options.enableSideMediaInfo : true; - var clickEntireItem = options.clickEntireItem; - var isLargeStyle = options.isLargeStyle; - var enableContentWrapper = options.enableContentWrapper; - var tagName = options.tagName; - var action = options.action; - - var html = ''; - - var downloadWidth = 80; - - if (isLargeStyle) { - downloadWidth = 600; - } - - if (enableContentWrapper) { - - html += '
'; - } - - if (options.image !== false) { - var imgUrl = options.imageSource === 'channel' ? getChannelImageUrl(item, downloadWidth) : getImageUrl(item, downloadWidth); - - var imageContainerClass = 'listItemImageContainer'; - var imageClass = 'listItemImage'; - - if (isLargeStyle) { - imageContainerClass += ' listItemImageContainer-large'; - - if (layoutManager.tv) { - imageContainerClass += ' listItemImageContainer-large-tv'; - } - } - - if (options.playlistItemId && options.playlistItemId === item.PlaylistItemId) { - imageContainerClass += ' playlistIndexIndicatorImage'; - } - - var playOnImageClick = options.imagePlayButton && !layoutManager.tv; - - if (!clickEntireItem) { - imageContainerClass += ' itemAction'; - } - - var imageAction = playOnImageClick ? 'resume' : action; - - html += '
'; - - if (imgUrl) { - if (supportsNativeLazyLoading) { - html += ''; - } else { - html += ''; - } - } - - var indicatorsHtml = indicators.getPlayedIndicatorHtml(item); - - if (indicatorsHtml) { - html += '
' + indicatorsHtml + '
'; - } - - if (playOnImageClick) { - html += ''; - } - - var progressHtml = indicators.getProgressBarHtml(item, { - containerClass: 'listItemProgressBar' - }); - - if (progressHtml) { - html += progressHtml; - } - html += '
'; - } - - if (options.showIndexNumberLeft) { - - html += '
'; - if (item.IndexNumber == null) { - html += ' '; - } else { - html += item.IndexNumber; - } - html += '
'; - } - - var textlines = []; - - if (options.showProgramDateTime) { - textlines.push(datetime.toLocaleString(datetime.parseISO8601Date(item.StartDate), { - - weekday: 'long', - month: 'short', - day: 'numeric', - hour: 'numeric', - minute: '2-digit' - })); - } - - if (options.showProgramTime) { - textlines.push(datetime.getDisplayTime(datetime.parseISO8601Date(item.StartDate))); - } - - if (options.showChannel) { - if (item.ChannelName) { - textlines.push(item.ChannelName); - } - } - - var parentTitle = null; - - if (options.showParentTitle) { - if (item.Type === 'Episode') { - parentTitle = item.SeriesName; - } - - else if (item.IsSeries || (item.EpisodeTitle && item.Name)) { - parentTitle = item.Name; - } - } - - var displayName = itemHelper.getDisplayName(item, { - includeParentInfo: options.includeParentInfoInTitle - }); - - if (options.showIndexNumber && item.IndexNumber != null) { - displayName = item.IndexNumber + ". " + displayName; - } - - if (options.showParentTitle && options.parentTitleWithTitle) { - - if (displayName) { - - if (parentTitle) { - parentTitle += ' - '; - } - parentTitle = (parentTitle || '') + displayName; - } - - textlines.push(parentTitle || ''); - } - else if (options.showParentTitle) { - textlines.push(parentTitle || ''); - } - - if (displayName && !options.parentTitleWithTitle) { - textlines.push(displayName); - } - - if (item.IsFolder) { - if (options.artist !== false) { - - if (item.AlbumArtist && item.Type === 'MusicAlbum') { - textlines.push(item.AlbumArtist); - } - } - } else { - - var showArtist = options.artist === true; - var artistItems = item.ArtistItems; - - if (!showArtist && options.artist !== false) { - - var containerAlbumArtistIds = options.containerAlbumArtistIds; - - if (!artistItems || !artistItems.length) { - showArtist = true; - } - else if (artistItems.length > 1 || containerAlbumArtistIds.length !== 1 || containerAlbumArtistIds.indexOf(artistItems[0].Id) === -1) { - showArtist = true; - } - } - - if (showArtist) { - - if (artistItems && item.Type !== 'MusicAlbum') { - textlines.push(artistItems.map(function (a) { - return a.Name; - }).join(', ')); - } - } - } - - if (item.Type === 'Game') { - textlines.push(item.GameSystem); - } - - if (item.Type === 'TvChannel') { - - if (item.CurrentProgram) { - textlines.push(itemHelper.getDisplayName(item.CurrentProgram)); - } - } - - var cssClass = 'listItemBody'; - if (!clickEntireItem) { - cssClass += ' itemAction'; - } - - if (options.image === false) { - cssClass += ' listItemBody-noleftpadding'; - } - - html += '
'; - - var moreIcon = ''; - - html += getTextLinesHtml(textlines, isLargeStyle); - - if (options.mediaInfo !== false) { - if (!enableSideMediaInfo) { - - var mediaInfoClass = 'listItemMediaInfo listItemBodyText listItemBodyText-secondary'; - - html += '
' + mediaInfo.getPrimaryMediaInfoHtml(item, { - episodeTitle: false, - originalAirDate: false, - subtitles: false, - endsAt: false - - }) + '
'; - } - } - - if (enableOverview && item.Overview) { - html += '
'; - html += dom.htmlEncode(item.Overview); - html += '
'; - } - - html += '
'; - - if (options.mediaInfo !== false) { - if (enableSideMediaInfo) { - html += '
' + mediaInfo.getPrimaryMediaInfoHtml(item, { - - year: false, - container: false, - episodeTitle: false, - criticRating: false, - endsAt: false - - }) + '
'; - } - } - - if (!options.recordButton && (item.Type === 'Timer' || item.Type === 'Program')) { - html += indicators.getTimerIndicator(item).replace('indicatorIcon', 'indicatorIcon listItemAside'); - } - - if (!clickEntireItem) { - - if (options.addToListButton) { - html += ''; - } - - if (options.moreButton !== false && item.Type !== 'Program') { - html += ''; - } - - if (options.infoButton) { - html += ''; - } - - if (options.rightButtons) { - html += getRightButtonsHtml(options); - } - - if (options.enableUserDataButtons !== false) { - - html += ''; - - var userData = item.UserData || {}; - var likes = userData.Likes == null ? '' : userData.Likes; - - if (itemHelper.canMarkPlayed(item)) { - html += ''; - } - - if (itemHelper.canRate(item)) { - html += ''; - } - - html += ''; - } - - if (options.dragHandle) { - //html += ''; - // Firefox and Edge are not allowing the button to be draggable - html += ''; - } - } - - if (enableContentWrapper) { - html += '
'; - - if (enableOverview && item.Overview) { - html += '
'; - html += dom.htmlEncode(item.Overview); - html += '
'; - } - } - - if (options.listItemParts) { - - var attributes = itemShortcuts.getShortcutAttributes(item, options); - - if (action) { - attributes.push({ name: 'data-action', value: action }); - } - - return { - attributes: attributes, - html: html - }; - } - - var dataAttributes = itemShortcuts.getShortcutAttributesHtml(item, options); - - if (action) { - dataAttributes += ' data-action="' + action + '"'; - } - - return '<' + tagName + ' class="' + options.className + '"' + dataAttributes + '>' + html + ''; - } - - function getItemParts(item, options) { - - options.listItemParts = true; - return getListItemHtml(item, options); - } - - function setListOptions(items, options) { - - options.enableContentWrapper = options.enableOverview && !layoutManager.tv; - options.containerAlbumArtistIds = (options.containerAlbumArtists || []).map(getId); - options.clickEntireItem = layoutManager.tv ? true : false; - options.isLargeStyle = options.imageSize === 'large'; - options.action = options.action || 'link'; - options.tagName = options.clickEntireItem ? 'button' : 'div'; - - var cssClass = "listItem"; - - if (options.border || (options.highlight !== false && !layoutManager.tv)) { - cssClass += ' listItem-border'; - } - - if (options.clickEntireItem) { - cssClass += ' itemAction listItem-button'; - } - - if (layoutManager.tv) { - cssClass += ' listItem-focusscale'; - } else { - - cssClass += ' listItem-touchzoom'; - - if (!options.dragHandle) { - // this transition causes drag and drops to be very slow - // to solve this and keep the transition, we'll have to rework the markup structure a bit - cssClass += ' listItem-touchzoom-transition'; - } - } - - if (options.isLargeStyle) { - cssClass += " listItem-largeImage"; - } - - if (options.enableContentWrapper) { - - cssClass += ' listItem-withContentWrapper'; - } - - options.className = cssClass; - - var innerHTML = ''; - - options.templateInnerHTML = innerHTML; - } - - function getListViewHtml(items, options) { - - setListOptions(items, options); - - var groupTitle = ''; - - var html = ''; - - for (var i = 0, length = items.length; i < length; i++) { - - var item = items[i]; - - if (options.showIndex) { - - var itemGroupTitle = getIndex(item, options); - - if (itemGroupTitle !== groupTitle) { - - if (i === 0) { - html += '

'; - } - else { - html += '

'; - } - - html += itemGroupTitle; - html += '

'; - - groupTitle = itemGroupTitle; - } - } - - html += getListItemHtml(item, options); - } - - return html; - } - - return { - getListViewHtml: getListViewHtml, - getListItemHtml: getListItemHtml, - setListOptions: setListOptions, - getItemParts: getItemParts - }; -}); \ No newline at end of file diff --git a/multiselect/multiselect.css b/multiselect/multiselect.css index 05b898a2..806535d8 100644 --- a/multiselect/multiselect.css +++ b/multiselect/multiselect.css @@ -1,14 +1,4 @@ -.itemSelectionPanel { - position: absolute; - bottom: 0; - left: 0; - right: 0; - top: 0; - background-color: rgba(0, 0, 0, .3); - z-index: 99998; -} - -.selectionCommandsPanel { +.selectionCommandsPanel { position: fixed; top: 0; top: var(--window-inset-top); @@ -24,21 +14,4 @@ vertical-align: middle; color: #fff !important; margin: 0; -} - -.chkItemSelectContainer { - height: auto !important; - margin-top: .1em; -} - -.chkItemSelectLabel::before { - border-radius: 0 !important; -} - -.withMultiSelect { - position: relative; -} - - .withMultiSelect .cardOverlayContainer { - opacity: 0 !important; - } +} \ No newline at end of file diff --git a/multiselect/multiselect.js b/multiselect/multiselect.js index 7d203d5f..e1293feb 100644 --- a/multiselect/multiselect.js +++ b/multiselect/multiselect.js @@ -2,6 +2,7 @@ 'use strict'; var selectedItems = []; + var selectedItemsMap = {}; var selectedElements = []; var currentSelectionCommandsPanel; @@ -14,94 +15,29 @@ currentSelectionCommandsPanel = null; selectedItems = []; + selectedItemsMap = {}; selectedElements = []; - var elems = document.querySelectorAll('.itemSelectionPanel'); - for (var i = 0, length = elems.length; i < length; i++) { - var parent = elems[i].parentNode; - parent.removeChild(elems[i]); - parent.classList.remove('withMultiSelect'); - } - } - } - - function onItemSelectionPanelClick(e, itemSelectionPanel) { - - // toggle the checkbox, if it wasn't clicked on - - var chkItemSelect = dom.parentWithClass(e.target, 'chkItemSelect'); - if (!chkItemSelect) { - chkItemSelect = itemSelectionPanel.querySelector('.chkItemSelect'); - } + var elems = document.querySelectorAll('.multi-select-active'); + var i, length; - if (chkItemSelect) { + for (i = 0, length = elems.length; i < length; i++) { - var newValue = !chkItemSelect.checked; - chkItemSelect.checked = newValue; - updateItemSelection(chkItemSelect, newValue); - } - - e.preventDefault(); - e.stopPropagation(); - return false; - } - - function updateItemSelection(chkItemSelect, selected) { - - var id = dom.parentWithAttribute(chkItemSelect, 'data-id').getAttribute('data-id'); - - if (selected) { - - var current = selectedItems.filter(function (i) { - return i === id; - }); - - if (!current.length) { - selectedItems.push(id); - selectedElements.push(chkItemSelect); + elems[i].classList.remove('multi-select-active'); } - } else { - selectedItems = selectedItems.filter(function (i) { - return i !== id; - }); - selectedElements = selectedElements.filter(function (i) { - return i !== chkItemSelect; - }); - } + elems = document.querySelectorAll('.chkCardSelect:checked'); + for (i = 0, length = elems.length; i < length; i++) { - if (selectedItems.length) { - var itemSelectionCount = document.querySelector('.itemSelectionCount'); - if (itemSelectionCount) { - itemSelectionCount.innerHTML = selectedItems.length; + elems[i].checked = false; } - } else { - hideSelections(); - } - } - - function onSelectionChange(e) { - updateItemSelection(this, this.checked); - } - - function showSelection(item, isChecked) { - - var itemSelectionPanel = item.querySelector('.itemSelectionPanel'); - if (!itemSelectionPanel) { + elems = document.querySelectorAll('.item-multiselected'); - itemSelectionPanel = document.createElement('div'); - itemSelectionPanel.classList.add('itemSelectionPanel'); + for (i = 0, length = elems.length; i < length; i++) { - var parent = item.querySelector('.cardBox') || item.querySelector('.cardContent'); - parent.classList.add('withMultiSelect'); - parent.appendChild(itemSelectionPanel); - - var cssClass = 'chkItemSelect'; - var checkedAttribute = isChecked ? ' checked' : ''; - itemSelectionPanel.innerHTML = ''; - var chkItemSelect = itemSelectionPanel.querySelector('.chkItemSelect'); - chkItemSelect.addEventListener('change', onSelectionChange); + elems[i].classList.remove('item-multiselected'); + } } } @@ -425,58 +361,101 @@ }); } - function showSelections(initialCard) { + function showSelections(chkItemSelect, selected) { + + if (!chkItemSelect.classList.contains('chkCardSelect')) { + chkItemSelect = chkItemSelect.querySelector('.chkCardSelect'); + } + + if (selected == null) { + selected = chkItemSelect.checked; + } + else { + chkItemSelect.checked = selected; + } + + var id = dom.parentWithAttribute(chkItemSelect, 'data-id').getAttribute('data-id'); + var card = dom.parentWithClass(chkItemSelect, 'card'); - require(['emby-checkbox'], function () { - var cards = document.querySelectorAll('.card'); - for (var i = 0, length = cards.length; i < length; i++) { - showSelection(cards[i], initialCard === cards[i]); + if (selected) { + + card.querySelector('.cardBox').classList.add('item-multiselected'); + + var current = selectedItems.filter(function (i) { + return i === id; + }); + + if (!current.length) { + selectedItems.push(id); + selectedItemsMap[id] = true; + selectedElements.push(chkItemSelect); } + } else { + card.querySelector('.cardBox').classList.remove('item-multiselected'); + + selectedItems = selectedItems.filter(function (i) { + return i !== id; + }); + selectedItemsMap[id] = null; + selectedElements = selectedElements.filter(function (i) { + return i !== chkItemSelect; + }); + } + + var container = dom.parentWithAttribute(chkItemSelect, 'is', 'emby-itemscontainer'); + + if (selectedItems.length) { + container.classList.add('multi-select-active'); + showSelectionCommands(); - updateItemSelection(initialCard, true); - }); - } - function onContainerClick(e) { + var itemSelectionCount = document.querySelector('.itemSelectionCount'); + if (itemSelectionCount) { + itemSelectionCount.innerHTML = selectedItems.length; + } + } else { + hideSelections(); + } - var target = e.target; + } + function onContainerClick(e) { if (selectedItems.length) { + var target = e.target; + var card = dom.parentWithClass(target, 'card'); if (card) { - var itemSelectionPanel = card.querySelector('.itemSelectionPanel'); - if (itemSelectionPanel) { - return onItemSelectionPanelClick(e, itemSelectionPanel); + + var chkItemSelectContainer = dom.parentWithClass(target, 'chkCardSelectContainer'); + if (!chkItemSelectContainer) { + var chkItemSelect = card.querySelector('.chkCardSelect'); + + showSelections(chkItemSelect, !chkItemSelect.checked); + + e.preventDefault(); + e.stopPropagation(); + return false; } } - - e.preventDefault(); - e.stopPropagation(); - return false; } } document.addEventListener('viewbeforehide', hideSelections); - return function (options) { + function MultiSelect(options) { var self = this; + } - var container = options.container; - - if (options.bindOnClick !== false) { - container.addEventListener('click', onContainerClick); - } - - self.showSelections = showSelections; - - self.onContainerClick = onContainerClick; + MultiSelect.prototype.showSelections = showSelections; + MultiSelect.prototype.onContainerClick = onContainerClick; - self.destroy = function () { + MultiSelect.isSelected = function (id) { - container.removeEventListener('click', onContainerClick); - }; + return selectedItemsMap[id]; }; + + return MultiSelect; }); \ No newline at end of file diff --git a/playback/playbackmanager.js b/playback/playbackmanager.js index 2f0c21b5..7a3f5416 100644 --- a/playback/playbackmanager.js +++ b/playback/playbackmanager.js @@ -1921,7 +1921,7 @@ // Setting this to true may cause some incorrect sorting Recursive: false, SortBy: options.shuffle ? 'Random' : 'SortName', - Limit: 1000 + Limit: 5000 }); } else if (firstItem.Type === "MusicGenre") { diff --git a/shortcuts.js b/shortcuts.js index cabc2bf7..7809cf22 100644 --- a/shortcuts.js +++ b/shortcuts.js @@ -1,31 +1,16 @@ define(['appSettings', 'layoutManager', 'playbackManager', 'inputManager', 'connectionManager', 'appRouter', 'globalize', 'loading', 'dom', 'recordingHelper'], function (appSettings, layoutManager, playbackManager, inputManager, connectionManager, appRouter, globalize, loading, dom, recordingHelper) { 'use strict'; - function playAllFromHere(card, serverId, queue) { + function playAllFromHere(card, itemId, serverId, queue) { - var parent = card.parentNode; - var className = card.classList.length ? ('.' + card.classList[0]) : ''; - var cards = parent.querySelectorAll(className + '[data-id]'); - - var ids = []; - - var foundCard = false; - var startIndex; - - for (var i = 0, length = cards.length; i < length; i++) { - if (cards[i] === card) { - foundCard = true; - startIndex = i; - } - if (foundCard || !queue) { - ids.push(cards[i].getAttribute('data-id')); - } - } + var startIndex = parseInt(card.getAttribute('data-index')); var itemsContainer = dom.parentWithClass(card, 'itemsContainer'); if (itemsContainer && itemsContainer.fetchData) { - var queryOptions = queue ? { StartIndex: startIndex } : {}; + var limit = 1000; + var fetchAll = !queue && startIndex < limit; + var queryOptions = fetchAll ? { Limit: limit } : { StartIndex: startIndex, Limit: limit }; return itemsContainer.fetchData(queryOptions).then(function (result) { @@ -37,12 +22,30 @@ define(['appSettings', 'layoutManager', 'playbackManager', 'inputManager', 'conn return playbackManager.play({ items: result.Items || result, - startIndex: startIndex + startIndex: fetchAll ? startIndex : null }); } }); } + var parent = card.parentNode; + var className = card.classList.length ? ('.' + card.classList[0]) : ''; + var cards = parent.querySelectorAll(className + '[data-id]'); + + var ids = []; + + var foundCard = false; + + for (var i = 0, length = cards.length; i < length; i++) { + if (cards[i] === card) { + foundCard = true; + startIndex = i; + } + if (foundCard || !queue) { + ids.push(cards[i].getAttribute('data-id')); + } + } + if (!ids.length) { return; } @@ -330,11 +333,11 @@ define(['appSettings', 'layoutManager', 'playbackManager', 'inputManager', 'conn } else if (action === 'playallfromhere') { - playAllFromHere(card, serverId); + playAllFromHere(card, playableItemId, serverId); } else if (action === 'queueallfromhere') { - playAllFromHere(card, serverId, true); + playAllFromHere(card, playableItemId, serverId, true); } else if (action === 'setplaylistindex') { @@ -539,9 +542,11 @@ define(['appSettings', 'layoutManager', 'playbackManager', 'inputManager', 'conn if (action) { executeAction(card, actionElement, action); - e.preventDefault(); - e.stopPropagation(); - return false; + if (action !== 'multiselect') { + e.preventDefault(); + e.stopPropagation(); + return false; + } } } } @@ -710,18 +715,17 @@ define(['appSettings', 'layoutManager', 'playbackManager', 'inputManager', 'conn }); } - var nameWithPrefix = (item.SortName || item.Name || ''); - var prefix = nameWithPrefix.substring(0, Math.min(3, nameWithPrefix.length)); + var nameWithPrefix = item.SortName; + if (nameWithPrefix) { - if (prefix) { - prefix = prefix.toUpperCase(); - } + var prefix = nameWithPrefix.substring(0, Math.min(3, nameWithPrefix.length)); - if (prefix) { - dataAttributes.push({ - name: 'data-prefix', - value: prefix - }); + if (prefix) { + dataAttributes.push({ + name: 'data-prefix', + value: prefix.toUpperCase() + }); + } } if (item.TimerId) { diff --git a/strings/hu.json b/strings/hu.json index 717fec31..785aacc5 100644 --- a/strings/hu.json +++ b/strings/hu.json @@ -1,310 +1,310 @@ { - "EmbyLoginTerms": "Emby is designed to help you manage your personal media library, such as home videos and photos. Please see our {0}terms of use{1}. The use of any Emby software constitutes acceptance of these terms.", - "MessageUnableToConnectToServer": "We're unable to connect to the selected server right now. Please ensure it is running and try again.", - "EmbyIntroMessage": "With Emby you can easily stream videos, music and photos to smart phones, tablets and other devices from your Emby Server.", + "EmbyLoginTerms": "Az Emby seg\u00edt menedzselni a szem\u00e9lyes m\u00e9diak\u00f6nyvt\u00e1radat, mint a saj\u00e1t vide\u00f3kat, \u00e9s k\u00e9peket. K\u00e9rj\u00fck, n\u00e9zd meg a {0}szolg\u00e1ltat\u00e1si felt\u00e9teleket{1}. Az Emby haszn\u00e1lat\u00e1val elfogadod ezeket a felt\u00e9teleket.", + "MessageUnableToConnectToServer": "Jelenleg nem lehet kapcsol\u00f3dni a kiv\u00e1lasztott szerverhez. K\u00e9rj\u00fck, ellen\u0151rizd, hogy a szerver fut-e, majd pr\u00f3b\u00e1ld \u00fajra.", + "EmbyIntroMessage": "Az Embyvel k\u00f6nnyed\u00e9n streamelhetsz vide\u00f3kat, zen\u00e9ket \u00e9s k\u00e9peket okostelefonra, t\u00e1blag\u00e9pekre \u00e9s m\u00e1s eszk\u00f6z\u00f6kre a szerveredr\u0151l.", "HeaderSignInWithConnect": "Bel\u00e9p\u00e9s Emby Connect seg\u00edts\u00e9g\u00e9vel", - "HeaderWelcomeToEmby": "Welcome to Emby", + "HeaderWelcomeToEmby": "\u00dcdv az Embyben!", "HeaderNewUsers": "\u00daj Felhaszn\u00e1l\u00f3k", - "HeaderPleaseSignIn": "Please Sign In", - "MessageInvalidUser": "Invalid username or password. Please try again.", - "MessageUnlockAppWithPurchaseOrSupporter": "Unlock this feature with a small one-time purchase, or with an active Emby Premiere subscription.", + "HeaderPleaseSignIn": "K\u00e9rlek, jelentkezz be", + "MessageInvalidUser": "\u00c9rv\u00e9nytelen felhaszn\u00e1l\u00f3n\u00e9v \u00e9s jelsz\u00f3. K\u00e9rlek, pr\u00f3b\u00e1ld \u00fajra!", + "MessageUnlockAppWithPurchaseOrSupporter": "Enged\u00e9lyezd ezt a funkci\u00f3t egy egyszeri fizet\u00e9ssel, vagy akt\u00edv Emby Premiere el\u0151fizet\u00e9ssel.", "MessageUnlockAppWithSupporter": "Enged\u00e9lyezd ezt a funkci\u00f3t akt\u00edv Emby Premiere el\u0151fizet\u00e9ssel.", - "MessageToValidateSupporter": "If you have an active Emby Premiere subscription, ensure you've setup Emby Premiere in your Emby Server Dashboard, which you can access by clicking Emby Premiere within the main menu.", - "ValueSpecialEpisodeName": "Special - {0}", - "HeaderSignIn": "Sign In", + "MessageToValidateSupporter": "Ha m\u00e1r rendelkezel akt\u00edv Emby Premier el\u0151fizet\u00e9ssel, ellen\u0151rizd, hogy be\u00e1ll\u00edtottad-e az Emby Premiert a szerver vez\u00e9rl\u0151pultj\u00e1n, amit a f\u0151men\u00fc Emby Premier men\u00fcpontj\u00e1ban \u00e9rhetsz el.", + "ValueSpecialEpisodeName": "K\u00fcl\u00f6nleges - {0}", + "HeaderSignIn": "Bejelentkez\u00e9s", "Share": "Megoszt\u00e1s", "Add": "Hozz\u00e1ad", - "Chapters": "Chapters", - "Password": "Password", + "Chapters": "Jelenetek", + "Password": "Jelsz\u00f3", "LabelPassword": "Jelsz\u00f3:", - "HeaderResetPassword": "Reset Password", - "Submit": "Submit", - "UploadOnlyOnWifi": "Upload only on Wifi", - "LabelPasswordConfirm": "Password (confirm):", - "LabelUsername": "Username:", - "HeaderAddServer": "Add Server", - "LabelEmail": "Email:", - "LabelHost": "Host:", - "LabelHostHelp": "192.168.1.100 or https:\/\/myserver.com", + "HeaderResetPassword": "Jelsz\u00f3 vissza\u00e1ll\u00edt\u00e1s", + "Submit": "Elk\u00fcld", + "UploadOnlyOnWifi": "Felt\u00f6lt\u00e9s csak WiFi-n kereszt\u00fcl", + "LabelPasswordConfirm": "Jelsz\u00f3 (meger\u0151s\u00edt\u00e9s):", + "LabelUsername": "Felhaszn\u00e1l\u00f3n\u00e9v:", + "HeaderAddServer": "Szerver Hozz\u00e1ad\u00e1sa", + "LabelEmail": "E-mail:", + "LabelHost": "Hoszt:", + "LabelHostHelp": "192.168.1.100 vagy https:\/\/myserver.com", "LabelPort": "Port:", - "Disabled": "Disabled", - "Uninstall": "Uninstall", - "NextValue": "Next: {0}", - "HeaderNextItem": "Next Item", - "HeaderPreviousItem": "Previous Item", - "NoTrailersMessage": "No Trailers found. To add Trailers, please install the Trailer plugin from the {0}Emby plugin catalog{1}.", - "UninstallPluginConfirmation": "Are you sure you wish to uninstall this plugin?", - "HeaderUninstallPlugin": "Uninstall Plugin", - "AreYouStillWatching": "Are you still watching?", - "LabelCurrentPassword": "Current password:", - "LabelNewPassword": "New password:", - "LabelNewPasswordConfirm": "New password confirm:", - "HeaderRemovePassword": "Remove Password", + "Disabled": "Letiltva", + "Uninstall": "Elt\u00e1vol\u00edt\u00e1s", + "NextValue": "K\u00f6vetkez\u0151 {0}", + "HeaderNextItem": "K\u00f6vetkez\u0151 elem", + "HeaderPreviousItem": "El\u0151z\u0151 elem", + "NoTrailersMessage": "Nem tal\u00e1lhat\u00f3 el\u0151zetes. El\u0151zetesek hozz\u00e1ad\u00e1s\u00e1hoz k\u00e9rlek, telep\u00edtsd az El\u0151zetesek b\u0151v\u00edtm\u00e9nyt az {0}Emby b\u0151v\u00edtm\u00e9nykatal\u00f3gusb\u00f3l{1}!", + "UninstallPluginConfirmation": "Biztosan elt\u00e1vol\u00edtod ezt a b\u0151v\u00edtm\u00e9nyt?", + "HeaderUninstallPlugin": "B\u0151v\u00edtm\u00e9ny Elt\u00e1vol\u00edt\u00e1sa", + "AreYouStillWatching": "M\u00e9g mindig n\u00e9zed?", + "LabelCurrentPassword": "Jelenlegi jelsz\u00f3:", + "LabelNewPassword": "\u00daj jelsz\u00f3:", + "LabelNewPasswordConfirm": "\u00daj jelsz\u00f3 meger\u0151s\u00edt\u00e9se:", + "HeaderRemovePassword": "Jelsz\u00f3 elt\u00e1vol\u00edt\u00e1sa", "ServerUpdateNeeded": "Ezt az Emby Sertvert friss\u00edteni kell. A leg\u00fajabb verzi\u00f3 let\u00f6lt\u00e9s\u00e9hez k\u00e9rj\u00fck, l\u00e1togass el ide {0}", "LiveTvRequiresUnlock": "A Live TV akt\u00edv Emby Premiere el\u0151fizet\u00e9st ig\u00e9nyel.", - "MessageThankYouForConnectSignUp": "Thank you for signing up for Emby Connect. An email will be sent to your address with instructions on how to confirm your new account. Please confirm the account and then return here to sign in.", - "MessageThankYouForConnectSignUpNoValidation": "Thank you for signing up for Emby Connect! You will now be asked to login with your Emby Connect information.", - "ErrorMessagePasswordNotMatchConfirm": "The password and password confirmation must match.", - "ErrorMessageUsernameInUse": "The username is already in use. Please choose a new name and try again.", - "ErrorMessageEmailInUse": "The email address is already in use. Please enter a new email address and try again, or use the forgot password feature.", - "HeaderUpcomingOnTV": "Upcoming On TV", - "HeaderConnectionFailure": "Connection Failure", - "HeaderConnectToServer": "Connect to Server", - "ConnectToServerManually": "Connect to server manually", + "MessageThankYouForConnectSignUp": "K\u00f6sz\u00f6nj\u00fck, hogy regisztr\u00e1lt\u00e1l az Emby Connecttel. K\u00fcldt\u00fck egy e-mailt a megadott c\u00edmedre az aktiv\u00e1l\u00e1shoz sz\u00fcks\u00e9ges inform\u00e1ci\u00f3kkal. K\u00e9rj\u00fck, igazold vissza az e-mailt, majd itt folytathatod a bel\u00e9p\u00e9st.", + "MessageThankYouForConnectSignUpNoValidation": "K\u00f6sz\u00f6nj\u00fck a regisztr\u00e1ci\u00f3t az Emby Connect-re! Most \u00fajra be kell jelentkezned a megadott adatokkal.", + "ErrorMessagePasswordNotMatchConfirm": "A jelsz\u00f3nak \u00e9s a jelsz\u00f3 meger\u0151s\u00edt\u00e9s\u00e9nek egyeznie kell!", + "ErrorMessageUsernameInUse": "Ez a felhaszn\u00e1l\u00f3n\u00e9v m\u00e1r foglalt. K\u00e9rlek, v\u00e1lassz egy \u00fajat \u00e9s pr\u00f3b\u00e1ld \u00fajra.", + "ErrorMessageEmailInUse": "Ez az e-mail c\u00edm m\u00e1r haszn\u00e1latban van. K\u00e9rlek, pr\u00f3b\u00e1lj meg egy \u00faj c\u00edmmel regisztr\u00e1lni, vagy k\u00e9rj jelsz\u00f3eml\u00e9keztet\u0151t.", + "HeaderUpcomingOnTV": "Hamarosan a TV-ben", + "HeaderConnectionFailure": "Kapcsol\u00f3d\u00e1si hiba", + "HeaderConnectToServer": "Kapcsol\u00f3d\u00e1s a Szerverhez", + "ConnectToServerManually": "Kapcsol\u00f3d\u00e1s a szerverhez manu\u00e1lisan", "LabelEnterConnectUserNameHelp": "Ez a Emby online fi\u00f3kod felhaszn\u00e1l\u00f3neve vagy e-mail c\u00edme", - "HeaderSignInError": "Sign In Error", - "HeaderManualLogin": "Manual Login", - "PasswordResetConfirmation": "Are you sure you wish to reset the password?", - "ContactAdminToResetPassword": "Please contact your system administrator to reset your password.", + "HeaderSignInError": "Bejelentkez\u00e9si hiba", + "HeaderManualLogin": "Manu\u00e1lis bel\u00e9p\u00e9s", + "PasswordResetConfirmation": "Biztosan vissza\u00e1ll\u00edtod a jelszavadat?", + "ContactAdminToResetPassword": "K\u00e9rlek, l\u00e9pj kapcsolatba az adminisztr\u00e1torral a jelsz\u00f3 vissza\u00e1ll\u00edt\u00e1s\u00e1hoz!", "ForgotPasswordInNetworkRequired": "Please try again within your home network to initiate the password reset process.", - "ForgotPasswordFileCreated": "The following file has been created on your server and contains instructions on how to proceed:", - "ForgotPasswordFileExpiration": "The reset pin will expire at {0}.", - "InvalidForgotPasswordPin": "An invalid or expired pin was entered. Please try again.", - "PasswordResetForUsers": "Passwords have been removed for the following users. To login, sign in with a blank password.", - "HeaderForgotPassword": "Forgot Password", - "ForgotPasswordUsernameHelp": "Enter your username, if you remember it.", - "HeaderPasswordReset": "Password Reset", + "ForgotPasswordFileCreated": "Ez a f\u00e1jl l\u00e9trehoz\u00e1sra ker\u00fclt \u00e9s tartalmazza a tov\u00e1bbl\u00e9p\u00e9shez sz\u00fcks\u00e9ges instrukci\u00f3kat:", + "ForgotPasswordFileExpiration": "A vissza\u00e1ll\u00edt\u00f3 PIN ekkor lej\u00e1r: {0}", + "InvalidForgotPasswordPin": "Hib\u00e1s, vagy lej\u00e1rt PIN-t adt\u00e1l meg. K\u00e9rlek, pr\u00f3b\u00e1ld \u00fajra.", + "PasswordResetForUsers": "Ezeknek a felhaszn\u00e1l\u00f3knak t\u00f6r\u00f6lt\u00fck a jelszavukat. A bel\u00e9p\u00e9s \u00fcresen hagyott jelsz\u00f3val lehets\u00e9ges:", + "HeaderForgotPassword": "Elfelejtett jelsz\u00f3", + "ForgotPasswordUsernameHelp": "Add meg a felhaszn\u00e1l\u00f3neved, ha eml\u00e9kszel r\u00e1.", + "HeaderPasswordReset": "Jelsz\u00f3 vissza\u00e1ll\u00edt\u00e1s", "AttributeNew": "\u00daj", "Premiere": "Premiere", - "LabelPinCode": "Pin code:", - "LabelLocalNetworkPinCode": "Local network pin code:", - "LabelLocalNetworkPasswordMode": "Local network sign in mode:", - "RequirePasswordInLocalNetwork": "Require a password on the local network", - "NoPasswordInLocalNetwork": "Don't require a password on the local network", - "PinCodeInLocalNetwork": "Allow a numeric pin code on the local network", - "LocalNetworkPasswordModeHelp": "Select the sign in method for devices on the same local network as your Emby Server.", - "HeaderLocalNetworkAccess": "Local Network Access", + "LabelPinCode": "PIN k\u00f3d:", + "LabelLocalNetworkPinCode": "Helyi h\u00e1l\u00f3zat PIN k\u00f3dja:", + "LabelLocalNetworkPasswordMode": "Helyi h\u00e1l\u00f3zat bejelentkez\u00e9si m\u00f3dja:", + "RequirePasswordInLocalNetwork": "Jelsz\u00f3 haszn\u00e1lata a helyi h\u00e1l\u00f3zaton", + "NoPasswordInLocalNetwork": "Jelsz\u00f3 haszn\u00e1lat\u00e1nak mell\u0151z\u00e9se helyi h\u00e1l\u00f3zaton", + "PinCodeInLocalNetwork": "PIN sz\u00e1mk\u00f3d haszn\u00e1lata a helyi h\u00e1l\u00f3zaton", + "LocalNetworkPasswordModeHelp": "V\u00e1laszd ki a helyi h\u00e1l\u00f3zaton tal\u00e1lhat\u00f3 t\u00f6bbi eszk\u00f6z bejelentkez\u00e9si m\u00f3dj\u00e1t.", + "HeaderLocalNetworkAccess": "Helyi h\u00e1l\u00f3zati c\u00edm", "Live": "\u00c9l\u0151", "Repeat": "Ism\u00e9tl\u00e9s", - "Tracks": "Tracks", - "HeaderCameraUpload": "Camera Upload", - "TrackCount": "{0} Tracks", - "ItemCount": "{0} Items", - "HeaderLatestMusic": "Latest Music", - "HeaderLatestDownloadedVideos": "Latest Downloaded Videos", - "HeaderRecentlyPlayed": "Recently Played", - "HeaderFrequentlyPlayed": "Frequently Played", - "HeaderMoreLikeThis": "More Like This", - "HeaderMoreLikeThisOnLiveTV": "More Like This on Live TV", + "Tracks": "S\u00e1vok", + "HeaderCameraUpload": "Kamera Felt\u00f6lt\u00e9s", + "TrackCount": "{0} s\u00e1v", + "ItemCount": "{0} elem", + "HeaderLatestMusic": "Leg\u00fajabb zene", + "HeaderLatestDownloadedVideos": "Leg\u00fajabb let\u00f6lt\u00f6tt vide\u00f3k", + "HeaderRecentlyPlayed": "Nemr\u00e9g j\u00e1tszott", + "HeaderFrequentlyPlayed": "Gyakran j\u00e1tszott", + "HeaderMoreLikeThis": "T\u00f6bb ehhez hasonl\u00f3", + "HeaderMoreLikeThisOnLiveTV": "T\u00f6bb ehhez hasonl\u00f3 az \u00e9l\u0151 TV-ben", "OriginalAirDateValue": "Eredeti vet\u00edt\u00e9s d\u00e1tuma: {0}", "EndsAtValue": "V\u00e1rhat\u00f3 befejez\u00e9s {0}", "HeaderSelectDate": "V\u00e1lassz d\u00e1tumot", "Watched": "Megtekintett", - "AirDate": "Air date", + "AirDate": "Vet\u00edt\u00e9s d\u00e1tuma", "Played": "Megn\u00e9zett", - "Daily": "Daily", - "RequireHashMatch": "Require a hash match", - "RequireHashMatchHelp": "Requiring a hash match will filter subtitles to include only those that have been tested with your exact video file. Unchecking this will increase the number of matched subtitles, but will also increase the chances of mistimed or incorrect subtitle text.", - "SearchForForcedSubtitlesOnly": "Forced subtitles only", + "Daily": "Napi", + "RequireHashMatch": "Hash egyez\u00e9s megk\u00f6vetel\u00e9se", + "RequireHashMatchHelp": "A hash egyez\u00e9s k\u00f6vetel\u00e9s\u00e9vel csak azok a feliratok t\u00f6lt\u0151dnek le, amelyek pontosan ahhoz a videof\u00e1jlhoz tartoznak, amivel te rendelkezel. Ha \u00fcresen hagyod, azzal t\u00f6bb feliratot tal\u00e1lsz, de olyanok is lesznek a list\u00e1n, amelyeknek rossz lehet az id\u0151z\u00edt\u00e9se vagy a sz\u00f6vege.", + "SearchForForcedSubtitlesOnly": "Csak k\u00e9nyszer\u00edtett feliratok", "SearchForForcedSubtitlesOnlyHelp": "Requiring forced subtitles will limit results to subtitles that are tagged as having a foreign language.", "LastEpisodeDateAdded": "Last episode date added", "LabelPlaystate": "Playstate:", - "LabelGenre": "Genre:", - "LabelStudio": "Studio:", - "LabelContainer": "Container:", - "Audio": "Audio", - "Video": "Video", - "Subtitle": "Subtitle", - "Image": "Image", + "LabelGenre": "M\u0171faj:", + "LabelStudio": "St\u00fadi\u00f3:", + "LabelContainer": "T\u00e1rol\u00f3:", + "Audio": "Hang", + "Video": "Vide\u00f3", + "Subtitle": "Felirat", + "Image": "K\u00e9p", "LabelYear": "\u00c9v:", - "LabelAudioCodec": "Audio codec:", - "LabelVideoCodec": "Video codec:", - "LabelSubtitleCodec": "Subtitle codec:", + "LabelAudioCodec": "Audi\u00f3 k\u00f3dek:", + "LabelVideoCodec": "Vide\u00f3 k\u00f3dek:", + "LabelSubtitleCodec": "Felirat k\u00f3dek:", "LabelParentalRating": "Korhat\u00e1r besorol\u00e1s:", - "BecauseYouLikeValue": "Because you like {0}", - "BecauseYouWatchedValue": "Because you watched {0}", - "DirectedByValue": "Directed by {0}", - "StarringValue": "Starring {0}", - "Invitations": "Invitations", - "ActorAsRole": "as {0}", + "BecauseYouLikeValue": "Mert tetszett a(z) {0}", + "BecauseYouWatchedValue": "Mert tetszett a(z) {0}", + "DirectedByValue": "Rendezte: {0}", + "StarringValue": "F\u0151szerepben: {0}", + "Invitations": "Megh\u00edv\u00e1sok", + "ActorAsRole": "mint {0}", "ButtonOk": "Ok", - "GroupItemsIntoCollections": "Group items into collections", - "GroupItemsIntoCollectionsHelp": "Group items based on collections they've been added to. Enabling certain filters or sort orders may automatically disable this.", - "Users": "Users", - "Library": "Library", - "Devices": "Devices", + "GroupItemsIntoCollections": "Filmek csoportos\u00edt\u00e1sa gy\u0171jtem\u00e9nyekbe", + "GroupItemsIntoCollectionsHelp": "Elemek csoportos\u00edt\u00e1sa aszerint, hogy milyen gy\u0171jtem\u00e9nyekhez ker\u00fcltek hozz\u00e1ad\u00e1sra. Tov\u00e1bbi sz\u0171r\u0151k vagy rendez\u00e9sek alkalmaz\u00e1sa automatikusan kikapcsolhatja ezt a funkci\u00f3t.", + "Users": "Felhaszn\u00e1l\u00f3k", + "Library": "K\u00f6nyvt\u00e1r", + "Devices": "Eszk\u00f6z\u00f6k", "Cancel": "M\u00e9gsem", "Restart": "\u00dajraind\u00edt\u00e1s", "Shutdown": "Le\u00e1ll\u00edt\u00e1s", - "Logs": "Logs", - "Notifications": "Notifications", - "Plugins": "Plugins", - "Systems": "Systems", - "Server": "Server", - "Dashboard": "Dashboard", - "PlayOnAnotherDevice": "Play on another device", + "Logs": "Napl\u00f3k", + "Notifications": "\u00c9rtes\u00edt\u00e9sek", + "Plugins": "B\u0151v\u00edtm\u00e9nyek", + "Systems": "Rendszerek", + "Server": "Szerver", + "Dashboard": "Vez\u00e9rl\u0151pult", + "PlayOnAnotherDevice": "Lej\u00e1tsz\u00e1s m\u00e1sik eszk\u00f6z\u00f6n", "HeaderConnectionHelp": "Kapcsolat seg\u00edts\u00e9g", - "AccessRestrictedTryAgainLater": "Access is currently restricted. Please try again later.", + "AccessRestrictedTryAgainLater": "A hozz\u00e1f\u00e9r\u00e9s jelenleg korl\u00e1tozott. Pr\u00f3b\u00e1ld \u00fajra k\u00e9s\u0151bb.", "ButtonGotIt": "\u00c9rtettem", - "RememberMe": "Remember me", - "ManageEmbyServer": "Manage Emby Server", + "RememberMe": "Eml\u00e9kezz r\u00e1m", + "ManageEmbyServer": "Emby szerver kezel\u00e9se", "ShutdownServer": "Emby Server le\u00e1ll\u00edt\u00e1sa", "RestartServer": "Emby Server \u00fajraind\u00edt\u00e1sa", - "RecordingCancelled": "Recording cancelled.", + "RecordingCancelled": "Felv\u00e9tel megszak\u00edtva.", "SeriesCancelled": "Series cancelled.", - "RecordingScheduled": "Recording scheduled.", - "SeriesRecordingScheduled": "Series recording scheduled.", + "RecordingScheduled": "A felv\u00e9tel \u00fctemezve.", + "SeriesRecordingScheduled": "A sorozat felv\u00e9tele \u00fctemezve.", "HeaderNewRecording": "\u00daj Felv\u00e9tel", "HeaderWakeServer": "Kiszolg\u00e1l\u00f3 fel\u00e9breszt\u00e9s", "AttemptingWakeServer": "A kiszolg\u00e1l\u00f3 fel\u00e9breszt\u00e9se folyamatban. K\u00e9rlek v\u00e1rj...", - "WakeServerSuccess": "Success!", + "WakeServerSuccess": "Siker!", "HeaderCustomizeHomeScreen": "Kezd\u0151k\u00e9perny\u0151 testreszab\u00e1sa", - "WakeServerError": "Wake On LAN packets were sent to your server machine, but we're unable to connect to your Emby Server. Your machine may need a little more time to wake, or Emby Server may not be actively running on the machine.", - "Sundays": "Sundays", - "Mondays": "Mondays", - "Tuesdays": "Tuesdays", - "Wednesdays": "Wednesdays", - "Thursdays": "Thursdays", - "Fridays": "Fridays", - "Saturdays": "Saturdays", + "WakeServerError": "A Wake On LAN csomagot elk\u00fcldt\u00fck a szerverg\u00e9pedre, de nem tudtunk kapcsol\u00f3dni az Emby szerverhez. Lehet, hogy az eszk\u00f6znek t\u00f6bb id\u0151re van sz\u00fcks\u00e9ge a bekapcsol\u00e1sra, vagy az Emby Szerver nincs aktiv\u00e1lva a g\u00e9pen.", + "Sundays": "Vas\u00e1rnaponk\u00e9nt", + "Mondays": "H\u00e9tf\u0151nk\u00e9nt", + "Tuesdays": "Keddenk\u00e9nt", + "Wednesdays": "Szerd\u00e1nk\u00e9nt", + "Thursdays": "Cs\u00fct\u00f6rt\u00f6k\u00f6nk\u00e9nt", + "Fridays": "P\u00e9ntekenk\u00e9nt", + "Saturdays": "Szombatonk\u00e9nt", "Days": "Nap", - "Network": "Network", - "Networks": "Networks", + "Network": "H\u00e1l\u00f3zat", + "Networks": "Csatorn\u00e1k", "SortByValue": "Rendezve: {0}", "LabelSortBy": "Rendez\u00e9s:", "LabelSortOrder": "Sorrend:", - "HeaderPhotoAlbums": "Photo Albums", + "HeaderPhotoAlbums": "F\u00e9nyk\u00e9p albumok", "Photos": "F\u00e9nyk\u00e9pek", "HeaderAppearsOn": "Appears On", - "List": "List", - "HeaderRecordSeries": "Record Series", - "HeaderCinemaMode": "Cinema Mode", + "List": "Lista", + "HeaderRecordSeries": "Sorozat felv\u00e9tele", + "HeaderCinemaMode": "Mozi el\u0151zetesek", "HeaderCloudSync": "Felh\u0151szinkroniz\u00e1ci\u00f3 ", "Conversions": "Conversions", "Downloads": "Let\u00f6lt\u00e9sek", - "InternalStorage": "Internal storage", - "ExternalStorage": "External storage", - "UploadToFollowingServers": "Upload to Servers", - "UploadingNumItems": "Uploading {0} of {1}", - "HeaderSampleRate": "Sample Rate", + "InternalStorage": "Bels\u0151 t\u00e1rhely", + "ExternalStorage": "K\u00fcls\u0151 t\u00e1rhely", + "UploadToFollowingServers": "Felt\u00f6lt\u00e9s szerverekre", + "UploadingNumItems": "{0} \/ {1} f\u00e1jl felt\u00f6lt\u00e9se", + "HeaderSampleRate": "Mintav\u00e9teli r\u00e1ta", "HeaderReferenceFrames": "Reference Frames", - "HeaderBitDepth": "Bit Depth", - "HeaderPixelFormat": "Pixel Format", - "Profile": "Profile", - "Bitrate": "Bitrate", - "Container": "Container", - "Format": "Format", - "Path": "Path", - "Size": "Size", - "Resolution": "Resolution", - "HeaderCodecTag": "Codec Tag", - "Framerate": "Framerate", + "HeaderBitDepth": "Bits\u0171r\u0171s\u00e9g", + "HeaderPixelFormat": "Pixelform\u00e1tum", + "Profile": "Profil", + "Bitrate": "Bitr\u00e1ta", + "Container": "T\u00e1rol\u00f3", + "Format": "Form\u00e1tum", + "Path": "\u00datvonal", + "Size": "M\u00e9ret", + "Resolution": "Felbont\u00e1s", + "HeaderCodecTag": "K\u00f3dek c\u00edmke", + "Framerate": "K\u00e9psebess\u00e9g", "Interlaced": "Interlaced", "Anamorphic": "Anamorphic", - "Level": "Level", - "Timestamp": "Timestamp", - "Language": "Language", - "Codec": "Codec", - "HeaderExtradata": "Extra Data", + "Level": "Szint", + "Timestamp": "Id\u0151b\u00e9lyeg", + "Language": "Nyelv", + "Codec": "K\u00f3dek", + "HeaderExtradata": "Extra adat", "HeaderOfflineDownloads": "Offline M\u00e9dia", - "HeaderOfflineDownloadsDescription": "Download media to your devices for easy offline use.", - "CloudSyncFeatureDescription": "Sync your media to the cloud for easy backup, archiving, and converting.", - "LiveTvFeatureDescription": "Stream Live TV to any Emby app, with a compatible TV tuner device installed on your Emby Server.", - "DvrFeatureDescription": "Schedule individual Live TV recordings, series recordings, and more with Emby DVR.", - "CinemaModeFeatureDescription": "A Cinema Mode igazi mozi \u00e9lm\u00e9nyt ny\u00fajt el\u0151zetessel \u00e9s egyedi intr\u00f3val a film vet\u00edt\u00e9se el\u0151tt.", + "HeaderOfflineDownloadsDescription": "M\u00e9dia let\u00f6lt\u00e9se az eszk\u00f6z\u00f6dre offline haszn\u00e1lathoz.", + "CloudSyncFeatureDescription": "M\u00e9dia szinkroniz\u00e1l\u00e1sa a felh\u0151be biztons\u00e1gi ment\u00e9s, archiv\u00e1l\u00e1s vagy konvert\u00e1l\u00e1s c\u00e9lj\u00e1b\u00f3l.", + "LiveTvFeatureDescription": "Streamelj \u00e9l\u0151 TV ad\u00e1sokat egy Emby alkalmaz\u00e1sba. Ehhez egy olyan Emby szerver sz\u00fcks\u00e9ges, ami rendelkezik kompatibilis TV tunerrel.", + "DvrFeatureDescription": "Id\u0151z\u00edts \u00e9l\u0151 TV felv\u00e9teleket egyedileg, sorozatfelv\u00e9teleket, \u00e9s m\u00e9g sok m\u00e1st az Emby DVR-ral.", + "CinemaModeFeatureDescription": "A Mozi el\u0151zetes m\u00f3d igazi mozi \u00e9lm\u00e9nyt ny\u00fajt el\u0151zetessel \u00e9s egyedi intr\u00f3val a film vet\u00edt\u00e9se el\u0151tt.", "HeaderFreeApps": "Ingyenes Emby alkalmaz\u00e1sok", - "FreeAppsFeatureDescription": "Enjoy free access to Emby apps for your devices.", + "FreeAppsFeatureDescription": "\u00c9lvezz ingyenes hozz\u00e1f\u00e9r\u00e9st az Emby alkalmaz\u00e1sokhoz.", "HeaderBecomeProjectSupporter": "Emby Premiere beszerz\u00e9se", "LabelEmailAddress": "E-mail c\u00edm:", - "PromoConvertRecordingsToStreamingFormat": "Automatically convert recordings to a streaming friendly format with Emby Premiere. Recordings will be converted on the fly to MP4 or MKV, based on Emby server settings.", - "FeatureRequiresEmbyPremiere": "Ez a szolg\u00e1ltat\u00e1s akt\u00edv Emby Premier el\u0151fizet\u00e9st ig\u00e9nyel.", - "HeaderConvertYourRecordings": "Convert Your Recordings", + "PromoConvertRecordingsToStreamingFormat": "Automatikusan konvert\u00e1ld \u00e1t a felv\u00e9teleket bar\u00e1ts\u00e1gosabb form\u00e1tumokba az Emby Premierrel. A felv\u00e9telek automatikusan MP4 vagy MKV form\u00e1tumokra lesznek konvert\u00e1lva az Emby be\u00e1ll\u00edt\u00e1sai alapj\u00e1n.", + "FeatureRequiresEmbyPremiere": "Ez a szolg\u00e1ltat\u00e1s akt\u00edv {0}Emby Premier{1} el\u0151fizet\u00e9st ig\u00e9nyel.", + "HeaderConvertYourRecordings": "Felv\u00e9telek konvert\u00e1l\u00e1sa", "Record": "Felv\u00e9tel", "Save": "Ment\u00e9s", "Edit": "Szerkeszt\u00e9s", - "HeaderSavePlaylist": "Save Playlist", - "Latest": "Latest", + "HeaderSavePlaylist": "Lej\u00e1tsz\u00e1si lista ment\u00e9se", + "Latest": "Leg\u00fajabb", "Download": "Let\u00f6lt\u00e9s", "Downloaded": "Let\u00f6lt\u00f6tt", "Downloading": "Let\u00f6lt\u00e9s", "Advanced": "Halad\u00f3", - "LinkedToEmbyConnect": "Linked to Emby Connect", + "LinkedToEmbyConnect": "Kapcsol\u00f3dva az Emby Connect-hez", "Delete": "T\u00f6rl\u00e9s", - "HeaderDeleteServer": "Delete Server", - "HeaderDeleteItem": "Delete Item", - "HeaderDeleteUser": "Delete User", - "DeleteServerConfirmation": "Are you sure you wish to delete this server?", - "DeleteUserConfirmation": "Are you sure you wish to delete user {0}?", - "HeaderDeleteDevice": "Delete Device", - "DeleteDeviceConfirmation": "Are you sure you wish to delete this device? It will reappear the next time a user signs in with it.", - "ConfirmDeleteItem": "Deleting this item will delete it from both the file system and your media library.", - "FollowingFilesWillBeDeleted": "The following files and folders will be deleted:", - "AreYouSureToContinue": "Are you sure you wish to continue?", + "HeaderDeleteServer": "Szerver t\u00f6rl\u00e9se", + "HeaderDeleteItem": "Elem t\u00f6rl\u00e9se", + "HeaderDeleteUser": "Felhaszn\u00e1l\u00f3 t\u00f6rl\u00e9se", + "DeleteServerConfirmation": "Biztosan elt\u00e1vol\u00edtod ezt a szervert?", + "DeleteUserConfirmation": "Biztosan t\u00f6rl\u00f6d {0} felhaszn\u00e1l\u00f3t?", + "HeaderDeleteDevice": "Eszk\u00f6z t\u00f6rl\u00e9se", + "DeleteDeviceConfirmation": "Biztosan elt\u00e1vol\u00edtod ezt az eszk\u00f6zt? \u00dajra meg fog jelenni, amikor legk\u00f6zelebb egy felhaszn\u00e1l\u00f3 bejelentkezik r\u00f3la.", + "ConfirmDeleteItem": "Az elem t\u00f6rl\u00e9s\u00e9vel elt\u00e1vol\u00edtod azt a k\u00f6nyvt\u00e1radb\u00f3l \u00e9s a f\u00e1jlrendszerb\u0151l is.", + "FollowingFilesWillBeDeleted": "A k\u00f6vetkez\u0151 f\u00e1jlok \u00e9s k\u00f6nyvt\u00e1rak t\u00f6rl\u00e9sre ker\u00fclnek:", + "AreYouSureToContinue": "Biztosan folytatni szeretn\u00e9d?", "Refresh": "Friss\u00edt\u00e9s", - "RefreshQueued": "Refresh queued.", + "RefreshQueued": "Friss\u00edt\u00e9s sorba\u00e1ll\u00edtva.", "AddToCollection": "Hozz\u00e1ad\u00e1s gy\u0171jtem\u00e9nyhez", "HeaderAddToCollection": "Hozz\u00e1ad\u00e1s gy\u0171jtem\u00e9nyhez", - "HeaderNewCollection": "New Collection", - "HeaderNewPlaylist": "New Playlist", - "Create": "Create", - "AddedToValue": "Added to {0}.", - "AddedToPlayQueue": "Added to play queue.", + "HeaderNewCollection": "\u00daj Gy\u0171jtem\u00e9ny", + "HeaderNewPlaylist": "\u00daj lej\u00e1tsz\u00e1si lista", + "Create": "L\u00e9trehoz\u00e1s", + "AddedToValue": "Hozz\u00e1adva ehhez: {0}.", + "AddedToPlayQueue": "Hozz\u00e1adva a lej\u00e1tsz\u00e1si list\u00e1hoz.", "LabelCollection": "Gy\u0171jtem\u00e9ny:", "Help": "Seg\u00edts\u00e9g", - "LabelDisplayMode": "Display mode:", - "Desktop": "Desktop", - "Mobile": "Mobile \/ Tablet", + "LabelDisplayMode": "Megjelen\u00edt\u00e9si m\u00f3d:", + "Desktop": "Asztal", + "Mobile": "Mobil \/ t\u00e1blag\u00e9p", "TV": "TV", "HeaderEmbyConnect": "Emby Connect", - "Seasons": "Seasons", - "OneTrack": "1 Track", - "OneSeason": "1 Season", - "Libraries": "Libraries", - "NumberSeasonsValue": "{0} Seasons", - "DisplayModeHelp": "Select the type of screen you're running Emby on.", - "LabelDisplayLanguage": "Display language:", - "LabelDisplayLanguageHelp": "Translating Emby is an ongoing project.", - "LearnHowYouCanContribute": "Learn how you can contribute.", - "NewCollectionHelp": "Collections allow you to create personalized groupings of movies and other library content.", - "SearchForCollectionInternetMetadata": "Search the internet for artwork and metadata", + "Seasons": "\u00c9vadok", + "OneTrack": "1 s\u00e1v", + "OneSeason": "1 \u00e9vad", + "Libraries": "K\u00f6nyvt\u00e1rak", + "NumberSeasonsValue": "{0} \u00e9vad", + "DisplayModeHelp": "V\u00e1laszd ki, hogy milyen k\u00e9perny\u0151n n\u00e9zed \u00e9ppen az Embyt.", + "LabelDisplayLanguage": "Megjelen\u00edt\u00e9si nyelv:", + "LabelDisplayLanguageHelp": "Az Emby ford\u00edt\u00e1sa egy folyamatban l\u00e9v\u0151 project.", + "LearnHowYouCanContribute": "\u00cdgy j\u00e1rulhatsz hozz\u00e1 a ford\u00edt\u00e1shoz.", + "NewCollectionHelp": "A gy\u0171jtem\u00e9nyek seg\u00edts\u00e9g\u00e9vel szem\u00e9lyre szabott csoportos\u00edt\u00e1sokat hozhatsz l\u00e9tre a filmekb\u0151l \u00e9s m\u00e1s tartalmakb\u00f3l.", + "SearchForCollectionInternetMetadata": "Keress k\u00e9peket \u00e9s metaadatokat az interneten", "DisplayMissingEpisodesWithinSeasons": "Hi\u00e1nyz\u00f3 \u00e9vad epiz\u00f3dok megjelen\u00edt\u00e9se", "DisplayMissingEpisodesWithinSeasonsHelp": "Ezt enged\u00e9lyezni kell az Emby Server be\u00e1ll\u00edt\u00e1sban l\u00e9v\u0151 TV k\u00f6nyvt\u00e1rak eset\u00e9ben is.", "EnableThemeSongs": "F\u0151c\u00edm dalok enged\u00e9lyez\u00e9se", "EnableBackdrops": "H\u00e1tt\u00e9rk\u00e9pek enged\u00e9lyezve", "EnableThemeSongsHelp": "Ha enged\u00e9lyezve van, a f\u0151c\u00edm dalok a h\u00e1tt\u00e9rben j\u00e1tsz\u00f3dnak le a k\u00f6nyvt\u00e1r b\u00f6ng\u00e9sz\u00e9se k\u00f6zben.", "EnableBackdropsHelp": "Ha enged\u00e9lyezve van, akkor a h\u00e1tt\u00e9rk\u00e9pek a k\u00f6nyvt\u00e1r b\u00f6ng\u00e9sz\u00e9se k\u00f6zben n\u00e9h\u00e1ny oldal h\u00e1tter\u00e9ben jelennek meg.", - "EnableThemeVideos": "Enable theme videos", - "EnableThemeVideosHelp": "If enabled, theme videos will be played in the background while browsing the library.", - "RunAtStartup": "Run at startup", - "LabelScreensaver": "Screensaver:", - "LabelSoundEffects": "Sound effects:", - "LabelSkin": "Skin:", + "EnableThemeVideos": "H\u00e1tt\u00e9rvide\u00f3k enged\u00e9lyez\u00e9se", + "EnableThemeVideosHelp": "Ha enged\u00e9lyezve van, a vide\u00f3k a h\u00e1tt\u00e9rben j\u00e1tsz\u00f3dnak le a k\u00f6nyvt\u00e1r b\u00f6ng\u00e9sz\u00e9se k\u00f6zben.", + "RunAtStartup": "Futtat\u00e1s a rendszer ind\u00edt\u00e1sakor", + "LabelScreensaver": "K\u00e9perny\u0151v\u00e9d\u0151:", + "LabelSoundEffects": "Hangeffekt:", + "LabelSkin": "Kin\u00e9zet:", "LabelName": "N\u00e9v:", "NewCollectionNameExample": "P\u00e9ld\u00e1ul: Star Wars Gy\u0171jtem\u00e9ny", - "MessageItemsAdded": "Items added.", + "MessageItemsAdded": "Elemek hozz\u00e1adva", "OptionNew": "\u00daj...", "LabelPlaylist": "Lej\u00e1tsz\u00e1si lista:", "AddToPlaylist": "Lej\u00e1tsz\u00e1si list\u00e1hoz adni", "HeaderAddToPlaylist": "Lej\u00e1tsz\u00e1si list\u00e1hoz adni", "Subtitles": "Feliratok", "LabelTheme": "Kin\u00e9zet:", - "LabelSettingsTheme": "Settings theme:", + "LabelSettingsTheme": "Be\u00e1ll\u00edt\u00e1sok t\u00e9m\u00e1ja:", "SearchForSubtitles": "Felirat keres\u00e9se", "LabelLanguage": "Nyelv:", "Search": "Keres\u00e9s", "NoSubtitleSearchResultsFound": "Nincs tal\u00e1lat.", "File": "File", - "Exit": "Exit", - "Sleep": "Sleep", - "MessageAreYouSureDeleteSubtitles": "Are you sure you wish to delete this subtitle file?", - "ConfirmDeletion": "Confirm Deletion", + "Exit": "Kil\u00e9p\u00e9s", + "Sleep": "Alv\u00e1s", + "MessageAreYouSureDeleteSubtitles": "Biztosan elt\u00e1vol\u00edtod ezt a feliratot?", + "ConfirmDeletion": "T\u00f6rl\u00e9s meger\u0151s\u00edt\u00e9se", "MySubtitles": "Feliratok", - "MessageDownloadQueued": "Download queued.", - "HeaderEditSubtitles": "Edit Subtitles", + "MessageDownloadQueued": "Let\u00f6lt\u00e9s sorba\u00e1ll\u00edtva.", + "HeaderEditSubtitles": "Feliratok szerkeszt\u00e9se", "UnlockGuide": "Unlock Guide", - "HeaderRefreshMetadata": "Refresh Metadata", - "HeaderRefreshAllMetadata": "Refresh All Metadata", + "HeaderRefreshMetadata": "Metaadat friss\u00edt\u00e9se", + "HeaderRefreshAllMetadata": "Minden metaadat friss\u00edt\u00e9se", "ReplaceExistingImages": "Cser\u00e9lje ki a megl\u00e9v\u0151 k\u00e9peket", "ReplaceAllMetadata": "\u00d6sszes metaadat cser\u00e9je", "SearchForMissingMetadata": "Keres\u00e9s a hi\u00e1nyz\u00f3 metaadatokra", "LabelRefreshMode": "Friss\u00edt\u00e9si m\u00f3d:", - "NoItemsFound": "No items found.", - "HeaderSaySomethingLike": "Say Something Like...", - "ButtonTryAgain": "Try Again", - "HeaderYouSaid": "You Said...", - "MessageWeDidntRecognizeCommand": "We're sorry, we didn't recognize that command.", - "MessageIfYouBlockedVoice": "If you denied voice access to the app you'll need to reconfigure before trying again.", - "ValueDiscNumber": "Disc {0}", + "NoItemsFound": "Nincs tal\u00e1lat.", + "HeaderSaySomethingLike": "Mondj valamit, mint...", + "ButtonTryAgain": "\u00dajrapr\u00f3b\u00e1lkoz\u00e1s", + "HeaderYouSaid": "Azt mondtad...", + "MessageWeDidntRecognizeCommand": "Sajn\u00e1ljuk, de nem ismert\u00fck fel ezt a parancsot.", + "MessageIfYouBlockedVoice": "Ha megtagadtad a hanghoz val\u00f3 hozz\u00e1f\u00e9r\u00e9st, \u00fajra kell konfigur\u00e1lnod az alkalmaz\u00e1st miel\u0151tt \u00fajra megpr\u00f3b\u00e1lod.", + "ValueDiscNumber": "{0} lemez", "Unrated": "Unrated", "Favorite": "Kedvenc", "Like": "Tettszik", @@ -328,8 +328,8 @@ "PictureInPicture": "Picture in picture", "Fullscreen": "Full screen", "ExitFullscreen": "Exit full screen", - "Rewind": "Rewind", - "FastForward": "Fast-forward", + "Rewind": "Ugr\u00e1s vissza", + "FastForward": "Ugr\u00e1s el\u0151re", "Remove": "Remove", "Rename": "Rename", "Queue": "Queue", @@ -404,10 +404,10 @@ "Genres": "M\u0171fajok", "Studios": "St\u00fadi\u00f3k", "Tags": "C\u00edmk\u00e9k", - "Links": "Links", + "Links": "Hivatkoz\u00e1sok", "HeaderMetadataSettings": "Metaadat Be\u00e1ll\u00edt\u00e1sok", "People": "Szem\u00e9lyek", - "LabelMetadataDownloadLanguage": "Els\u0151dleges let\u00f6ltend\u0151 nyelv:", + "LabelMetadataDownloadLanguage": "Els\u0151dleges metaadat let\u00f6lt\u00e9si nyelv:", "LabelImageDownloadLanguage": "Preferred image download language:", "LabelLockItemToPreventChanges": "Lock this item to prevent future changes", "MessageLeaveEmptyToInherit": "Leave empty to inherit settings from a parent item, or the global default value.", @@ -520,8 +520,8 @@ "Episodes": "Epiz\u00f3dok", "HDPrograms": "HD\/4K programs", "Programs": "Programs", - "HeaderCastCrew": "Cast & Crew", - "LiveBroadcasts": "Live broadcasts", + "HeaderCastCrew": "Szerepl\u0151k \u00e9s St\u00e1b", + "LiveBroadcasts": "\u00c9l\u0151 k\u00f6zvet\u00edt\u00e9sek", "Premieres": "Premieres", "RepeatEpisodes": "Repeat episodes", "DvrSubscriptionRequired": "Emby Live TV & DVR require an active {0}Emby Premiere subscription{1}.", @@ -565,7 +565,7 @@ "Movies": "Filmek", "Music": "Zene", "Kids": "Kids", - "MoreFromValue": "More from {0}", + "MoreFromValue": "M\u00e9g t\u00f6bb innen: {0}", "BirthPlaceValue": "Birth place: {0}", "DiedValue": "Died: {0}", "BornValue": "Born: {0}", @@ -579,7 +579,7 @@ "HowDidYouPay": "How did you pay?", "IHaveEmbyPremiere": "I have Emby Premiere", "IPurchasedThisApp": "I purchased this app", - "ButtonRestorePreviousPurchase": "Restore Purchase", + "ButtonRestorePreviousPurchase": "V\u00e1s\u00e1rl\u00e1s vissza\u00e1ll\u00edt\u00e1sa", "ButtonUnlockWithPurchase": "Unlock with Purchase", "ButtonUnlockPrice": "Unlock {0}", "EmbyPremiereMonthlyWithPrice": "Emby Premiere Monthly {0}", @@ -587,7 +587,7 @@ "ButtonPlayOneMinute": "Egy perc lej\u00e1tsz\u00e1sa", "PlaceFavoriteChannelsAtBeginning": "Place favorite channels at the beginning", "HeaderUnlockFeature": "Funkci\u00f3 felold\u00e1sa", - "MessageDidYouKnowCinemaMode": "Tudtad, hogy az Emby Premiere-t haszn\u00e1lva olyan funkci\u00f3kkal fokozhatod az \u00e9lm\u00e9nyeket, mint a Cinema Mode?", + "MessageDidYouKnowCinemaMode": "Tudtad, hogy az Emby Premiere-t haszn\u00e1lva olyan funkci\u00f3kkal fokozhatod az \u00e9lm\u00e9nyeket, mint a mozi el\u0151zetesek?", "HeaderPlayMyMedia": "Play my Media", "HeaderDiscoverEmbyPremiere": "Fedezd fel az Emby Premiere-t", "HeaderNowPlaying": "Now Playing", @@ -612,14 +612,14 @@ "Retry": "Retry", "Continue": "Tov\u00e1bb", "ContinueInSecondsValue": "Tov\u00e1bb {0} mp m\u00falva.", - "HeaderRemoteControl": "Remote Control", + "HeaderRemoteControl": "T\u00e1vir\u00e1ny\u00edt\u00e1s", "Disconnect": "Disconnect", "EnableDisplayMirroring": "Enable display mirroring", "HeaderPlayOn": "Vet\u00edt\u00e9s itt", "Quality": "Min\u0151s\u00e9g", "Auto": "Automatikus", "AndroidUnlockRestoreHelp": "To restore your previous purchase, please ensure you're signed into the device with the same Google (or Amazon) account that originally made the purchase. Make sure the app store is enabled and not restricted by any parental controls, and ensure you have an active internet connection. You'll only have to do this once to restore your previous purchase.", - "HeaderAspectRatio": "Aspect Ratio", + "HeaderAspectRatio": "K\u00e9par\u00e1ny", "Original": "Original", "Fill": "Fill", "Cover": "Cover", @@ -640,15 +640,15 @@ "HeaderActiveRecordings": "Active Recordings", "HeaderLatestRecordings": "Latest Recordings", "LabelConvertTo": "Convert to:", - "LabelDownloadTo": "Download to:", - "HeaderDownloadToDots": "Download to...", - "Next": "Next", + "LabelDownloadTo": "Let\u00f6lt\u00e9s ide:", + "HeaderDownloadToDots": "Let\u00f6lt\u00e9s ide...", + "Next": "K\u00f6vetkez\u0151", "LabelSource": "Forr\u00e1s:", "LabelVersion": "Version:", "AllLanguages": "\u00d6sszes nyelv", - "Previous": "Previous", + "Previous": "El\u0151z\u0151", "HeaderNextUp": "K\u00f6vetkezik", - "HeaderPlayNextUp": "Play Next Up", + "HeaderPlayNextUp": "K\u00f6vetkez\u0151 epiz\u00f3d", "HeaderLatestFrom": "Leg\u00fajabb innen {0}", "LabelHomeScreenSectionValue": "Kezd\u0151k\u00e9perny\u0151 blokk {0}:", "PasswordResetComplete": "The password has been reset.", @@ -661,7 +661,7 @@ "Down": "Le", "Home": "Kezd\u0151lap", "Back": "Back", - "Playback": "Playback", + "Playback": "Lej\u00e1tsz\u00e1s", "Favorites": "Kedvencek", "HeaderHomeScreen": "Kezd\u0151k\u00e9perny\u0151", "HeaderLatestChannelItems": "Latest Channel Items", @@ -669,7 +669,7 @@ "HideWatchedContentFromLatestMedia": "A megtekintett tartalom elrejt\u00e9se a leg\u00fajabb m\u00e9di\u00e1b\u00f3l", "HeaderOnNow": "On Now", "HeaderForKids": "For Kids", - "HeaderPlaybackError": "Playback Error", + "HeaderPlaybackError": "Lej\u00e1tsz\u00e1si hiba", "PlaybackErrorNotAllowed": "You're currently not authorized to play this content. Please contact your system administrator for details.", "RateLimitExceeded": "Your account has exceeded the maximum streaming limit set by your Emby Server administrator. Please contact them for assistance.", "PlaybackErrorNoCompatibleStream": "No compatible streams are currently available. Please try again later or contact your system administrator for details.", @@ -686,7 +686,7 @@ "Unmute": "Unmute", "Folders": "Mapp\u00e1k", "DisplayInOtherHomeScreenSections": "Display in secondary home screen sections such as latest media and continue watching", - "DisplayInMyMedia": "Display on home screen", + "DisplayInMyMedia": "Megjelen\u00edt\u00e9s a kezd\u0151k\u00e9perny\u0151n", "Shows": "Shows", "HeaderMusicVideos": "Zenei Vide\u00f3k", "MusicVideos": "Zenei Vide\u00f3k", @@ -699,7 +699,7 @@ "HeaderTermsOfPurchase": "Terms of Purchase", "PrivacyPolicy": "Privacy policy", "TermsOfUse": "Terms of use", - "HeaderRepeatMode": "Repeat Mode", + "HeaderRepeatMode": "Ism\u00e9tl\u00e9si m\u00f3d", "RepeatOne": "Ism\u00e9tl\u00e9s egyszer", "RepeatAll": "Folyamatos ism\u00e9tl\u00e9s ", "LabelDefaultScreen": "Default screen:", @@ -707,7 +707,7 @@ "Yesterday": "Yesterday", "Yes": "Yes", "No": "No", - "HeaderScanLibraryFiles": "Scan Library Files", + "HeaderScanLibraryFiles": "K\u00f6nyvt\u00e1r f\u00e1jljainak beolvas\u00e1sa", "LiveTV": "Live TV", "Schedule": "Schedule", "Recordings": "Recordings", @@ -761,12 +761,12 @@ "CreatePinErrorMessage": "An error occurred while creating a pin code. Please click Generate New Pin to try again.", "PinExpiredMessage": "The pin code has expired. Please click Generate New Pin to try again.", "ConnectPinCodeHeader": "To sign in with Emby Connect, use a mobile device or computer to visit {0} and enter the following pin code:", - "LabelSubtitlePlaybackMode": "Subtitle mode:", + "LabelSubtitlePlaybackMode": "Felirat m\u00f3d:", "ErrorDeletingItem": "There was an error deleting the item from Emby Server. Please check that Emby Server has write access to the media folder and try again.", "NoSubtitles": "No subtitles", "Default": "Default", "Absolute": "Absolute", - "Smart": "Smart", + "Smart": "Okos", "Small": "Small", "Smaller": "Smaller", "Medium": "Medium", @@ -811,11 +811,11 @@ "HeaderDownloadSettings": "Let\u00f6lt\u00e9s be\u00e1ll\u00edt\u00e1sok", "LabelDownloadLocation": "Download location:", "BrowseForFolder": "BrowseForFolder", - "Unlimited": "Unlimited", - "Hide": "Hide", - "HeaderStartNow": "Start Now", - "HeaderNextVideoPlayingInValue": "Next Video Playing in {0}", - "HeaderNextEpisodePlayingInValue": "Next Episode Playing in {0}", + "Unlimited": "Korl\u00e1tlan", + "Hide": "Elrejt", + "HeaderStartNow": "Ind\u00edt\u00e1s most", + "HeaderNextVideoPlayingInValue": "A k\u00f6vetkez\u0151 vide\u00f3 {0} m\u00falva indul", + "HeaderNextEpisodePlayingInValue": "A k\u00f6vetkez\u0151 epiz\u00f3d {0} m\u00falva indul", "HeaderSecondsValue": "{0} Seconds", "AudioBitDepthNotSupported": "Audio bit depth not supported", "VideoProfileNotSupported": "Vide\u00f3 profil nem t\u00e1mogatott", @@ -850,9 +850,9 @@ "LabelPlayDefaultAudioTrack": "Play default audio track regardless of language", "HeaderVideoQuality": "Video Quality", "CinemaModeConfigurationHelp": "Cinema Intros bring the theater experience straight to your living room with the ability to play trailers and custom intros before the main feature.", - "EnableNextVideoInfoOverlay": "Enable next video info during playback", - "EnableNextVideoInfoOverlayHelp": "At the end of a video, display info about the next video coming up in the current playlist.", - "PlayNextEpisodeAutomatically": "Play next episode automatically", + "EnableNextVideoInfoOverlay": "A k\u00f6vetkez\u0151 vide\u00f3 inform\u00e1ci\u00f3j\u00e1nak megjelen\u00edt\u00e9se lej\u00e1tsz\u00e1s k\u00f6zben", + "EnableNextVideoInfoOverlayHelp": "A vide\u00f3 v\u00e9g\u00e9n jelen\u00edtse meg az aktu\u00e1lis lej\u00e1tsz\u00e1si list\u00e1n megjelen\u0151 k\u00f6vetkez\u0151 vide\u00f3 adatait.", + "PlayNextEpisodeAutomatically": "K\u00f6vetkez\u0151 epiz\u00f3d automatikus lej\u00e1tsz\u00e1sa ", "LabelMaxChromecastBitrate": "Chromecast streaming quality:", "LabelSkipBackLength": "Skip back length:", "LabelSkipForwardLength": "Skip forward length:", @@ -863,7 +863,7 @@ "HeaderLatestMedia": "Leg\u00fajabb m\u00e9dia", "HeaderRestartingEmbyServer": "Emby Server \u00fajraind\u00edt\u00e1sa", "RestartPleaseWaitMessage": "K\u00e9rlek v\u00e1rj, am\u00edg az Emby Server le\u00e1ll \u00e9s \u00fajraindul. \nEz ak\u00e1r egy-k\u00e9t percig is eltarthat.", - "HeaderPlayNext": "Play Next", + "HeaderPlayNext": "K\u00f6vetkez\u0151 lej\u00e1tsz\u00e1sa", "AllowSeasonalThemes": "Allow automatic seasonal themes", "AllowSeasonalThemesHelp": "If enabled, seasonal themes will occasionally override your theme setting.", "AutoBasedOnLanguageSetting": "Automatikus (a nyelvi be\u00e1ll\u00edt\u00e1sok alapj\u00e1n)", @@ -921,7 +921,7 @@ "HardwareAccelerated": "Hardware accelerated", "Software": "Software", "Metadata": "Metadata", - "HeaderMediaInfo": "Media Info", + "HeaderMediaInfo": "M\u00e9dia inform\u00e1ci\u00f3k", "Locked": "Locked", "HeaderSplitVersionsApart": "Split Versions Apart", "Any": "Any", diff --git a/sync/syncjobeditor.js b/sync/syncjobeditor.js index 19768e0f..0f581676 100644 --- a/sync/syncjobeditor.js +++ b/sync/syncjobeditor.js @@ -32,6 +32,7 @@ } var supportsNativeLazyLoading = 'loading' in HTMLImageElement.prototype; + function getJobItemHtml(jobItem, apiClient, index) { var html = ''; diff --git a/sync/syncjoblist.js b/sync/syncjoblist.js index edc4b1a2..67400535 100644 --- a/sync/syncjoblist.js +++ b/sync/syncjoblist.js @@ -97,6 +97,8 @@ } var supportsNativeLazyLoading = 'loading' in HTMLImageElement.prototype; + // unfortunately right now Chrome's lazy loading is too eager and loads too much + supportsNativeLazyLoading = false; function getSyncJobHtml(listInstance, job, apiClient, mode) {