1
0
Fork 0
mirror of https://github.com/jellyfin/jellyfin-web synced 2025-03-30 19:56:21 +00:00

Refactor translateItemsForPlayback

This commit is contained in:
Connor Smith 2024-04-20 14:58:48 -04:00
parent 13dfa62eb4
commit 595983f102

View file

@ -1790,42 +1790,85 @@ class PlaybackManager {
}); });
} }
function translateItemsForPlayback(items, options) { async function translateItemsForPlayback(items, options) {
if (!items.length) return Promise.resolve([]); if (!items.length) return [];
if (items.length > 1 && options && options.ids) { sortItemsIfNeeded(items, options);
const firstItem = items[0];
const serverId = firstItem.ServerId;
const queryOptions = options.queryOptions || {};
const promise = getPlaybackPromise(firstItem, serverId, options, queryOptions, items);
if (promise) {
const result = await promise;
return result ? result.Items : items;
} else {
return items;
}
}
function sortItemsIfNeeded(items, options) {
if (items.length > 1 && options?.ids) {
// Use the original request id array for sorting the result in the proper order // Use the original request id array for sorting the result in the proper order
items.sort(function (a, b) { items.sort(function (a, b) {
return options.ids.indexOf(a.Id) - options.ids.indexOf(b.Id); return options.ids.indexOf(a.Id) - options.ids.indexOf(b.Id);
}); });
} }
}
const firstItem = items[0]; function getPlaybackPromise(firstItem, serverId, options, queryOptions, items) {
let promise; switch (firstItem.Type) {
case 'Program':
const serverId = firstItem.ServerId; return getItemsForPlayback(serverId, {
const queryOptions = options.queryOptions || {};
if (firstItem.Type === 'Program') {
promise = getItemsForPlayback(serverId, {
Ids: firstItem.ChannelId Ids: firstItem.ChannelId
}); });
} else if (firstItem.Type === 'Playlist') { case 'Playlist':
promise = getItemsForPlayback(serverId, { return getItemsForPlayback(serverId, {
ParentId: firstItem.Id, ParentId: firstItem.Id,
SortBy: options.shuffle ? 'Random' : null SortBy: options.shuffle ? 'Random' : null
}); });
} else if (firstItem.Type === 'MusicArtist') { case 'MusicArtist':
promise = getItemsForPlayback(serverId, mergePlaybackQueries({ return getItemsForPlayback(serverId, mergePlaybackQueries({
ArtistIds: firstItem.Id, ArtistIds: firstItem.Id,
Filters: 'IsNotFolder', Filters: 'IsNotFolder',
Recursive: true, Recursive: true,
SortBy: options.shuffle ? 'Random' : 'SortName', SortBy: options.shuffle ? 'Random' : 'SortName',
MediaTypes: 'Audio' MediaTypes: 'Audio'
}, queryOptions)); }, queryOptions));
} else if (firstItem.MediaType === 'Photo') { case 'PhotoAlbum':
promise = getItemsForPlayback(serverId, mergePlaybackQueries({ return getItemsForPlayback(serverId, mergePlaybackQueries({
ParentId: firstItem.Id,
Filters: 'IsNotFolder',
// Setting this to true may cause some incorrect sorting
Recursive: false,
SortBy: options.shuffle ? 'Random' : 'SortName',
// Only include Photos because we do not handle mixed queues currently
MediaTypes: 'Photo',
Limit: UNLIMITED_ITEMS
}, queryOptions));
case 'MusicGenre':
return getItemsForPlayback(serverId, mergePlaybackQueries({
GenreIds: firstItem.Id,
Filters: 'IsNotFolder',
Recursive: true,
SortBy: options.shuffle ? 'Random' : 'SortName',
MediaTypes: 'Audio'
}, queryOptions));
case 'Series':
case 'Season':
return getSeriesOrSeasonPlaybackPromise(firstItem, options);
case 'Episode':
return getEpisodePlaybackPromise(firstItem, options, items);
}
return getNonItemTypePromise(firstItem, serverId, options, queryOptions);
}
function getNonItemTypePromise(firstItem, serverId, options, queryOptions) {
if (firstItem.MediaType === 'Photo') {
return getItemsForPlayback(serverId, mergePlaybackQueries({
ParentId: firstItem.ParentId, ParentId: firstItem.ParentId,
Filters: 'IsNotFolder', Filters: 'IsNotFolder',
// Setting this to true may cause some incorrect sorting // Setting this to true may cause some incorrect sorting
@ -1848,37 +1891,50 @@ class PlaybackManager {
return Promise.resolve(result); return Promise.resolve(result);
}); });
} else if (firstItem.Type === 'PhotoAlbum') { } else if (firstItem.IsFolder && firstItem.CollectionType === 'homevideos') {
promise = getItemsForPlayback(serverId, mergePlaybackQueries({ return getItemsForPlayback(serverId, mergePlaybackQueries({
ParentId: firstItem.Id, ParentId: firstItem.Id,
Filters: 'IsNotFolder', Filters: 'IsNotFolder',
// Setting this to true may cause some incorrect sorting Recursive: true,
Recursive: false,
SortBy: options.shuffle ? 'Random' : 'SortName', SortBy: options.shuffle ? 'Random' : 'SortName',
// Only include Photos because we do not handle mixed queues currently // Only include Photos because we do not handle mixed queues currently
MediaTypes: 'Photo', MediaTypes: 'Photo',
Limit: UNLIMITED_ITEMS Limit: UNLIMITED_ITEMS
}, queryOptions)); }, queryOptions));
} else if (firstItem.Type === 'MusicGenre') { } else if (firstItem.IsFolder) {
promise = getItemsForPlayback(serverId, mergePlaybackQueries({ let sortBy = null;
GenreIds: firstItem.Id, if (options.shuffle) {
sortBy = 'Random';
} else if (firstItem.Type !== 'BoxSet') {
sortBy = 'SortName';
}
return getItemsForPlayback(serverId, mergePlaybackQueries({
ParentId: firstItem.Id,
Filters: 'IsNotFolder', Filters: 'IsNotFolder',
Recursive: true, Recursive: true,
SortBy: options.shuffle ? 'Random' : 'SortName', // These are pre-sorted
MediaTypes: 'Audio' SortBy: sortBy,
MediaTypes: 'Audio,Video'
}, queryOptions)); }, queryOptions));
} else if (firstItem.Type === 'Series' || firstItem.Type === 'Season') { }
return null;
}
async function getSeriesOrSeasonPlaybackPromise(firstItem, options) {
const apiClient = ServerConnections.getApiClient(firstItem.ServerId); const apiClient = ServerConnections.getApiClient(firstItem.ServerId);
const isSeason = firstItem.Type === 'Season'; const isSeason = firstItem.Type === 'Season';
promise = apiClient.getEpisodes(firstItem.SeriesId || firstItem.Id, { const episodesResult = await apiClient.getEpisodes(firstItem.SeriesId || firstItem.Id, {
IsVirtualUnaired: false, IsVirtualUnaired: false,
IsMissing: false, IsMissing: false,
SeasonId: isSeason ? firstItem.Id : undefined, SeasonId: isSeason ? firstItem.Id : undefined,
SortBy: options.shuffle ? 'Random' : undefined, SortBy: options.shuffle ? 'Random' : undefined,
UserId: apiClient.getCurrentUserId(), UserId: apiClient.getCurrentUserId(),
Fields: ['Chapters', 'Trickplay'] Fields: ['Chapters', 'Trickplay']
}).then(function (episodesResult) { });
const originalResults = episodesResult.Items; const originalResults = episodesResult.Items;
let foundItem = false; let foundItem = false;
@ -1905,34 +1961,18 @@ class PlaybackManager {
episodesResult.TotalRecordCount = episodesResult.Items.length; episodesResult.TotalRecordCount = episodesResult.Items.length;
return episodesResult; return episodesResult;
});
} else if (firstItem.IsFolder && firstItem.CollectionType === 'homevideos') {
promise = getItemsForPlayback(serverId, mergePlaybackQueries({
ParentId: firstItem.Id,
Filters: 'IsNotFolder',
Recursive: true,
SortBy: options.shuffle ? 'Random' : 'SortName',
// Only include Photos because we do not handle mixed queues currently
MediaTypes: 'Photo',
Limit: UNLIMITED_ITEMS
}, queryOptions));
} else if (firstItem.IsFolder) {
let sortBy = null;
if (options.shuffle) {
sortBy = 'Random';
} else if (firstItem.Type !== 'BoxSet') {
sortBy = 'SortName';
} }
promise = getItemsForPlayback(serverId, mergePlaybackQueries({
ParentId: firstItem.Id, function getEpisodePlaybackPromise(firstItem, options, items) {
Filters: 'IsNotFolder', if (items.length === 1 && getPlayer(firstItem, options).supportsProgress !== false) {
Recursive: true, return getEpisodes(firstItem);
// These are pre-sorted } else {
SortBy: sortBy, return null;
MediaTypes: 'Audio,Video' }
}, queryOptions)); }
} else if (firstItem.Type === 'Episode' && items.length === 1 && getPlayer(firstItem, options).supportsProgress !== false) {
promise = new Promise(function (resolve, reject) { function getEpisodes(firstItem) {
return new Promise(function (resolve, reject) {
const apiClient = ServerConnections.getApiClient(firstItem.ServerId); const apiClient = ServerConnections.getApiClient(firstItem.ServerId);
if (!firstItem.SeriesId) { if (!firstItem.SeriesId) {
@ -1946,6 +1986,12 @@ class PlaybackManager {
UserId: apiClient.getCurrentUserId(), UserId: apiClient.getCurrentUserId(),
Fields: ['Chapters', 'Trickplay'] Fields: ['Chapters', 'Trickplay']
}).then(function (episodesResult) { }).then(function (episodesResult) {
resolve(filterEpisodes(episodesResult, firstItem));
}, reject);
});
}
function filterEpisodes(episodesResult, firstItem) {
let foundItem = false; let foundItem = false;
episodesResult.Items = episodesResult.Items.filter(function (e) { episodesResult.Items = episodesResult.Items.filter(function (e) {
if (foundItem) { if (foundItem) {
@ -1959,18 +2005,7 @@ class PlaybackManager {
return false; return false;
}); });
episodesResult.TotalRecordCount = episodesResult.Items.length; episodesResult.TotalRecordCount = episodesResult.Items.length;
resolve(episodesResult); return episodesResult;
}, reject);
});
}
if (promise) {
return promise.then(function (result) {
return result ? result.Items : items;
});
} else {
return Promise.resolve(items);
}
} }
self.translateItemsForPlayback = translateItemsForPlayback; self.translateItemsForPlayback = translateItemsForPlayback;