2020-12-10 10:53:54 -05:00
|
|
|
import { version as appVersion } from '../../package.json';
|
2020-08-14 08:46:34 +02:00
|
|
|
import appSettings from '../scripts/settings/appSettings';
|
|
|
|
import browser from '../scripts/browser';
|
2020-09-08 02:05:02 -04:00
|
|
|
import { Events } from 'jellyfin-apiclient';
|
2020-08-14 08:46:34 +02:00
|
|
|
import * as htmlMediaHelper from '../components/htmlMediaHelper';
|
|
|
|
import * as webSettings from '../scripts/settings/webSettings';
|
|
|
|
import globalize from '../scripts/globalize';
|
2020-10-17 20:04:52 +01:00
|
|
|
import profileBuilder from '../scripts/browserDeviceProfile';
|
2018-10-23 00:48:22 +03:00
|
|
|
|
2020-11-30 01:28:33 +08:00
|
|
|
const appName = 'Jellyfin Web';
|
|
|
|
|
2020-07-16 22:19:09 +02:00
|
|
|
function getBaseProfileOptions(item) {
|
|
|
|
const disableHlsVideoAudioCodecs = [];
|
2020-08-02 15:25:20 +03:00
|
|
|
|
2020-07-16 22:19:09 +02:00
|
|
|
if (item && htmlMediaHelper.enableHlsJsPlayer(item.RunTimeTicks, item.MediaType)) {
|
|
|
|
if (browser.edge) {
|
|
|
|
disableHlsVideoAudioCodecs.push('mp3');
|
2018-10-23 00:48:22 +03:00
|
|
|
}
|
2019-03-17 21:52:56 +00:00
|
|
|
|
2020-07-16 22:19:09 +02:00
|
|
|
disableHlsVideoAudioCodecs.push('ac3');
|
|
|
|
disableHlsVideoAudioCodecs.push('eac3');
|
|
|
|
disableHlsVideoAudioCodecs.push('opus');
|
2018-10-23 00:48:22 +03:00
|
|
|
}
|
|
|
|
|
2020-07-16 22:19:09 +02:00
|
|
|
return {
|
|
|
|
enableMkvProgressive: false,
|
|
|
|
disableHlsVideoAudioCodecs: disableHlsVideoAudioCodecs
|
|
|
|
};
|
|
|
|
}
|
2019-03-17 21:52:56 +00:00
|
|
|
|
2020-12-09 12:33:46 -05:00
|
|
|
function getDeviceProfile(item) {
|
2020-07-16 22:19:09 +02:00
|
|
|
return new Promise(function (resolve) {
|
2020-10-17 20:04:52 +01:00
|
|
|
let profile;
|
2019-03-17 21:52:56 +00:00
|
|
|
|
2020-10-17 20:04:52 +01:00
|
|
|
if (window.NativeShell) {
|
2020-12-10 10:53:54 -05:00
|
|
|
profile = window.NativeShell.AppHost.getDeviceProfile(profileBuilder, appVersion);
|
2020-10-17 20:04:52 +01:00
|
|
|
} else {
|
|
|
|
const builderOpts = getBaseProfileOptions(item);
|
|
|
|
profile = profileBuilder(builderOpts);
|
|
|
|
}
|
2019-03-17 21:52:56 +00:00
|
|
|
|
2020-10-17 20:04:52 +01:00
|
|
|
resolve(profile);
|
2020-07-16 22:19:09 +02:00
|
|
|
});
|
|
|
|
}
|
2018-10-23 00:48:22 +03:00
|
|
|
|
2020-07-16 22:19:09 +02:00
|
|
|
function escapeRegExp(str) {
|
|
|
|
return str.replace(/([.*+?^=!:${}()|[\]/\\])/g, '\\$1');
|
|
|
|
}
|
2018-10-23 00:48:22 +03:00
|
|
|
|
2020-07-16 22:19:09 +02:00
|
|
|
function replaceAll(originalString, strReplace, strWith) {
|
|
|
|
const strReplace2 = escapeRegExp(strReplace);
|
|
|
|
const reg = new RegExp(strReplace2, 'ig');
|
|
|
|
return originalString.replace(reg, strWith);
|
|
|
|
}
|
|
|
|
|
|
|
|
function generateDeviceId() {
|
|
|
|
const keys = [];
|
|
|
|
|
2020-08-25 10:12:35 +09:00
|
|
|
if (keys.push(navigator.userAgent), keys.push(new Date().getTime()), window.btoa) {
|
2020-07-16 22:19:09 +02:00
|
|
|
const result = replaceAll(btoa(keys.join('|')), '=', '1');
|
2020-10-17 19:08:56 +01:00
|
|
|
return result;
|
2018-10-23 00:48:22 +03:00
|
|
|
}
|
|
|
|
|
2020-10-17 19:08:56 +01:00
|
|
|
return new Date().getTime();
|
2020-07-16 22:19:09 +02:00
|
|
|
}
|
2019-03-17 21:52:56 +00:00
|
|
|
|
2020-07-16 22:19:09 +02:00
|
|
|
function getDeviceId() {
|
2020-10-17 19:08:56 +01:00
|
|
|
if (!deviceId) {
|
2020-11-08 23:11:22 +00:00
|
|
|
const key = '_deviceId2';
|
2019-03-17 21:52:56 +00:00
|
|
|
|
2020-11-08 23:11:22 +00:00
|
|
|
deviceId = appSettings.get(key);
|
|
|
|
|
|
|
|
if (!deviceId) {
|
|
|
|
deviceId = generateDeviceId();
|
|
|
|
appSettings.set(key, deviceId);
|
|
|
|
}
|
2018-10-23 00:48:22 +03:00
|
|
|
}
|
|
|
|
|
2020-10-17 19:08:56 +01:00
|
|
|
return deviceId;
|
2020-07-16 22:19:09 +02:00
|
|
|
}
|
2019-03-17 21:52:56 +00:00
|
|
|
|
2020-07-16 22:19:09 +02:00
|
|
|
function getDeviceName() {
|
2020-11-08 23:11:22 +00:00
|
|
|
if (!deviceName) {
|
|
|
|
if (browser.tizen) {
|
|
|
|
deviceName = 'Samsung Smart TV';
|
|
|
|
} else if (browser.web0s) {
|
|
|
|
deviceName = 'LG Smart TV';
|
|
|
|
} else if (browser.operaTv) {
|
|
|
|
deviceName = 'Opera TV';
|
|
|
|
} else if (browser.xboxOne) {
|
|
|
|
deviceName = 'Xbox One';
|
|
|
|
} else if (browser.ps4) {
|
|
|
|
deviceName = 'Sony PS4';
|
|
|
|
} else if (browser.chrome) {
|
|
|
|
deviceName = 'Chrome';
|
|
|
|
} else if (browser.edgeChromium) {
|
|
|
|
deviceName = 'Edge Chromium';
|
|
|
|
} else if (browser.edge) {
|
|
|
|
deviceName = 'Edge';
|
|
|
|
} else if (browser.firefox) {
|
|
|
|
deviceName = 'Firefox';
|
|
|
|
} else if (browser.opera) {
|
|
|
|
deviceName = 'Opera';
|
|
|
|
} else if (browser.safari) {
|
|
|
|
deviceName = 'Safari';
|
|
|
|
} else {
|
|
|
|
deviceName = 'Web Browser';
|
|
|
|
}
|
2019-03-17 21:52:56 +00:00
|
|
|
|
2020-11-08 23:11:22 +00:00
|
|
|
if (browser.ipad) {
|
|
|
|
deviceName += ' iPad';
|
|
|
|
} else if (browser.iphone) {
|
|
|
|
deviceName += ' iPhone';
|
|
|
|
} else if (browser.android) {
|
|
|
|
deviceName += ' Android';
|
|
|
|
}
|
2018-10-23 00:48:22 +03:00
|
|
|
}
|
|
|
|
|
2020-07-16 22:19:09 +02:00
|
|
|
return deviceName;
|
|
|
|
}
|
2019-03-17 21:52:56 +00:00
|
|
|
|
2020-07-16 22:19:09 +02:00
|
|
|
function supportsVoiceInput() {
|
|
|
|
if (!browser.tv) {
|
|
|
|
return window.SpeechRecognition || window.webkitSpeechRecognition || window.mozSpeechRecognition || window.oSpeechRecognition || window.msSpeechRecognition;
|
2018-10-23 00:48:22 +03:00
|
|
|
}
|
|
|
|
|
2020-07-16 22:19:09 +02:00
|
|
|
return false;
|
|
|
|
}
|
2019-03-17 21:52:56 +00:00
|
|
|
|
2020-07-16 22:19:09 +02:00
|
|
|
function supportsFullscreen() {
|
|
|
|
if (browser.tv) {
|
2019-03-17 21:52:56 +00:00
|
|
|
return false;
|
2018-10-23 00:48:22 +03:00
|
|
|
}
|
|
|
|
|
2020-07-16 22:19:09 +02:00
|
|
|
const element = document.documentElement;
|
|
|
|
return (element.requestFullscreen || element.mozRequestFullScreen || element.webkitRequestFullscreen || element.msRequestFullscreen) || document.createElement('video').webkitEnterFullscreen;
|
|
|
|
}
|
2018-10-23 00:48:22 +03:00
|
|
|
|
2020-07-16 22:19:09 +02:00
|
|
|
function getDefaultLayout() {
|
|
|
|
return 'desktop';
|
|
|
|
}
|
2019-03-17 21:52:56 +00:00
|
|
|
|
2020-07-16 22:19:09 +02:00
|
|
|
function supportsHtmlMediaAutoplay() {
|
|
|
|
if (browser.edgeUwp || browser.tizen || browser.web0s || browser.orsay || browser.operaTv || browser.ps4 || browser.xboxOne) {
|
2020-01-24 18:45:37 +09:00
|
|
|
return true;
|
2018-10-23 00:48:22 +03:00
|
|
|
}
|
|
|
|
|
2020-07-16 22:19:09 +02:00
|
|
|
if (browser.mobile) {
|
|
|
|
return false;
|
|
|
|
}
|
2020-01-24 02:57:29 +09:00
|
|
|
|
2020-07-16 22:19:09 +02:00
|
|
|
return true;
|
|
|
|
}
|
2020-01-24 02:57:29 +09:00
|
|
|
|
2020-07-16 22:19:09 +02:00
|
|
|
function supportsCue() {
|
|
|
|
try {
|
|
|
|
const video = document.createElement('video');
|
|
|
|
const style = document.createElement('style');
|
2020-01-24 02:57:29 +09:00
|
|
|
|
2020-07-16 22:19:09 +02:00
|
|
|
style.textContent = 'video::cue {background: inherit}';
|
|
|
|
document.body.appendChild(style);
|
|
|
|
document.body.appendChild(video);
|
2018-10-23 00:48:22 +03:00
|
|
|
|
2020-07-16 22:19:09 +02:00
|
|
|
const cue = window.getComputedStyle(video, '::cue').background;
|
|
|
|
document.body.removeChild(style);
|
|
|
|
document.body.removeChild(video);
|
|
|
|
|
|
|
|
return !!cue.length;
|
|
|
|
} catch (err) {
|
|
|
|
console.error('error detecting cue support: ' + err);
|
|
|
|
return false;
|
2018-10-23 00:48:22 +03:00
|
|
|
}
|
2020-07-16 22:19:09 +02:00
|
|
|
}
|
2018-10-23 00:48:22 +03:00
|
|
|
|
2020-07-16 22:19:09 +02:00
|
|
|
function onAppVisible() {
|
|
|
|
if (isHidden) {
|
|
|
|
isHidden = false;
|
2020-09-08 02:05:02 -04:00
|
|
|
Events.trigger(appHost, 'resume');
|
2018-10-23 00:48:22 +03:00
|
|
|
}
|
2020-07-16 22:19:09 +02:00
|
|
|
}
|
2019-01-22 02:33:17 +09:00
|
|
|
|
2020-07-16 22:19:09 +02:00
|
|
|
function onAppHidden() {
|
|
|
|
if (!isHidden) {
|
|
|
|
isHidden = true;
|
|
|
|
}
|
|
|
|
}
|
2019-03-17 21:52:56 +00:00
|
|
|
|
2020-07-16 22:19:09 +02:00
|
|
|
const supportedFeatures = function () {
|
|
|
|
const features = [];
|
2019-03-17 21:52:56 +00:00
|
|
|
|
2020-07-16 22:19:09 +02:00
|
|
|
if (navigator.share) {
|
|
|
|
features.push('sharing');
|
|
|
|
}
|
2019-03-17 21:52:56 +00:00
|
|
|
|
2020-07-16 22:19:09 +02:00
|
|
|
if (!browser.edgeUwp && !browser.tv && !browser.xboxOne && !browser.ps4) {
|
|
|
|
features.push('filedownload');
|
|
|
|
}
|
2019-03-17 21:52:56 +00:00
|
|
|
|
2020-07-16 22:19:09 +02:00
|
|
|
if (browser.operaTv || browser.tizen || browser.orsay || browser.web0s) {
|
|
|
|
features.push('exit');
|
|
|
|
} else {
|
|
|
|
features.push('exitmenu');
|
|
|
|
features.push('plugins');
|
|
|
|
}
|
2019-03-17 21:52:56 +00:00
|
|
|
|
2020-07-16 22:19:09 +02:00
|
|
|
if (!browser.operaTv && !browser.tizen && !browser.orsay && !browser.web0s && !browser.ps4) {
|
|
|
|
features.push('externallinks');
|
|
|
|
features.push('externalpremium');
|
|
|
|
}
|
2019-03-17 21:52:56 +00:00
|
|
|
|
2020-07-16 22:19:09 +02:00
|
|
|
if (!browser.operaTv) {
|
|
|
|
features.push('externallinkdisplay');
|
|
|
|
}
|
2019-03-17 21:52:56 +00:00
|
|
|
|
2020-07-16 22:19:09 +02:00
|
|
|
if (supportsVoiceInput()) {
|
|
|
|
features.push('voiceinput');
|
|
|
|
}
|
2019-03-17 21:52:56 +00:00
|
|
|
|
2020-07-16 22:19:09 +02:00
|
|
|
if (supportsHtmlMediaAutoplay()) {
|
|
|
|
features.push('htmlaudioautoplay');
|
|
|
|
features.push('htmlvideoautoplay');
|
|
|
|
}
|
2019-03-17 21:52:56 +00:00
|
|
|
|
2020-07-16 22:19:09 +02:00
|
|
|
if (browser.edgeUwp) {
|
|
|
|
features.push('sync');
|
|
|
|
}
|
2019-03-17 21:52:56 +00:00
|
|
|
|
2020-07-16 22:19:09 +02:00
|
|
|
if (supportsFullscreen()) {
|
|
|
|
features.push('fullscreenchange');
|
|
|
|
}
|
2019-03-17 21:52:56 +00:00
|
|
|
|
2020-07-16 22:19:09 +02:00
|
|
|
if (browser.tv || browser.xboxOne || browser.ps4 || browser.mobile) {
|
|
|
|
features.push('physicalvolumecontrol');
|
|
|
|
}
|
2019-03-17 21:52:56 +00:00
|
|
|
|
2020-07-16 22:19:09 +02:00
|
|
|
if (!browser.tv && !browser.xboxOne && !browser.ps4) {
|
|
|
|
features.push('remotecontrol');
|
|
|
|
}
|
2019-03-17 21:52:56 +00:00
|
|
|
|
2020-07-16 22:19:09 +02:00
|
|
|
if (!browser.operaTv && !browser.tizen && !browser.orsay && !browser.web0s && !browser.edgeUwp) {
|
|
|
|
features.push('remotevideo');
|
|
|
|
}
|
2019-03-17 21:52:56 +00:00
|
|
|
|
2020-07-16 22:19:09 +02:00
|
|
|
features.push('displaylanguage');
|
|
|
|
features.push('otherapppromotions');
|
|
|
|
features.push('displaymode');
|
|
|
|
features.push('targetblank');
|
|
|
|
features.push('screensaver');
|
2020-02-16 12:17:13 +09:00
|
|
|
|
2020-08-06 22:09:24 +02:00
|
|
|
webSettings.getMultiServer().then(enabled => {
|
2020-07-16 22:19:09 +02:00
|
|
|
if (enabled) features.push('multiserver');
|
|
|
|
});
|
2019-03-17 21:52:56 +00:00
|
|
|
|
2020-07-16 22:19:09 +02:00
|
|
|
if (!browser.orsay && (browser.firefox || browser.ps4 || browser.edge || supportsCue())) {
|
|
|
|
features.push('subtitleappearancesettings');
|
|
|
|
}
|
2019-03-17 21:52:56 +00:00
|
|
|
|
2020-07-16 22:19:09 +02:00
|
|
|
if (!browser.orsay) {
|
|
|
|
features.push('subtitleburnsettings');
|
|
|
|
}
|
2019-03-17 21:52:56 +00:00
|
|
|
|
2020-07-16 22:19:09 +02:00
|
|
|
if (!browser.tv && !browser.ps4 && !browser.xboxOne) {
|
|
|
|
features.push('fileinput');
|
|
|
|
}
|
2019-03-17 21:52:56 +00:00
|
|
|
|
2020-08-11 15:37:48 +02:00
|
|
|
if (browser.chrome || browser.edgeChromium) {
|
2020-07-16 22:19:09 +02:00
|
|
|
features.push('chromecast');
|
|
|
|
}
|
2019-03-17 21:52:56 +00:00
|
|
|
|
2020-07-16 22:19:09 +02:00
|
|
|
return features;
|
|
|
|
}();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Do exit according to platform
|
|
|
|
*/
|
|
|
|
function doExit() {
|
|
|
|
try {
|
2021-04-10 21:53:32 -04:00
|
|
|
if (window.NativeShell && window.NativeShell.AppHost.exit) {
|
2020-07-16 22:19:09 +02:00
|
|
|
window.NativeShell.AppHost.exit();
|
|
|
|
} else if (browser.tizen) {
|
|
|
|
tizen.application.getCurrentApplication().exit();
|
|
|
|
} else if (browser.web0s) {
|
|
|
|
webOS.platformBack();
|
|
|
|
} else {
|
|
|
|
window.close();
|
2020-01-21 12:51:33 +03:00
|
|
|
}
|
2020-07-16 22:19:09 +02:00
|
|
|
} catch (err) {
|
|
|
|
console.error('error closing application: ' + err);
|
2020-01-21 12:51:33 +03:00
|
|
|
}
|
2020-07-16 22:19:09 +02:00
|
|
|
}
|
2020-01-21 12:51:33 +03:00
|
|
|
|
2020-07-16 22:19:09 +02:00
|
|
|
let exitPromise;
|
2020-01-21 12:51:33 +03:00
|
|
|
|
2020-07-16 22:19:09 +02:00
|
|
|
/**
|
|
|
|
* Ask user for exit
|
|
|
|
*/
|
|
|
|
function askForExit() {
|
|
|
|
if (exitPromise) {
|
|
|
|
return;
|
2020-01-21 12:51:33 +03:00
|
|
|
}
|
|
|
|
|
2020-08-14 08:46:34 +02:00
|
|
|
import('../components/actionSheet/actionSheet').then((actionsheet) => {
|
2020-07-16 22:19:09 +02:00
|
|
|
exitPromise = actionsheet.show({
|
|
|
|
title: globalize.translate('MessageConfirmAppExit'),
|
|
|
|
items: [
|
|
|
|
{id: 'yes', name: globalize.translate('Yes')},
|
|
|
|
{id: 'no', name: globalize.translate('No')}
|
|
|
|
]
|
|
|
|
}).then(function (value) {
|
|
|
|
if (value === 'yes') {
|
2020-01-21 12:51:33 +03:00
|
|
|
doExit();
|
2019-03-17 21:52:56 +00:00
|
|
|
}
|
2020-07-16 22:19:09 +02:00
|
|
|
}).finally(function () {
|
|
|
|
exitPromise = null;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
let deviceId;
|
|
|
|
let deviceName;
|
|
|
|
|
2020-08-16 20:24:45 +02:00
|
|
|
export const appHost = {
|
2020-07-16 22:19:09 +02:00
|
|
|
getWindowState: function () {
|
|
|
|
return document.windowState || 'Normal';
|
|
|
|
},
|
|
|
|
setWindowState: function () {
|
|
|
|
alert('setWindowState is not supported and should not be called');
|
|
|
|
},
|
|
|
|
exit: function () {
|
|
|
|
if (!!window.appMode && browser.tizen) {
|
|
|
|
askForExit();
|
|
|
|
} else {
|
|
|
|
doExit();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
supports: function (command) {
|
|
|
|
if (window.NativeShell) {
|
|
|
|
return window.NativeShell.AppHost.supports(command);
|
2019-01-22 02:33:17 +09:00
|
|
|
}
|
2019-03-17 21:52:56 +00:00
|
|
|
|
2020-07-16 22:19:09 +02:00
|
|
|
return supportedFeatures.indexOf(command.toLowerCase()) !== -1;
|
|
|
|
},
|
|
|
|
preferVisualCards: browser.android || browser.chrome,
|
|
|
|
getDefaultLayout: function () {
|
|
|
|
if (window.NativeShell) {
|
|
|
|
return window.NativeShell.AppHost.getDefaultLayout();
|
|
|
|
}
|
2019-03-17 21:52:56 +00:00
|
|
|
|
2020-07-16 22:19:09 +02:00
|
|
|
return getDefaultLayout();
|
|
|
|
},
|
|
|
|
getDeviceProfile: getDeviceProfile,
|
|
|
|
init: function () {
|
|
|
|
if (window.NativeShell) {
|
|
|
|
return window.NativeShell.AppHost.init();
|
2020-04-10 21:42:27 +02:00
|
|
|
}
|
2019-03-17 21:52:56 +00:00
|
|
|
|
2020-10-17 19:08:56 +01:00
|
|
|
return {
|
2020-11-08 23:11:22 +00:00
|
|
|
deviceId: getDeviceId(),
|
|
|
|
deviceName: getDeviceName()
|
2020-10-17 19:08:56 +01:00
|
|
|
};
|
2020-07-16 22:19:09 +02:00
|
|
|
},
|
|
|
|
deviceName: function () {
|
2021-04-10 21:53:32 -04:00
|
|
|
return window.NativeShell && window.NativeShell.AppHost.deviceName
|
|
|
|
? window.NativeShell.AppHost.deviceName() : getDeviceName();
|
2020-07-16 22:19:09 +02:00
|
|
|
},
|
|
|
|
deviceId: function () {
|
2021-04-10 21:53:32 -04:00
|
|
|
return window.NativeShell && window.NativeShell.AppHost.deviceId
|
|
|
|
? window.NativeShell.AppHost.deviceId() : getDeviceId();
|
2020-07-16 22:19:09 +02:00
|
|
|
},
|
|
|
|
appName: function () {
|
|
|
|
return window.NativeShell ? window.NativeShell.AppHost.appName() : appName;
|
|
|
|
},
|
|
|
|
appVersion: function () {
|
2020-12-10 10:53:54 -05:00
|
|
|
return window.NativeShell ? window.NativeShell.AppHost.appVersion() : appVersion;
|
2020-07-16 22:19:09 +02:00
|
|
|
},
|
|
|
|
getPushTokenInfo: function () {
|
|
|
|
return {};
|
|
|
|
},
|
|
|
|
setUserScalable: function (scalable) {
|
|
|
|
if (!browser.tv) {
|
|
|
|
const 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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
let isHidden = false;
|
|
|
|
let hidden;
|
|
|
|
let visibilityChange;
|
|
|
|
|
|
|
|
if (typeof document.hidden !== 'undefined') { /* eslint-disable-line compat/compat */
|
|
|
|
hidden = 'hidden';
|
|
|
|
visibilityChange = 'visibilitychange';
|
|
|
|
} else if (typeof document.webkitHidden !== 'undefined') {
|
|
|
|
hidden = 'webkitHidden';
|
|
|
|
visibilityChange = 'webkitvisibilitychange';
|
|
|
|
}
|
|
|
|
|
|
|
|
document.addEventListener(visibilityChange, function () {
|
|
|
|
/* eslint-disable-next-line compat/compat */
|
|
|
|
if (document[hidden]) {
|
|
|
|
onAppHidden();
|
|
|
|
} else {
|
|
|
|
onAppVisible();
|
2019-01-24 22:26:24 +09:00
|
|
|
}
|
2020-07-16 22:19:09 +02:00
|
|
|
}, false);
|
|
|
|
|
2020-08-25 10:12:35 +09:00
|
|
|
if (window.addEventListener) {
|
|
|
|
window.addEventListener('focus', onAppVisible);
|
|
|
|
window.addEventListener('blur', onAppHidden);
|
2020-07-16 22:19:09 +02:00
|
|
|
}
|
2019-03-17 21:52:56 +00:00
|
|
|
|
2020-10-17 19:08:56 +01:00
|
|
|
// load app host on module load
|
|
|
|
appHost.init();
|