From ea9e79f4d35446d527c49ae9059e240896037980 Mon Sep 17 00:00:00 2001 From: dkanada Date: Sun, 16 Feb 2020 12:17:13 +0900 Subject: [PATCH 001/338] add basic web client configuration --- .gitignore | 584 +--------------------------- src/components/apphost.js | 8 +- src/config.example.json | 3 + src/scripts/settings/webSettings.js | 30 ++ src/scripts/site.js | 1 + 5 files changed, 47 insertions(+), 579 deletions(-) create mode 100644 src/config.example.json create mode 100644 src/scripts/settings/webSettings.js diff --git a/.gitignore b/.gitignore index 2e12adf22..2bb5bc64d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,578 +1,10 @@ +# config +config.json -# Created by https://www.gitignore.io/api/node,rider,macos,linux,windows,visualstudio,visualstudiocode -# Edit at https://www.gitignore.io/?templates=node,rider,macos,linux,windows,visualstudio,visualstudiocode +# npm +dist +node_modules -### Linux ### -*~ - -# temporary files which can be created if a process still has a handle open of a deleted file -.fuse_hidden* - -# KDE directory preferences -.directory - -# Linux trash folder which might appear on any partition or disk -.Trash-* - -# .nfs files are created when an open file is removed but is still being accessed -.nfs* - -### macOS ### -# General -.DS_Store -.AppleDouble -.LSOverride - -# Icon must end with two \r -Icon - -# Thumbnails -._* - -# Files that might appear in the root of a volume -.DocumentRevisions-V100 -.fseventsd -.Spotlight-V100 -.TemporaryItems -.Trashes -.VolumeIcon.icns -.com.apple.timemachine.donotpresent - -# Directories potentially created on remote AFP share -.AppleDB -.AppleDesktop -Network Trash Folder -Temporary Items -.apdisk - -### Node ### -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* - -# Runtime data -pids -*.pid -*.seed -*.pid.lock - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage - -# nyc test coverage -.nyc_output - -# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# node-waf configuration -.lock-wscript - -# Compiled binary addons (https://nodejs.org/api/addons.html) -build/Release - -# Dependency directories -node_modules/ -jspm_packages/ - -# Dependency lockfile -package-lock.json - -# TypeScript v1 declaration files -typings/ - -# Optional npm cache directory -.npm - -# Optional eslint cache -.eslintcache - -# Optional REPL history -.node_repl_history - -# Output of 'npm pack' -*.tgz - -# Yarn Integrity file -.yarn-integrity - -# dotenv environment variables file -.env -.env.test - -# parcel-bundler cache (https://parceljs.org/) -.cache - -# next.js build output -.next - -# nuxt.js build output -.nuxt - -# vuepress build output -.vuepress/dist - -# Serverless directories -.serverless/ - -# FuseBox cache -.fusebox/ - -# DynamoDB Local files -.dynamodb/ - -### Rider ### -# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm -# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 - -# User-specific stuff -.idea/**/workspace.xml -.idea/**/tasks.xml -.idea/**/usage.statistics.xml -.idea/**/dictionaries -.idea/**/shelf - -# Generated files -.idea/**/contentModel.xml - -# Sensitive or high-churn files -.idea/**/dataSources/ -.idea/**/dataSources.ids -.idea/**/dataSources.local.xml -.idea/**/sqlDataSources.xml -.idea/**/dynamic.xml -.idea/**/uiDesigner.xml -.idea/**/dbnavigator.xml - -# Gradle -.idea/**/gradle.xml -.idea/**/libraries - -# Gradle and Maven with auto-import -# When using Gradle or Maven with auto-import, you should exclude module files, -# since they will be recreated, and may cause churn. Uncomment if using -# auto-import. -# .idea/modules.xml -# .idea/*.iml -# .idea/modules - -# CMake -cmake-build-*/ - -# Mongo Explorer plugin -.idea/**/mongoSettings.xml - -# File-based project format -*.iws - -# IntelliJ -out/ - -# mpeltonen/sbt-idea plugin -.idea_modules/ - -# JIRA plugin -atlassian-ide-plugin.xml - -# Cursive Clojure plugin -.idea/replstate.xml - -# Crashlytics plugin (for Android Studio and IntelliJ) -com_crashlytics_export_strings.xml -crashlytics.properties -crashlytics-build.properties -fabric.properties - -# Editor-based Rest Client -.idea/httpRequests - -# Android studio 3.1+ serialized cache file -.idea/caches/build_file_checksums.ser - -### VisualStudioCode ### -.vscode/* -!.vscode/settings.json -!.vscode/tasks.json -!.vscode/launch.json -!.vscode/extensions.json - -### VisualStudioCode Patch ### -# Ignore all local history of files -.history - -### Windows ### -# Windows thumbnail cache files -Thumbs.db -ehthumbs.db -ehthumbs_vista.db - -# Dump file -*.stackdump - -# Folder config file -[Dd]esktop.ini - -# Recycle Bin used on file shares -$RECYCLE.BIN/ - -# Windows Installer files -*.cab -*.msi -*.msix -*.msm -*.msp - -# Windows shortcuts -*.lnk - -### VisualStudio ### -## Ignore Visual Studio temporary files, build results, and -## files generated by popular Visual Studio add-ons. -## -## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore - -# User-specific files -*.rsuser -*.suo -*.user -*.userosscache -*.sln.docstates - -# User-specific files (MonoDevelop/Xamarin Studio) -*.userprefs - -# Build results -[Dd]ebug/ -[Dd]ebugPublic/ -[Rr]elease/ -[Rr]eleases/ -x64/ -x86/ -[Aa][Rr][Mm]/ -[Aa][Rr][Mm]64/ -bld/ -[Bb]in/ -[Oo]bj/ -[Ll]og/ - -# Visual Studio 2015/2017 cache/options directory -.vs/ -# Uncomment if you have tasks that create the project's static files in wwwroot -#wwwroot/ - -# Visual Studio 2017 auto generated files -Generated\ Files/ - -# MSTest test Results -[Tt]est[Rr]esult*/ -[Bb]uild[Ll]og.* - -# NUNIT -*.VisualState.xml -TestResult.xml - -# Build Results of an ATL Project -[Dd]ebugPS/ -[Rr]eleasePS/ -dlldata.c - -# Benchmark Results -BenchmarkDotNet.Artifacts/ - -# .NET Core -project.lock.json -project.fragment.lock.json -artifacts/ - -# StyleCop -StyleCopReport.xml - -# Files built by Visual Studio -*_i.c -*_p.c -*_h.h -*.ilk -*.meta -*.obj -*.iobj -*.pch -*.pdb -*.ipdb -*.pgc -*.pgd -*.rsp -*.sbr -*.tlb -*.tli -*.tlh -*.tmp -*.tmp_proj -*_wpftmp.csproj -*.vspscc -*.vssscc -.builds -*.pidb -*.svclog -*.scc - -# Chutzpah Test files -_Chutzpah* - -# Visual C++ cache files -ipch/ -*.aps -*.ncb -*.opendb -*.opensdf -*.sdf -*.cachefile -*.VC.db -*.VC.VC.opendb - -# Visual Studio profiler -*.psess -*.vsp -*.vspx -*.sap - -# Visual Studio Trace Files -*.e2e - -# TFS 2012 Local Workspace -$tf/ - -# Guidance Automation Toolkit -*.gpState - -# ReSharper is a .NET coding add-in -_ReSharper*/ -*.[Rr]e[Ss]harper -*.DotSettings.user - -# JustCode is a .NET coding add-in -.JustCode - -# TeamCity is a build add-in -_TeamCity* - -# DotCover is a Code Coverage Tool -*.dotCover - -# AxoCover is a Code Coverage Tool -.axoCover/* -!.axoCover/settings.json - -# Visual Studio code coverage results -*.coverage -*.coveragexml - -# NCrunch -_NCrunch_* -.*crunch*.local.xml -nCrunchTemp_* - -# MightyMoose -*.mm.* -AutoTest.Net/ - -# Web workbench (sass) -.sass-cache/ - -# Installshield output folder -[Ee]xpress/ - -# DocProject is a documentation generator add-in -DocProject/buildhelp/ -DocProject/Help/*.HxT -DocProject/Help/*.HxC -DocProject/Help/*.hhc -DocProject/Help/*.hhk -DocProject/Help/*.hhp -DocProject/Help/Html2 -DocProject/Help/html - -# Click-Once directory -publish/ - -# Publish Web Output -*.[Pp]ublish.xml -*.azurePubxml -# Note: Comment the next line if you want to checkin your web deploy settings, -# but database connection strings (with potential passwords) will be unencrypted -*.pubxml -*.publishproj - -# Microsoft Azure Web App publish settings. Comment the next line if you want to -# checkin your Azure Web App publish settings, but sensitive information contained -# in these scripts will be unencrypted -PublishScripts/ - -# NuGet Packages -*.nupkg -# The packages folder can be ignored because of Package Restore -**/[Pp]ackages/* -# except build/, which is used as an MSBuild target. -!**/[Pp]ackages/build/ -# Uncomment if necessary however generally it will be regenerated when needed -#!**/[Pp]ackages/repositories.config -# NuGet v3's project.json files produces more ignorable files -*.nuget.props -*.nuget.targets - -# Microsoft Azure Build Output -csx/ -*.build.csdef - -# Microsoft Azure Emulator -ecf/ -rcf/ - -# Windows Store app package directories and files -AppPackages/ -BundleArtifacts/ -Package.StoreAssociation.xml -_pkginfo.txt -*.appx - -# Visual Studio cache files -# files ending in .cache can be ignored -*.[Cc]ache -# but keep track of directories ending in .cache -!?*.[Cc]ache/ - -# Others -ClientBin/ -~$* -*.dbmdl -*.dbproj.schemaview -*.jfm -*.pfx -*.publishsettings -orleans.codegen.cs - -# Including strong name files can present a security risk -# (https://github.com/github/gitignore/pull/2483#issue-259490424) -#*.snk - -# Since there are multiple workflows, uncomment next line to ignore bower_components -# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) -#bower_components/ -# ASP.NET Core default setup: bower directory is configured as wwwroot/lib/ and bower restore is true -**/wwwroot/lib/ - -# RIA/Silverlight projects -Generated_Code/ - -# Backup & report files from converting an old project file -# to a newer Visual Studio version. Backup files are not needed, -# because we have git ;-) -_UpgradeReport_Files/ -Backup*/ -UpgradeLog*.XML -UpgradeLog*.htm -ServiceFabricBackup/ -*.rptproj.bak - -# SQL Server files -*.mdf -*.ldf -*.ndf - -# Business Intelligence projects -*.rdl.data -*.bim.layout -*.bim_*.settings -*.rptproj.rsuser -*- Backup*.rdl - -# Microsoft Fakes -FakesAssemblies/ - -# GhostDoc plugin setting file -*.GhostDoc.xml - -# Node.js Tools for Visual Studio -.ntvs_analysis.dat - -# Visual Studio 6 build log -*.plg - -# Visual Studio 6 workspace options file -*.opt - -# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) -*.vbw - -# Visual Studio LightSwitch build output -**/*.HTMLClient/GeneratedArtifacts -**/*.DesktopClient/GeneratedArtifacts -**/*.DesktopClient/ModelManifest.xml -**/*.Server/GeneratedArtifacts -**/*.Server/ModelManifest.xml -_Pvt_Extensions - -# Paket dependency manager -.paket/paket.exe -paket-files/ - -# FAKE - F# Make -.fake/ - -# JetBrains Rider -.idea/ -*.sln.iml - -# CodeRush personal settings -.cr/personal - -# Python Tools for Visual Studio (PTVS) -__pycache__/ -*.pyc - -# Cake - Uncomment if you are using it -# tools/** -# !tools/packages.config - -# Tabs Studio -*.tss - -# Telerik's JustMock configuration file -*.jmconfig - -# BizTalk build output -*.btp.cs -*.btm.cs -*.odx.cs -*.xsd.cs - -# OpenCover UI analysis results -OpenCover/ - -# Azure Stream Analytics local run output -ASALocalRun/ - -# MSBuild Binary and Structured Log -*.binlog - -# NVidia Nsight GPU debugger configuration file -*.nvuser - -# MFractors (Xamarin productivity tool) working folder -.mfractor/ - -# Local History for Visual Studio -.localhistory/ - -# BeatPulse healthcheck temp database -healthchecksdb - -# End of https://www.gitignore.io/api/node,rider,macos,linux,windows,visualstudio,visualstudiocode - -# dist for webpack output -dist \ No newline at end of file +# ide +.idea +.vscode diff --git a/src/components/apphost.js b/src/components/apphost.js index 2a0b7b19e..5058148ae 100644 --- a/src/components/apphost.js +++ b/src/components/apphost.js @@ -1,4 +1,4 @@ -define(["appSettings", "browser", "events", "htmlMediaHelper"], function (appSettings, browser, events, htmlMediaHelper) { +define(["appSettings", "browser", "events", "htmlMediaHelper", "webSettings"], function (appSettings, browser, events, htmlMediaHelper, webSettings) { "use strict"; function getBaseProfileOptions(item) { @@ -276,10 +276,12 @@ define(["appSettings", "browser", "events", "htmlMediaHelper"], function (appSet features.push("otherapppromotions"); features.push("displaymode"); features.push("targetblank"); - // allows users to connect to more than one server - //features.push("multiserver"); features.push("screensaver"); + if (webSettings.getMultiserver()) { + features.push("multiserver") + } + if (!browser.orsay && !browser.tizen && !browser.msie && (browser.firefox || browser.ps4 || browser.edge || supportsCue())) { features.push("subtitleappearancesettings"); } diff --git a/src/config.example.json b/src/config.example.json new file mode 100644 index 000000000..1e7927094 --- /dev/null +++ b/src/config.example.json @@ -0,0 +1,3 @@ +{ + "multiserver": true +} diff --git a/src/scripts/settings/webSettings.js b/src/scripts/settings/webSettings.js new file mode 100644 index 000000000..e5bafb0b9 --- /dev/null +++ b/src/scripts/settings/webSettings.js @@ -0,0 +1,30 @@ +define(['appStorage', 'events'], function (appStorage, events) { + 'use strict'; + + function readConfig(path, callback) { + var file = new XMLHttpRequest(); + file.overrideMimeType("application/json"); + file.open("GET", path, true); + file.onreadystatechange = function() { + if (file.readyState === 4 && file.status == "200") { + callback(file.responseText); + } + } + + file.send(null); + } + + var data = {}; + + function WebSettings() { + readConfig("/config.json", function(text) { + data = JSON.parse(text); + }); + } + + WebSettings.prototype.getMultiserver = function () { + return data.multiserver !== false; + }; + + return new WebSettings(); +}); diff --git a/src/scripts/site.js b/src/scripts/site.js index f26e6b68b..e1ea480f5 100644 --- a/src/scripts/site.js +++ b/src/scripts/site.js @@ -809,6 +809,7 @@ var AppInfo = {}; define("appSettings", [scriptsPath + "/settings/appSettings"], returnFirstDependency); define("userSettings", [scriptsPath + "/settings/userSettings"], returnFirstDependency); + define("webSettings", [scriptsPath + "/settings/webSettings"], returnFirstDependency); define("chromecastHelper", [componentsPath + "/chromecast/chromecasthelpers"], returnFirstDependency); define("mediaSession", [componentsPath + "/playback/mediasession"], returnFirstDependency); From ed1b35f50fcf7bb2746842ab0cb566d2e230b9f0 Mon Sep 17 00:00:00 2001 From: dkanada Date: Sun, 16 Feb 2020 22:11:36 +0900 Subject: [PATCH 002/338] update some strings and use fetch for the global config --- src/components/apphost.js | 2 +- .../displaysettings.template.html | 2 +- src/components/skinManager.js | 4 ++-- .../subtitlesettings/subtitlesettings.js | 13 ++--------- .../subtitlesettings.template.html | 11 +++++---- src/scripts/settings/appSettings.js | 16 ++++++------- src/scripts/settings/webSettings.js | 23 ++++--------------- src/strings/en-us.json | 16 ++++++------- 8 files changed, 34 insertions(+), 53 deletions(-) diff --git a/src/components/apphost.js b/src/components/apphost.js index 5058148ae..0a9b9d638 100644 --- a/src/components/apphost.js +++ b/src/components/apphost.js @@ -278,7 +278,7 @@ define(["appSettings", "browser", "events", "htmlMediaHelper", "webSettings"], f features.push("targetblank"); features.push("screensaver"); - if (webSettings.getMultiserver()) { + if (webSettings.getMultiServer()) { features.push("multiserver") } diff --git a/src/components/displaysettings/displaysettings.template.html b/src/components/displaysettings/displaysettings.template.html index 16bbf0dd8..4ef8c8b1c 100644 --- a/src/components/displaysettings/displaysettings.template.html +++ b/src/components/displaysettings/displaysettings.template.html @@ -63,7 +63,7 @@
+
@@ -34,7 +34,6 @@
-

${HeaderSubtitleAppearance}

@@ -61,6 +60,7 @@
+
+
+
+
+ ${PreferEmbeddedEpisodeInfosOverFileNames} + +
${PreferEmbeddedEpisodeInfosOverFileNamesHelp}
+
"; if (task.State === "Running") { - html += ''; + html += ''; } else if (task.State === "Idle") { html += ''; } @@ -90,16 +90,23 @@ define(["jQuery", "loading", "events", "globalize", "serverNotifications", "huma return html; } + function setTaskButtonIcon(button, icon) { + var inner = button.querySelector("i"); + inner.classList.remove("stop"); + inner.classList.remove("play_arrow"); + inner.classList.add(icon); + } + function updateTaskButton(elem, state) { if (state === "Running") { elem.classList.remove("btnStartTask"); elem.classList.add("btnStopTask"); - elem.querySelector("i").innerHTML = "stop"; + setTaskButtonIcon(elem, "stop"); elem.title = globalize.translate("ButtonStop"); } else if (state === "Idle") { elem.classList.add("btnStartTask"); elem.classList.remove("btnStopTask"); - elem.querySelector("i").innerHTML = ""; + setTaskButtonIcon(elem, "play_arrow"); elem.title = globalize.translate("ButtonStart"); } $(elem).parents(".listItem")[0].setAttribute("data-status", state); From e016836d3e353590eb9a78523d55d45df1d4dbbb Mon Sep 17 00:00:00 2001 From: Dmitry Lyzo Date: Tue, 10 Mar 2020 12:44:42 +0300 Subject: [PATCH 015/338] Fix library icons in WebOS 4 --- src/components/cardbuilder/cardBuilder.js | 2 +- src/components/homesections/homesections.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/cardbuilder/cardBuilder.js b/src/components/cardbuilder/cardBuilder.js index 3e54f91ee..ab4f85748 100644 --- a/src/components/cardbuilder/cardBuilder.js +++ b/src/components/cardbuilder/cardBuilder.js @@ -1484,7 +1484,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana function getDefaultText(item, options) { if (item.CollectionType) { - return '' + imageHelper.getLibraryIcon(item.CollectionType) + '' + return '' } switch (item.Type) { diff --git a/src/components/homesections/homesections.js b/src/components/homesections/homesections.js index 430c06bc5..b02452854 100644 --- a/src/components/homesections/homesections.js +++ b/src/components/homesections/homesections.js @@ -183,7 +183,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la for (var i = 0, length = items.length; i < length; i++) { var item = items[i]; var icon = imageHelper.getLibraryIcon(item.CollectionType); - html += '' + icon + '' + item.Name + ''; + html += '' + item.Name + ''; } html += ''; From 13a03b6e2cea3c21d1e91270966f985d920e6300 Mon Sep 17 00:00:00 2001 From: Dmitry Lyzo Date: Tue, 10 Mar 2020 12:57:09 +0300 Subject: [PATCH 016/338] Fix slideshow button icons in WebOS 4 --- src/components/slideshow/slideshow.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/components/slideshow/slideshow.js b/src/components/slideshow/slideshow.js index 40d87e951..4d426f248 100644 --- a/src/components/slideshow/slideshow.js +++ b/src/components/slideshow/slideshow.js @@ -70,7 +70,7 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f var tabIndex = canFocus ? '' : ' tabindex="-1"'; autoFocus = autoFocus ? ' autofocus' : ''; - return ''; + return ''; } function setUserScalable(scalable) { @@ -201,14 +201,16 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f function onAutoplayStart() { var btnSlideshowPause = dlg.querySelector('.btnSlideshowPause i'); if (btnSlideshowPause) { - btnSlideshowPause.innerHTML = "pause"; + btnSlideshowPause.classList.remove("play_arrow"); + btnSlideshowPause.classList.add("pause"); } } function onAutoplayStop() { var btnSlideshowPause = dlg.querySelector('.btnSlideshowPause i'); if (btnSlideshowPause) { - btnSlideshowPause.innerHTML = ""; + btnSlideshowPause.classList.remove("pause"); + btnSlideshowPause.classList.add("play_arrow"); } } @@ -365,8 +367,7 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f } function playPause() { - - var paused = dlg.querySelector('.btnSlideshowPause i').innerHTML !== "pause"; + var paused = !dlg.querySelector('.btnSlideshowPause i').classList.contains("pause"); if (paused) { play(); } else { From b348c69844c6dd7eecc4a1a3a05eef0d0d29592f Mon Sep 17 00:00:00 2001 From: Dmitry Lyzo Date: Tue, 10 Mar 2020 12:59:36 +0300 Subject: [PATCH 017/338] Fix emby-collapse icon in WebOS 4 --- src/elements/emby-collapse/emby-collapse.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/elements/emby-collapse/emby-collapse.js b/src/elements/emby-collapse/emby-collapse.js index 600af5551..fdd77adf0 100644 --- a/src/elements/emby-collapse/emby-collapse.js +++ b/src/elements/emby-collapse/emby-collapse.js @@ -80,7 +80,7 @@ define(['browser', 'css!./emby-collapse', 'registerElement', 'emby-button'], fun var title = this.getAttribute('title'); - var html = ''; + var html = ''; this.insertAdjacentHTML('afterbegin', html); From ed25f0bac1c884a789bbcb0e1df07d35e28d51ec Mon Sep 17 00:00:00 2001 From: Dmitry Lyzo <56478732+dmitrylyzo@users.noreply.github.com> Date: Tue, 10 Mar 2020 19:00:51 +0300 Subject: [PATCH 018/338] Update src/controllers/dashboard/scheduledtasks/scheduledtasks.js Co-Authored-By: Julien Machiels --- src/controllers/dashboard/scheduledtasks/scheduledtasks.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/controllers/dashboard/scheduledtasks/scheduledtasks.js b/src/controllers/dashboard/scheduledtasks/scheduledtasks.js index 10ea0538d..390fd1735 100644 --- a/src/controllers/dashboard/scheduledtasks/scheduledtasks.js +++ b/src/controllers/dashboard/scheduledtasks/scheduledtasks.js @@ -92,8 +92,7 @@ define(["jQuery", "loading", "events", "globalize", "serverNotifications", "huma function setTaskButtonIcon(button, icon) { var inner = button.querySelector("i"); - inner.classList.remove("stop"); - inner.classList.remove("play_arrow"); + inner.classList.remove("stop", "play_arrow"); inner.classList.add(icon); } From a44473dca2495aa08ed680125cf4d82ed633bf88 Mon Sep 17 00:00:00 2001 From: Dmitry Lyzo Date: Wed, 11 Mar 2020 15:04:29 +0300 Subject: [PATCH 019/338] Fix radiobutton change notification --- src/elements/emby-radio/emby-radio.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/elements/emby-radio/emby-radio.js b/src/elements/emby-radio/emby-radio.js index 9b9159105..7cba80fda 100644 --- a/src/elements/emby-radio/emby-radio.js +++ b/src/elements/emby-radio/emby-radio.js @@ -9,7 +9,13 @@ define(['css!./emby-radio', 'registerElement'], function () { if (e.keyCode === 13) { e.preventDefault(); - this.checked = true; + if (!this.checked) { + this.checked = true; + + this.dispatchEvent(new CustomEvent('change', { + bubbles: true + })); + } return false; } From 30414c98d7dc880845d2f293579e5a901676b141 Mon Sep 17 00:00:00 2001 From: Dmitry Lyzo Date: Wed, 11 Mar 2020 22:19:26 +0300 Subject: [PATCH 020/338] Fix radio and checkbox on Tizen --- src/elements/emby-checkbox/emby-checkbox.js | 3 ++- src/elements/emby-radio/emby-radio.js | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/elements/emby-checkbox/emby-checkbox.js b/src/elements/emby-checkbox/emby-checkbox.js index 2e49a2d18..b5e587d5a 100644 --- a/src/elements/emby-checkbox/emby-checkbox.js +++ b/src/elements/emby-checkbox/emby-checkbox.js @@ -5,7 +5,8 @@ define(['browser', 'dom', 'css!./emby-checkbox', 'registerElement'], function (b function onKeyDown(e) { // Don't submit form on enter - if (e.keyCode === 13) { + // Real (non-emulator) Tizen does nothing on Space + if (e.keyCode === 13 || e.keyCode === 32) { e.preventDefault(); this.checked = !this.checked; diff --git a/src/elements/emby-radio/emby-radio.js b/src/elements/emby-radio/emby-radio.js index 7cba80fda..000c65682 100644 --- a/src/elements/emby-radio/emby-radio.js +++ b/src/elements/emby-radio/emby-radio.js @@ -6,7 +6,8 @@ define(['css!./emby-radio', 'registerElement'], function () { function onKeyDown(e) { // Don't submit form on enter - if (e.keyCode === 13) { + // Real (non-emulator) Tizen does nothing on Space + if (e.keyCode === 13 || e.keyCode === 32) { e.preventDefault(); if (!this.checked) { From 8646b66f6ccbd6b1cba823e4ba1fbbb6491bf033 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Wed, 11 Mar 2020 21:31:04 +0100 Subject: [PATCH 021/338] Improve image size handling --- src/components/cardbuilder/cardBuilder.js | 3 +-- src/components/cardbuilder/chaptercardbuilder.js | 2 +- src/components/dom.js | 4 ++-- src/controllers/auth/login.js | 2 +- src/controllers/dashboard/dashboard.js | 8 ++++---- src/controllers/playback/videoosd.js | 12 ++++++------ src/controllers/userprofilespage.js | 2 +- src/libraries/apiclient/apiclient.js | 4 ++-- src/libraries/apiclient/apiclientcore.js | 5 ++--- src/libraries/apiclient/connectionmanager.js | 4 ++-- src/scripts/site.js | 4 ++-- 11 files changed, 24 insertions(+), 26 deletions(-) diff --git a/src/components/cardbuilder/cardBuilder.js b/src/components/cardbuilder/cardBuilder.js index c20f6999f..6cdbf5514 100644 --- a/src/components/cardbuilder/cardBuilder.js +++ b/src/components/cardbuilder/cardBuilder.js @@ -2,7 +2,6 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana function (datetime, imageLoader, connectionManager, itemHelper, focusManager, indicators, globalize, layoutManager, appHost, dom, browser, playbackManager, itemShortcuts, imageHelper) { 'use strict'; - var devicePixelRatio = window.devicePixelRatio || 1; var enableFocusTransform = !browser.slow && !browser.edge; function getCardsHtml(items, options) { @@ -592,7 +591,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana }); } else if (item.AlbumId && item.AlbumPrimaryImageTag) { - width = primaryImageAspectRatio ? Math.round(height * primaryImageAspectRatio) : null; + height = width && primaryImageAspectRatio ? Math.round(width / primaryImageAspectRatio) : null; imgUrl = apiClient.getScaledImageUrl(item.AlbumId, { type: "Primary", diff --git a/src/components/cardbuilder/chaptercardbuilder.js b/src/components/cardbuilder/chaptercardbuilder.js index 02d583abc..16326b6c5 100644 --- a/src/components/cardbuilder/chaptercardbuilder.js +++ b/src/components/cardbuilder/chaptercardbuilder.js @@ -68,7 +68,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'layoutManager', 'browse return apiClient.getScaledImageUrl(item.Id, { - maxWidth: maxWidth, + maxWidth: maxWidth * 2, tag: chapter.ImageTag, type: "Chapter", index: index diff --git a/src/components/dom.js b/src/components/dom.js index a000373b6..bdd7d5d95 100644 --- a/src/components/dom.js +++ b/src/components/dom.js @@ -114,8 +114,8 @@ define([], function () { var standardWidths = [480, 720, 1280, 1440, 1920, 2560, 3840, 5120, 7680]; function getScreenWidth() { - var width = window.innerWidth * window.devicePixelRatio; - var height = window.innerHeight * window.devicePixelRatio; + var width = window.innerWidth; + var height = window.innerHeight; if (height > width) { /* If we're in portrait, compute the proper width for this height, diff --git a/src/controllers/auth/login.js b/src/controllers/auth/login.js index a97f2e849..4296b8bfb 100644 --- a/src/controllers/auth/login.js +++ b/src/controllers/auth/login.js @@ -106,7 +106,7 @@ define(["apphost", "appSettings", "dom", "connectionManager", "loading", "layout if (user.PrimaryImageTag) { imgUrl = apiClient.getUserImageUrl(user.Id, { - width: 300 * window.devicePixelRatio, + width: 300, tag: user.PrimaryImageTag, type: "Primary" }); diff --git a/src/controllers/dashboard/dashboard.js b/src/controllers/dashboard/dashboard.js index 51e8c2e19..6a260d8df 100644 --- a/src/controllers/dashboard/dashboard.js +++ b/src/controllers/dashboard/dashboard.js @@ -493,15 +493,15 @@ define(["datetime", "events", "itemHelper", "serverNotifications", "dom", "globa if (nowPlayingItem.ImageTags && nowPlayingItem.ImageTags.Logo) { imgUrl = ApiClient.getScaledImageUrl(nowPlayingItem.Id, { tag: nowPlayingItem.ImageTags.Logo, - maxHeight: 24 * window.devicePixelRatio, - maxWidth: 130 * window.devicePixelRatio, + maxHeight: 24, + maxWidth: 130, type: "Logo" }); } else if (nowPlayingItem.ParentLogoImageTag) { imgUrl = ApiClient.getScaledImageUrl(nowPlayingItem.ParentLogoItemId, { tag: nowPlayingItem.ParentLogoImageTag, - maxHeight: 24 * window.devicePixelRatio, - maxWidth: 130 * window.devicePixelRatio, + maxHeight: 24, + maxWidth: 130, type: "Logo" }); } diff --git a/src/controllers/playback/videoosd.js b/src/controllers/playback/videoosd.js index bf605976c..24b654854 100644 --- a/src/controllers/playback/videoosd.js +++ b/src/controllers/playback/videoosd.js @@ -334,24 +334,24 @@ define(["playbackManager", "dom", "inputManager", "datetime", "itemHelper", "med if (item) { var imgUrl = seriesImageUrl(item, { - maxWidth: Math.round(dom.getScreenWidth() * 0.20), + maxWidth: osdPoster.clientWidth * 2, type: "Primary" }) || seriesImageUrl(item, { - maxWidth: Math.round(dom.getScreenWidth() * 0.20), + maxWidth: osdPoster.clientWidth * 2, type: "Thumb" }) || imageUrl(item, { - maxWidth: Math.round(dom.getScreenWidth() * 0.20), + maxWidth: osdPoster.clientWidth * 2, type: "Primary" }); if (!imgUrl && secondaryItem && (imgUrl = seriesImageUrl(secondaryItem, { - maxWidth: Math.round(dom.getScreenWidth() * 0.20), + maxWidth: osdPoster.clientWidth * 2, type: "Primary" }) || seriesImageUrl(secondaryItem, { - maxWidth: Math.round(dom.getScreenWidth() * 0.20), + maxWidth: osdPoster.clientWidth * 2, type: "Thumb" }) || imageUrl(secondaryItem, { - maxWidth: Math.round(dom.getScreenWidth() * 0.20), + maxWidth: osdPoster.clientWidth * 2, type: "Primary" })), imgUrl) { return void (osdPoster.innerHTML = ''); diff --git a/src/controllers/userprofilespage.js b/src/controllers/userprofilespage.js index 3e41c0485..2a2387ab6 100644 --- a/src/controllers/userprofilespage.js +++ b/src/controllers/userprofilespage.js @@ -88,7 +88,7 @@ define(["loading", "dom", "globalize", "humanedate", "paper-icon-button-light", if (user.PrimaryImageTag) { imgUrl = ApiClient.getUserImageUrl(user.Id, { - width: 300 * window.devicePixelRatio, + width: 300, tag: user.PrimaryImageTag, type: "Primary" }); diff --git a/src/libraries/apiclient/apiclient.js b/src/libraries/apiclient/apiclient.js index d848358c3..58cfa300b 100644 --- a/src/libraries/apiclient/apiclient.js +++ b/src/libraries/apiclient/apiclient.js @@ -59,8 +59,8 @@ define(["libraries/apiclient/apiclientcore", "localassetmanager"], function(ApiC }) } - function ApiClientEx(serverAddress, clientName, applicationVersion, deviceName, deviceId, devicePixelRatio) { - ApiClient.call(this, serverAddress, clientName, applicationVersion, deviceName, deviceId, devicePixelRatio) + function ApiClientEx(serverAddress, clientName, applicationVersion, deviceName, deviceId) { + ApiClient.call(this, serverAddress, clientName, applicationVersion, deviceName, deviceId) } var localPrefix = "local:", localViewPrefix = "localview:"; diff --git a/src/libraries/apiclient/apiclientcore.js b/src/libraries/apiclient/apiclientcore.js index ec1a329b1..557a4e103 100644 --- a/src/libraries/apiclient/apiclientcore.js +++ b/src/libraries/apiclient/apiclientcore.js @@ -58,7 +58,7 @@ define(["events", "appStorage"], function(events, appStorage) { return request.data && ("string" == typeof request.data ? fetchRequest.body = request.data : (fetchRequest.body = paramsToString(request.data), contentType = contentType || "application/x-www-form-urlencoded; charset=UTF-8")), contentType && (headers["Content-Type"] = contentType), request.timeout ? fetchWithTimeout(request.url, fetchRequest, request.timeout) : fetch(request.url, fetchRequest) } - function ApiClient(serverAddress, appName, appVersion, deviceName, deviceId, devicePixelRatio) { + function ApiClient(serverAddress, appName, appVersion, deviceName, deviceId) { if (!serverAddress) { throw new Error("Must supply a serverAddress"); } @@ -75,7 +75,6 @@ define(["events", "appStorage"], function(events, appStorage) { this._deviceName = deviceName; this._appName = appName; this._appVersion = appVersion; - this._devicePixelRatio = devicePixelRatio; } function setSavedEndpointInfo(instance, info) { @@ -218,7 +217,7 @@ define(["events", "appStorage"], function(events, appStorage) { } function normalizeImageOptions(instance, options) { - var ratio = instance._devicePixelRatio || 1; + var ratio = window.devicePixelRatio; ratio && (options.minScale && (ratio = Math.max(options.minScale, ratio)), options.width && (options.width = Math.round(options.width * ratio)), options.height && (options.height = Math.round(options.height * ratio)), options.maxWidth && (options.maxWidth = Math.round(options.maxWidth * ratio)), options.maxHeight && (options.maxHeight = Math.round(options.maxHeight * ratio))), options.quality = options.quality || instance.getDefaultImageQuality(options.type), instance.normalizeImageOptions && instance.normalizeImageOptions(options) } diff --git a/src/libraries/apiclient/connectionmanager.js b/src/libraries/apiclient/connectionmanager.js index a8e389bd0..dc5ef406e 100644 --- a/src/libraries/apiclient/connectionmanager.js +++ b/src/libraries/apiclient/connectionmanager.js @@ -186,7 +186,7 @@ define(["events", "apiclient", "appStorage"], function (events, apiClientFactory Manual: 2 }; - var ConnectionManager = function (credentialProvider, appName, appVersion, deviceName, deviceId, capabilities, devicePixelRatio) { + var ConnectionManager = function (credentialProvider, appName, appVersion, deviceName, deviceId, capabilities) { function onAuthenticated(apiClient, result, options, saveCredentials) { var credentials = credentialProvider.credentials(); @@ -540,7 +540,7 @@ define(["events", "apiclient", "appStorage"], function (events, apiClientFactory var apiClient = self.getApiClient(server.Id); if (!apiClient) { - apiClient = new apiClientFactory(serverUrl, appName, appVersion, deviceName, deviceId, devicePixelRatio); + apiClient = new apiClientFactory(serverUrl, appName, appVersion, deviceName, deviceId); self._apiClients.push(apiClient); apiClient.serverInfo(server); apiClient.onAuthenticated = function (instance, result) { diff --git a/src/scripts/site.js b/src/scripts/site.js index 7332ba7b8..5dae39a68 100644 --- a/src/scripts/site.js +++ b/src/scripts/site.js @@ -280,7 +280,7 @@ var AppInfo = {}; capabilities.DeviceProfile = deviceProfile; - var connectionManager = new ConnectionManager(credentialProviderInstance, apphost.appName(), apphost.appVersion(), apphost.deviceName(), apphost.deviceId(), capabilities, window.devicePixelRatio); + var connectionManager = new ConnectionManager(credentialProviderInstance, apphost.appName(), apphost.appVersion(), apphost.deviceName(), apphost.deviceId(), capabilities); defineConnectionManager(connectionManager); bindConnectionManagerEvents(connectionManager, events, userSettings); @@ -291,7 +291,7 @@ var AppInfo = {}; return require(["apiclient"], function (apiClientFactory) { console.debug("creating ApiClient singleton"); - var apiClient = new apiClientFactory(Dashboard.serverAddress(), apphost.appName(), apphost.appVersion(), apphost.deviceName(), apphost.deviceId(), window.devicePixelRatio); + var apiClient = new apiClientFactory(Dashboard.serverAddress(), apphost.appName(), apphost.appVersion(), apphost.deviceName(), apphost.deviceId()); apiClient.enableAutomaticNetworking = false; apiClient.manualAddressOnly = true; From 3e80d5d47c1d464b346e66a4f1c8c5d0362280d9 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Wed, 11 Mar 2020 21:48:30 +0100 Subject: [PATCH 022/338] Show hamburger menu on mobile and fix title padding --- src/assets/css/librarybrowser.css | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/assets/css/librarybrowser.css b/src/assets/css/librarybrowser.css index 67afef237..4c2cf9581 100644 --- a/src/assets/css/librarybrowser.css +++ b/src/assets/css/librarybrowser.css @@ -115,7 +115,7 @@ display: -webkit-inline-box; display: -webkit-inline-flex; display: inline-flex; - margin: 0.3em 0 0 0.5em; + margin: 0 0 0 0.5em; height: 1.7em; -webkit-box-align: center; -webkit-align-items: center; @@ -242,7 +242,6 @@ } @media all and (min-width: 40em) { - .dashboardDocument .adminDrawerLogo, .dashboardDocument .mainDrawerButton { display: none !important; } @@ -268,12 +267,6 @@ } } -@media all and (max-width: 60em) { - .libraryDocument .mainDrawerButton { - display: none; - } -} - @media all and (max-width: 84em) { .withSectionTabs .headerTop { padding-bottom: 0.55em; From 6260db82e219ab963595029e1ee65b8b8877d9b1 Mon Sep 17 00:00:00 2001 From: dkanada Date: Thu, 12 Mar 2020 23:55:59 +0900 Subject: [PATCH 023/338] remove query string from source --- package.json | 1 + src/bundle.js | 12 +++-- src/libraries/query-string/index.js | 18 ------- src/libraries/query-string/test.js | 83 ----------------------------- src/scripts/site.js | 4 +- 5 files changed, 11 insertions(+), 107 deletions(-) delete mode 100644 src/libraries/query-string/index.js delete mode 100644 src/libraries/query-string/test.js diff --git a/package.json b/package.json index 9fcf535a4..41a9c4196 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "material-design-icons-iconfont": "^5.0.1", "native-promise-only": "^0.8.0-a", "page": "^1.11.5", + "query-string": "^6.11.1", "resize-observer-polyfill": "^1.5.1", "shaka-player": "^2.5.9", "sortablejs": "^1.10.2", diff --git a/src/bundle.js b/src/bundle.js index 5d05e4b68..6a462b422 100644 --- a/src/bundle.js +++ b/src/bundle.js @@ -16,6 +16,12 @@ _define("fetch", function() { return fetch }); +// query-string +var query = require("query-string"); +_define("queryString", function() { + return query; +}); + // flvjs var flvjs = require("flv.js/dist/flv").default; _define("flvjs", function() { @@ -75,7 +81,7 @@ _define("sortable", function() { // webcomponents var webcomponents = require("webcomponents.js/webcomponents-lite"); _define("webcomponents", function() { - return webcomponents + return webcomponents; }); // libjass @@ -97,9 +103,9 @@ _define("material-icons", function() { return material_icons; }); -var jellyfin_noto = require("jellyfin-noto"); +var noto = require("jellyfin-noto"); _define("jellyfin-noto", function () { - return jellyfin_noto; + return noto; }); // page.js diff --git a/src/libraries/query-string/index.js b/src/libraries/query-string/index.js deleted file mode 100644 index cc63f52b8..000000000 --- a/src/libraries/query-string/index.js +++ /dev/null @@ -1,18 +0,0 @@ -"use strict"; -window.queryString = {}, window.queryString.extract = function(maybeUrl) { - return maybeUrl.split("?")[1] || "" -}, window.queryString.parse = function(str) { - return "string" != typeof str ? {} : (str = str.trim().replace(/^(\?|#|&)/, ""), str ? str.split("&").reduce(function(ret, param) { - var parts = param.replace(/\+/g, " ").split("="), - key = parts[0], - val = parts[1]; - return key = decodeURIComponent(key), val = void 0 === val ? null : decodeURIComponent(val), ret.hasOwnProperty(key) ? Array.isArray(ret[key]) ? ret[key].push(val) : ret[key] = [ret[key], val] : ret[key] = val, ret - }, {}) : {}) -}, window.queryString.stringify = function(obj) { - return obj ? Object.keys(obj).sort().map(function(key) { - var val = obj[key]; - return Array.isArray(val) ? val.sort().map(function(val2) { - return encodeURIComponent(key) + "=" + encodeURIComponent(val2) - }).join("&") : encodeURIComponent(key) + "=" + encodeURIComponent(val) - }).join("&") : "" -}; diff --git a/src/libraries/query-string/test.js b/src/libraries/query-string/test.js deleted file mode 100644 index 072a33fb1..000000000 --- a/src/libraries/query-string/test.js +++ /dev/null @@ -1,83 +0,0 @@ -"use strict"; -var assert = require("assert"), - qs = require("./"); -describe(".parse()", function() { - it("query strings starting with a `?`", function() { - assert.deepEqual(qs.parse("?foo=bar"), { - foo: "bar" - }) - }), it("query strings starting with a `#`", function() { - assert.deepEqual(qs.parse("#foo=bar"), { - foo: "bar" - }) - }), it("query strings starting with a `&", function() { - assert.deepEqual(qs.parse("&foo=bar&foo=baz"), { - foo: ["bar", "baz"] - }) - }), it("parse a query string", function() { - assert.deepEqual(qs.parse("foo=bar"), { - foo: "bar" - }) - }), it("parse multiple query string", function() { - assert.deepEqual(qs.parse("foo=bar&key=val"), { - foo: "bar", - key: "val" - }) - }), it("parse query string without a value", function() { - assert.deepEqual(qs.parse("foo"), { - foo: null - }), assert.deepEqual(qs.parse("foo&key"), { - foo: null, - key: null - }), assert.deepEqual(qs.parse("foo=bar&key"), { - foo: "bar", - key: null - }) - }), it("return empty object if no qss can be found", function() { - assert.deepEqual(qs.parse("?"), {}), assert.deepEqual(qs.parse("&"), {}), assert.deepEqual(qs.parse("#"), {}), assert.deepEqual(qs.parse(" "), {}) - }), it("handle `+` correctly", function() { - assert.deepEqual(qs.parse("foo+faz=bar+baz++"), { - "foo faz": "bar baz " - }) - }), it("handle multiple of the same key", function() { - assert.deepEqual(qs.parse("foo=bar&foo=baz"), { - foo: ["bar", "baz"] - }) - }), it("query strings params including embedded `=`", function() { - assert.deepEqual(qs.parse("?param=http%3A%2F%2Fsomeurl%3Fid%3D2837"), { - param: "http://someurl?id=2837" - }) - }) -}), describe(".stringify()", function() { - it("stringify", function() { - assert.strictEqual(qs.stringify({ - foo: "bar" - }), "foo=bar"), assert.strictEqual(qs.stringify({ - foo: "bar", - bar: "baz" - }), "bar=baz&foo=bar") - }), it("different types", function() { - assert.strictEqual(qs.stringify(), ""), assert.strictEqual(qs.stringify(0), "") - }), it("URI encode", function() { - assert.strictEqual(qs.stringify({ - "foo bar": "baz faz" - }), "foo%20bar=baz%20faz") - }), it("handle array value", function() { - assert.strictEqual(qs.stringify({ - abc: "abc", - foo: ["bar", "baz"] - }), "abc=abc&foo=bar&foo=baz") - }) -}), describe(".extract()", function() { - it("should extract qs from url", function() { - assert.equal(qs.extract("http://foo.bar/?abc=def&hij=klm"), "abc=def&hij=klm"), assert.equal(qs.extract("http://foo.bar/?"), "") - }), it("should handle strings not containing qs", function() { - assert.equal(qs.extract("http://foo.bar/"), ""), assert.equal(qs.extract(""), "") - }), it("should throw for invalid values", function() { - assert.throws(function() { - qs.extract(null) - }, TypeError), assert.throws(function() { - qs.extract(void 0) - }, TypeError) - }) -}); diff --git a/src/scripts/site.js b/src/scripts/site.js index 1d8285325..d6626009b 100644 --- a/src/scripts/site.js +++ b/src/scripts/site.js @@ -733,6 +733,7 @@ var AppInfo = {}; "resize-observer-polyfill", "shaka", "swiper", + "queryString", "sortable", "libjass", "webcomponents", @@ -795,9 +796,6 @@ var AppInfo = {}; define("headroom", [componentsPath + "/headroom/headroom"], returnFirstDependency); define("scroller", [componentsPath + "/scroller"], returnFirstDependency); define("navdrawer", [componentsPath + "/navdrawer/navdrawer"], returnFirstDependency); - define("queryString", [bowerPath + "/query-string/index"], function () { - return queryString; - }); define("emby-button", [elementsPath + "/emby-button/emby-button"], returnFirstDependency); define("paper-icon-button-light", [elementsPath + "/emby-button/paper-icon-button-light"], returnFirstDependency); From a2f337b8c382a3d4eb70c92b494e615cdd84aa04 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Thu, 12 Mar 2020 21:11:06 +0100 Subject: [PATCH 024/338] Add comments for hardcoded scaling values --- src/controllers/dashboard/dashboard.js | 2 ++ src/controllers/itemdetailpage.js | 3 +++ 2 files changed, 5 insertions(+) diff --git a/src/controllers/dashboard/dashboard.js b/src/controllers/dashboard/dashboard.js index 6a260d8df..1927abf17 100644 --- a/src/controllers/dashboard/dashboard.js +++ b/src/controllers/dashboard/dashboard.js @@ -634,6 +634,8 @@ define(["datetime", "events", "itemHelper", "serverNotifications", "dom", "globa return ""; }, getNowPlayingImageUrl: function (item) { + /* Screen width is multiplied by 0.2, as the there is now way to get the width of + elements that aren't crated yet. */ if (item && item.BackdropImageTags && item.BackdropImageTags.length) { return ApiClient.getScaledImageUrl(item.Id, { maxWidth: Math.round(dom.getScreenWidth() * 0.20), diff --git a/src/controllers/itemdetailpage.js b/src/controllers/itemdetailpage.js index 5b1f5d9e1..994983763 100644 --- a/src/controllers/itemdetailpage.js +++ b/src/controllers/itemdetailpage.js @@ -767,6 +767,9 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "userSetti var shape = "portrait"; var detectRatio = false; + /* In the following section, getScreenWidth() is multiplied by 0.5 as the posters + are 25vw and we need double the resolution to counter Skia's scaling. */ + // TODO: Find a reliable way to get the poster width if (imageTags.Primary) { url = apiClient.getScaledImageUrl(item.Id, { type: "Primary", From def9da2f0d823418e3899532a8007566f05a728f Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Thu, 12 Mar 2020 21:17:13 +0100 Subject: [PATCH 025/338] Use 16:9 instead of 1.78:1 to derive width of screen --- src/components/dom.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/components/dom.js b/src/components/dom.js index bdd7d5d95..cc37e2fc5 100644 --- a/src/components/dom.js +++ b/src/components/dom.js @@ -118,9 +118,7 @@ define([], function () { var height = window.innerHeight; if (height > width) { - /* If we're in portrait, compute the proper width for this height, - taking 16:9 as the most common ratio */ - width = height * 1.78; + width = height * (16.0 / 9.0); } var closest = standardWidths.sort(function (a, b) { From 639db44ad1d1bd2f080e1d6e94f088b13785c38a Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Fri, 13 Mar 2020 09:22:08 +0100 Subject: [PATCH 026/338] Fix spelling issue in comment --- src/controllers/dashboard/dashboard.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/controllers/dashboard/dashboard.js b/src/controllers/dashboard/dashboard.js index 1927abf17..2057deaf6 100644 --- a/src/controllers/dashboard/dashboard.js +++ b/src/controllers/dashboard/dashboard.js @@ -634,8 +634,8 @@ define(["datetime", "events", "itemHelper", "serverNotifications", "dom", "globa return ""; }, getNowPlayingImageUrl: function (item) { - /* Screen width is multiplied by 0.2, as the there is now way to get the width of - elements that aren't crated yet. */ + /* Screen width is multiplied by 0.2, as the there is currently no way to get the width of + elements that aren't created yet. */ if (item && item.BackdropImageTags && item.BackdropImageTags.length) { return ApiClient.getScaledImageUrl(item.Id, { maxWidth: Math.round(dom.getScreenWidth() * 0.20), From faa46f5bad4c50368a5ef484dc90e722feea5e1a Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Sat, 14 Mar 2020 22:48:39 +0100 Subject: [PATCH 027/338] Double size of remotecontrol and listview images --- src/components/listview/listview.js | 2 +- src/components/remotecontrol/remotecontrol.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/listview/listview.js b/src/components/listview/listview.js index f0f5440aa..25f7e5291 100644 --- a/src/components/listview/listview.js +++ b/src/components/listview/listview.js @@ -72,7 +72,7 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan var apiClient = connectionManager.getApiClient(item.ServerId); var options = { - maxWidth: width, + maxWidth: width * 2, type: "Primary" }; diff --git a/src/components/remotecontrol/remotecontrol.js b/src/components/remotecontrol/remotecontrol.js index 90115b3a8..7b620d536 100644 --- a/src/components/remotecontrol/remotecontrol.js +++ b/src/components/remotecontrol/remotecontrol.js @@ -122,9 +122,9 @@ define(["browser", "datetime", "backdrop", "libraryBrowser", "listView", "imageL } var url = item ? seriesImageUrl(item, { - maxHeight: 300 + maxHeight: 300 * 2 }) || imageUrl(item, { - maxHeight: 300 + maxHeight: 300 * 2 }) : null; console.debug("updateNowPlayingInfo"); From bdc3ec00c82b8706705fd9ec1fd6993b620000b8 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Sun, 15 Mar 2020 21:29:26 +0100 Subject: [PATCH 028/338] Re-add image maxWidth in listview --- src/components/listview/listview.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/listview/listview.js b/src/components/listview/listview.js index 25f7e5291..532ba094a 100644 --- a/src/components/listview/listview.js +++ b/src/components/listview/listview.js @@ -105,6 +105,7 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan var apiClient = connectionManager.getApiClient(item.ServerId); var options = { + maxWidth: width * 2, type: "Primary" }; From e7f441277116efceb3019e2edbdc9e4909c20857 Mon Sep 17 00:00:00 2001 From: dkanada Date: Mon, 16 Mar 2020 23:49:56 +0900 Subject: [PATCH 029/338] remove tar from published artifacts --- .ci/azure-pipelines.yml | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/.ci/azure-pipelines.yml b/.ci/azure-pipelines.yml index 7505f9ab5..1a0f11a64 100644 --- a/.ci/azure-pipelines.yml +++ b/.ci/azure-pipelines.yml @@ -24,10 +24,12 @@ jobs: strategy: matrix: - bundle: - BuildConfiguration: Bundle - standalone: - BuildConfiguration: Standalone + Development: + BuildConfiguration: development + Bundle: + BuildConfiguration: bundle + Standalone: + BuildConfiguration: standalone maxParallel: 2 steps: @@ -40,20 +42,25 @@ jobs: displayName: 'Install Dependencies' - script: 'yarn build' - displayName: 'Build' + displayName: 'Build Bundle' + condition: eq(variables['BuildConfiguration'], 'bundle') + + - script: 'yarn build --standalone' + displayName: 'Build Standalone' + condition: eq(variables['BuildConfiguration'], 'standalone') - script: 'test -d dist' displayName: 'Check Build' - - script: 'yarn pack --filename jellyfin-web.tgz' - displayName: 'Bundle Release' + - script: 'mv dist jellyfin-web' + displayName: 'Rename Directory' - task: PublishPipelineArtifact@1 displayName: 'Publish Release' condition: succeeded() inputs: - targetPath: '$(Build.SourcesDirectory)/jellyfin-web.tgz' - artifactName: 'jellyfin-web' + targetPath: '$(Build.SourcesDirectory)/jellyfin-web' + artifactName: 'jellyfin-web-$(BuildConfiguration)' - job: lint displayName: 'Lint' From 2cb68b9a243f11ca0c7a8aafcb7ce96a938aa4c9 Mon Sep 17 00:00:00 2001 From: dkanada Date: Tue, 17 Mar 2020 00:04:52 +0900 Subject: [PATCH 030/338] improve build times and modify yarn scripts --- .ci/azure-pipelines.yml | 10 ++++++---- package.json | 5 +++-- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/.ci/azure-pipelines.yml b/.ci/azure-pipelines.yml index 1a0f11a64..7e929f40f 100644 --- a/.ci/azure-pipelines.yml +++ b/.ci/azure-pipelines.yml @@ -16,9 +16,6 @@ jobs: - job: build displayName: 'Build' - dependsOn: lint - condition: succeeded() - pool: vmImage: 'ubuntu-latest' @@ -30,7 +27,7 @@ jobs: BuildConfiguration: bundle Standalone: BuildConfiguration: standalone - maxParallel: 2 + maxParallel: 3 steps: - task: NodeTool@0 @@ -41,6 +38,10 @@ jobs: - script: 'yarn install' displayName: 'Install Dependencies' + - script: 'yarn build' + displayName: 'Build Development' + condition: eq(variables['BuildConfiguration'], 'development') + - script: 'yarn build' displayName: 'Build Bundle' condition: eq(variables['BuildConfiguration'], 'bundle') @@ -54,6 +55,7 @@ jobs: - script: 'mv dist jellyfin-web' displayName: 'Rename Directory' + condition: succeeded() - task: PublishPipelineArtifact@1 displayName: 'Publish Release' diff --git a/package.json b/package.json index 90d463fb4..5ad70cacd 100644 --- a/package.json +++ b/package.json @@ -90,9 +90,10 @@ ], "scripts": { "serve": "gulp serve", - "build": "gulp --bundle", + "build": "gulp", + "build development": "gulp --development", + "build bundle": "gulp --bundle", "build standalone": "gulp --standalone", - "build development": "gulp", "lint": "eslint \"src\"", "stylelint": "stylelint \"src/**/*.css\"" } From 89ba9cf5d76108bbdaa8c5b7efb93dde741df4e8 Mon Sep 17 00:00:00 2001 From: dkanada Date: Tue, 17 Mar 2020 00:17:46 +0900 Subject: [PATCH 031/338] cache build dependencies on ci --- .ci/azure-pipelines.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.ci/azure-pipelines.yml b/.ci/azure-pipelines.yml index 7e929f40f..b606ac410 100644 --- a/.ci/azure-pipelines.yml +++ b/.ci/azure-pipelines.yml @@ -38,6 +38,12 @@ jobs: - script: 'yarn install' displayName: 'Install Dependencies' + - task: Cache@2 + displayName: 'Cache Dependencies' + inputs: + key: 'yarn | yarn.lock' + path: '$(Pipeline.Workspace)/.yarn' + - script: 'yarn build' displayName: 'Build Development' condition: eq(variables['BuildConfiguration'], 'development') From 9767ecb47440e31257c0ad1ee2012e9d240035ad Mon Sep 17 00:00:00 2001 From: dkanada Date: Tue, 17 Mar 2020 00:32:46 +0900 Subject: [PATCH 032/338] cache the right folder --- .ci/azure-pipelines.yml | 2 +- README.md | 11 +++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/.ci/azure-pipelines.yml b/.ci/azure-pipelines.yml index b606ac410..c14717136 100644 --- a/.ci/azure-pipelines.yml +++ b/.ci/azure-pipelines.yml @@ -42,7 +42,7 @@ jobs: displayName: 'Cache Dependencies' inputs: key: 'yarn | yarn.lock' - path: '$(Pipeline.Workspace)/.yarn' + path: '$(Pipeline.Workspace)/.node_modules' - script: 'yarn build' displayName: 'Build Development' diff --git a/README.md b/README.md index 4ee78ed78..6ad4bfcbb 100644 --- a/README.md +++ b/README.md @@ -50,25 +50,32 @@ Jellyfin Web is the frontend used for most of the clients available for end user ### Getting Started 1. Clone or download this repository. + ```sh git clone https://github.com/jellyfin/jellyfin-web.git cd jellyfin-web ``` + 2. Install build dependencies in the project directory. + ```sh yarn install ``` 3. Run the web client with webpack for local development. + ```sh yarn serve ``` 4. Build the client with sourcemaps. + '''sh yarn ''' - Or without sourcemaps + + You can build a nginx compatible version as well. + '''sh - yarn --production + yarn --standalone ''' \ No newline at end of file From 2ecba9cd14a712054e7246c5fa4252d1296e492c Mon Sep 17 00:00:00 2001 From: dkanada Date: Tue, 17 Mar 2020 00:37:21 +0900 Subject: [PATCH 033/338] more readme changes --- .ci/azure-pipelines.yml | 2 +- README.md | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.ci/azure-pipelines.yml b/.ci/azure-pipelines.yml index c14717136..f5515e8f6 100644 --- a/.ci/azure-pipelines.yml +++ b/.ci/azure-pipelines.yml @@ -42,7 +42,7 @@ jobs: displayName: 'Cache Dependencies' inputs: key: 'yarn | yarn.lock' - path: '$(Pipeline.Workspace)/.node_modules' + path: '$(Pipeline.Workspace)/node_modules' - script: 'yarn build' displayName: 'Build Development' diff --git a/README.md b/README.md index 6ad4bfcbb..f1716d046 100644 --- a/README.md +++ b/README.md @@ -70,12 +70,12 @@ Jellyfin Web is the frontend used for most of the clients available for end user 4. Build the client with sourcemaps. - '''sh + ```sh yarn - ''' + ``` You can build a nginx compatible version as well. - '''sh + ```sh yarn --standalone - ''' \ No newline at end of file + ``` \ No newline at end of file From 62e8d22f660675642ab67b20d07efda9ac29e434 Mon Sep 17 00:00:00 2001 From: dkanada Date: Tue, 17 Mar 2020 00:43:13 +0900 Subject: [PATCH 034/338] check cache before installing dependencies --- .ci/azure-pipelines.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.ci/azure-pipelines.yml b/.ci/azure-pipelines.yml index f5515e8f6..bb11c83e8 100644 --- a/.ci/azure-pipelines.yml +++ b/.ci/azure-pipelines.yml @@ -35,15 +35,15 @@ jobs: inputs: versionSpec: '10.x' - - script: 'yarn install' - displayName: 'Install Dependencies' - - task: Cache@2 - displayName: 'Cache Dependencies' + displayName: 'Check Cache' inputs: key: 'yarn | yarn.lock' path: '$(Pipeline.Workspace)/node_modules' + - script: 'yarn install' + displayName: 'Install Dependencies' + - script: 'yarn build' displayName: 'Build Development' condition: eq(variables['BuildConfiguration'], 'development') From 88309a9cb4c8dbd841d9fffe7cbf0ae345f5ba0c Mon Sep 17 00:00:00 2001 From: dkanada Date: Tue, 17 Mar 2020 00:49:38 +0900 Subject: [PATCH 035/338] output files for testing --- .ci/azure-pipelines.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.ci/azure-pipelines.yml b/.ci/azure-pipelines.yml index bb11c83e8..13970939c 100644 --- a/.ci/azure-pipelines.yml +++ b/.ci/azure-pipelines.yml @@ -44,6 +44,9 @@ jobs: - script: 'yarn install' displayName: 'Install Dependencies' + - script: 'ls -al $(Pipeline.Workspace)' + displayName: 'Output Files' + - script: 'yarn build' displayName: 'Build Development' condition: eq(variables['BuildConfiguration'], 'development') From 43d81f5cd954d163e3a1f6be206b3a17936021df Mon Sep 17 00:00:00 2001 From: dkanada Date: Tue, 17 Mar 2020 01:02:11 +0900 Subject: [PATCH 036/338] update cache and add prepare --- .ci/azure-pipelines.yml | 5 +---- package.json | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/.ci/azure-pipelines.yml b/.ci/azure-pipelines.yml index 13970939c..de7780f67 100644 --- a/.ci/azure-pipelines.yml +++ b/.ci/azure-pipelines.yml @@ -39,14 +39,11 @@ jobs: displayName: 'Check Cache' inputs: key: 'yarn | yarn.lock' - path: '$(Pipeline.Workspace)/node_modules' + path: 'node_modules' - script: 'yarn install' displayName: 'Install Dependencies' - - script: 'ls -al $(Pipeline.Workspace)' - displayName: 'Output Files' - - script: 'yarn build' displayName: 'Build Development' condition: eq(variables['BuildConfiguration'], 'development') diff --git a/package.json b/package.json index 5ad70cacd..7ec376e74 100644 --- a/package.json +++ b/package.json @@ -90,7 +90,7 @@ ], "scripts": { "serve": "gulp serve", - "build": "gulp", + "prepare": "gulp --bundle", "build development": "gulp --development", "build bundle": "gulp --bundle", "build standalone": "gulp --standalone", From b5a9273a2413b848a8c053615ded10b1a7df52ed Mon Sep 17 00:00:00 2001 From: dkanada Date: Tue, 17 Mar 2020 01:09:25 +0900 Subject: [PATCH 037/338] change build commands --- .ci/azure-pipelines.yml | 6 +++--- package.json | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.ci/azure-pipelines.yml b/.ci/azure-pipelines.yml index de7780f67..a3426e011 100644 --- a/.ci/azure-pipelines.yml +++ b/.ci/azure-pipelines.yml @@ -44,15 +44,15 @@ jobs: - script: 'yarn install' displayName: 'Install Dependencies' - - script: 'yarn build' + - script: 'yarn build:development' displayName: 'Build Development' condition: eq(variables['BuildConfiguration'], 'development') - - script: 'yarn build' + - script: 'yarn build:bundle' displayName: 'Build Bundle' condition: eq(variables['BuildConfiguration'], 'bundle') - - script: 'yarn build --standalone' + - script: 'yarn build:standalone' displayName: 'Build Standalone' condition: eq(variables['BuildConfiguration'], 'standalone') diff --git a/package.json b/package.json index 7ec376e74..c4679e51e 100644 --- a/package.json +++ b/package.json @@ -91,9 +91,9 @@ "scripts": { "serve": "gulp serve", "prepare": "gulp --bundle", - "build development": "gulp --development", - "build bundle": "gulp --bundle", - "build standalone": "gulp --standalone", + "build:development": "gulp --development", + "build:bundle": "gulp --bundle", + "build:standalone": "gulp --standalone", "lint": "eslint \"src\"", "stylelint": "stylelint \"src/**/*.css\"" } From be65bdad161cceb0c2b3d2bde99088bc8e3d4c1d Mon Sep 17 00:00:00 2001 From: dkanada Date: Tue, 17 Mar 2020 01:27:14 +0900 Subject: [PATCH 038/338] update build process in readme --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f1716d046..e2aac6b15 100644 --- a/README.md +++ b/README.md @@ -71,11 +71,11 @@ Jellyfin Web is the frontend used for most of the clients available for end user 4. Build the client with sourcemaps. ```sh - yarn + yarn build:development ``` You can build a nginx compatible version as well. ```sh - yarn --standalone + yarn build:standalone ``` \ No newline at end of file From a0c5920e7178a1d59dfdcb374b03b1557754ad5c Mon Sep 17 00:00:00 2001 From: dkanada Date: Tue, 17 Mar 2020 01:47:57 +0900 Subject: [PATCH 039/338] run ci without changing the lockfile --- .ci/azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/azure-pipelines.yml b/.ci/azure-pipelines.yml index a3426e011..bbac82efe 100644 --- a/.ci/azure-pipelines.yml +++ b/.ci/azure-pipelines.yml @@ -41,7 +41,7 @@ jobs: key: 'yarn | yarn.lock' path: 'node_modules' - - script: 'yarn install' + - script: 'yarn install --pure-lockfile' displayName: 'Install Dependencies' - script: 'yarn build:development' From fa5e1feaab8c8a2665af1680c359cfff34146f49 Mon Sep 17 00:00:00 2001 From: dkanada Date: Tue, 17 Mar 2020 01:49:43 +0900 Subject: [PATCH 040/338] skip dependency step when cache exists --- .ci/azure-pipelines.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.ci/azure-pipelines.yml b/.ci/azure-pipelines.yml index bbac82efe..6f3e2f98e 100644 --- a/.ci/azure-pipelines.yml +++ b/.ci/azure-pipelines.yml @@ -40,9 +40,11 @@ jobs: inputs: key: 'yarn | yarn.lock' path: 'node_modules' + cacheHitVar: CACHE_RESTORED - script: 'yarn install --pure-lockfile' displayName: 'Install Dependencies' + condition: ne(variables.CACHE_RESTORED, 'true') - script: 'yarn build:development' displayName: 'Build Development' From 3958548b1f5f39f3f852fccbfbe53ddf05af7856 Mon Sep 17 00:00:00 2001 From: dkanada Date: Tue, 17 Mar 2020 02:12:05 +0900 Subject: [PATCH 041/338] fix issues with standalone build --- .ci/azure-pipelines.yml | 8 ++++---- gulpfile.js | 12 ++++++------ package.json | 6 +++--- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.ci/azure-pipelines.yml b/.ci/azure-pipelines.yml index 6f3e2f98e..28053bf3a 100644 --- a/.ci/azure-pipelines.yml +++ b/.ci/azure-pipelines.yml @@ -23,8 +23,8 @@ jobs: matrix: Development: BuildConfiguration: development - Bundle: - BuildConfiguration: bundle + Production: + BuildConfiguration: production Standalone: BuildConfiguration: standalone maxParallel: 3 @@ -50,9 +50,9 @@ jobs: displayName: 'Build Development' condition: eq(variables['BuildConfiguration'], 'development') - - script: 'yarn build:bundle' + - script: 'yarn build:production' displayName: 'Build Bundle' - condition: eq(variables['BuildConfiguration'], 'bundle') + condition: eq(variables['BuildConfiguration'], 'production') - script: 'yarn build:standalone' displayName: 'Build Standalone' diff --git a/gulpfile.js b/gulpfile.js index f49805d34..ca6cf36dd 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -10,7 +10,7 @@ const htmlmin = require('gulp-htmlmin'); const imagemin = require('gulp-imagemin'); const sourcemaps = require('gulp-sourcemaps'); const mode = require('gulp-mode')({ - modes: ["development", "bundle", "standalone"], + modes: ["development", "production"], default: "development", verbose: false }); @@ -22,7 +22,7 @@ const sass = require('gulp-sass'); sass.compiler = require('node-sass') -if (mode.bundle() || mode.standalone()) { +if (mode.production()) { var config = require('./webpack.prod.js'); } else { var config = require('./webpack.dev.js'); @@ -91,15 +91,14 @@ function css() { function html() { return src(['src/**/*.html', '!src/index.html'], { base: './src/' }) - .pipe(mode.bundle(htmlmin({ collapseWhitespace: true }))) - .pipe(mode.standalone(htmlmin({ collapseWhitespace: true }))) + .pipe(mode.production(htmlmin({ collapseWhitespace: true }))) .pipe(dest('dist/')) .pipe(browserSync.stream()); } function images() { return src(['src/**/*.png', 'src/**/*.jpg', 'src/**/*.gif', 'src/**/*.svg'], { base: './src/' }) - .pipe(imagemin()) + .pipe(mode.production(imagemin())) .pipe(dest('dist/')) .pipe(browserSync.stream()); } @@ -120,4 +119,5 @@ function injectBundle() { } exports.default = series(clean, parallel(javascript, webpack, css, html, images, copy), injectBundle) -exports.serve = series(exports.default, standalone, serve) +exports.standalone = series(exports.default, standalone) +exports.serve = series(exports.standalone, serve) diff --git a/package.json b/package.json index c4679e51e..90cfa954a 100644 --- a/package.json +++ b/package.json @@ -90,10 +90,10 @@ ], "scripts": { "serve": "gulp serve", - "prepare": "gulp --bundle", + "prepare": "gulp --production", "build:development": "gulp --development", - "build:bundle": "gulp --bundle", - "build:standalone": "gulp --standalone", + "build:production": "gulp --production", + "build:standalone": "gulp standalone --development", "lint": "eslint \"src\"", "stylelint": "stylelint \"src/**/*.css\"" } From 38b7da8f34676beef6b6fa982ae7c90cedc82be8 Mon Sep 17 00:00:00 2001 From: dkanada Date: Tue, 17 Mar 2020 02:17:12 +0900 Subject: [PATCH 042/338] use cache for linting as well --- .ci/azure-pipelines.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.ci/azure-pipelines.yml b/.ci/azure-pipelines.yml index 28053bf3a..40d9a7815 100644 --- a/.ci/azure-pipelines.yml +++ b/.ci/azure-pipelines.yml @@ -84,8 +84,16 @@ jobs: inputs: versionSpec: '10.x' - - script: 'yarn install' + - task: Cache@2 + displayName: 'Check Cache' + inputs: + key: 'yarn | yarn.lock' + path: 'node_modules' + cacheHitVar: CACHE_RESTORED + + - script: 'yarn install --pure-lockfile' displayName: 'Install Dependencies' + condition: ne(variables.CACHE_RESTORED, 'true') - script: 'yarn run lint' displayName: 'Run ESLint' From 519751649d30b9667ead714c9643702e936577ed Mon Sep 17 00:00:00 2001 From: dkanada Date: Tue, 17 Mar 2020 03:05:18 +0900 Subject: [PATCH 043/338] apply suggestions from code review Co-Authored-By: Julien Machiels --- .ci/azure-pipelines.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.ci/azure-pipelines.yml b/.ci/azure-pipelines.yml index 40d9a7815..48f042d72 100644 --- a/.ci/azure-pipelines.yml +++ b/.ci/azure-pipelines.yml @@ -42,7 +42,7 @@ jobs: path: 'node_modules' cacheHitVar: CACHE_RESTORED - - script: 'yarn install --pure-lockfile' + - script: 'yarn install --frozen-lockfile' displayName: 'Install Dependencies' condition: ne(variables.CACHE_RESTORED, 'true') @@ -91,7 +91,7 @@ jobs: path: 'node_modules' cacheHitVar: CACHE_RESTORED - - script: 'yarn install --pure-lockfile' + - script: 'yarn install --frozen-lockfile' displayName: 'Install Dependencies' condition: ne(variables.CACHE_RESTORED, 'true') From c5cdea622a99067f98f52198384b6af066a44016 Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Mon, 16 Mar 2020 16:02:47 -0400 Subject: [PATCH 044/338] Fix schedules direct buttons being hidden by default --- src/components/tvproviders/schedulesdirect.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/components/tvproviders/schedulesdirect.js b/src/components/tvproviders/schedulesdirect.js index a1265e7cc..5283cd231 100644 --- a/src/components/tvproviders/schedulesdirect.js +++ b/src/components/tvproviders/schedulesdirect.js @@ -264,13 +264,15 @@ define(["jQuery", "loading", "emby-checkbox", "listViewStyle", "emby-input", "em self.init = function () { options = options || {}; - if (options.showCancelButton) { + // Show cancel button by default + if (options.showCancelButton !== false) { page.querySelector(".btnCancel").classList.remove("hide"); } else { page.querySelector(".btnCancel").classList.add("hide"); } - if (options.showSubmitButton) { + // Show submit button by default + if (options.showSubmitButton !== false) { page.querySelector(".btnSubmitListings").classList.remove("hide"); } else { page.querySelector(".btnSubmitListings").classList.add("hide"); From 9b96e7a658d09834b3eea0728268bd14ff954b15 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Tue, 17 Mar 2020 08:20:05 +0100 Subject: [PATCH 045/338] Show missing indicator in ListView --- src/components/listview/listview.css | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/components/listview/listview.css b/src/components/listview/listview.css index b653502da..1e485a80e 100644 --- a/src/components/listview/listview.css +++ b/src/components/listview/listview.css @@ -238,13 +238,6 @@ background-color: transparent !important; } -.listItemMediaInfo { - /* Don't display if flex not supported */ - display: none; - align-items: center; - margin-right: 1em; -} - .listGroupHeader-first { margin-top: 0; } From 2c0ee853377e1567920edcccfc4a86852c6ef1c9 Mon Sep 17 00:00:00 2001 From: Fernando Date: Wed, 18 Mar 2020 18:35:05 +0000 Subject: [PATCH 046/338] Translated using Weblate (Spanish) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/es/ --- src/strings/es.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/strings/es.json b/src/strings/es.json index 6abc351d5..3d56ff56d 100644 --- a/src/strings/es.json +++ b/src/strings/es.json @@ -1248,8 +1248,8 @@ "Descending": "Descendiente", "DirectStreamHelp1": "El tipo de archivo (H.264, AC3, etc.) y la resolución son compatibles con el dispositivo, pero no el contenedor (mkv, avi, wmv, etc.). El vídeo será re-empaquetado al vuelo antes de transmitirlo al dispositivo.", "DirectStreamHelp2": "La transmisión directa del archivo usa muy poco procesamiento sin ninguna pérdida de calidad en el vídeo.", - "Director": "Director", - "DirectorValue": "Director: {0}", + "Director": "Dirección de", + "DirectorValue": "Dirección de: {0}", "DirectorsValue": "Directores: {0}", "Display": "Mostrar", "DisplayInMyMedia": "Mostrar en la pantalla de inicio", From a01c03c9caf3f2e65654776bc9de66fa0c25b696 Mon Sep 17 00:00:00 2001 From: Julien Machiels Date: Wed, 18 Mar 2020 13:58:23 +0000 Subject: [PATCH 047/338] Translated using Weblate (French) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/fr/ --- src/strings/fr.json | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/strings/fr.json b/src/strings/fr.json index da4505424..4a52756ec 100644 --- a/src/strings/fr.json +++ b/src/strings/fr.json @@ -175,9 +175,9 @@ "DirectStreamHelp1": "Le média est compatible avec l'appareil en ce qui concerne la résolution et le type de média (H.264, AC3, etc), mais se trouve dans un conteneur de fichiers incompatible (mkv, avi, wmv, etc). La vidéo sera rempaquetée à la volée avant d'être diffusée à l'appareil.", "DirectStreamHelp2": "Le streaming en direct d'un fichier utilise très peu de puissance de traitement sans perte de qualité vidéo.", "DirectStreaming": "Streaming direct", - "Director": "Réalisateur(trice)", - "DirectorValue": "Réalisateur: {0}", - "DirectorsValue": "Réalisateurs: {0}", + "Director": "Réalisation", + "DirectorValue": "Réalisation : {0}", + "DirectorsValue": "Réalisation : {0}", "Disabled": "Désactivé", "Disc": "Disque", "Disconnect": "Déconnecter", @@ -1457,14 +1457,14 @@ "SelectAdminUsername": "Veuillez choisir un nom d'utilisateur pour le compte administrateur.", "HeaderNavigation": "Navigation", "OptionForceRemoteSourceTranscoding": "Transcodage forcé pour sources de media à distance (ex: TV en direct)", - "MessageConfirmAppExit": "Sortir?", - "LabelVideoResolution": "Résolution vidéo", - "LabelStreamType": "Type de flux", + "MessageConfirmAppExit": "Voulez-vous quitter ?", + "LabelVideoResolution": "Résolution vidéo :", + "LabelStreamType": "Type de flux :", "EnableFastImageFadeInHelp": "Activer un transition plus rapide pour images téléchargées", "EnableFastImageFadeIn": "Transition d'image rapide", - "LabelPlayerDimensions": "Dimension du lecteur", - "LabelDroppedFrames": "Cadre informatique oublié", - "LabelCorruptedFrames": "Cadre informatique corrompu", + "LabelPlayerDimensions": "Dimension du lecteur:", + "LabelDroppedFrames": "Images perdues:", + "LabelCorruptedFrames": "Images corrompues:", "CopyStreamURLError": "Il y a eu une erreur lors de la copie du URL.", "AskAdminToCreateLibrary": "Demander à un administrateur de créer une médiathèque.", "AllowFfmpegThrottlingHelp": "Quand le transcodage ou le remultiplexage est suffisamment loin de la position de lecture, le processus se mettra en pause afin d’économiser des ressources. Plus utile lors d’une lecture continue. À désactiver en cas de problèmes de lecture.", From d791da07e39240696e57463466a681cafcb9ba49 Mon Sep 17 00:00:00 2001 From: ferferga Date: Thu, 19 Mar 2020 00:17:51 +0100 Subject: [PATCH 048/338] Translate alerts --- src/components/directorybrowser/directorybrowser.js | 7 +++---- src/strings/en-us.json | 4 +++- src/strings/es.json | 4 +++- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/components/directorybrowser/directorybrowser.js b/src/components/directorybrowser/directorybrowser.js index b71f7bbb0..db53f0a39 100644 --- a/src/components/directorybrowser/directorybrowser.js +++ b/src/components/directorybrowser/directorybrowser.js @@ -163,16 +163,15 @@ define(['loading', 'dialogHelper', 'dom', 'listViewStyle', 'emby-input', 'paper- } }).catch(function(response) { if (response) { - // TODO All alerts (across the project), should use Globalize.translate() if (response.status === 404) { - alertText("The path could not be found. Please ensure the path is valid and try again."); + alertText(Globalize.translate("PathNotFound")); return Promise.reject(); } if (response.status === 500) { if (validateWriteable) { - alertText("Jellyfin Server requires write access to this folder. Please ensure write access and try again."); + alertText(Globalize.translate("WriteAccessRequired")); } else { - alertText("The path could not be found. Please ensure the path is valid and try again.") + alertText(Globalize.translate("PathNotFound")) } return Promise.reject() } diff --git a/src/strings/en-us.json b/src/strings/en-us.json index 62e8fa3f8..784fa7c7a 100644 --- a/src/strings/en-us.json +++ b/src/strings/en-us.json @@ -1468,5 +1468,7 @@ "XmlTvPathHelp": "A path to a XMLTV file. Jellyfin will read this file and periodically check it for updates. You are responsible for creating and updating the file.", "XmlTvSportsCategoriesHelp": "Programs with these categories will be displayed as sports programs. Separate multiple with '|'.", "Yes": "Yes", - "Yesterday": "Yesterday" + "Yesterday": "Yesterday", + "PathNotFound": "The path could not be found. Please ensure the path is valid and try again.", + "WriteAccessRequired": "Jellyfin Server requires write access to this folder. Please ensure write access and try again." } diff --git a/src/strings/es.json b/src/strings/es.json index 3d56ff56d..442459c9e 100644 --- a/src/strings/es.json +++ b/src/strings/es.json @@ -1476,5 +1476,7 @@ "LabelDroppedFrames": "Frames perdidos:", "LabelCorruptedFrames": "Frames corruptos:", "AskAdminToCreateLibrary": "Solo un administrador puede crear librerías.", - "AllowFfmpegThrottling": "Acelerar transcodificación" + "AllowFfmpegThrottling": "Acelerar transcodificación", + "PathNotFound": "No se encontró la ruta especificada. Asegúrate de que existe e inténtalo de nuevo.", + "WriteAccessRequired": "Jellyfin requiere de permisos de escritura en esta carpeta. Asegúrate de que existe este permiso e inténtalo de nuevo." } From e383c3dee1c52d17b644079359a8e5ff70ce2f6c Mon Sep 17 00:00:00 2001 From: ferferga Date: Thu, 19 Mar 2020 00:40:17 +0100 Subject: [PATCH 049/338] Translate paging phrase --- src/components/imagedownloader/imagedownloader.js | 2 +- src/scripts/librarybrowser.js | 2 +- src/strings/en-us.json | 3 ++- src/strings/es.json | 3 ++- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/components/imagedownloader/imagedownloader.js b/src/components/imagedownloader/imagedownloader.js index ce53b5cf0..947a50135 100644 --- a/src/components/imagedownloader/imagedownloader.js +++ b/src/components/imagedownloader/imagedownloader.js @@ -109,7 +109,7 @@ define(['loading', 'apphost', 'dialogHelper', 'connectionManager', 'imageLoader' html += ''; var startAtDisplay = totalRecordCount ? startIndex + 1 : 0; - html += startAtDisplay + '-' + recordsEnd + ' of ' + totalRecordCount; + html += globalize.translate("ListPaging").replace("{0}", startAtDisplay + '-' + recordsEnd).replace("{1}", totalRecordCount); html += ''; diff --git a/src/scripts/librarybrowser.js b/src/scripts/librarybrowser.js index bd8980aed..a570558f4 100644 --- a/src/scripts/librarybrowser.js +++ b/src/scripts/librarybrowser.js @@ -83,7 +83,7 @@ define(["userSettings"], function (userSettings) { if (html += '
', showControls) { html += ''; - html += (totalRecordCount ? startIndex + 1 : 0) + "-" + recordsEnd + " of " + totalRecordCount; + html += Globalize.translate("ListPaging").replace("{0}", (totalRecordCount ? startIndex + 1 : 0) + "-" + recordsEnd).replace("{1}", totalRecordCount); html += ""; } diff --git a/src/strings/en-us.json b/src/strings/en-us.json index 784fa7c7a..f3e7756f5 100644 --- a/src/strings/en-us.json +++ b/src/strings/en-us.json @@ -1470,5 +1470,6 @@ "Yes": "Yes", "Yesterday": "Yesterday", "PathNotFound": "The path could not be found. Please ensure the path is valid and try again.", - "WriteAccessRequired": "Jellyfin Server requires write access to this folder. Please ensure write access and try again." + "WriteAccessRequired": "Jellyfin Server requires write access to this folder. Please ensure write access and try again.", + "ListPaging": "{0} of {1}" } diff --git a/src/strings/es.json b/src/strings/es.json index 442459c9e..138d19f86 100644 --- a/src/strings/es.json +++ b/src/strings/es.json @@ -1478,5 +1478,6 @@ "AskAdminToCreateLibrary": "Solo un administrador puede crear librerías.", "AllowFfmpegThrottling": "Acelerar transcodificación", "PathNotFound": "No se encontró la ruta especificada. Asegúrate de que existe e inténtalo de nuevo.", - "WriteAccessRequired": "Jellyfin requiere de permisos de escritura en esta carpeta. Asegúrate de que existe este permiso e inténtalo de nuevo." + "WriteAccessRequired": "Jellyfin requiere de permisos de escritura en esta carpeta. Asegúrate de que existe este permiso e inténtalo de nuevo.", + "ListPaging": "{0} de {1}" } From 3f47733c35fe0075bb6ab6eff199d8690021743b Mon Sep 17 00:00:00 2001 From: Mednis Date: Wed, 18 Mar 2020 23:47:58 +0000 Subject: [PATCH 050/338] Translated using Weblate (Latvian) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/lv/ --- src/strings/lv.json | 53 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 42 insertions(+), 11 deletions(-) diff --git a/src/strings/lv.json b/src/strings/lv.json index ca28c7758..034609a48 100644 --- a/src/strings/lv.json +++ b/src/strings/lv.json @@ -32,11 +32,11 @@ "MessageDownloadQueued": "Lejupielāde ierindota.", "MessageCreateAccountAt": "Izveido kontu {0}", "MessageContactAdminToResetPassword": "Lūdzu sazinies ar sistēmas administratoru lai atiestatītu paroli.", - "MessageConfirmShutdown": "Vai tu tiešām gribi izslēgt serveri?", - "MessageConfirmRestart": "Vai tu tiešām gribi restartēt Jellyfin Server?", - "MessageConfirmRemoveMediaLocation": "Vai tu tiešām gribi noņemt šo ceļu?", + "MessageConfirmShutdown": "Vai tu tiešām vēlies izslēgt serveri?", + "MessageConfirmRestart": "Vai tu tiešām vēlies restartēt Jellyfin Server?", + "MessageConfirmRemoveMediaLocation": "Vai tu tiešām vēlies noņemt šo ceļu?", "MessageConfirmRecordingCancellation": "Atcelt ierakstu?", - "MessageConfirmAppExit": "Vai tu gribi iziet?", + "MessageConfirmAppExit": "Vai tu vēlies iziet?", "MessageAlreadyInstalled": "Šī versija jau ir uzstādīta.", "MediaInfoStreamTypeVideo": "Video", "MediaInfoStreamTypeSubtitle": "Subtitri", @@ -698,7 +698,7 @@ "Unplayed": "Neatskaņots", "Unmute": "Ieslēgt skaņu", "UninstallPluginHeader": "Noņemt Paplašinājumu", - "UninstallPluginConfirmation": "Vai tu tiešām gribi noņemt {0}?", + "UninstallPluginConfirmation": "Vai tu tiešām vēlies noņemt {0}?", "Tuesday": "Otrdiena", "Transcoding": "Trans-kodēšana", "Trailers": "Treileri", @@ -916,9 +916,9 @@ "HeaderTaskTriggers": "Uzdevumu Trigeri", "HeaderSelectTranscodingPathHelp": "Pārlūko vai ievadi ceļu, kurā tiks glabātas īslaicīgās trans-kodēšanas datnes. Šai mapei jābūt rakstāmai.", "HeaderSelectTranscodingPath": "Izvēlies Trans-kodēšanas Īslaicīgo Ceļu", - "HeaderSelectServerCachePathHelp": "Pārlūko vai ievadi ceļu, kurā tu gribi saglabāt servera keša datnes. Šai mapei jābūt rakstāmai.", + "HeaderSelectServerCachePathHelp": "Pārlūko vai ievadi ceļu, kurā vēlies saglabāt servera keša datnes. Šai mapei jābūt rakstāmai.", "HeaderSelectPath": "Izvēlies Ceļu", - "HeaderSelectMetadataPathHelp": "Pārlūko vai ievadi ceļu, kurā tu gribi saglabāt metadatus. Šai mapei jābūt rakstāmai.", + "HeaderSelectMetadataPathHelp": "Pārlūko vai ievadi ceļu, kurā vēlies saglabāt metadatus. Šai mapei jābūt rakstāmai.", "HeaderSelectMetadataPath": "Izvēlies Metadatu Ceļu", "HeaderSelectCertificatePath": "Izvēlies Sertifikāta Ceļu", "HeaderScenes": "Ainas", @@ -975,11 +975,11 @@ "DirectStreamHelp1": "Šis medijs ir saderīgs ar ierīci pēc izšķirtspējas un medija veida (H.264, AC3, utt.), bet atrodas nesaderīgā datnes konteinerī (mkv, avi, wmv, utt.). Video tiks pārpakots uz saderīgu formātu pirms tas tiks straumēts uz ierīci.", "Descending": "Disltošs", "Depressed": "Atspiests", - "DeleteUserConfirmation": "Vai tu tiešām gribi izdzēst šo lietotāju?", + "DeleteUserConfirmation": "Vai tu tiešām vēlies izdzēst šo lietotāju?", "DeleteUser": "Dzēst Lietotāju", "DeleteMedia": "Dzēst mediju", - "DeleteImageConfirmation": "Vai tu tiešām gribi izdzēst šo attēlu?", - "DeleteDeviceConfirmation": "Vai tu tiešām gribi noņemt šo ierīci? Tā parādīsies atkārtoti nākamo reizi, kad lietotājs ieiet ar to.", + "DeleteImageConfirmation": "Vai tu tiešām vēlies izdzēst šo attēlu?", + "DeleteDeviceConfirmation": "Vai tu tiešām vēlies noņemt šo ierīci? Tā parādīsies atkārtoti nākamo reizi, kad lietotājs ieiet ar to.", "DefaultErrorMessage": "Apstrādājot pieprasījumu notika kļūda. Pēc brītiņa lūdzu mēģini vēlreiz.", "DeathDateValue": "Miris: {0}", "ConfirmEndPlayerSession": "Vai jūs gribat izslēgt Jellyfin uz {0}?", @@ -1046,5 +1046,36 @@ "LabelKodiMetadataSaveImagePathsHelp": "Tas ir ieteicams ja tev ir attēlu datņu nosaukumi, kas neatbilst Kodi vadlīnijām.", "LabelKodiMetadataSaveImagePaths": "Saglabāt attēlu ceļus iekš nfo datnēm", "LabelKodiMetadataEnablePathSubstitutionHelp": "Iespējot ceļu substitūciju attēlu ceļiem izmantojot serveru ceļu substitūcijas iestatījumus.", - "LabelKodiMetadataEnablePathSubstitution": "Iespējot ceļu substitūciju" + "LabelKodiMetadataEnablePathSubstitution": "Iespējot ceļu substitūciju", + "MessageDirectoryPickerBSDInstruction": "Priekš BSD, tev var būt vajadzēs nokonfigurēt glabātuvi savā FreeNAS jail, lai atļautu Jellyfin tai piekļuvi.", + "MessageConfirmRevokeApiKey": "Vai tu tiešām vēlies atsaukt šo api atslēgu? Lietotnes savienojums ar Jellyfin Serveri tiks strauji atslēgts.", + "MessageConfirmProfileDeletion": "Vai tu tiešām vēlies izdzēst šo profilu?", + "LabelTranscodingProgress": "Trans-kodēšanas progress:", + "LabelTranscodingFramerate": "Trans-kodēšanas kadru ātrums:", + "LabelRecordingPathHelp": "Ievadi noklusējuma vietējo vietu, kur saglabāt ierakstus. Ja atstāsts tukšs, servera programmas datu mape tiks lietota tā vietā.", + "LabelPublicHttpsPortHelp": "Publiskais porta numurs, ko kartēt uz vietējo HTTPS portu.", + "LabelOriginalAspectRatio": "Oriģinālās proporcijas:", + "LabelMaxStreamingBitrateHelp": "Ievadi maksimālo bitu ātrumu straumēšanai.", + "LabelLocalHttpServerPortNumberHelp": "TCP porta numurs, kuru izmantos Jellyfin HTTP serveris.", + "MessageAreYouSureYouWishToRemoveMediaFolder": "Vai tiešām vēlies noņemt šo mediju datni?", + "MessageAreYouSureDeleteSubtitles": "Vai tiešām vēlies izdzēst šo subtitru datni?", + "MediaIsBeingConverted": "Medijs tiek pārveidots uz formātu kuru atbalsta tā atskaņojošā ierīce.", + "MediaInfoStreamTypeEmbeddedImage": "Iegults Attēls", + "MediaInfoTimestamp": "Laika zīmogs", + "MediaInfoSampleRate": "Izlases ātrums", + "MediaInfoInterlaced": "Rindpārlēkts", + "MediaInfoFramerate": "Kadru ātrums", + "MediaInfoAspectRatio": "Attēla proporcijas", + "MaxParentalRatingHelp": "Saturs ar augstāku reitingu tiks paslēpts no šī lietotāja.", + "LibraryAccessHelp": "Izvēlies bibliotēkas, ko koplietot ar šo lietotāju. Administratori spēs rediģēt visas bibliotēkas izmantojot metadatu pārvaldnieku.", + "LearnHowYouCanContribute": "Uzzini, kā tu vari dot ieguldījumu.", + "LabelUserLoginAttemptsBeforeLockout": "Neizdevušies piekļuves mēģinājumi pirms lietotājs tiek bloķēts:", + "LabelTranscodingThreadCount": "Trans-kodēšanas kodolu daudzums:", + "LabelTranscodes": "Transkodi:", + "LabelTitle": "Tituls:", + "LabelSaveLocalMetadata": "Saglabāt māksu media mapēs", + "LabelReadHowYouCanContribute": "Uzzini, kā tu vari dot ieguldījumu.", + "LabelNumberOfGuideDays": "Dienu daudzumus, kuram lejupielādēt gidu:", + "LabelLockItemToPreventChanges": "Aizslēgt šo objektu lai aizliegtu izmaiņas", + "LabelLocalHttpServerPortNumber": "Vietējais HTTP porta numurs:" } From 401c2fa076a8c4350cb8993ebf1f0f1ae59cbd45 Mon Sep 17 00:00:00 2001 From: rtg Date: Thu, 19 Mar 2020 05:16:19 +0000 Subject: [PATCH 051/338] Translated using Weblate (Hindi) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/hi/ --- src/strings/hi-in.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/strings/hi-in.json b/src/strings/hi-in.json index cbcac1133..122f4aa98 100644 --- a/src/strings/hi-in.json +++ b/src/strings/hi-in.json @@ -32,5 +32,7 @@ "Aired": "प्रसारित हो चुका", "AdditionalNotificationServices": "अतिरिक्त सूचना सेवाओं को स्थापित करने के लिए प्लगइन सूची पर नज़र डालें।", "AddedOnValue": "जोड़ दिया", - "AddToPlaylist": "प्लेलिस्ट में जोड़ें" + "AddToPlaylist": "प्लेलिस्ट में जोड़ें", + "AllowMediaConversionHelp": "मीडिया परिवर्तन के लिये अनुमति दें", + "AllowMediaConversion": "मीडिया रूपांतरण की अनुमति दें" } From e0a5c5c558072d97d1ce6a70f287d1d9888d0ec1 Mon Sep 17 00:00:00 2001 From: Mednis Date: Thu, 19 Mar 2020 10:31:28 +0000 Subject: [PATCH 052/338] Translated using Weblate (Latvian) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/lv/ --- src/strings/lv.json | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/strings/lv.json b/src/strings/lv.json index 034609a48..657a2261a 100644 --- a/src/strings/lv.json +++ b/src/strings/lv.json @@ -1077,5 +1077,11 @@ "LabelReadHowYouCanContribute": "Uzzini, kā tu vari dot ieguldījumu.", "LabelNumberOfGuideDays": "Dienu daudzumus, kuram lejupielādēt gidu:", "LabelLockItemToPreventChanges": "Aizslēgt šo objektu lai aizliegtu izmaiņas", - "LabelLocalHttpServerPortNumber": "Vietējais HTTP porta numurs:" + "LabelLocalHttpServerPortNumber": "Vietējais HTTP porta numurs:", + "OptionAllowManageLiveTv": "Atļaut Tiešraides TV ierakstu pārvaldīšanu", + "OptionAllowLinkSharing": "Atļaut dalīšanos sociālajos tīklos", + "OptionAllowBrowsingLiveTv": "Atļaut Tiešraides TV piekļuvi", + "MediaInfoForced": "Piespiests", + "LabelPublicHttpPortHelp": "Publiskai porta numurs, kas tiks kartēts uz vietējo HTTP portu.", + "LabelOptionalNetworkPath": "(Neobligāts) Koplietota tīkla mape:" } From 2ef912d96078fa6978bfa8d0d082a4b9e746b672 Mon Sep 17 00:00:00 2001 From: dkanada Date: Fri, 20 Mar 2020 02:54:12 +0900 Subject: [PATCH 053/338] add method to open client settings --- src/controllers/user/menu.js | 10 ++++++++++ src/mypreferencesmenu.html | 9 +++++++++ src/strings/en-us.json | 1 + 3 files changed, 20 insertions(+) diff --git a/src/controllers/user/menu.js b/src/controllers/user/menu.js index 6087beadf..b1e2b7b51 100644 --- a/src/controllers/user/menu.js +++ b/src/controllers/user/menu.js @@ -10,6 +10,10 @@ define(["apphost", "connectionManager", "listViewStyle", "emby-button"], functio Dashboard.selectServer(); }); + view.querySelector(".clientSettings").addEventListener("click", function () { + window.NativeShell.openClientSettings(); + }); + view.addEventListener("viewshow", function() { // this page can also be used by admins to change user preferences from the user edit page var userId = params.userId || Dashboard.getCurrentUserId(); @@ -21,6 +25,12 @@ define(["apphost", "connectionManager", "listViewStyle", "emby-button"], functio page.querySelector(".lnkPlaybackPreferences").setAttribute("href", "mypreferencesplayback.html?userId=" + userId); page.querySelector(".lnkSubtitlePreferences").setAttribute("href", "mypreferencessubtitles.html?userId=" + userId); + if (window.NativeShell && window.NativeShell.AppHost.supports("clientsettings")) { + page.querySelector(".clientSettings").classList.remove("hide"); + } else { + page.querySelector(".clientSettings").classList.add("hide"); + } + if (appHost.supports("multiserver")) { page.querySelector(".selectServer").classList.remove("hide"); } else { diff --git a/src/mypreferencesmenu.html b/src/mypreferencesmenu.html index 41fcd1b75..4219059dd 100644 --- a/src/mypreferencesmenu.html +++ b/src/mypreferencesmenu.html @@ -47,6 +47,15 @@
+ + +
+ +
+
${ClientSettings}
+
+
+

${HeaderAdmin}

diff --git a/src/strings/en-us.json b/src/strings/en-us.json index 62e8fa3f8..f08de6b46 100644 --- a/src/strings/en-us.json +++ b/src/strings/en-us.json @@ -147,6 +147,7 @@ "ChannelNumber": "Channel number", "Channels": "Channels", "CinemaModeConfigurationHelp": "Cinema mode brings the theater experience straight to your living room with the ability to play trailers and custom intros before the main feature.", + "ClientSettings": "Client Settings", "Collections": "Collections", "ColorPrimaries": "Color primaries", "ColorSpace": "Color space", From 69a3c7cd538d5b35fef35b914f453e34e84ff20c Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Thu, 19 Mar 2020 14:37:48 -0400 Subject: [PATCH 054/338] Add FIXME to revisit show/hide button logic for tv providers --- src/components/tvproviders/schedulesdirect.js | 18 ++++++++++-------- src/components/tvproviders/xmltv.js | 16 ++++++++++------ 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/src/components/tvproviders/schedulesdirect.js b/src/components/tvproviders/schedulesdirect.js index 5283cd231..4a6f3d297 100644 --- a/src/components/tvproviders/schedulesdirect.js +++ b/src/components/tvproviders/schedulesdirect.js @@ -264,18 +264,20 @@ define(["jQuery", "loading", "emby-checkbox", "listViewStyle", "emby-input", "em self.init = function () { options = options || {}; - // Show cancel button by default - if (options.showCancelButton !== false) { - page.querySelector(".btnCancel").classList.remove("hide"); - } else { + // Only hide the button if explicitly set to false; default to showing if undefined or null + // FIXME: rename this option to clarify logic + if (options.showCancelButton === false) { page.querySelector(".btnCancel").classList.add("hide"); + } else { + page.querySelector(".btnCancel").classList.remove("hide"); } - // Show submit button by default - if (options.showSubmitButton !== false) { - page.querySelector(".btnSubmitListings").classList.remove("hide"); - } else { + // Only hide the button if explicitly set to false; default to showing if undefined or null + // FIXME: rename this option to clarify logic + if (options.showSubmitButton === false) { page.querySelector(".btnSubmitListings").classList.add("hide"); + } else { + page.querySelector(".btnSubmitListings").classList.remove("hide"); } $(".formLogin", page).on("submit", function () { diff --git a/src/components/tvproviders/xmltv.js b/src/components/tvproviders/xmltv.js index a86a1e109..0ba164fe2 100644 --- a/src/components/tvproviders/xmltv.js +++ b/src/components/tvproviders/xmltv.js @@ -163,16 +163,20 @@ define(["jQuery", "loading", "emby-checkbox", "emby-input", "listViewStyle", "pa self.init = function () { options = options || {}; - if (false !== options.showCancelButton) { - page.querySelector(".btnCancel").classList.remove("hide"); - } else { + // Only hide the button if explicitly set to false; default to showing if undefined or null + // FIXME: rename this option to clarify logic + if (options.showCancelButton === false) { page.querySelector(".btnCancel").classList.add("hide"); + } else { + page.querySelector(".btnCancel").classList.remove("hide"); } - if (false !== options.showSubmitButton) { - page.querySelector(".btnSubmitListings").classList.remove("hide"); - } else { + // Only hide the button if explicitly set to false; default to showing if undefined or null + // FIXME: rename this option to clarify logic + if (options.showSubmitButton === false) { page.querySelector(".btnSubmitListings").classList.add("hide"); + } else { + page.querySelector(".btnSubmitListings").classList.remove("hide"); } $("form", page).on("submit", function () { From c5bb25809bd29ce4f4baf74b379c810906987d39 Mon Sep 17 00:00:00 2001 From: pakkosauna Date: Thu, 19 Mar 2020 19:52:07 +0000 Subject: [PATCH 055/338] Translated using Weblate (Finnish) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/fi/ --- src/strings/fi.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/strings/fi.json b/src/strings/fi.json index 91e32afe6..11d497fd1 100644 --- a/src/strings/fi.json +++ b/src/strings/fi.json @@ -305,5 +305,10 @@ "EnableDisplayMirroring": "Näytön peilaus", "EnableColorCodedBackgrounds": "Väri-koodatut taustat", "EnableCinemaMode": "Teatteri-tila", - "EnableBackdropsHelp": "Näytä taustat tietyillä sivuilla selatessasi kirjastoa." + "EnableBackdropsHelp": "Näytä taustat tietyillä sivuilla selatessasi kirjastoa.", + "EnableExternalVideoPlayersHelp": "Videota soitettaessa näytetään erillinen valikko.", + "Depressed": "Painettu", + "CopyStreamURLError": "Verkko-osoitteen kopioinnissa tapahtui virhe.", + "ButtonSplit": "jaa", + "AskAdminToCreateLibrary": "Pyydä järjestelmän ylläpitäjää luomaan kirjasto." } From e8bc839d0babd2c1a63e3eb4ff253ce43c948a9c Mon Sep 17 00:00:00 2001 From: dkanada Date: Fri, 20 Mar 2020 17:49:32 +0900 Subject: [PATCH 056/338] update methods for native shell --- src/components/shell.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/components/shell.js b/src/components/shell.js index f82f5eea3..4f1aa0c8d 100644 --- a/src/components/shell.js +++ b/src/components/shell.js @@ -10,12 +10,6 @@ define([], function () { } }, - canExec: false, - exec: function (options) { - // options.path - // options.arguments - return Promise.reject(); - }, enableFullscreen: function () { if (window.NativeShell) { window.NativeShell.enableFullscreen(); From 10a49012262a9bcee2b400acce264f1f7c805e99 Mon Sep 17 00:00:00 2001 From: Medzhnun Date: Fri, 20 Mar 2020 11:28:28 +0000 Subject: [PATCH 057/338] Translated using Weblate (Bulgarian) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/bg/ --- src/strings/bg-bg.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/strings/bg-bg.json b/src/strings/bg-bg.json index d1f6b11b9..c2b0bb692 100644 --- a/src/strings/bg-bg.json +++ b/src/strings/bg-bg.json @@ -832,5 +832,9 @@ "ButtonNetwork": "Мрежа", "ButtonFullscreen": "На цял екран", "ButtonDown": "Надолу", - "ButtonConnect": "Свързване" + "ButtonConnect": "Свързване", + "AllowOnTheFlySubtitleExtraction": "Позволява моментално извличане на поднадписи", + "AllowHWTranscodingHelp": "Позволява на тунера да прекодира моментално. Това може да помогне за редуциране на прекодирането от сървъра.", + "AddItemToCollectionHelp": "Добавяне към колекция чрез търсенето им и използване на дясно-щракване с мишката или контекстното меню.", + "Absolute": "Aбсолютен" } From b34a376691d2a0bea4a085bb1ebc30c94e1cefe5 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Sat, 21 Mar 2020 00:26:55 +0100 Subject: [PATCH 058/338] Add library page size settings on movies --- src/components/displaysettings/displaysettings.js | 4 ++++ .../displaysettings/displaysettings.template.html | 5 +++++ src/controllers/movies/movies.js | 10 ++++++++-- src/scripts/settings/userSettingsBuilder.js | 13 +++++++++++++ src/strings/en-us.json | 2 ++ 5 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/components/displaysettings/displaysettings.js b/src/components/displaysettings/displaysettings.js index da407c11f..47924f137 100644 --- a/src/components/displaysettings/displaysettings.js +++ b/src/components/displaysettings/displaysettings.js @@ -186,6 +186,8 @@ define(['require', 'browser', 'layoutManager', 'appSettings', 'pluginManager', ' context.querySelector('#selectLanguage').value = userSettings.language() || ''; context.querySelector('.selectDateTimeLocale').value = userSettings.dateTimeLocale() || ''; + context.querySelector('#txtLibraryPageSize').value = userSettings.libraryPageSize() || 100; + selectDashboardTheme.value = userSettings.dashboardTheme() || ''; selectTheme.value = userSettings.theme() || ''; @@ -215,6 +217,8 @@ define(['require', 'browser', 'layoutManager', 'appSettings', 'pluginManager', ' userSettingsInstance.soundEffects(context.querySelector('.selectSoundEffects').value); userSettingsInstance.screensaver(context.querySelector('.selectScreensaver').value); + userSettingsInstance.libraryPageSize(context.querySelector('#txtLibraryPageSize').value); + userSettingsInstance.skin(context.querySelector('.selectSkin').value); userSettingsInstance.enableFastFadein(context.querySelector('#chkFadein').checked); diff --git a/src/components/displaysettings/displaysettings.template.html b/src/components/displaysettings/displaysettings.template.html index 16bbf0dd8..9f89117f5 100644 --- a/src/components/displaysettings/displaysettings.template.html +++ b/src/components/displaysettings/displaysettings.template.html @@ -143,6 +143,11 @@
+
+ +
${LabelLibraryPageSizeHelp}
+
+