2020-09-25 09:44:30 +02:00
|
|
|
import { Events } from 'jellyfin-apiclient';
|
2020-12-03 16:25:50 +01:00
|
|
|
import SyncPlay from '../core';
|
2020-10-14 20:40:46 +01:00
|
|
|
import SyncPlaySettingsEditor from './settings/SettingsEditor';
|
2022-10-01 02:57:30 -04:00
|
|
|
import loading from '../../../components/loading/loading';
|
|
|
|
import toast from '../../../components/toast/toast';
|
|
|
|
import actionsheet from '../../../components/actionSheet/actionSheet';
|
2020-09-25 09:44:30 +02:00
|
|
|
import globalize from '../../../scripts/globalize';
|
|
|
|
import playbackPermissionManager from './playbackPermissionManager';
|
2022-10-01 02:57:30 -04:00
|
|
|
import ServerConnections from '../../../components/ServerConnections';
|
2021-03-19 01:27:44 +00:00
|
|
|
import './groupSelectionMenu.scss';
|
2020-09-25 09:44:30 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Class that manages the SyncPlay group selection menu.
|
|
|
|
*/
|
|
|
|
class GroupSelectionMenu {
|
|
|
|
constructor() {
|
|
|
|
// Register to SyncPlay events.
|
|
|
|
this.syncPlayEnabled = false;
|
|
|
|
Events.on(SyncPlay.Manager, 'enabled', (e, enabled) => {
|
|
|
|
this.syncPlayEnabled = enabled;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Used when user needs to join a group.
|
|
|
|
* @param {HTMLElement} button - Element where to place the menu.
|
|
|
|
* @param {Object} user - Current user.
|
|
|
|
* @param {Object} apiClient - ApiClient.
|
|
|
|
*/
|
|
|
|
showNewJoinGroupSelection(button, user, apiClient) {
|
|
|
|
const policy = user.localUser ? user.localUser.Policy : {};
|
|
|
|
|
|
|
|
apiClient.getSyncPlayGroups().then(function (response) {
|
|
|
|
response.json().then(function (groups) {
|
|
|
|
const menuItems = groups.map(function (group) {
|
|
|
|
return {
|
|
|
|
name: group.GroupName,
|
|
|
|
icon: 'person',
|
|
|
|
id: group.GroupId,
|
|
|
|
selected: false,
|
|
|
|
secondaryText: group.Participants.join(', ')
|
|
|
|
};
|
|
|
|
});
|
|
|
|
|
|
|
|
if (policy.SyncPlayAccess === 'CreateAndJoinGroups') {
|
|
|
|
menuItems.push({
|
|
|
|
name: globalize.translate('LabelSyncPlayNewGroup'),
|
|
|
|
icon: 'add',
|
|
|
|
id: 'new-group',
|
|
|
|
selected: true,
|
|
|
|
secondaryText: globalize.translate('LabelSyncPlayNewGroupDescription')
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
if (menuItems.length === 0 && policy.SyncPlayAccess === 'JoinGroups') {
|
|
|
|
toast({
|
|
|
|
text: globalize.translate('MessageSyncPlayCreateGroupDenied')
|
|
|
|
});
|
|
|
|
loading.hide();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const menuOptions = {
|
|
|
|
title: globalize.translate('HeaderSyncPlaySelectGroup'),
|
|
|
|
items: menuItems,
|
|
|
|
positionTo: button,
|
2021-03-19 01:27:44 +00:00
|
|
|
border: true,
|
|
|
|
dialogClass: 'syncPlayGroupMenu'
|
2020-09-25 09:44:30 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
actionsheet.show(menuOptions).then(function (id) {
|
|
|
|
if (id == 'new-group') {
|
|
|
|
apiClient.createSyncPlayGroup({
|
|
|
|
GroupName: globalize.translate('SyncPlayGroupDefaultTitle', user.localUser.Name)
|
|
|
|
});
|
|
|
|
} else if (id) {
|
|
|
|
apiClient.joinSyncPlayGroup({
|
|
|
|
GroupId: id
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}).catch((error) => {
|
2021-09-01 12:39:01 -04:00
|
|
|
if (error) {
|
|
|
|
console.error('SyncPlay: unexpected error listing groups:', error);
|
|
|
|
}
|
2020-09-25 09:44:30 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
loading.hide();
|
|
|
|
});
|
|
|
|
}).catch(function (error) {
|
|
|
|
console.error(error);
|
|
|
|
loading.hide();
|
|
|
|
toast({
|
|
|
|
text: globalize.translate('MessageSyncPlayErrorAccessingGroups')
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Used when user has joined a group.
|
|
|
|
* @param {HTMLElement} button - Element where to place the menu.
|
|
|
|
* @param {Object} user - Current user.
|
|
|
|
* @param {Object} apiClient - ApiClient.
|
|
|
|
*/
|
|
|
|
showLeaveGroupSelection(button, user, apiClient) {
|
|
|
|
const groupInfo = SyncPlay.Manager.getGroupInfo();
|
|
|
|
const menuItems = [];
|
|
|
|
|
|
|
|
if (!SyncPlay.Manager.isPlaylistEmpty() && !SyncPlay.Manager.isPlaybackActive()) {
|
|
|
|
menuItems.push({
|
|
|
|
name: globalize.translate('LabelSyncPlayResumePlayback'),
|
|
|
|
icon: 'play_circle_filled',
|
|
|
|
id: 'resume-playback',
|
|
|
|
selected: false,
|
|
|
|
secondaryText: globalize.translate('LabelSyncPlayResumePlaybackDescription')
|
|
|
|
});
|
|
|
|
} else if (SyncPlay.Manager.isPlaybackActive()) {
|
|
|
|
menuItems.push({
|
|
|
|
name: globalize.translate('LabelSyncPlayHaltPlayback'),
|
|
|
|
icon: 'pause_circle_filled',
|
|
|
|
id: 'halt-playback',
|
|
|
|
selected: false,
|
|
|
|
secondaryText: globalize.translate('LabelSyncPlayHaltPlaybackDescription')
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2020-10-14 20:40:46 +01:00
|
|
|
menuItems.push({
|
|
|
|
name: globalize.translate('Settings'),
|
|
|
|
icon: 'video_settings',
|
|
|
|
id: 'settings',
|
|
|
|
selected: false,
|
|
|
|
secondaryText: globalize.translate('LabelSyncPlaySettingsDescription')
|
|
|
|
});
|
|
|
|
|
2020-09-25 09:44:30 +02:00
|
|
|
menuItems.push({
|
|
|
|
name: globalize.translate('LabelSyncPlayLeaveGroup'),
|
|
|
|
icon: 'meeting_room',
|
|
|
|
id: 'leave-group',
|
|
|
|
selected: true,
|
|
|
|
secondaryText: globalize.translate('LabelSyncPlayLeaveGroupDescription')
|
|
|
|
});
|
|
|
|
|
|
|
|
const menuOptions = {
|
|
|
|
title: groupInfo.GroupName,
|
2021-03-19 01:27:44 +00:00
|
|
|
text: groupInfo.Participants.join(', '),
|
|
|
|
dialogClass: 'syncPlayGroupMenu',
|
2020-09-25 09:44:30 +02:00
|
|
|
items: menuItems,
|
|
|
|
positionTo: button,
|
2021-08-25 14:01:12 +03:00
|
|
|
border: true
|
2020-09-25 09:44:30 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
actionsheet.show(menuOptions).then(function (id) {
|
|
|
|
if (id == 'resume-playback') {
|
|
|
|
SyncPlay.Manager.resumeGroupPlayback(apiClient);
|
|
|
|
} else if (id == 'halt-playback') {
|
|
|
|
SyncPlay.Manager.haltGroupPlayback(apiClient);
|
|
|
|
} else if (id == 'leave-group') {
|
|
|
|
apiClient.leaveSyncPlayGroup();
|
2020-10-14 20:40:46 +01:00
|
|
|
} else if (id == 'settings') {
|
2021-09-01 13:23:39 -04:00
|
|
|
new SyncPlaySettingsEditor(apiClient, SyncPlay.Manager.getTimeSyncCore(), { groupInfo: groupInfo })
|
|
|
|
.embed()
|
|
|
|
.catch(error => {
|
|
|
|
if (error) {
|
|
|
|
console.error('Error creating SyncPlay settings editor', error);
|
|
|
|
}
|
|
|
|
});
|
2020-09-25 09:44:30 +02:00
|
|
|
}
|
|
|
|
}).catch((error) => {
|
2021-09-01 12:39:01 -04:00
|
|
|
if (error) {
|
|
|
|
console.error('SyncPlay: unexpected error showing group menu:', error);
|
|
|
|
}
|
2020-09-25 09:44:30 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
loading.hide();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Shows a menu to handle SyncPlay groups.
|
|
|
|
* @param {HTMLElement} button - Element where to place the menu.
|
|
|
|
*/
|
|
|
|
show(button) {
|
|
|
|
loading.show();
|
|
|
|
|
|
|
|
// TODO: should feature be disabled if playback permission is missing?
|
|
|
|
playbackPermissionManager.check().then(() => {
|
|
|
|
console.debug('Playback is allowed.');
|
|
|
|
}).catch((error) => {
|
|
|
|
console.error('Playback not allowed!', error);
|
|
|
|
toast({
|
|
|
|
text: globalize.translate('MessageSyncPlayPlaybackPermissionRequired')
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
const apiClient = ServerConnections.currentApiClient();
|
|
|
|
ServerConnections.user(apiClient).then((user) => {
|
|
|
|
if (this.syncPlayEnabled) {
|
|
|
|
this.showLeaveGroupSelection(button, user, apiClient);
|
|
|
|
} else {
|
|
|
|
this.showNewJoinGroupSelection(button, user, apiClient);
|
|
|
|
}
|
|
|
|
}).catch((error) => {
|
|
|
|
console.error(error);
|
|
|
|
loading.hide();
|
|
|
|
toast({
|
|
|
|
text: globalize.translate('MessageSyncPlayNoGroupsAvailable')
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/** GroupSelectionMenu singleton. */
|
|
|
|
const groupSelectionMenu = new GroupSelectionMenu();
|
|
|
|
export default groupSelectionMenu;
|