mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
228 lines
6.6 KiB
JavaScript
228 lines
6.6 KiB
JavaScript
import { playbackManager } from './playback/playbackmanager';
|
|
import serverNotifications from '../scripts/serverNotifications';
|
|
import Events from '../utils/events.ts';
|
|
|
|
function onUserDataChanged() {
|
|
const instance = this;
|
|
const eventsToMonitor = getEventsToMonitor(instance);
|
|
|
|
// TODO: Check user data change reason?
|
|
if (eventsToMonitor.indexOf('markfavorite') !== -1
|
|
|| eventsToMonitor.indexOf('markplayed') !== -1
|
|
) {
|
|
instance.notifyRefreshNeeded();
|
|
}
|
|
}
|
|
|
|
function getEventsToMonitor(instance) {
|
|
const options = instance.options;
|
|
const monitor = options ? options.monitorEvents : null;
|
|
if (monitor) {
|
|
return monitor.split(',');
|
|
}
|
|
|
|
return [];
|
|
}
|
|
|
|
function notifyTimerRefresh() {
|
|
const instance = this;
|
|
|
|
if (getEventsToMonitor(instance).indexOf('timers') !== -1) {
|
|
instance.notifyRefreshNeeded();
|
|
}
|
|
}
|
|
|
|
function notifySeriesTimerRefresh() {
|
|
const instance = this;
|
|
if (getEventsToMonitor(instance).indexOf('seriestimers') !== -1) {
|
|
instance.notifyRefreshNeeded();
|
|
}
|
|
}
|
|
|
|
function onLibraryChanged(e, apiClient, data) {
|
|
const instance = this;
|
|
const eventsToMonitor = getEventsToMonitor(instance);
|
|
if (eventsToMonitor.indexOf('seriestimers') !== -1 || eventsToMonitor.indexOf('timers') !== -1) {
|
|
// yes this is an assumption
|
|
return;
|
|
}
|
|
|
|
const itemsAdded = data.ItemsAdded || [];
|
|
const itemsRemoved = data.ItemsRemoved || [];
|
|
if (!itemsAdded.length && !itemsRemoved.length) {
|
|
return;
|
|
}
|
|
|
|
const options = instance.options || {};
|
|
const parentId = options.parentId;
|
|
if (parentId) {
|
|
const foldersAddedTo = data.FoldersAddedTo || [];
|
|
const foldersRemovedFrom = data.FoldersRemovedFrom || [];
|
|
const collectionFolders = data.CollectionFolders || [];
|
|
|
|
if (foldersAddedTo.indexOf(parentId) === -1 && foldersRemovedFrom.indexOf(parentId) === -1 && collectionFolders.indexOf(parentId) === -1) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
instance.notifyRefreshNeeded();
|
|
}
|
|
|
|
function onPlaybackStopped(e, stopInfo) {
|
|
const instance = this;
|
|
|
|
const state = stopInfo.state;
|
|
|
|
const eventsToMonitor = getEventsToMonitor(instance);
|
|
if (state.NowPlayingItem?.MediaType === 'Video') {
|
|
if (eventsToMonitor.indexOf('videoplayback') !== -1) {
|
|
instance.notifyRefreshNeeded(true);
|
|
return;
|
|
}
|
|
} else if (state.NowPlayingItem?.MediaType === 'Audio' && eventsToMonitor.indexOf('audioplayback') !== -1) {
|
|
instance.notifyRefreshNeeded(true);
|
|
return;
|
|
}
|
|
}
|
|
|
|
function addNotificationEvent(instance, name, handler, owner) {
|
|
const localHandler = handler.bind(instance);
|
|
owner = owner || serverNotifications;
|
|
Events.on(owner, name, localHandler);
|
|
instance['event_' + name] = localHandler;
|
|
}
|
|
|
|
function removeNotificationEvent(instance, name, owner) {
|
|
const handler = instance['event_' + name];
|
|
if (handler) {
|
|
owner = owner || serverNotifications;
|
|
Events.off(owner, name, handler);
|
|
instance['event_' + name] = null;
|
|
}
|
|
}
|
|
|
|
class ItemsRefresher {
|
|
constructor(options) {
|
|
this.options = options || {};
|
|
|
|
addNotificationEvent(this, 'UserDataChanged', onUserDataChanged);
|
|
addNotificationEvent(this, 'TimerCreated', notifyTimerRefresh);
|
|
addNotificationEvent(this, 'SeriesTimerCreated', notifySeriesTimerRefresh);
|
|
addNotificationEvent(this, 'TimerCancelled', notifyTimerRefresh);
|
|
addNotificationEvent(this, 'SeriesTimerCancelled', notifySeriesTimerRefresh);
|
|
addNotificationEvent(this, 'LibraryChanged', onLibraryChanged);
|
|
addNotificationEvent(this, 'playbackstop', onPlaybackStopped, playbackManager);
|
|
}
|
|
|
|
pause() {
|
|
clearRefreshInterval(this, true);
|
|
|
|
this.paused = true;
|
|
}
|
|
|
|
resume(options) {
|
|
this.paused = false;
|
|
|
|
const refreshIntervalEndTime = this.refreshIntervalEndTime;
|
|
if (refreshIntervalEndTime) {
|
|
const remainingMs = refreshIntervalEndTime - new Date().getTime();
|
|
if (remainingMs > 0 && !this.needsRefresh) {
|
|
resetRefreshInterval(this, remainingMs);
|
|
} else {
|
|
this.needsRefresh = true;
|
|
this.refreshIntervalEndTime = null;
|
|
}
|
|
}
|
|
|
|
if (this.needsRefresh || (options && options.refresh)) {
|
|
return this.refreshItems();
|
|
}
|
|
|
|
return Promise.resolve();
|
|
}
|
|
|
|
refreshItems() {
|
|
if (!this.fetchData) {
|
|
return Promise.resolve();
|
|
}
|
|
|
|
if (this.paused) {
|
|
this.needsRefresh = true;
|
|
return Promise.resolve();
|
|
}
|
|
|
|
this.needsRefresh = false;
|
|
|
|
return this.fetchData().then(onDataFetched.bind(this));
|
|
}
|
|
|
|
notifyRefreshNeeded(isInForeground) {
|
|
if (this.paused) {
|
|
this.needsRefresh = true;
|
|
return;
|
|
}
|
|
|
|
const timeout = this.refreshTimeout;
|
|
if (timeout) {
|
|
clearTimeout(timeout);
|
|
}
|
|
|
|
if (isInForeground === true) {
|
|
this.refreshItems();
|
|
} else {
|
|
this.refreshTimeout = setTimeout(this.refreshItems.bind(this), 10000);
|
|
}
|
|
}
|
|
|
|
destroy() {
|
|
clearRefreshInterval(this);
|
|
|
|
removeNotificationEvent(this, 'UserDataChanged');
|
|
removeNotificationEvent(this, 'TimerCreated');
|
|
removeNotificationEvent(this, 'SeriesTimerCreated');
|
|
removeNotificationEvent(this, 'TimerCancelled');
|
|
removeNotificationEvent(this, 'SeriesTimerCancelled');
|
|
removeNotificationEvent(this, 'LibraryChanged');
|
|
removeNotificationEvent(this, 'playbackstop', playbackManager);
|
|
|
|
this.fetchData = null;
|
|
this.options = null;
|
|
}
|
|
}
|
|
|
|
function clearRefreshInterval(instance, isPausing) {
|
|
if (instance.refreshInterval) {
|
|
clearInterval(instance.refreshInterval);
|
|
instance.refreshInterval = null;
|
|
|
|
if (!isPausing) {
|
|
instance.refreshIntervalEndTime = null;
|
|
}
|
|
}
|
|
}
|
|
|
|
function resetRefreshInterval(instance, intervalMs) {
|
|
clearRefreshInterval(instance);
|
|
|
|
if (!intervalMs) {
|
|
const options = instance.options;
|
|
if (options) {
|
|
intervalMs = options.refreshIntervalMs;
|
|
}
|
|
}
|
|
|
|
if (intervalMs) {
|
|
instance.refreshInterval = setInterval(instance.notifyRefreshNeeded.bind(instance), intervalMs);
|
|
instance.refreshIntervalEndTime = new Date().getTime() + intervalMs;
|
|
}
|
|
}
|
|
|
|
function onDataFetched(result) {
|
|
resetRefreshInterval(this);
|
|
|
|
if (this.afterRefresh) {
|
|
this.afterRefresh(result);
|
|
}
|
|
}
|
|
|
|
export default ItemsRefresher;
|