2020-08-14 08:46:34 +02:00
|
|
|
import appSettings from '../../scripts/settings/appSettings';
|
2020-09-08 02:05:02 -04:00
|
|
|
import { Events } from 'jellyfin-apiclient';
|
2020-08-14 08:46:34 +02:00
|
|
|
import browser from '../../scripts/browser';
|
|
|
|
import loading from '../loading/loading';
|
2020-08-16 20:24:45 +02:00
|
|
|
import { playbackManager } from '../playback/playbackmanager';
|
|
|
|
import { appRouter } from '../appRouter';
|
2020-08-14 08:46:34 +02:00
|
|
|
import globalize from '../../scripts/globalize';
|
2020-08-16 20:24:45 +02:00
|
|
|
import { appHost } from '../apphost';
|
2020-08-14 08:46:34 +02:00
|
|
|
import { enable, isEnabled, supported } from '../../scripts/autocast';
|
2020-11-08 20:14:55 +00:00
|
|
|
import '../../elements/emby-checkbox/emby-checkbox';
|
|
|
|
import '../../elements/emby-button/emby-button';
|
|
|
|
import dialog from '../dialog/dialog';
|
|
|
|
import dialogHelper from '../dialogHelper/dialogHelper';
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2020-05-21 15:28:19 +02:00
|
|
|
function mirrorItem(info, player) {
|
2020-10-07 21:12:14 +09:00
|
|
|
const item = info.item;
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-05-21 15:28:19 +02:00
|
|
|
playbackManager.displayContent({
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-05-21 15:28:19 +02:00
|
|
|
ItemName: item.Name,
|
|
|
|
ItemId: item.Id,
|
|
|
|
ItemType: item.Type,
|
|
|
|
Context: info.context
|
|
|
|
}, player);
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2020-05-21 15:28:19 +02:00
|
|
|
function mirrorIfEnabled(info) {
|
|
|
|
if (info && playbackManager.enableDisplayMirroring()) {
|
2020-10-07 21:12:14 +09:00
|
|
|
const getPlayerInfo = playbackManager.getPlayerInfo();
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-05-21 15:28:19 +02:00
|
|
|
if (getPlayerInfo) {
|
|
|
|
if (!getPlayerInfo.isLocalPlayer && getPlayerInfo.supportedCommands.indexOf('DisplayContent') !== -1) {
|
|
|
|
mirrorItem(info, playbackManager.getCurrentPlayer());
|
2019-01-10 15:39:37 +03:00
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
|
|
|
}
|
2020-05-21 15:28:19 +02:00
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2020-05-21 15:28:19 +02:00
|
|
|
function emptyCallback() {
|
|
|
|
// avoid console logs about uncaught promises
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2020-05-21 15:28:19 +02:00
|
|
|
function getTargetSecondaryText(target) {
|
|
|
|
if (target.user) {
|
|
|
|
return target.user.Name;
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
|
|
|
|
2020-05-21 15:28:19 +02:00
|
|
|
return null;
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-05-21 15:28:19 +02:00
|
|
|
function getIcon(target) {
|
2020-10-07 21:12:14 +09:00
|
|
|
let deviceType = target.deviceType;
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-05-21 15:28:19 +02:00
|
|
|
if (!deviceType && target.isLocalPlayer) {
|
|
|
|
if (browser.tv) {
|
2019-01-10 15:39:37 +03:00
|
|
|
deviceType = 'tv';
|
2020-05-21 15:28:19 +02:00
|
|
|
} else if (browser.mobile) {
|
|
|
|
deviceType = 'smartphone';
|
|
|
|
} else {
|
|
|
|
deviceType = 'desktop';
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-21 15:28:19 +02:00
|
|
|
if (!deviceType) {
|
|
|
|
deviceType = 'tv';
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-05-21 15:28:19 +02:00
|
|
|
switch (deviceType) {
|
|
|
|
case 'smartphone':
|
|
|
|
return 'smartphone';
|
|
|
|
case 'tablet':
|
|
|
|
return 'tablet';
|
|
|
|
case 'tv':
|
|
|
|
return 'tv';
|
|
|
|
case 'cast':
|
|
|
|
return 'cast';
|
|
|
|
case 'desktop':
|
|
|
|
return 'computer';
|
|
|
|
default:
|
|
|
|
return 'tv';
|
|
|
|
}
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-05-21 19:16:19 +02:00
|
|
|
export function show(button) {
|
2020-10-07 21:12:14 +09:00
|
|
|
const currentPlayerInfo = playbackManager.getPlayerInfo();
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-05-21 15:28:19 +02:00
|
|
|
if (currentPlayerInfo) {
|
|
|
|
if (!currentPlayerInfo.isLocalPlayer) {
|
|
|
|
showActivePlayerMenu(currentPlayerInfo);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-10-07 21:12:14 +09:00
|
|
|
const currentPlayerId = currentPlayerInfo ? currentPlayerInfo.id : null;
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-05-21 15:28:19 +02:00
|
|
|
loading.show();
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-05-21 15:28:19 +02:00
|
|
|
playbackManager.getTargets().then(function (targets) {
|
2020-10-07 21:12:14 +09:00
|
|
|
const menuItems = targets.map(function (t) {
|
|
|
|
let name = t.name;
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-05-21 15:28:19 +02:00
|
|
|
if (t.appName && t.appName !== t.name) {
|
|
|
|
name += ' - ' + t.appName;
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-05-21 15:28:19 +02:00
|
|
|
return {
|
|
|
|
name: name,
|
|
|
|
id: t.id,
|
|
|
|
selected: currentPlayerId === t.id,
|
|
|
|
secondaryText: getTargetSecondaryText(t),
|
|
|
|
icon: getIcon(t)
|
|
|
|
};
|
|
|
|
});
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-08-14 08:46:34 +02:00
|
|
|
import('../actionSheet/actionSheet').then((actionsheet) => {
|
2020-05-21 15:28:19 +02:00
|
|
|
loading.hide();
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-10-07 21:12:14 +09:00
|
|
|
const menuOptions = {
|
2020-05-21 15:28:19 +02:00
|
|
|
title: globalize.translate('HeaderPlayOn'),
|
|
|
|
items: menuItems,
|
|
|
|
positionTo: button,
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-05-21 15:28:19 +02:00
|
|
|
resolveOnClick: true,
|
|
|
|
border: true
|
|
|
|
};
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-05-21 15:28:19 +02:00
|
|
|
// Unfortunately we can't allow the url to change or chromecast will throw a security error
|
|
|
|
// Might be able to solve this in the future by moving the dialogs to hashbangs
|
2020-07-27 21:11:12 +08:00
|
|
|
if (!(!browser.chrome && !browser.edgeChromium || appHost.supports('castmenuhashchange'))) {
|
2020-05-21 15:28:19 +02:00
|
|
|
menuOptions.enableHistory = false;
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-05-21 15:28:19 +02:00
|
|
|
actionsheet.show(menuOptions).then(function (id) {
|
2020-10-07 21:12:14 +09:00
|
|
|
const target = targets.filter(function (t) {
|
2020-05-21 15:28:19 +02:00
|
|
|
return t.id === id;
|
|
|
|
})[0];
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-05-21 15:28:19 +02:00
|
|
|
playbackManager.trySetActivePlayer(target.playerName, target);
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2020-05-21 15:28:19 +02:00
|
|
|
mirrorIfEnabled();
|
|
|
|
}, emptyCallback);
|
2019-01-10 15:39:37 +03:00
|
|
|
});
|
2020-05-21 15:28:19 +02:00
|
|
|
});
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-05-21 15:28:19 +02:00
|
|
|
function showActivePlayerMenu(playerInfo) {
|
2020-11-08 20:56:08 +00:00
|
|
|
showActivePlayerMenuInternal(playerInfo);
|
2020-05-21 15:28:19 +02:00
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-05-21 15:28:19 +02:00
|
|
|
function disconnectFromPlayer(currentDeviceName) {
|
|
|
|
if (playbackManager.getSupportedCommands().indexOf('EndSession') !== -1) {
|
2020-11-08 20:14:55 +00:00
|
|
|
const menuItems = [];
|
|
|
|
|
|
|
|
menuItems.push({
|
|
|
|
name: globalize.translate('Yes'),
|
|
|
|
id: 'yes'
|
|
|
|
});
|
|
|
|
menuItems.push({
|
|
|
|
name: globalize.translate('No'),
|
|
|
|
id: 'no'
|
|
|
|
});
|
|
|
|
|
|
|
|
dialog.show({
|
|
|
|
buttons: menuItems,
|
|
|
|
text: globalize.translate('ConfirmEndPlayerSession', currentDeviceName)
|
|
|
|
|
|
|
|
}).then(function (id) {
|
|
|
|
switch (id) {
|
|
|
|
case 'yes':
|
|
|
|
playbackManager.getCurrentPlayer().endSession();
|
|
|
|
playbackManager.setDefaultPlayerActive();
|
|
|
|
break;
|
|
|
|
case 'no':
|
|
|
|
playbackManager.setDefaultPlayerActive();
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2020-05-21 15:28:19 +02:00
|
|
|
});
|
|
|
|
} else {
|
|
|
|
playbackManager.setDefaultPlayerActive();
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
2020-05-21 15:28:19 +02:00
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2020-11-08 20:56:08 +00:00
|
|
|
function showActivePlayerMenuInternal(playerInfo) {
|
2020-10-07 21:12:14 +09:00
|
|
|
let html = '';
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-10-07 21:12:14 +09:00
|
|
|
const dialogOptions = {
|
2020-05-21 15:28:19 +02:00
|
|
|
removeOnClose: true
|
|
|
|
};
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-05-21 15:28:19 +02:00
|
|
|
dialogOptions.modal = false;
|
|
|
|
dialogOptions.entryAnimationDuration = 160;
|
|
|
|
dialogOptions.exitAnimationDuration = 160;
|
|
|
|
dialogOptions.autoFocus = false;
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-10-07 21:12:14 +09:00
|
|
|
const dlg = dialogHelper.createDialog(dialogOptions);
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-05-21 15:28:19 +02:00
|
|
|
dlg.classList.add('promptDialog');
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-10-07 21:12:14 +09:00
|
|
|
const currentDeviceName = (playerInfo.deviceName || playerInfo.name);
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-05-21 15:28:19 +02:00
|
|
|
html += '<div class="promptDialogContent" style="padding:1.5em;">';
|
|
|
|
html += '<h2 style="margin-top:.5em;">';
|
|
|
|
html += currentDeviceName;
|
|
|
|
html += '</h2>';
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-05-21 15:28:19 +02:00
|
|
|
html += '<div>';
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-05-21 15:28:19 +02:00
|
|
|
if (playerInfo.supportedCommands.indexOf('DisplayContent') !== -1) {
|
|
|
|
html += '<label class="checkboxContainer">';
|
2020-10-07 21:12:14 +09:00
|
|
|
const checkedHtml = playbackManager.enableDisplayMirroring() ? ' checked' : '';
|
2020-05-21 15:28:19 +02:00
|
|
|
html += '<input type="checkbox" is="emby-checkbox" class="chkMirror"' + checkedHtml + '/>';
|
|
|
|
html += '<span>' + globalize.translate('EnableDisplayMirroring') + '</span>';
|
|
|
|
html += '</label>';
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-09-22 07:34:46 -04:00
|
|
|
html += '</div>';
|
2020-09-07 12:54:12 -04:00
|
|
|
|
2020-08-14 08:46:34 +02:00
|
|
|
if (supported()) {
|
2020-09-22 07:34:46 -04:00
|
|
|
html += '<div><label class="checkboxContainer">';
|
2020-08-14 08:46:34 +02:00
|
|
|
const checkedHtmlAC = isEnabled() ? ' checked' : '';
|
2020-09-07 13:10:38 -04:00
|
|
|
html += '<input type="checkbox" is="emby-checkbox" class="chkAutoCast"' + checkedHtmlAC + '/>';
|
2020-09-07 12:54:12 -04:00
|
|
|
html += '<span>' + globalize.translate('EnableAutoCast') + '</span>';
|
2020-09-22 07:34:46 -04:00
|
|
|
html += '</label></div>';
|
2020-09-07 12:54:12 -04:00
|
|
|
}
|
|
|
|
|
2020-05-21 15:28:19 +02:00
|
|
|
html += '<div style="margin-top:1em;display:flex;justify-content: flex-end;">';
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-05-21 15:28:19 +02:00
|
|
|
html += '<button is="emby-button" type="button" class="button-flat btnRemoteControl promptDialogButton">' + globalize.translate('HeaderRemoteControl') + '</button>';
|
|
|
|
html += '<button is="emby-button" type="button" class="button-flat btnDisconnect promptDialogButton ">' + globalize.translate('Disconnect') + '</button>';
|
|
|
|
html += '<button is="emby-button" type="button" class="button-flat btnCancel promptDialogButton">' + globalize.translate('ButtonCancel') + '</button>';
|
|
|
|
html += '</div>';
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-05-21 15:28:19 +02:00
|
|
|
html += '</div>';
|
|
|
|
dlg.innerHTML = html;
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-10-07 21:12:14 +09:00
|
|
|
const chkMirror = dlg.querySelector('.chkMirror');
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-05-21 15:28:19 +02:00
|
|
|
if (chkMirror) {
|
|
|
|
chkMirror.addEventListener('change', onMirrorChange);
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-10-07 21:12:14 +09:00
|
|
|
const chkAutoCast = dlg.querySelector('.chkAutoCast');
|
2020-09-07 12:54:12 -04:00
|
|
|
|
|
|
|
if (chkAutoCast) {
|
|
|
|
chkAutoCast.addEventListener('change', onAutoCastChange);
|
|
|
|
}
|
|
|
|
|
2020-10-07 21:12:14 +09:00
|
|
|
let destination = '';
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-10-07 21:12:14 +09:00
|
|
|
const btnRemoteControl = dlg.querySelector('.btnRemoteControl');
|
2020-05-21 15:28:19 +02:00
|
|
|
if (btnRemoteControl) {
|
|
|
|
btnRemoteControl.addEventListener('click', function () {
|
|
|
|
destination = 'nowplaying';
|
2019-01-10 15:39:37 +03:00
|
|
|
dialogHelper.close(dlg);
|
|
|
|
});
|
2020-05-21 15:28:19 +02:00
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-05-21 15:28:19 +02:00
|
|
|
dlg.querySelector('.btnDisconnect').addEventListener('click', function () {
|
|
|
|
destination = 'disconnectFromPlayer';
|
|
|
|
dialogHelper.close(dlg);
|
|
|
|
});
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-05-21 15:28:19 +02:00
|
|
|
dlg.querySelector('.btnCancel').addEventListener('click', function () {
|
|
|
|
dialogHelper.close(dlg);
|
|
|
|
});
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2020-05-21 15:28:19 +02:00
|
|
|
dialogHelper.open(dlg).then(function () {
|
|
|
|
if (destination === 'nowplaying') {
|
|
|
|
appRouter.showNowPlaying();
|
|
|
|
} else if (destination === 'disconnectFromPlayer') {
|
|
|
|
disconnectFromPlayer(currentDeviceName);
|
|
|
|
}
|
|
|
|
}, emptyCallback);
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-05-21 15:28:19 +02:00
|
|
|
function onMirrorChange() {
|
|
|
|
playbackManager.enableDisplayMirroring(this.checked);
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-09-07 12:54:12 -04:00
|
|
|
function onAutoCastChange() {
|
2020-08-14 08:46:34 +02:00
|
|
|
enable(this.checked);
|
2020-09-07 12:54:12 -04:00
|
|
|
}
|
|
|
|
|
2020-05-21 15:28:19 +02:00
|
|
|
document.addEventListener('viewshow', function (e) {
|
2020-10-07 21:12:14 +09:00
|
|
|
const state = e.detail.state || {};
|
|
|
|
const item = state.item;
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-05-21 15:28:19 +02:00
|
|
|
if (item && item.ServerId) {
|
|
|
|
mirrorIfEnabled({
|
|
|
|
item: item
|
|
|
|
});
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
});
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-09-08 02:05:02 -04:00
|
|
|
Events.on(appSettings, 'change', function (e, name) {
|
2020-05-21 15:28:19 +02:00
|
|
|
if (name === 'displaymirror') {
|
|
|
|
mirrorIfEnabled();
|
|
|
|
}
|
|
|
|
});
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2021-01-26 22:20:12 -05:00
|
|
|
Events.on(playbackManager, 'pairing', function () {
|
2020-05-21 15:28:19 +02:00
|
|
|
loading.show();
|
|
|
|
});
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2021-01-26 22:20:12 -05:00
|
|
|
Events.on(playbackManager, 'paired', function () {
|
2020-05-21 15:28:19 +02:00
|
|
|
loading.hide();
|
|
|
|
});
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2021-01-26 22:20:12 -05:00
|
|
|
Events.on(playbackManager, 'pairerror', function () {
|
2020-05-21 15:28:19 +02:00
|
|
|
loading.hide();
|
2019-11-20 00:24:54 +03:00
|
|
|
});
|
2020-05-21 15:28:19 +02:00
|
|
|
|
|
|
|
export default {
|
2020-05-21 19:16:19 +02:00
|
|
|
show: show
|
2020-05-21 15:28:19 +02:00
|
|
|
};
|