2020-08-06 11:41:18 +01:00
|
|
|
import serverNotifications from 'serverNotifications';
|
|
|
|
import playbackManager from 'playbackManager';
|
|
|
|
import events from 'events';
|
|
|
|
import globalize from 'globalize';
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2020-08-06 11:41:18 +01:00
|
|
|
function onOneDocumentClick() {
|
|
|
|
document.removeEventListener('click', onOneDocumentClick);
|
|
|
|
document.removeEventListener('keydown', onOneDocumentClick);
|
2020-07-31 09:12:44 +01:00
|
|
|
|
2020-08-06 11:41:18 +01:00
|
|
|
// don't request notification permissions if they're already granted or denied
|
|
|
|
if (window.Notification && window.Notification.permission === 'default') {
|
|
|
|
/* eslint-disable-next-line compat/compat */
|
|
|
|
Notification.requestPermission();
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
2020-08-06 11:41:18 +01:00
|
|
|
}
|
2019-11-30 20:46:32 +09:00
|
|
|
|
2020-08-06 11:41:18 +01:00
|
|
|
document.addEventListener('click', onOneDocumentClick);
|
|
|
|
document.addEventListener('keydown', onOneDocumentClick);
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-08-06 11:41:18 +01:00
|
|
|
let serviceWorkerRegistration;
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2020-08-06 11:41:18 +01:00
|
|
|
function closeAfter(notification, timeoutMs) {
|
|
|
|
setTimeout(function () {
|
|
|
|
if (notification.close) {
|
|
|
|
notification.close();
|
|
|
|
} else if (notification.cancel) {
|
|
|
|
notification.cancel();
|
2019-01-10 15:39:37 +03:00
|
|
|
}
|
2020-08-06 11:41:18 +01:00
|
|
|
}, timeoutMs);
|
|
|
|
}
|
|
|
|
|
|
|
|
function resetRegistration() {
|
|
|
|
/* eslint-disable-next-line compat/compat */
|
|
|
|
let serviceWorker = navigator.serviceWorker;
|
|
|
|
if (serviceWorker) {
|
|
|
|
serviceWorker.ready.then(function (registration) {
|
|
|
|
serviceWorkerRegistration = registration;
|
|
|
|
});
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
2020-08-06 11:41:18 +01:00
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2020-08-06 11:41:18 +01:00
|
|
|
resetRegistration();
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-08-06 11:41:18 +01:00
|
|
|
function showPersistentNotification(title, options, timeoutMs) {
|
|
|
|
serviceWorkerRegistration.showNotification(title, options);
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2020-08-06 11:41:18 +01:00
|
|
|
function showNonPersistentNotification(title, options, timeoutMs) {
|
|
|
|
try {
|
|
|
|
let notif = new Notification(title, options); /* eslint-disable-line compat/compat */
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-08-06 11:41:18 +01:00
|
|
|
if (notif.show) {
|
|
|
|
notif.show();
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-08-06 11:41:18 +01:00
|
|
|
if (timeoutMs) {
|
|
|
|
closeAfter(notif, timeoutMs);
|
|
|
|
}
|
|
|
|
} catch (err) {
|
|
|
|
if (options.actions) {
|
|
|
|
options.actions = [];
|
|
|
|
showNonPersistentNotification(title, options, timeoutMs);
|
|
|
|
} else {
|
|
|
|
throw err;
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
|
|
|
}
|
2020-08-06 11:41:18 +01:00
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2020-08-06 11:41:18 +01:00
|
|
|
function showNotification(options, timeoutMs, apiClient) {
|
|
|
|
let title = options.title;
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-08-06 11:41:18 +01:00
|
|
|
options.data = options.data || {};
|
|
|
|
options.data.serverId = apiClient.serverInfo().Id;
|
|
|
|
options.icon = options.icon || getIconUrl();
|
|
|
|
options.badge = options.badge || getIconUrl('badge.png');
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-08-06 11:41:18 +01:00
|
|
|
resetRegistration();
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-08-06 11:41:18 +01:00
|
|
|
if (serviceWorkerRegistration) {
|
|
|
|
showPersistentNotification(title, options, timeoutMs);
|
|
|
|
return;
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
|
|
|
|
2020-08-06 11:41:18 +01:00
|
|
|
showNonPersistentNotification(title, options, timeoutMs);
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-08-06 11:41:18 +01:00
|
|
|
function showNewItemNotification(item, apiClient) {
|
|
|
|
if (playbackManager.isPlayingLocally(['Video'])) {
|
|
|
|
return;
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-08-06 11:41:18 +01:00
|
|
|
let body = item.Name;
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-08-06 11:41:18 +01:00
|
|
|
if (item.SeriesName) {
|
|
|
|
body = item.SeriesName + ' - ' + body;
|
|
|
|
}
|
|
|
|
|
|
|
|
let notification = {
|
|
|
|
title: 'New ' + item.Type,
|
|
|
|
body: body,
|
|
|
|
vibrate: true,
|
|
|
|
tag: 'newItem' + item.Id,
|
|
|
|
data: {}
|
|
|
|
};
|
|
|
|
|
|
|
|
let imageTags = item.ImageTags || {};
|
|
|
|
|
|
|
|
if (imageTags.Primary) {
|
|
|
|
notification.icon = apiClient.getScaledImageUrl(item.Id, {
|
|
|
|
width: 80,
|
|
|
|
tag: imageTags.Primary,
|
|
|
|
type: 'Primary'
|
|
|
|
});
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-08-06 11:41:18 +01:00
|
|
|
showNotification(notification, 15000, apiClient);
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-08-06 11:41:18 +01:00
|
|
|
function onLibraryChanged(data, apiClient) {
|
|
|
|
let newItems = data.ItemsAdded;
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-08-06 11:41:18 +01:00
|
|
|
if (!newItems.length) {
|
|
|
|
return;
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
|
|
|
|
2020-08-06 11:41:18 +01:00
|
|
|
// Don't put a massive number of Id's onto the query string
|
|
|
|
if (newItems.length > 12) {
|
|
|
|
newItems.length = 12;
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-08-06 11:41:18 +01:00
|
|
|
apiClient.getItems(apiClient.getCurrentUserId(), {
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-08-06 11:41:18 +01:00
|
|
|
Recursive: true,
|
|
|
|
Limit: 3,
|
|
|
|
Filters: 'IsNotFolder',
|
|
|
|
SortBy: 'DateCreated',
|
|
|
|
SortOrder: 'Descending',
|
|
|
|
Ids: newItems.join(','),
|
|
|
|
MediaTypes: 'Audio,Video',
|
|
|
|
EnableTotalRecordCount: false
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-08-06 11:41:18 +01:00
|
|
|
}).then(function (result) {
|
|
|
|
let items = result.Items;
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-08-06 11:41:18 +01:00
|
|
|
for (const item of items) {
|
|
|
|
showNewItemNotification(item, apiClient);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-08-06 11:41:18 +01:00
|
|
|
function getIconUrl(name) {
|
|
|
|
name = name || 'notificationicon.png';
|
|
|
|
return './components/notifications/' + name;
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2020-08-06 11:41:18 +01:00
|
|
|
function showPackageInstallNotification(apiClient, installation, status) {
|
|
|
|
apiClient.getCurrentUser().then(function (user) {
|
|
|
|
if (!user.Policy.IsAdministrator) {
|
|
|
|
return;
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2020-08-06 11:41:18 +01:00
|
|
|
let notification = {
|
|
|
|
tag: 'install' + installation.Id,
|
|
|
|
data: {}
|
|
|
|
};
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-08-06 11:41:18 +01:00
|
|
|
if (status === 'completed') {
|
|
|
|
notification.title = globalize.translate('PackageInstallCompleted', installation.Name, installation.Version);
|
|
|
|
notification.vibrate = true;
|
|
|
|
} else if (status === 'cancelled') {
|
|
|
|
notification.title = globalize.translate('PackageInstallCancelled', installation.Name, installation.Version);
|
|
|
|
} else if (status === 'failed') {
|
|
|
|
notification.title = globalize.translate('PackageInstallFailed', installation.Name, installation.Version);
|
|
|
|
notification.vibrate = true;
|
|
|
|
} else if (status === 'progress') {
|
|
|
|
notification.title = globalize.translate('InstallingPackage', installation.Name, installation.Version);
|
|
|
|
|
|
|
|
notification.actions =
|
2019-01-10 15:39:37 +03:00
|
|
|
[
|
|
|
|
{
|
|
|
|
action: 'cancel-install',
|
2019-02-03 02:41:16 +09:00
|
|
|
title: globalize.translate('ButtonCancel'),
|
2018-10-23 01:05:09 +03:00
|
|
|
icon: getIconUrl()
|
2019-01-10 15:39:37 +03:00
|
|
|
}
|
|
|
|
];
|
|
|
|
|
2020-08-06 11:41:18 +01:00
|
|
|
notification.data.id = installation.id;
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-08-06 11:41:18 +01:00
|
|
|
if (status === 'progress') {
|
|
|
|
let percentComplete = Math.round(installation.PercentComplete || 0);
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-08-06 11:41:18 +01:00
|
|
|
notification.body = percentComplete + '% complete.';
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-08-06 11:41:18 +01:00
|
|
|
let timeout = status === 'cancelled' ? 5000 : 0;
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-08-06 11:41:18 +01:00
|
|
|
showNotification(notification, timeout, apiClient);
|
2019-01-10 15:39:37 +03:00
|
|
|
});
|
2020-08-06 11:41:18 +01:00
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-08-06 11:41:18 +01:00
|
|
|
events.on(serverNotifications, 'LibraryChanged', function (e, apiClient, data) {
|
|
|
|
onLibraryChanged(data, apiClient);
|
|
|
|
});
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-08-06 11:41:18 +01:00
|
|
|
events.on(serverNotifications, 'PackageInstallationCompleted', function (e, apiClient, data) {
|
|
|
|
showPackageInstallNotification(apiClient, data, 'completed');
|
|
|
|
});
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-08-06 11:41:18 +01:00
|
|
|
events.on(serverNotifications, 'PackageInstallationFailed', function (e, apiClient, data) {
|
|
|
|
showPackageInstallNotification(apiClient, data, 'failed');
|
|
|
|
});
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-08-06 11:41:18 +01:00
|
|
|
events.on(serverNotifications, 'PackageInstallationCancelled', function (e, apiClient, data) {
|
|
|
|
showPackageInstallNotification(apiClient, data, 'cancelled');
|
|
|
|
});
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-08-06 11:41:18 +01:00
|
|
|
events.on(serverNotifications, 'PackageInstalling', function (e, apiClient, data) {
|
|
|
|
showPackageInstallNotification(apiClient, data, 'progress');
|
|
|
|
});
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-08-06 11:41:18 +01:00
|
|
|
events.on(serverNotifications, 'ServerShuttingDown', function (e, apiClient, data) {
|
|
|
|
let serverId = apiClient.serverInfo().Id;
|
|
|
|
let notification = {
|
|
|
|
tag: 'restart' + serverId,
|
|
|
|
title: globalize.translate('ServerNameIsShuttingDown', apiClient.serverInfo().Name)
|
|
|
|
};
|
|
|
|
showNotification(notification, 0, apiClient);
|
|
|
|
});
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-08-06 11:41:18 +01:00
|
|
|
events.on(serverNotifications, 'ServerRestarting', function (e, apiClient, data) {
|
|
|
|
let serverId = apiClient.serverInfo().Id;
|
|
|
|
let notification = {
|
|
|
|
tag: 'restart' + serverId,
|
|
|
|
title: globalize.translate('ServerNameIsRestarting', apiClient.serverInfo().Name)
|
|
|
|
};
|
|
|
|
showNotification(notification, 0, apiClient);
|
|
|
|
});
|
|
|
|
|
|
|
|
events.on(serverNotifications, 'RestartRequired', function (e, apiClient) {
|
|
|
|
let serverId = apiClient.serverInfo().Id;
|
|
|
|
let notification = {
|
|
|
|
tag: 'restart' + serverId,
|
|
|
|
title: globalize.translate('PleaseRestartServerName', apiClient.serverInfo().Name)
|
|
|
|
};
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-08-06 11:41:18 +01:00
|
|
|
notification.actions =
|
2019-01-10 15:39:37 +03:00
|
|
|
[
|
|
|
|
{
|
|
|
|
action: 'restart',
|
2020-08-27 09:28:09 +09:00
|
|
|
title: globalize.translate('Restart'),
|
2019-01-10 15:39:37 +03:00
|
|
|
icon: getIconUrl()
|
|
|
|
}
|
|
|
|
];
|
|
|
|
|
2020-08-06 11:41:18 +01:00
|
|
|
showNotification(notification, 0, apiClient);
|
2019-11-30 20:46:32 +09:00
|
|
|
});
|
2020-08-06 11:41:18 +01:00
|
|
|
|