From 9e38eeeb16eb99a3b969d2e46c4b559a8ee852a7 Mon Sep 17 00:00:00 2001 From: vitorsemeano Date: Sat, 16 Mar 2019 16:50:51 +0000 Subject: [PATCH 01/29] removing nativedirectorychooser require --- src/scripts/site.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/scripts/site.js b/src/scripts/site.js index 3d3c986aeb..2a2f8a6980 100644 --- a/src/scripts/site.js +++ b/src/scripts/site.js @@ -538,10 +538,6 @@ var AppInfo = {}; } function init() { - if ("android" === self.appMode) { - define("nativedirectorychooser", ["cordova/nativedirectorychooser"], returnFirstDependency); - } - define("livetvcss", ["css!css/livetv.css"], returnFirstDependency); define("detailtablecss", ["css!css/detailtable.css"], returnFirstDependency); define("buttonenabled", ["legacy/buttonenabled"], returnFirstDependency); From c2d35ee599eff085b8d01815db6fb9018132c2ee Mon Sep 17 00:00:00 2001 From: vitorsemeano Date: Sat, 16 Mar 2019 16:52:41 +0000 Subject: [PATCH 02/29] removing require for module file upload --- src/scripts/site.js | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/scripts/site.js b/src/scripts/site.js index 2a2f8a6980..193f616b05 100644 --- a/src/scripts/site.js +++ b/src/scripts/site.js @@ -1475,13 +1475,6 @@ var AppInfo = {}; define("filterMenu", [componentsPath + "/filtermenu/filtermenu"], returnFirstDependency); define("sortMenu", [componentsPath + "/sortmenu/sortmenu"], returnFirstDependency); define("registrationServices", [componentsPath + "/registrationservices/registrationservices"], returnFirstDependency); - - if ("cordova" === self.appMode || "android" === self.appMode) { - define("fileupload", ["cordova/fileupload"], returnFirstDependency); - } else { - define("fileupload", [apiClientBowerPath + "/fileupload"], returnFirstDependency); - } - define("connectionmanager", [apiClientBowerPath + "/connectionmanager"]); define("serversync", [apiClientBowerPath + "/sync/serversync"], returnFirstDependency); define("multiserversync", [apiClientBowerPath + "/sync/multiserversync"], returnFirstDependency); From c391eaf5453d99a4980f55ea759cf57d38c2a54d Mon Sep 17 00:00:00 2001 From: vitorsemeano Date: Sat, 16 Mar 2019 16:52:49 +0000 Subject: [PATCH 03/29] removing module fileupload --- src/bower_components/emby-apiclient/fileupload.js | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 src/bower_components/emby-apiclient/fileupload.js diff --git a/src/bower_components/emby-apiclient/fileupload.js b/src/bower_components/emby-apiclient/fileupload.js deleted file mode 100644 index 91f77395e6..0000000000 --- a/src/bower_components/emby-apiclient/fileupload.js +++ /dev/null @@ -1,8 +0,0 @@ -define([], function() { - "use strict"; - - function FileUpload() {} - return FileUpload.prototype.upload = function(file, url) { - return Promise.reject() - }, FileUpload -}); \ No newline at end of file From 4be8a788b08e049284a5a1910976cf078d81a917 Mon Sep 17 00:00:00 2001 From: vitorsemeano Date: Sat, 16 Mar 2019 17:15:37 +0000 Subject: [PATCH 04/29] assume server discovery is in NativeShell api --- .../emby-apiclient/connectionmanager.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/bower_components/emby-apiclient/connectionmanager.js b/src/bower_components/emby-apiclient/connectionmanager.js index 39824d31f7..93e9673a46 100644 --- a/src/bower_components/emby-apiclient/connectionmanager.js +++ b/src/bower_components/emby-apiclient/connectionmanager.js @@ -269,12 +269,15 @@ define(["events", "apiclient", "appStorage"], function(events, apiClientFactory, }); resolve(servers) }; - require(["serverdiscovery"], function(serverDiscovery) { - serverDiscovery.findServers(1e3).then(onFinish, function() { + + if (window.NativeShell && typeof window.NativeShell.findServers === 'function') { + window.NativeShell.findServers(1e3).then(onFinish, function() { onFinish([]) - }) - }) - }) + }); + } else { + resolve([]); + } + }); } function convertEndpointAddressToManualAddress(info) { From 04480fc8eb9006ef6394a76892f37e045ab80879 Mon Sep 17 00:00:00 2001 From: vitorsemeano Date: Sat, 16 Mar 2019 17:15:59 +0000 Subject: [PATCH 05/29] removed serverdiscovery require --- src/scripts/site.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/scripts/site.js b/src/scripts/site.js index 193f616b05..b64686ac67 100644 --- a/src/scripts/site.js +++ b/src/scripts/site.js @@ -462,12 +462,6 @@ var AppInfo = {}; define("registerElement", [bowerPath + "/document-register-element/build/document-register-element"], returnFirstDependency); } - if ("cordova" === self.appMode || "android" === self.appMode) { - define("serverdiscovery", ["cordova/serverdiscovery"], returnFirstDependency); - } else { - define("serverdiscovery", [apiClientBowerPath + "/serverdiscovery"], returnFirstDependency); - } - if ("cordova" === self.appMode && browser.iOSVersion && browser.iOSVersion < 11) { define("imageFetcher", ["cordova/imagestore"], returnFirstDependency); } else { From 60c0e58c647a51aa5349bc4c80d50f5cbd91d1f2 Mon Sep 17 00:00:00 2001 From: vitorsemeano Date: Sat, 16 Mar 2019 17:16:11 +0000 Subject: [PATCH 06/29] removed serverdiscovery module --- src/bower_components/emby-apiclient/serverdiscovery.js | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 src/bower_components/emby-apiclient/serverdiscovery.js diff --git a/src/bower_components/emby-apiclient/serverdiscovery.js b/src/bower_components/emby-apiclient/serverdiscovery.js deleted file mode 100644 index 4f18505ecc..0000000000 --- a/src/bower_components/emby-apiclient/serverdiscovery.js +++ /dev/null @@ -1,8 +0,0 @@ -define([], function() { - "use strict"; - return { - findServers: function(timeoutMs) { - return Promise.resolve([]) - } - } -}); \ No newline at end of file From 3de82f210af7c08123af70bdb2f48fa3d4da324a Mon Sep 17 00:00:00 2001 From: vitorsemeano Date: Sat, 16 Mar 2019 18:11:46 +0000 Subject: [PATCH 07/29] using NativeShell api for native apps in shell.js --- src/components/shell.js | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/components/shell.js b/src/components/shell.js index 0083404e19..762039ac42 100644 --- a/src/components/shell.js +++ b/src/components/shell.js @@ -2,8 +2,13 @@ define([], function () { 'use strict'; return { - openUrl: function (url) { - window.open(url, '_blank'); + openUrl: function (url, target) { + if (window.NativeShell) { + window.NativeShell.openUrl(url, target); + } else { + window.open(url, target || '_blank'); + } + }, canExec: false, exec: function (options) { @@ -12,10 +17,14 @@ define([], function () { return Promise.reject(); }, enableFullscreen: function () { - // do nothing since this is for native apps + if (window.NativeShell) { + window.NativeShell.enableFullscreen(); + } }, disableFullscreen: function () { - // do nothing since this is for native apps + if (window.NativeShell) { + window.NativeShell.disableFullscreen(); + } } }; }); \ No newline at end of file From c22ad0f204e8adc5c670e095ab308cc42aabf14e Mon Sep 17 00:00:00 2001 From: vitorsemeano Date: Sat, 16 Mar 2019 18:13:26 +0000 Subject: [PATCH 08/29] removing require for module cordova shell --- src/scripts/site.js | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/scripts/site.js b/src/scripts/site.js index b64686ac67..fc7d1d1cf6 100644 --- a/src/scripts/site.js +++ b/src/scripts/site.js @@ -441,11 +441,7 @@ var AppInfo = {}; define("lazyLoader", [componentsPath + "/lazyloader/lazyloader-scroll"], returnFirstDependency); } - if ("android" === self.appMode) { - define("shell", ["cordova/shell"], returnFirstDependency); - } else { - define("shell", [componentsPath + "/shell"], returnFirstDependency); - } + define("shell", [componentsPath + "/shell"], returnFirstDependency); if ("cordova" === self.appMode || "android" === self.appMode) { define("apiclientcore", ["bower_components/emby-apiclient/apiclient"], returnFirstDependency); @@ -1222,7 +1218,7 @@ var AppInfo = {}; require(["mediaSession"]); } - require(["apiInput"]); + require(["serverNotifications"]); if (!browser.tv && !browser.xboxOne) { require(["components/playback/playbackorientation"]); From d8d3b0b4c75a80405d69d80ad28627896e25640c Mon Sep 17 00:00:00 2001 From: vitorsemeano Date: Sat, 16 Mar 2019 18:21:07 +0000 Subject: [PATCH 09/29] remove unused module wakeonlan --- src/bower_components/emby-apiclient/wakeonlan.js | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 src/bower_components/emby-apiclient/wakeonlan.js diff --git a/src/bower_components/emby-apiclient/wakeonlan.js b/src/bower_components/emby-apiclient/wakeonlan.js deleted file mode 100644 index 58c01e61a5..0000000000 --- a/src/bower_components/emby-apiclient/wakeonlan.js +++ /dev/null @@ -1,15 +0,0 @@ -define([], function() { - "use strict"; - - function send(info) { - return Promise.reject() - } - - function isSupported() { - return !1 - } - return { - send: send, - isSupported: isSupported - } -}); \ No newline at end of file From 5cc1821e1206c06c9c0158f2e6cd1c00d890f90f Mon Sep 17 00:00:00 2001 From: vitorsemeano Date: Sat, 16 Mar 2019 18:26:42 +0000 Subject: [PATCH 10/29] remove require for module cordova chromecast --- src/scripts/site.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/scripts/site.js b/src/scripts/site.js index fc7d1d1cf6..f5a4233bfb 100644 --- a/src/scripts/site.js +++ b/src/scripts/site.js @@ -1126,10 +1126,6 @@ var AppInfo = {}; "components/youtubeplayer/plugin" ]; - if ("cordova" === self.appMode) { - list.push("cordova/chromecast"); - } - if ("android" === self.appMode) { list.push("cordova/externalplayer"); } From e13796e4f3d986a80a9c4369ec5e0b35dbf9d8d2 Mon Sep 17 00:00:00 2001 From: vitorsemeano Date: Sat, 16 Mar 2019 19:19:00 +0000 Subject: [PATCH 11/29] add NativeShell API to filesystem module --- src/components/filesystem.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/components/filesystem.js b/src/components/filesystem.js index 4489d2921f..e022a1c6d0 100644 --- a/src/components/filesystem.js +++ b/src/components/filesystem.js @@ -3,10 +3,14 @@ define([], function () { return { fileExists: function (path) { - return Promise.reject(); + if (window.NativeShell && window.NativeShell.FileSystem) { + return window.NativeShell.FileSystem.fileExists(path); + } }, directoryExists: function (path) { - return Promise.reject(); + if (window.NativeShell && window.NativeShell.FileSystem) { + return window.NativeShell.FileSystem.directoryExists(path); + } } }; }); \ No newline at end of file From 42beea23b6ce3a49fcd2a08c41c3f6fcf4961616 Mon Sep 17 00:00:00 2001 From: vitorsemeano Date: Sat, 16 Mar 2019 19:19:24 +0000 Subject: [PATCH 12/29] removed require for module cordova filesystem --- src/scripts/site.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/scripts/site.js b/src/scripts/site.js index f5a4233bfb..989d3161f9 100644 --- a/src/scripts/site.js +++ b/src/scripts/site.js @@ -429,11 +429,7 @@ var AppInfo = {}; var apiClientBowerPath = bowerPath + "/emby-apiclient"; var componentsPath = "components"; - if ("android" === self.appMode) { - define("filesystem", ["cordova/filesystem"], returnFirstDependency); - } else { - define("filesystem", [componentsPath + "/filesystem"], returnFirstDependency); - } + define("filesystem", [componentsPath + "/filesystem"], returnFirstDependency); if (window.IntersectionObserver && !browser.edge) { define("lazyLoader", [componentsPath + "/lazyloader/lazyloader-intersectionobserver"], returnFirstDependency); From e39d364874827e98523771f444831dc6006b130c Mon Sep 17 00:00:00 2001 From: vitorsemeano Date: Sat, 16 Mar 2019 19:20:38 +0000 Subject: [PATCH 13/29] removed require module for cordova imagestore --- src/scripts/site.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/scripts/site.js b/src/scripts/site.js index 989d3161f9..1908b2b816 100644 --- a/src/scripts/site.js +++ b/src/scripts/site.js @@ -454,11 +454,7 @@ var AppInfo = {}; define("registerElement", [bowerPath + "/document-register-element/build/document-register-element"], returnFirstDependency); } - if ("cordova" === self.appMode && browser.iOSVersion && browser.iOSVersion < 11) { - define("imageFetcher", ["cordova/imagestore"], returnFirstDependency); - } else { - define("imageFetcher", [componentsPath + "/images/basicimagefetcher"], returnFirstDependency); - } + define("imageFetcher", [componentsPath + "/images/basicimagefetcher"], returnFirstDependency); var preferNativeAlerts = browser.tv; From a77058de6192d44f19a99013a2ed62e147d9ced8 Mon Sep 17 00:00:00 2001 From: vitorsemeano Date: Sat, 16 Mar 2019 19:25:46 +0000 Subject: [PATCH 14/29] added NativeShell API to localsync module --- src/bower_components/emby-apiclient/sync/localsync.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/bower_components/emby-apiclient/sync/localsync.js b/src/bower_components/emby-apiclient/sync/localsync.js index cea244de08..f2f5f4e9e3 100644 --- a/src/bower_components/emby-apiclient/sync/localsync.js +++ b/src/bower_components/emby-apiclient/sync/localsync.js @@ -3,6 +3,10 @@ define(["connectionManager"], function(connectionManager) { var isSyncing; return { sync: function(options) { + if (window.NativeShell) { + return window.NativeShell.sync(options); + } + return console.log("localSync.sync starting..."), isSyncing ? Promise.resolve() : (isSyncing = !0, new Promise(function(resolve, reject) { require(["multiserversync", "appSettings"], function(MultiServerSync, appSettings) { options = options || {}, options.cameraUploadServers = appSettings.cameraUploadServers(), (new MultiServerSync).sync(connectionManager, options).then(function() { From 164bba2fafa3694dfc70524634fb282b7093b752 Mon Sep 17 00:00:00 2001 From: vitorsemeano Date: Sat, 16 Mar 2019 19:26:30 +0000 Subject: [PATCH 15/29] removed require for module cordova localsync --- src/scripts/site.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/scripts/site.js b/src/scripts/site.js index 1908b2b816..5683e1538c 100644 --- a/src/scripts/site.js +++ b/src/scripts/site.js @@ -512,12 +512,8 @@ var AppInfo = {}; define("filerepository", [apiClientBowerPath + "/sync/filerepository"], returnFirstDependency); } - if ("android" === self.appMode) { - define("localsync", ["cordova/localsync"], returnFirstDependency); - } else { define("localsync", [apiClientBowerPath + "/sync/localsync"], returnFirstDependency); } - } function init() { define("livetvcss", ["css!css/livetv.css"], returnFirstDependency); From 8b6b9974c79812fd9c7e0e761b66cb1309049852 Mon Sep 17 00:00:00 2001 From: vitorsemeano Date: Sat, 16 Mar 2019 19:34:19 +0000 Subject: [PATCH 16/29] removed require for cordova appshortcuts --- src/scripts/site.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/scripts/site.js b/src/scripts/site.js index 5683e1538c..e3bfe5c8b2 100644 --- a/src/scripts/site.js +++ b/src/scripts/site.js @@ -512,8 +512,8 @@ var AppInfo = {}; define("filerepository", [apiClientBowerPath + "/sync/filerepository"], returnFirstDependency); } - define("localsync", [apiClientBowerPath + "/sync/localsync"], returnFirstDependency); - } + define("localsync", [apiClientBowerPath + "/sync/localsync"], returnFirstDependency); + } function init() { define("livetvcss", ["css!css/livetv.css"], returnFirstDependency); @@ -1180,7 +1180,7 @@ var AppInfo = {}; if ("cordova" === self.appMode || "android" === self.appMode) { if (browser.android) { - require(["cordova/mediasession", "cordova/chromecast", "cordova/appshortcuts"]); + require(["cordova/mediasession"]); } else if (browser.safari) { require(["cordova/mediasession", "cordova/volume", "cordova/statusbar", "cordova/backgroundfetch"]); } From 856d87a9b2d1f43a0b7c9253966511f245fca236 Mon Sep 17 00:00:00 2001 From: vitorsemeano Date: Sat, 16 Mar 2019 21:21:40 +0000 Subject: [PATCH 17/29] clean filerepository and transfermanager requires --- src/scripts/site.js | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/src/scripts/site.js b/src/scripts/site.js index e3bfe5c8b2..222717969c 100644 --- a/src/scripts/site.js +++ b/src/scripts/site.js @@ -497,21 +497,8 @@ var AppInfo = {}; define("castSenderApiLoader", [], getCastSenderApiLoader); } - if (self.Windows) { - define("bgtaskregister", ["environments/windows-uwp/bgtaskregister"], returnFirstDependency); - define("transfermanager", ["environments/windows-uwp/transfermanager"], returnFirstDependency); - define("filerepository", ["environments/windows-uwp/filerepository"], returnFirstDependency); - } else if ("cordova" === self.appMode) { - define("filerepository", ["cordova/filerepository"], returnFirstDependency); - define("transfermanager", ["filerepository"], returnFirstDependency); - } else if ("android" === self.appMode) { - define("transfermanager", ["cordova/transfermanager"], returnFirstDependency); - define("filerepository", ["cordova/filerepository"], returnFirstDependency); - } else { - define("transfermanager", [apiClientBowerPath + "/sync/transfermanager"], returnFirstDependency); - define("filerepository", [apiClientBowerPath + "/sync/filerepository"], returnFirstDependency); - } - + define("transfermanager", [apiClientBowerPath + "/sync/transfermanager"], returnFirstDependency); + define("filerepository", [apiClientBowerPath + "/sync/filerepository"], returnFirstDependency); define("localsync", [apiClientBowerPath + "/sync/localsync"], returnFirstDependency); } From 071963ec5a79f1552579fdaf474be088c93255a0 Mon Sep 17 00:00:00 2001 From: vitorsemeano Date: Sat, 16 Mar 2019 21:48:44 +0000 Subject: [PATCH 18/29] added nativeshell API to filedownloader module --- src/components/filedownloader.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/components/filedownloader.js b/src/components/filedownloader.js index c8e3011be2..c5810b460e 100644 --- a/src/components/filedownloader.js +++ b/src/components/filedownloader.js @@ -4,9 +4,15 @@ define(['multi-download'], function (multiDownload) { return { download: function (items) { - multiDownload(items.map(function (item) { - return item.url; - })); + if (window.NativeShell) { + items.map(function (item) { + window.NativeShell.downloadFile(item.url); + }); + } else { + multiDownload(items.map(function (item) { + return item.url; + })); + } } }; }); \ No newline at end of file From 01d38d04bacb62edd05d3bf5c2f55a87417c3f2e Mon Sep 17 00:00:00 2001 From: vitorsemeano Date: Sat, 16 Mar 2019 21:49:05 +0000 Subject: [PATCH 19/29] removed require for module cordova filedownloader --- src/scripts/site.js | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/scripts/site.js b/src/scripts/site.js index 222717969c..d97b5d3bf2 100644 --- a/src/scripts/site.js +++ b/src/scripts/site.js @@ -482,13 +482,7 @@ var AppInfo = {}; } define("multi-download", [componentsPath + "/multidownload"], returnFirstDependency); - - if ("android" === self.appMode) { - define("fileDownloader", ["cordova/filedownloader"], returnFirstDependency); - } else { - define("fileDownloader", [componentsPath + "/filedownloader"], returnFirstDependency); - } - + define("fileDownloader", [componentsPath + "/filedownloader"], returnFirstDependency); define("localassetmanager", [apiClientBowerPath + "/localassetmanager"], returnFirstDependency); if ("cordova" === self.appMode || "android" === self.appMode) { From 7fc4165b538c105a4a0c65644d269c3622238088 Mon Sep 17 00:00:00 2001 From: vitorsemeano Date: Sat, 16 Mar 2019 22:56:55 +0000 Subject: [PATCH 20/29] remove some require modules of cordova --- src/scripts/site.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/scripts/site.js b/src/scripts/site.js index d97b5d3bf2..d2a01c873e 100644 --- a/src/scripts/site.js +++ b/src/scripts/site.js @@ -1160,11 +1160,7 @@ var AppInfo = {}; require(["components/thememediaplayer", "scripts/autobackdrops"]); if ("cordova" === self.appMode || "android" === self.appMode) { - if (browser.android) { - require(["cordova/mediasession"]); - } else if (browser.safari) { - require(["cordova/mediasession", "cordova/volume", "cordova/statusbar", "cordova/backgroundfetch"]); - } + require(["cordova/mediasession"]); } if (!browser.tv && !browser.xboxOne && !browser.ps4) { From e4c7282b92ce5f4f96655410adcfc57aa3a765bf Mon Sep 17 00:00:00 2001 From: vitorsemeano Date: Sun, 17 Mar 2019 00:31:56 +0000 Subject: [PATCH 21/29] refactor mediaSession to support NativeShell API --- src/components/playback/mediasession.js | 170 ++++++++++++++++-------- 1 file changed, 116 insertions(+), 54 deletions(-) diff --git a/src/components/playback/mediasession.js b/src/components/playback/mediasession.js index 8e2f7d0c01..fc899918f6 100644 --- a/src/components/playback/mediasession.js +++ b/src/components/playback/mediasession.js @@ -1,5 +1,10 @@ define(['playbackManager', 'nowPlayingHelper', 'events', 'connectionManager'], function (playbackManager, nowPlayingHelper, events, connectionManager) { "use strict"; + + // no support for mediaSession + if (!navigator.mediaSession && !window.NativeShell) { + return; + } // Reports media playback to the device for lock screen control @@ -64,15 +69,16 @@ define(['playbackManager', 'nowPlayingHelper', 'events', 'connectionManager'], f return null; } - function pushImageUrl(item, height, list) { - - var imageOptions = { - height: height - }; - + function pushImageUrl(item, imageOptions, list) { var url = seriesImageUrl(item, imageOptions) || imageUrl(item, imageOptions); + if (url) { - list.push({ src: url, sizes: height + 'x' + height }); + var height = imageOptions.height || imageOptions.maxHeight; + + list.push({ + src: url, + sizes: height + 'x' + height + }); } } @@ -80,12 +86,12 @@ define(['playbackManager', 'nowPlayingHelper', 'events', 'connectionManager'], f var list = []; - pushImageUrl(item, 96, list); - pushImageUrl(item, 128, list); - pushImageUrl(item, 192, list); - pushImageUrl(item, 256, list); - pushImageUrl(item, 384, list); - pushImageUrl(item, 512, list); + pushImageUrl(item, {height: 96}, list); + pushImageUrl(item, {height: 128}, list); + pushImageUrl(item, {height: 192}, list); + pushImageUrl(item, {height: 256}, list); + pushImageUrl(item, {height: 384}, list); + pushImageUrl(item, {height: 512}, list); return list; } @@ -99,6 +105,19 @@ define(['playbackManager', 'nowPlayingHelper', 'events', 'connectionManager'], f return; } + // dummy this up + if (eventName == 'init') { + eventName = 'timeupdate'; + } + + var isVideo = item.MediaType === 'Video'; + var isLocalPlayer = player.isLocalPlayer || false; + + // Local players do their own notifications + if (isLocalPlayer && isVideo) { + return; + } + var playState = state.PlayState || {}; var parts = nowPlayingHelper.getNowPlayingNames(item); @@ -106,8 +125,6 @@ define(['playbackManager', 'nowPlayingHelper', 'events', 'connectionManager'], f var artist = parts.length === 1 ? '' : parts[0].text; var title = parts[parts.length - 1].text; - var isVideo = item.MediaType === 'Video'; - // Switch these two around for video if (isVideo && parts.length > 1) { var temp = artist; @@ -131,18 +148,54 @@ define(['playbackManager', 'nowPlayingHelper', 'events', 'connectionManager'], f var isPaused = playState.IsPaused || false; var canSeek = playState.CanSeek || false; - navigator.mediaSession.metadata = new MediaMetadata({ - title: title, - artist: artist, - album: album, - artwork: getImageUrls(item), - albumArtist: albumArtist, - currentTime: currentTime, - duration: duration, - paused: isPaused, - itemId: itemId, - mediaType: item.MediaType - }); + var now = new Date().getTime(); + + // Don't go crazy reporting position changes + if (eventName == 'timeupdate' && (now - lastUpdateTime) < 5000) { + // Only report if this item hasn't been reported yet, or if there's an actual playback change. + // Don't report on simple time updates + return; + } + + lastUpdateTime = now; + + if (navigator.mediaSession){ + navigator.mediaSession.metadata = new MediaMetadata({ + title: title, + artist: artist, + album: album, + artwork: getImageUrls(item), + albumArtist: albumArtist, + currentTime: currentTime, + duration: duration, + paused: isPaused, + itemId: itemId, + mediaType: item.MediaType + }); + } else { + var imageUrl = []; + pushImageUrl(item, {maxHeight: 400}, imageUrl); + + if (imageUrl.length) { + imageUrl = imageUrl[0].src; + } else { + imageUrl = null; + } + + window.NativeShell.updateMediaSession({ + action: eventName, + isLocalPlayer: isLocalPlayer, + itemId: itemId, + title: title, + artist: artist, + album: album, + duration: duration, + position: currentTime, + imageUrl: imageUrl, + canSeek: canSeek, + isPaused: isPaused + }); + } } function onGeneralEvent(e) { @@ -191,7 +244,13 @@ define(['playbackManager', 'nowPlayingHelper', 'events', 'connectionManager'], f } function hideMediaControls() { - navigator.mediaSession.metadata = null; + lastUpdateTime = 0; + + if (navigator.mediaSession) { + navigator.mediaSession.metadata = null; + } else { + window.NativeShell.hideMediaSession(); + } } function bindToPlayer(player) { @@ -215,34 +274,37 @@ define(['playbackManager', 'nowPlayingHelper', 'events', 'connectionManager'], f events.on(currentPlayer, 'timeupdate', onGeneralEvent); } - function execute(name) { - playbackManager[name](currentPlayer); + if (navigator.mediaSession) { + + function execute(name) { + playbackManager[name](currentPlayer); + } + + navigator.mediaSession.setActionHandler('previoustrack', function () { + execute('previousTrack'); + }); + + navigator.mediaSession.setActionHandler('nexttrack', function () { + execute('nextTrack'); + }); + + navigator.mediaSession.setActionHandler('play', function () { + execute('unpause'); + }); + + navigator.mediaSession.setActionHandler('pause', function () { + execute('pause'); + }); + + navigator.mediaSession.setActionHandler('seekbackward', function () { + execute('rewind'); + }); + + navigator.mediaSession.setActionHandler('seekforward', function () { + execute('fastForward'); + }); } - navigator.mediaSession.setActionHandler('previoustrack', function () { - execute('previousTrack'); - }); - - navigator.mediaSession.setActionHandler('nexttrack', function () { - execute('nextTrack'); - }); - - navigator.mediaSession.setActionHandler('play', function () { - execute('unpause'); - }); - - navigator.mediaSession.setActionHandler('pause', function () { - execute('pause'); - }); - - navigator.mediaSession.setActionHandler('seekbackward', function () { - execute('rewind'); - }); - - navigator.mediaSession.setActionHandler('seekforward', function () { - execute('fastForward'); - }); - events.on(playbackManager, 'playerchange', function () { bindToPlayer(playbackManager.getCurrentPlayer()); From 01d82010ed5353bd16ff5c9ab772e37a10f430f5 Mon Sep 17 00:00:00 2001 From: vitorsemeano Date: Sun, 17 Mar 2019 00:32:15 +0000 Subject: [PATCH 22/29] cleanup for mediaSession require --- src/scripts/site.js | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/scripts/site.js b/src/scripts/site.js index d2a01c873e..83c3b8bde2 100644 --- a/src/scripts/site.js +++ b/src/scripts/site.js @@ -1159,10 +1159,6 @@ var AppInfo = {}; require(["components/thememediaplayer", "scripts/autobackdrops"]); - if ("cordova" === self.appMode || "android" === self.appMode) { - require(["cordova/mediasession"]); - } - if (!browser.tv && !browser.xboxOne && !browser.ps4) { require(["components/nowplayingbar/nowplayingbar"]); } @@ -1175,11 +1171,7 @@ var AppInfo = {}; require(["components/playback/volumeosd"]); } - if (navigator.mediaSession) { - require(["mediaSession"]); - } - - require(["serverNotifications"]); + require(["mediaSession", "serverNotifications"]); if (!browser.tv && !browser.xboxOne) { require(["components/playback/playbackorientation"]); From 91ef01cbc00328438afb3b8d17d0e271ae191aa6 Mon Sep 17 00:00:00 2001 From: vitorsemeano Date: Sun, 17 Mar 2019 21:42:36 +0000 Subject: [PATCH 23/29] removed require for cordova externalPlayer --- src/scripts/site.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/scripts/site.js b/src/scripts/site.js index 83c3b8bde2..5d1f70df67 100644 --- a/src/scripts/site.js +++ b/src/scripts/site.js @@ -1095,10 +1095,6 @@ var AppInfo = {}; "components/youtubeplayer/plugin" ]; - if ("android" === self.appMode) { - list.push("cordova/externalplayer"); - } - if (appHost.supports("remotecontrol")) { list.push("components/sessionplayer"); From 9967edcb353813393d9093a273af0aac8c190421 Mon Sep 17 00:00:00 2001 From: vitorsemeano Date: Sun, 17 Mar 2019 21:52:56 +0000 Subject: [PATCH 24/29] deuglify apphost.js --- src/components/apphost.js | 444 ++++++++++++++++++++++++++++---------- 1 file changed, 329 insertions(+), 115 deletions(-) diff --git a/src/components/apphost.js b/src/components/apphost.js index 9cffd2d8a4..21d474a3e1 100644 --- a/src/components/apphost.js +++ b/src/components/apphost.js @@ -1,109 +1,178 @@ -define(["appSettings", "browser", "events", "htmlMediaHelper"], function(appSettings, browser, events, htmlMediaHelper) { +define(["appSettings", "browser", "events", "htmlMediaHelper"], function (appSettings, browser, events, htmlMediaHelper) { "use strict"; function getBaseProfileOptions(item) { var disableHlsVideoAudioCodecs = []; - return item && htmlMediaHelper.enableHlsJsPlayer(item.RunTimeTicks, item.MediaType) && ((browser.edge || browser.msie) && disableHlsVideoAudioCodecs.push("mp3"), disableHlsVideoAudioCodecs.push("ac3"), disableHlsVideoAudioCodecs.push("eac3"), disableHlsVideoAudioCodecs.push("opus")), { - enableMkvProgressive: !1, - disableHlsVideoAudioCodecs: disableHlsVideoAudioCodecs + + if (item && htmlMediaHelper.enableHlsJsPlayer(item.RunTimeTicks, item.MediaType)) { + if (browser.edge || browser.msie) { + disableHlsVideoAudioCodecs.push("mp3"); + } + + disableHlsVideoAudioCodecs.push("ac3"); + disableHlsVideoAudioCodecs.push("eac3"); + disableHlsVideoAudioCodecs.push("opus"); } + + return { + enableMkvProgressive: false, + disableHlsVideoAudioCodecs: disableHlsVideoAudioCodecs + }; } function getDeviceProfileForWindowsUwp(item) { - return new Promise(function(resolve, reject) { - require(["browserdeviceprofile", "environments/windows-uwp/mediacaps"], function(profileBuilder, uwpMediaCaps) { + return new Promise(function (resolve, reject) { + require(["browserdeviceprofile", "environments/windows-uwp/mediacaps"], function (profileBuilder, uwpMediaCaps) { var profileOptions = getBaseProfileOptions(item); - profileOptions.supportsDts = uwpMediaCaps.supportsDTS(), profileOptions.supportsTrueHd = uwpMediaCaps.supportsDolby(), profileOptions.audioChannels = uwpMediaCaps.getAudioChannels(), resolve(profileBuilder(profileOptions)) - }) - }) + profileOptions.supportsDts = uwpMediaCaps.supportsDTS(); + profileOptions.supportsTrueHd = uwpMediaCaps.supportsDolby(); + profileOptions.audioChannels = uwpMediaCaps.getAudioChannels(); + resolve(profileBuilder(profileOptions)); + }); + }); } function getDeviceProfile(item, options) { - return options = options || {}, self.Windows ? getDeviceProfileForWindowsUwp(item) : new Promise(function(resolve, reject) { - require(["browserdeviceprofile"], function(profileBuilder) { + options = options || {}; + + if (self.Windows) { + return getDeviceProfileForWindowsUwp(item); + } + + return new Promise(function (resolve, reject) { + require(["browserdeviceprofile"], function (profileBuilder) { var profile = profileBuilder(getBaseProfileOptions(item)); - item && !options.isRetry && "allcomplexformats" !== appSettings.get("subtitleburnin") && (browser.orsay || browser.tizen || (profile.SubtitleProfiles.push({ - Format: "ass", - Method: "External" - }), profile.SubtitleProfiles.push({ - Format: "ssa", - Method: "External" - }))), resolve(profile) - }) - }) + + if (item && !options.isRetry && "allcomplexformats" !== appSettings.get("subtitleburnin")) { + if (!(browser.orsay || browser.tizen)) { + profile.SubtitleProfiles.push({ + Format: "ass", + Method: "External" + }); + profile.SubtitleProfiles.push({ + Format: "ssa", + Method: "External" + }); + } + } + + resolve(profile); + }); + }); } function escapeRegExp(str) { - return str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1") + return str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1"); } function replaceAll(originalString, strReplace, strWith) { - var strReplace2 = escapeRegExp(strReplace), - reg = new RegExp(strReplace2, "ig"); - return originalString.replace(reg, strWith) + var strReplace2 = escapeRegExp(strReplace); + var reg = new RegExp(strReplace2, "ig"); + return originalString.replace(reg, strWith); } function generateDeviceId() { var keys = []; - if (keys.push(navigator.userAgent), keys.push((new Date).getTime()), self.btoa) { + + if (keys.push(navigator.userAgent), keys.push(new Date().getTime()), self.btoa) { var result = replaceAll(btoa(keys.join("|")), "=", "1"); - return Promise.resolve(result) + return Promise.resolve(result); } - return Promise.resolve((new Date).getTime()) + + return Promise.resolve(new Date().getTime()); } function getDeviceId() { - var key = "_deviceId2", - deviceId = appSettings.get(key); - return deviceId ? Promise.resolve(deviceId) : generateDeviceId().then(function(deviceId) { - return appSettings.set(key, deviceId), deviceId - }) + var key = "_deviceId2"; + var deviceId = appSettings.get(key); + + if (deviceId) { + return Promise.resolve(deviceId); + } + + return generateDeviceId().then(function (deviceId) { + appSettings.set(key, deviceId); + return deviceId; + }); } function getDeviceName() { var deviceName; - return deviceName = browser.tizen ? "Samsung Smart TV" : browser.web0s ? "LG Smart TV" : browser.operaTv ? "Opera TV" : browser.xboxOne ? "Xbox One" : browser.ps4 ? "Sony PS4" : browser.chrome ? "Chrome" : browser.edge ? "Edge" : browser.firefox ? "Firefox" : browser.msie ? "Internet Explorer" : browser.opera ? "Opera" : "Web Browser", browser.ipad ? deviceName += " Ipad" : browser.iphone ? deviceName += " Iphone" : browser.android && (deviceName += " Android"), deviceName + deviceName = browser.tizen ? "Samsung Smart TV" : browser.web0s ? "LG Smart TV" : browser.operaTv ? "Opera TV" : browser.xboxOne ? "Xbox One" : browser.ps4 ? "Sony PS4" : browser.chrome ? "Chrome" : browser.edge ? "Edge" : browser.firefox ? "Firefox" : browser.msie ? "Internet Explorer" : browser.opera ? "Opera" : "Web Browser"; + + if (browser.ipad) { + deviceName += " Ipad"; + } else { + if (browser.iphone) { + deviceName += " Iphone"; + } else { + if (browser.android) { + deviceName += " Android"; + } + } + } + + return deviceName; } function supportsVoiceInput() { - return !browser.tv && (window.SpeechRecognition || window.webkitSpeechRecognition || window.mozSpeechRecognition || window.oSpeechRecognition || window.msSpeechRecognition) + if (!browser.tv) { + return window.SpeechRecognition || window.webkitSpeechRecognition || window.mozSpeechRecognition || window.oSpeechRecognition || window.msSpeechRecognition; + } + + return false; } function supportsFullscreen() { - if (browser.tv) return !1; + if (browser.tv) { + return false; + } + var element = document.documentElement; - return !!(element.requestFullscreen || element.mozRequestFullScreen || element.webkitRequestFullscreen || element.msRequestFullscreen) || !!document.createElement("video").webkitEnterFullscreen + return !!(element.requestFullscreen || element.mozRequestFullScreen || element.webkitRequestFullscreen || element.msRequestFullscreen) || !!document.createElement("video").webkitEnterFullscreen; } function getSyncProfile() { - return new Promise(function(resolve, reject) { - require(["browserdeviceprofile", "appSettings"], function(profileBuilder, appSettings) { + return new Promise(function (resolve, reject) { + require(["browserdeviceprofile", "appSettings"], function (profileBuilder, appSettings) { var profile = profileBuilder(); - profile.MaxStaticMusicBitrate = appSettings.maxStaticMusicBitrate(), resolve(profile) - }) - }) + profile.MaxStaticMusicBitrate = appSettings.maxStaticMusicBitrate(); + resolve(profile); + }); + }); } function getDefaultLayout() { - return "desktop" + return "desktop"; } function supportsHtmlMediaAutoplay() { - if (browser.edgeUwp || browser.tizen || browser.web0s || browser.orsay || browser.operaTv || browser.ps4 || browser.xboxOne) return !0; - if (browser.mobile) return !1; + if (browser.edgeUwp || browser.tizen || browser.web0s || browser.orsay || browser.operaTv || browser.ps4 || browser.xboxOne) { + return true; + } + + if (browser.mobile) { + return false; + } + var savedResult = appSettings.get(htmlMediaAutoplayAppStorageKey); - return "true" === savedResult || "false" !== savedResult && null + return "true" === savedResult || "false" !== savedResult && null; } function cueSupported() { try { - var video = document.createElement("video"), - style = document.createElement("style"); - style.textContent = "video::cue {background: inherit}", document.body.appendChild(style), document.body.appendChild(video); + var video = document.createElement("video"); + var style = document.createElement("style"); + style.textContent = "video::cue {background: inherit}"; + document.body.appendChild(style); + document.body.appendChild(video); var cue = window.getComputedStyle(video, "::cue").background; - return document.body.removeChild(style), document.body.removeChild(video), !!cue.length + document.body.removeChild(style); + document.body.removeChild(video); + return !!cue.length; } catch (err) { - return console.log("Error detecting cue support:" + err), !1 + console.log("Error detecting cue support:" + err); + return false; } } @@ -123,41 +192,104 @@ define(["appSettings", "browser", "events", "htmlMediaHelper"], function(appSett } var htmlMediaAutoplayAppStorageKey = "supportshtmlmediaautoplay0"; - var supportedFeatures = function() { + + var supportedFeatures = function () { var features = []; - navigator.share && features.push("sharing"); - browser.edgeUwp || browser.tv || browser.xboxOne || browser.ps4 || features.push("filedownload"); - browser.operaTv || browser.tizen || browser.orsay || browser.web0s - ? features.push("exit") - : (features.push("exitmenu"), features.push("plugins")); - browser.operaTv || browser.tizen || browser.orsay || browser.web0s || browser.ps4 || (features.push("externallinks"), features.push("externalpremium")); - browser.operaTv || features.push("externallinkdisplay"); - supportsVoiceInput() && features.push("voiceinput"); - !browser.tv && !browser.xboxOne && browser.ps4, supportsHtmlMediaAutoplay() && (features.push("htmlaudioautoplay"), features.push("htmlvideoautoplay")); - browser.edgeUwp && features.push("sync"); - supportsFullscreen() && features.push("fullscreenchange"); - (browser.chrome || browser.edge && !browser.slow) && (browser.noAnimation || browser.edgeUwp || browser.xboxOne || features.push("imageanalysis")); - (browser.tv || browser.xboxOne || browser.ps4 || browser.mobile) && features.push("physicalvolumecontrol"); - browser.tv || browser.xboxOne || browser.ps4 || features.push("remotecontrol"); - browser.operaTv || browser.tizen || browser.orsay || browser.web0s || browser.edgeUwp || features.push("remotevideo"); + + if (navigator.share) { + features.push("sharing"); + } + + if (!(browser.edgeUwp || browser.tv || browser.xboxOne || browser.ps4)) { + features.push("filedownload"); + } + + if (browser.operaTv || browser.tizen || browser.orsay || browser.web0s) { + features.push("exit"); + } else { + features.push("exitmenu"); + features.push("plugins"); + } + + if (!(browser.operaTv || browser.tizen || browser.orsay || browser.web0s || browser.ps4)) { + features.push("externallinks"); + features.push("externalpremium"); + } + + if (!browser.operaTv) { + features.push("externallinkdisplay"); + } + + if (supportsVoiceInput()) { + features.push("voiceinput"); + } + + if (!browser.tv && !browser.xboxOne) { + browser.ps4; + } + + if (supportsHtmlMediaAutoplay()) { + features.push("htmlaudioautoplay"); + features.push("htmlvideoautoplay"); + } + + if (browser.edgeUwp) { + features.push("sync"); + } + + if (supportsFullscreen()) { + features.push("fullscreenchange"); + } + + if (browser.chrome || browser.edge && !browser.slow) { + if (!(browser.noAnimation || browser.edgeUwp || browser.xboxOne)) { + features.push("imageanalysis"); + } + } + + if (browser.tv || browser.xboxOne || browser.ps4 || browser.mobile) { + features.push("physicalvolumecontrol"); + } + + if (!(browser.tv || browser.xboxOne || browser.ps4)) { + features.push("remotecontrol"); + } + + if (!(browser.operaTv || browser.tizen || browser.orsay || browser.web0s || browser.edgeUwp)) { + features.push("remotevideo"); + } + features.push("displaylanguage"); features.push("otherapppromotions"); - features.push("targetblank"); - // allows users to connect to more than one server + features.push("targetblank"); // allows users to connect to more than one server //features.push("multiserver"); - browser.orsay || browser.tizen || browser.msie || !(browser.firefox || browser.ps4 || browser.edge || cueSupported()) || features.push("subtitleappearancesettings"); - browser.orsay || browser.tizen || features.push("subtitleburnsettings"); - browser.tv || browser.ps4 || browser.xboxOne || features.push("fileinput"); - browser.chrome && features.push("chromecast"); + + if (!(browser.orsay || browser.tizen || browser.msie || !(browser.firefox || browser.ps4 || browser.edge || cueSupported()))) { + features.push("subtitleappearancesettings"); + } + + if (!(browser.orsay || browser.tizen)) { + features.push("subtitleburnsettings"); + } + + if (!(browser.tv || browser.ps4 || browser.xboxOne)) { + features.push("fileinput"); + } + + if (browser.chrome) { + features.push("chromecast"); + } + return features; }(); + if (supportedFeatures.indexOf("htmlvideoautoplay") === -1 && supportsHtmlMediaAutoplay() !== false) { - require(["autoPlayDetect"], function(autoPlayDetect) { - autoPlayDetect.supportsHtmlMediaAutoplay().then(function() { + require(["autoPlayDetect"], function (autoPlayDetect) { + autoPlayDetect.supportsHtmlMediaAutoplay().then(function () { appSettings.set(htmlMediaAutoplayAppStorageKey, "true"); supportedFeatures.push("htmlvideoautoplay"); supportedFeatures.push("htmlaudioautoplay"); - }, function() { + }, function () { appSettings.set(htmlMediaAutoplayAppStorageKey, "false"); }); }); @@ -169,73 +301,155 @@ define(["appSettings", "browser", "events", "htmlMediaHelper"], function(appSett var visibilityState; var appVersion = window.dashboardVersion || "3.0"; var appHost = { - getWindowState: function() { - return document.windowState || "Normal" + getWindowState: function () { + return document.windowState || "Normal"; }, - setWindowState: function(state) { - alert("setWindowState is not supported and should not be called") + setWindowState: function (state) { + alert("setWindowState is not supported and should not be called"); }, - exit: function() { - if (browser.tizen) try { - tizen.application.getCurrentApplication().exit() - } catch (err) { - console.log("error closing application: " + err) - } else window.close() + exit: function () { + if (browser.tizen) { + try { + tizen.application.getCurrentApplication().exit(); + } catch (err) { + console.log("error closing application: " + err); + } + } else { + window.close(); + } }, - supports: function(command) { - return -1 !== supportedFeatures.indexOf(command.toLowerCase()) + supports: function (command) { + return -1 !== supportedFeatures.indexOf(command.toLowerCase()); }, preferVisualCards: browser.android || browser.chrome, moreIcon: browser.android ? "dots-vert" : "dots-horiz", getSyncProfile: getSyncProfile, getDefaultLayout: getDefaultLayout, getDeviceProfile: getDeviceProfile, - init: function() { - return deviceName = getDeviceName(), getDeviceId().then(function(resolvedDeviceId) { - deviceId = resolvedDeviceId - }) + init: function () { + deviceName = getDeviceName(); + return getDeviceId().then(function (resolvedDeviceId) { + deviceId = resolvedDeviceId; + }); }, - deviceName: function() { - return deviceName + deviceName: function () { + return deviceName; }, - deviceId: function() { - return deviceId + deviceId: function () { + return deviceId; }, - appName: function() { - return "Jellyfin Web" + appName: function () { + return "Jellyfin Web"; }, - appVersion: function() { - return appVersion + appVersion: function () { + return appVersion; }, - getPushTokenInfo: function() { - return {} + getPushTokenInfo: function () { + return {}; }, - setThemeColor: function(color) { + setThemeColor: function (color) { var metaThemeColor = document.querySelector("meta[name=theme-color]"); - metaThemeColor && metaThemeColor.setAttribute("content", color) - }, - setUserScalable: function(scalable) { - if (!browser.tv) { - var att = scalable ? "width=device-width, initial-scale=1, minimum-scale=1, user-scalable=yes" : "width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no"; - document.querySelector("meta[name=viewport]").setAttribute("content", att) + + if (metaThemeColor) { + metaThemeColor.setAttribute("content", color); } }, - deviceIconUrl: function() { - return browser.edgeUwp, browser.edgeUwp ? "https://github.com/MediaBrowser/Emby.Resources/raw/master/images/devices/windowsrt.png" : browser.opera || browser.operaTv ? "https://github.com/MediaBrowser/Emby.Resources/raw/master/images/devices/opera.png" : browser.orsay || browser.tizen ? "https://github.com/MediaBrowser/Emby.Resources/raw/master/images/devices/samsungtv.png" : browser.web0s ? "https://github.com/MediaBrowser/Emby.Resources/raw/master/images/devices/lgtv.png" : browser.ps4 ? "https://github.com/MediaBrowser/Emby.Resources/raw/master/images/devices/ps4.png" : browser.chromecast ? "https://github.com/MediaBrowser/Emby.Resources/raw/master/images/devices/chromecast.png" : browser.chrome ? "https://github.com/MediaBrowser/Emby.Resources/raw/master/images/devices/chrome.png" : browser.edge ? "https://github.com/MediaBrowser/Emby.Resources/raw/master/images/devices/edge.png" : browser.firefox ? "https://github.com/MediaBrowser/Emby.Resources/raw/master/images/devices/firefox.png" : browser.msie ? "https://github.com/MediaBrowser/Emby.Resources/raw/master/images/devices/internetexplorer.png" : browser.safari ? "https://github.com/MediaBrowser/Emby.Resources/raw/master/images/devices/safari.png" : "https://github.com/MediaBrowser/Emby.Resources/raw/master/images/devices/html5.png" + setUserScalable: function (scalable) { + if (!browser.tv) { + var att = scalable ? "width=device-width, initial-scale=1, minimum-scale=1, user-scalable=yes" : "width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no"; + document.querySelector("meta[name=viewport]").setAttribute("content", att); + } + }, + deviceIconUrl: function () { + browser.edgeUwp; + + if (browser.edgeUwp) { + return "https://github.com/MediaBrowser/Emby.Resources/raw/master/images/devices/windowsrt.png"; + } + + if (browser.opera || browser.operaTv) { + return "https://github.com/MediaBrowser/Emby.Resources/raw/master/images/devices/opera.png"; + } + + if (browser.orsay || browser.tizen) { + return "https://github.com/MediaBrowser/Emby.Resources/raw/master/images/devices/samsungtv.png"; + } + + if (browser.web0s) { + return "https://github.com/MediaBrowser/Emby.Resources/raw/master/images/devices/lgtv.png"; + } + + if (browser.ps4) { + return "https://github.com/MediaBrowser/Emby.Resources/raw/master/images/devices/ps4.png"; + } + + if (browser.chromecast) { + return "https://github.com/MediaBrowser/Emby.Resources/raw/master/images/devices/chromecast.png"; + } + + if (browser.chrome) { + return "https://github.com/MediaBrowser/Emby.Resources/raw/master/images/devices/chrome.png"; + } + + if (browser.edge) { + return "https://github.com/MediaBrowser/Emby.Resources/raw/master/images/devices/edge.png"; + } + + if (browser.firefox) { + return "https://github.com/MediaBrowser/Emby.Resources/raw/master/images/devices/firefox.png"; + } + + if (browser.msie) { + return "https://github.com/MediaBrowser/Emby.Resources/raw/master/images/devices/internetexplorer.png"; + } + + if (browser.safari) { + return "https://github.com/MediaBrowser/Emby.Resources/raw/master/images/devices/safari.png"; + } + + return "https://github.com/MediaBrowser/Emby.Resources/raw/master/images/devices/html5.png"; } }; - var doc = self.document; - doc && (void 0 !== doc.visibilityState ? (visibilityChange = "visibilitychange", visibilityState = "hidden") : void 0 !== doc.mozHidden ? (visibilityChange = "mozvisibilitychange", visibilityState = "mozVisibilityState") : void 0 !== doc.msHidden ? (visibilityChange = "msvisibilitychange", visibilityState = "msVisibilityState") : void 0 !== doc.webkitHidden && (visibilityChange = "webkitvisibilitychange", visibilityState = "webkitVisibilityState")); - var isHidden = false; + if (doc) { - doc.addEventListener(visibilityChange, function() { - document[visibilityState] ? onAppHidden() : onAppVisible() + if (void 0 !== doc.visibilityState) { + visibilityChange = "visibilitychange"; + visibilityState = "hidden"; + } else { + if (void 0 !== doc.mozHidden) { + visibilityChange = "mozvisibilitychange"; + visibilityState = "mozVisibilityState"; + } else { + if (void 0 !== doc.msHidden) { + visibilityChange = "msvisibilitychange"; + visibilityState = "msVisibilityState"; + } else { + if (void 0 !== doc.webkitHidden) { + visibilityChange = "webkitvisibilitychange"; + visibilityState = "webkitVisibilityState"; + } + } + } + } + } + + var isHidden = false; + + if (doc) { + doc.addEventListener(visibilityChange, function () { + if (document[visibilityState]) { + onAppHidden(); + } else { + onAppVisible(); + } }); } + if (self.addEventListener) { self.addEventListener("focus", onAppVisible); self.addEventListener("blur", onAppHidden); } + return appHost; }); From 8315f4a2d40398c01e9428e3247e780d5c079577 Mon Sep 17 00:00:00 2001 From: vitorsemeano Date: Sun, 17 Mar 2019 22:02:24 +0000 Subject: [PATCH 25/29] invert some conditions for readability in apphost --- src/components/apphost.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/components/apphost.js b/src/components/apphost.js index 21d474a3e1..d1d865a63a 100644 --- a/src/components/apphost.js +++ b/src/components/apphost.js @@ -44,7 +44,7 @@ define(["appSettings", "browser", "events", "htmlMediaHelper"], function (appSet var profile = profileBuilder(getBaseProfileOptions(item)); if (item && !options.isRetry && "allcomplexformats" !== appSettings.get("subtitleburnin")) { - if (!(browser.orsay || browser.tizen)) { + if (!browser.orsay && !browser.tizen) { profile.SubtitleProfiles.push({ Format: "ass", Method: "External" @@ -129,7 +129,7 @@ define(["appSettings", "browser", "events", "htmlMediaHelper"], function (appSet } var element = document.documentElement; - return !!(element.requestFullscreen || element.mozRequestFullScreen || element.webkitRequestFullscreen || element.msRequestFullscreen) || !!document.createElement("video").webkitEnterFullscreen; + return (element.requestFullscreen || element.mozRequestFullScreen || element.webkitRequestFullscreen || element.msRequestFullscreen) || document.createElement("video").webkitEnterFullscreen; } function getSyncProfile() { @@ -200,7 +200,7 @@ define(["appSettings", "browser", "events", "htmlMediaHelper"], function (appSet features.push("sharing"); } - if (!(browser.edgeUwp || browser.tv || browser.xboxOne || browser.ps4)) { + if (!browser.edgeUwp && !browser.tv && !browser.xboxOne && !browser.ps4) { features.push("filedownload"); } @@ -211,7 +211,7 @@ define(["appSettings", "browser", "events", "htmlMediaHelper"], function (appSet features.push("plugins"); } - if (!(browser.operaTv || browser.tizen || browser.orsay || browser.web0s || browser.ps4)) { + if (!browser.operaTv && !browser.tizen && !browser.orsay && !browser.web0s && !browser.ps4) { features.push("externallinks"); features.push("externalpremium"); } @@ -242,7 +242,7 @@ define(["appSettings", "browser", "events", "htmlMediaHelper"], function (appSet } if (browser.chrome || browser.edge && !browser.slow) { - if (!(browser.noAnimation || browser.edgeUwp || browser.xboxOne)) { + if (!browser.noAnimation && !browser.edgeUwp && !browser.xboxOne) { features.push("imageanalysis"); } } @@ -251,11 +251,11 @@ define(["appSettings", "browser", "events", "htmlMediaHelper"], function (appSet features.push("physicalvolumecontrol"); } - if (!(browser.tv || browser.xboxOne || browser.ps4)) { + if (!browser.tv && !browser.xboxOne && !browser.ps4) { features.push("remotecontrol"); } - if (!(browser.operaTv || browser.tizen || browser.orsay || browser.web0s || browser.edgeUwp)) { + if (!browser.operaTv && !browser.tizen && !browser.orsay && !browser.web0s && !browser.edgeUwp) { features.push("remotevideo"); } @@ -264,15 +264,15 @@ define(["appSettings", "browser", "events", "htmlMediaHelper"], function (appSet features.push("targetblank"); // allows users to connect to more than one server //features.push("multiserver"); - if (!(browser.orsay || browser.tizen || browser.msie || !(browser.firefox || browser.ps4 || browser.edge || cueSupported()))) { + if (!browser.orsay && !browser.tizen && !browser.msie && (browser.firefox || browser.ps4 || browser.edge || cueSupported())) { features.push("subtitleappearancesettings"); } - if (!(browser.orsay || browser.tizen)) { + if (!browser.orsay && !browser.tizen) { features.push("subtitleburnsettings"); } - if (!(browser.tv || browser.ps4 || browser.xboxOne)) { + if (!browser.tv && !browser.ps4 && !browser.xboxOne) { features.push("fileinput"); } From c4ada25fe72f6b169c8eff3fd881bd7f8ee870d9 Mon Sep 17 00:00:00 2001 From: vitorsemeano Date: Sun, 17 Mar 2019 23:23:45 +0000 Subject: [PATCH 26/29] nativeshell API added to apphost --- src/components/apphost.js | 71 +++++++++++++++++++++++++++------------ 1 file changed, 50 insertions(+), 21 deletions(-) diff --git a/src/components/apphost.js b/src/components/apphost.js index d1d865a63a..369dff0f6f 100644 --- a/src/components/apphost.js +++ b/src/components/apphost.js @@ -39,20 +39,26 @@ define(["appSettings", "browser", "events", "htmlMediaHelper"], function (appSet return getDeviceProfileForWindowsUwp(item); } - return new Promise(function (resolve, reject) { + return new Promise(function (resolve) { require(["browserdeviceprofile"], function (profileBuilder) { - var profile = profileBuilder(getBaseProfileOptions(item)); + var profile; - if (item && !options.isRetry && "allcomplexformats" !== appSettings.get("subtitleburnin")) { - if (!browser.orsay && !browser.tizen) { - profile.SubtitleProfiles.push({ - Format: "ass", - Method: "External" - }); - profile.SubtitleProfiles.push({ - Format: "ssa", - Method: "External" - }); + if (window.NativeShell) { + profile = window.NativeShell.AppHost.getDeviceProfile(profileBuilder); + } else { + profile = profileBuilder(getBaseProfileOptions(item)); + + if (item && !options.isRetry && "allcomplexformats" !== appSettings.get("subtitleburnin")) { + if (!browser.orsay && !browser.tizen) { + profile.SubtitleProfiles.push({ + Format: "ass", + Method: "External" + }); + profile.SubtitleProfiles.push({ + Format: "ssa", + Method: "External" + }); + } } } @@ -133,10 +139,17 @@ define(["appSettings", "browser", "events", "htmlMediaHelper"], function (appSet } function getSyncProfile() { - return new Promise(function (resolve, reject) { + return new Promise(function (resolve) { require(["browserdeviceprofile", "appSettings"], function (profileBuilder, appSettings) { - var profile = profileBuilder(); - profile.MaxStaticMusicBitrate = appSettings.maxStaticMusicBitrate(); + var profile; + + if (window.NativeShell) { + profile = window.NativeShell.AppHost.getSyncProfile(profileBuilder, appSettings); + } else { + profile = profileBuilder(); + profile.MaxStaticMusicBitrate = appSettings.maxStaticMusicBitrate(); + } + resolve(profile); }); }); @@ -308,7 +321,9 @@ define(["appSettings", "browser", "events", "htmlMediaHelper"], function (appSet alert("setWindowState is not supported and should not be called"); }, exit: function () { - if (browser.tizen) { + if (window.NativeShell) { + window.NativeShell.AppHost.exit(); + } else if (browser.tizen) { try { tizen.application.getCurrentApplication().exit(); } catch (err) { @@ -319,30 +334,44 @@ define(["appSettings", "browser", "events", "htmlMediaHelper"], function (appSet } }, supports: function (command) { + if (window.NativeShell) { + return window.NativeShell.AppHost.supports(command); + } + return -1 !== supportedFeatures.indexOf(command.toLowerCase()); }, preferVisualCards: browser.android || browser.chrome, moreIcon: browser.android ? "dots-vert" : "dots-horiz", getSyncProfile: getSyncProfile, - getDefaultLayout: getDefaultLayout, + getDefaultLayout: function () { + if (window.NativeShell) { + return window.NativeShell.AppHost.getDefaultLayout(); + } + + return getDefaultLayout() + }, getDeviceProfile: getDeviceProfile, init: function () { + if (window.NativeShell) { + return window.NativeShell.AppHost.init(); + } + deviceName = getDeviceName(); return getDeviceId().then(function (resolvedDeviceId) { deviceId = resolvedDeviceId; }); }, deviceName: function () { - return deviceName; + return window.NativeShell ? window.NativeShell.AppHost.deviceName() : deviceName; }, deviceId: function () { - return deviceId; + return window.NativeShell ? window.NativeShell.AppHost.deviceId() : deviceId; }, appName: function () { - return "Jellyfin Web"; + return window.NativeShell ? window.NativeShell.AppHost.appName() : "Jellyfin Web"; }, appVersion: function () { - return appVersion; + return window.NativeShell ? window.NativeShell.AppHost.appVersion() : appVersion; }, getPushTokenInfo: function () { return {}; From 19cb905d5ace5cadcd6adaed86db5ab48cc87461 Mon Sep 17 00:00:00 2001 From: vitorsemeano Date: Sun, 17 Mar 2019 23:23:59 +0000 Subject: [PATCH 27/29] removed require for cordova apphost --- src/scripts/site.js | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/scripts/site.js b/src/scripts/site.js index 5d1f70df67..7f8e8aa720 100644 --- a/src/scripts/site.js +++ b/src/scripts/site.js @@ -1373,13 +1373,9 @@ var AppInfo = {}; return viewManager; }); - if ("cordova" === self.appMode || "android" === self.appMode) { - paths.apphost = "cordova/apphost"; - } else { - paths.apphost = "components/apphost"; - } - + paths.apphost = "components/apphost"; paths.appStorage = getAppStorage(apiClientBowerPath); + requirejs.config({ waitSeconds: 0, map: { From e8e098f9b15eb20e0b14e24fb2349e1ffe5e5374 Mon Sep 17 00:00:00 2001 From: vitorsemeano Date: Mon, 18 Mar 2019 23:08:11 +0000 Subject: [PATCH 28/29] removed nativelshell sync invokation --- src/bower_components/emby-apiclient/sync/localsync.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/bower_components/emby-apiclient/sync/localsync.js b/src/bower_components/emby-apiclient/sync/localsync.js index f2f5f4e9e3..cea244de08 100644 --- a/src/bower_components/emby-apiclient/sync/localsync.js +++ b/src/bower_components/emby-apiclient/sync/localsync.js @@ -3,10 +3,6 @@ define(["connectionManager"], function(connectionManager) { var isSyncing; return { sync: function(options) { - if (window.NativeShell) { - return window.NativeShell.sync(options); - } - return console.log("localSync.sync starting..."), isSyncing ? Promise.resolve() : (isSyncing = !0, new Promise(function(resolve, reject) { require(["multiserversync", "appSettings"], function(MultiServerSync, appSettings) { options = options || {}, options.cameraUploadServers = appSettings.cameraUploadServers(), (new MultiServerSync).sync(connectionManager, options).then(function() { From ad5d9be566e13eacb5ef95092e5bfb7784b494d0 Mon Sep 17 00:00:00 2001 From: vitorsemeano Date: Thu, 21 Mar 2019 21:54:36 +0000 Subject: [PATCH 29/29] add comment for init conversion into timeupdate --- src/components/playback/mediasession.js | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/components/playback/mediasession.js b/src/components/playback/mediasession.js index fc899918f6..b92e581b25 100644 --- a/src/components/playback/mediasession.js +++ b/src/components/playback/mediasession.js @@ -1,6 +1,6 @@ define(['playbackManager', 'nowPlayingHelper', 'events', 'connectionManager'], function (playbackManager, nowPlayingHelper, events, connectionManager) { "use strict"; - + // no support for mediaSession if (!navigator.mediaSession && !window.NativeShell) { return; @@ -105,8 +105,7 @@ define(['playbackManager', 'nowPlayingHelper', 'events', 'connectionManager'], f return; } - // dummy this up - if (eventName == 'init') { + if (eventName == 'init') { // transform "init" event into "timeupdate" to restraint update rate eventName = 'timeupdate'; } @@ -181,7 +180,7 @@ define(['playbackManager', 'nowPlayingHelper', 'events', 'connectionManager'], f } else { imageUrl = null; } - + window.NativeShell.updateMediaSession({ action: eventName, isLocalPlayer: isLocalPlayer, @@ -283,23 +282,23 @@ define(['playbackManager', 'nowPlayingHelper', 'events', 'connectionManager'], f navigator.mediaSession.setActionHandler('previoustrack', function () { execute('previousTrack'); }); - + navigator.mediaSession.setActionHandler('nexttrack', function () { execute('nextTrack'); }); - + navigator.mediaSession.setActionHandler('play', function () { execute('unpause'); }); - + navigator.mediaSession.setActionHandler('pause', function () { execute('pause'); }); - + navigator.mediaSession.setActionHandler('seekbackward', function () { execute('rewind'); }); - + navigator.mediaSession.setActionHandler('seekforward', function () { execute('fastForward'); });