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

Merge pull request #5398 from ConnorS1110/fix-broken-next-episode-setting

Fix playing next episode when autoplay is disabled
This commit is contained in:
Bill Thornton 2024-04-30 13:43:41 -04:00 committed by GitHub
commit 573e9aba71
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -18,6 +18,7 @@ import { PluginType } from '../../types/plugin.ts';
import { includesAny } from '../../utils/container.ts'; import { includesAny } from '../../utils/container.ts';
import { getItems } from '../../utils/jellyfin-apiclient/getItems.ts'; import { getItems } from '../../utils/jellyfin-apiclient/getItems.ts';
import { getItemBackdropImageUrl } from '../../utils/jellyfin-apiclient/backdropImage'; import { getItemBackdropImageUrl } from '../../utils/jellyfin-apiclient/backdropImage';
import { MediaType } from '@jellyfin/sdk/lib/generated-client/models/media-type';
import { MediaError } from 'types/mediaError'; import { MediaError } from 'types/mediaError';
import { getMediaError } from 'utils/mediaError'; import { getMediaError } from 'utils/mediaError';
@ -1789,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':
return getItemsForPlayback(serverId, {
Ids: firstItem.ChannelId
});
case 'Playlist':
return getItemsForPlayback(serverId, {
ParentId: firstItem.Id,
SortBy: options.shuffle ? 'Random' : null
});
case 'MusicArtist':
return getItemsForPlayback(serverId, mergePlaybackQueries({
ArtistIds: firstItem.Id,
Filters: 'IsNotFolder',
Recursive: true,
SortBy: options.shuffle ? 'Random' : 'SortName',
MediaTypes: 'Audio'
}, queryOptions));
case 'PhotoAlbum':
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);
}
const serverId = firstItem.ServerId; return getNonItemTypePromise(firstItem, serverId, options, queryOptions);
}
const queryOptions = options.queryOptions || {}; function getNonItemTypePromise(firstItem, serverId, options, queryOptions) {
if (firstItem.MediaType === 'Photo') {
if (firstItem.Type === 'Program') { return getItemsForPlayback(serverId, mergePlaybackQueries({
promise = getItemsForPlayback(serverId, {
Ids: firstItem.ChannelId
});
} else if (firstItem.Type === 'Playlist') {
promise = getItemsForPlayback(serverId, {
ParentId: firstItem.Id,
SortBy: options.shuffle ? 'Random' : null
});
} else if (firstItem.Type === 'MusicArtist') {
promise = getItemsForPlayback(serverId, mergePlaybackQueries({
ArtistIds: firstItem.Id,
Filters: 'IsNotFolder',
Recursive: true,
SortBy: options.shuffle ? 'Random' : 'SortName',
MediaTypes: 'Audio'
}, queryOptions));
} else if (firstItem.MediaType === 'Photo') {
promise = 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
@ -1847,66 +1891,8 @@ class PlaybackManager {
return Promise.resolve(result); return Promise.resolve(result);
}); });
} else if (firstItem.Type === 'PhotoAlbum') {
promise = 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));
} else if (firstItem.Type === 'MusicGenre') {
promise = getItemsForPlayback(serverId, mergePlaybackQueries({
GenreIds: firstItem.Id,
Filters: 'IsNotFolder',
Recursive: true,
SortBy: options.shuffle ? 'Random' : 'SortName',
MediaTypes: 'Audio'
}, queryOptions));
} else if (firstItem.Type === 'Series' || firstItem.Type === 'Season') {
const apiClient = ServerConnections.getApiClient(firstItem.ServerId);
const isSeason = firstItem.Type === 'Season';
promise = apiClient.getEpisodes(firstItem.SeriesId || firstItem.Id, {
IsVirtualUnaired: false,
IsMissing: false,
SeasonId: isSeason ? firstItem.Id : undefined,
SortBy: options.shuffle ? 'Random' : undefined,
UserId: apiClient.getCurrentUserId(),
Fields: ['Chapters', 'Trickplay']
}).then(function (episodesResult) {
const originalResults = episodesResult.Items;
let foundItem = false;
if (!options.shuffle) {
episodesResult.Items = episodesResult.Items.filter(function (e) {
if (foundItem) {
return true;
}
if (!e.UserData.Played) {
foundItem = true;
return true;
}
return false;
});
}
if (episodesResult.Items.length === 0) {
episodesResult.Items = originalResults;
}
episodesResult.TotalRecordCount = episodesResult.Items.length;
return episodesResult;
});
} else if (firstItem.IsFolder && firstItem.CollectionType === 'homevideos') { } 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',
Recursive: true, Recursive: true,
@ -1922,7 +1908,8 @@ class PlaybackManager {
} else if (firstItem.Type !== 'BoxSet') { } else if (firstItem.Type !== 'BoxSet') {
sortBy = 'SortName'; sortBy = 'SortName';
} }
promise = getItemsForPlayback(serverId, mergePlaybackQueries({
return getItemsForPlayback(serverId, mergePlaybackQueries({
ParentId: firstItem.Id, ParentId: firstItem.Id,
Filters: 'IsNotFolder', Filters: 'IsNotFolder',
Recursive: true, Recursive: true,
@ -1930,50 +1917,97 @@ class PlaybackManager {
SortBy: sortBy, SortBy: sortBy,
MediaTypes: 'Audio,Video' MediaTypes: 'Audio,Video'
}, queryOptions)); }, queryOptions));
} else if (firstItem.Type === 'Episode' && items.length === 1 && getPlayer(firstItem, options).supportsProgress !== false) { }
promise = new Promise(function (resolve, reject) {
const apiClient = ServerConnections.getApiClient(firstItem.ServerId);
apiClient.getCurrentUser().then(function (user) { return null;
if (!user.Configuration.EnableNextEpisodeAutoPlay || !firstItem.SeriesId) { }
resolve(null);
return;
}
apiClient.getEpisodes(firstItem.SeriesId, { async function getSeriesOrSeasonPlaybackPromise(firstItem, options) {
IsVirtualUnaired: false, const apiClient = ServerConnections.getApiClient(firstItem.ServerId);
IsMissing: false, const isSeason = firstItem.Type === 'Season';
UserId: apiClient.getCurrentUserId(),
Fields: ['Chapters', 'Trickplay']
}).then(function (episodesResult) {
let foundItem = false;
episodesResult.Items = episodesResult.Items.filter(function (e) {
if (foundItem) {
return true;
}
if (e.Id === firstItem.Id) {
foundItem = true;
return true;
}
return false; const episodesResult = await apiClient.getEpisodes(firstItem.SeriesId || firstItem.Id, {
}); IsVirtualUnaired: false,
episodesResult.TotalRecordCount = episodesResult.Items.length; IsMissing: false,
resolve(episodesResult); SeasonId: isSeason ? firstItem.Id : undefined,
}, reject); SortBy: options.shuffle ? 'Random' : undefined,
}); UserId: apiClient.getCurrentUserId(),
Fields: ['Chapters', 'Trickplay']
});
const originalResults = episodesResult.Items;
let foundItem = false;
if (!options.shuffle) {
episodesResult.Items = episodesResult.Items.filter(function (e) {
if (foundItem) {
return true;
}
if (!e.UserData.Played) {
foundItem = true;
return true;
}
return false;
}); });
} }
if (promise) { if (episodesResult.Items.length === 0) {
return promise.then(function (result) { episodesResult.Items = originalResults;
return result ? result.Items : items; }
});
episodesResult.TotalRecordCount = episodesResult.Items.length;
return episodesResult;
}
function getEpisodePlaybackPromise(firstItem, options, items) {
if (items.length === 1 && getPlayer(firstItem, options).supportsProgress !== false) {
return getEpisodes(firstItem);
} else { } else {
return Promise.resolve(items); return null;
} }
} }
function getEpisodes(firstItem) {
return new Promise(function (resolve, reject) {
const apiClient = ServerConnections.getApiClient(firstItem.ServerId);
if (!firstItem.SeriesId) {
resolve(null);
return;
}
apiClient.getEpisodes(firstItem.SeriesId, {
IsVirtualUnaired: false,
IsMissing: false,
UserId: apiClient.getCurrentUserId(),
Fields: ['Chapters', 'Trickplay']
}).then(function (episodesResult) {
resolve(filterEpisodes(episodesResult, firstItem));
}, reject);
});
}
function filterEpisodes(episodesResult, firstItem) {
let foundItem = false;
episodesResult.Items = episodesResult.Items.filter(function (e) {
if (foundItem) {
return true;
}
if (e.Id === firstItem.Id) {
foundItem = true;
return true;
}
return false;
});
episodesResult.TotalRecordCount = episodesResult.Items.length;
return episodesResult;
}
self.translateItemsForPlayback = translateItemsForPlayback; self.translateItemsForPlayback = translateItemsForPlayback;
self.getItemsForPlayback = getItemsForPlayback; self.getItemsForPlayback = getItemsForPlayback;
@ -3313,7 +3347,13 @@ class PlaybackManager {
if (errorOccurred) { if (errorOccurred) {
showPlaybackInfoErrorMessage(self, 'PlaybackError' + displayErrorCode); showPlaybackInfoErrorMessage(self, 'PlaybackError' + displayErrorCode);
} else if (nextItem) { } else if (nextItem) {
self.nextTrack(); const apiClient = ServerConnections.getApiClient(nextItem.item.ServerId);
apiClient.getCurrentUser().then(function (user) {
if (user.Configuration.EnableNextEpisodeAutoPlay || nextMediaType !== MediaType.Video) {
self.nextTrack();
}
});
} }
} }