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

Merge pull request #4320 from pl-ducharme/feature/3494-add-eslint-max-params-rule

Add eslint max-params rule with a max of 7 parameters
This commit is contained in:
Bill Thornton 2023-03-08 22:57:40 -05:00 committed by GitHub
commit 9e784034d3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 154 additions and 109 deletions

View file

@ -46,6 +46,7 @@ module.exports = {
'keyword-spacing': ['error'], 'keyword-spacing': ['error'],
'no-throw-literal': ['error'], 'no-throw-literal': ['error'],
'max-statements-per-line': ['error'], 'max-statements-per-line': ['error'],
'max-params': ['error', 7],
'no-duplicate-imports': ['error'], 'no-duplicate-imports': ['error'],
'no-empty-function': ['error'], 'no-empty-function': ['error'],
'no-floating-decimal': ['error'], 'no-floating-decimal': ['error'],

View file

@ -59,6 +59,7 @@
- [Vankerkom](https://github.com/vankerkom) - [Vankerkom](https://github.com/vankerkom)
- [edvwib](https://github.com/edvwib) - [edvwib](https://github.com/edvwib)
- [Rob Farraher](https://github.com/farraherbg) - [Rob Farraher](https://github.com/farraherbg)
- [Pier-Luc Ducharme](https://github.com/pl-ducharme)
# Emby Contributors # Emby Contributors

View file

@ -773,27 +773,24 @@ import { appRouter } from '../appRouter';
* @param {Object} item - Item used to generate the footer text. * @param {Object} item - Item used to generate the footer text.
* @param {Object} apiClient - API client instance. * @param {Object} apiClient - API client instance.
* @param {Object} options - Options used to generate the footer text. * @param {Object} options - Options used to generate the footer text.
* @param {string} showTitle - Flag to show the title in the footer.
* @param {boolean} forceName - Flag to force showing the name of the item.
* @param {boolean} overlayText - Flag to show overlay text.
* @param {Object} imgUrl - Object representing the card's image URL.
* @param {string} footerClass - CSS classes of the footer element. * @param {string} footerClass - CSS classes of the footer element.
* @param {string} progressHtml - HTML markup of the progress bar element. * @param {string} progressHtml - HTML markup of the progress bar element.
* @param {string} logoUrl - URL of the logo for the item. * @param {Object} flags - Various flags for the footer
* @param {boolean} isOuterFooter - Flag to mark the text as outer footer. * @param {Object} urls - Various urls for the footer
* @returns {string} HTML markup of the card's footer text element. * @returns {string} HTML markup of the card's footer text element.
*/ */
function getCardFooterText(item, apiClient, options, showTitle, forceName, overlayText, imgUrl, footerClass, progressHtml, logoUrl, isOuterFooter) { function getCardFooterText(item, apiClient, options, footerClass, progressHtml, flags, urls) {
item = item.ProgramInfo || item; item = item.ProgramInfo || item;
let html = ''; let html = '';
if (logoUrl) { if (urls.logoUrl) {
html += '<div class="lazy cardFooterLogo" data-src="' + logoUrl + '"></div>'; html += '<div class="lazy cardFooterLogo" data-src="' + urls.logoUrl + '"></div>';
} }
const showOtherText = isOuterFooter ? !overlayText : overlayText; const showTitle = options.showTitle === 'auto' ? true : (options.showTitle || item.Type === 'PhotoAlbum' || item.Type === 'Folder');
const showOtherText = flags.isOuterFooter ? !flags.overlayText : flags.overlayText;
if (isOuterFooter && options.cardLayout && layoutManager.mobile && options.cardFooterAside !== 'none') { if (flags.isOuterFooter && options.cardLayout && layoutManager.mobile && options.cardFooterAside !== 'none') {
html += `<button is="paper-icon-button-light" class="itemAction btnCardOptions cardText-secondary" data-action="menu" title="${globalize.translate('ButtonMore')}"><span class="material-icons more_vert" aria-hidden="true"></span></button>`; html += `<button is="paper-icon-button-light" class="itemAction btnCardOptions cardText-secondary" data-action="menu" title="${globalize.translate('ButtonMore')}"><span class="material-icons more_vert" aria-hidden="true"></span></button>`;
} }
@ -805,7 +802,7 @@ import { appRouter } from '../appRouter';
let titleAdded; let titleAdded;
if (showOtherText && (options.showParentTitle || options.showParentTitleOrTitle) && !parentTitleUnderneath) { if (showOtherText && (options.showParentTitle || options.showParentTitleOrTitle) && !parentTitleUnderneath) {
if (isOuterFooter && item.Type === 'Episode' && item.SeriesName) { if (flags.isOuterFooter && item.Type === 'Episode' && item.SeriesName) {
if (item.SeriesId) { if (item.SeriesId) {
lines.push(getTextActionButton({ lines.push(getTextActionButton({
Id: item.SeriesId, Id: item.SeriesId,
@ -835,7 +832,7 @@ import { appRouter } from '../appRouter';
} }
let showMediaTitle = (showTitle && !titleAdded) || (options.showParentTitleOrTitle && !lines.length); let showMediaTitle = (showTitle && !titleAdded) || (options.showParentTitleOrTitle && !lines.length);
if (!showMediaTitle && !titleAdded && (showTitle || forceName)) { if (!showMediaTitle && !titleAdded && (showTitle || flags.forceName)) {
showMediaTitle = true; showMediaTitle = true;
} }
@ -856,7 +853,7 @@ import { appRouter } from '../appRouter';
if (showOtherText) { if (showOtherText) {
if (options.showParentTitle && parentTitleUnderneath) { if (options.showParentTitle && parentTitleUnderneath) {
if (isOuterFooter && item.AlbumArtists && item.AlbumArtists.length) { if (flags.isOuterFooter && item.AlbumArtists && item.AlbumArtists.length) {
item.AlbumArtists[0].Type = 'MusicArtist'; item.AlbumArtists[0].Type = 'MusicArtist';
item.AlbumArtists[0].IsFolder = true; item.AlbumArtists[0].IsFolder = true;
lines.push(getTextActionButton(item.AlbumArtists[0], null, serverId)); lines.push(getTextActionButton(item.AlbumArtists[0], null, serverId));
@ -991,23 +988,23 @@ import { appRouter } from '../appRouter';
} }
} }
if ((showTitle || !imgUrl) && forceName && overlayText && lines.length === 1) { if ((showTitle || !urls.imgUrl) && flags.forceName && flags.overlayText && lines.length === 1) {
lines = []; lines = [];
} }
if (overlayText && showTitle) { if (flags.overlayText && showTitle) {
lines = [escapeHtml(item.Name)]; lines = [escapeHtml(item.Name)];
} }
const addRightTextMargin = isOuterFooter && options.cardLayout && !options.centerText && options.cardFooterAside !== 'none' && layoutManager.mobile; const addRightTextMargin = flags.isOuterFooter && options.cardLayout && !options.centerText && options.cardFooterAside !== 'none' && layoutManager.mobile;
html += getCardTextLines(lines, cssClass, !options.overlayText, isOuterFooter, options.cardLayout, addRightTextMargin, options.lines); html += getCardTextLines(lines, cssClass, !options.overlayText, flags.isOuterFooter, options.cardLayout, addRightTextMargin, options.lines);
if (progressHtml) { if (progressHtml) {
html += progressHtml; html += progressHtml;
} }
if (html && (!isOuterFooter || logoUrl || options.cardLayout)) { if (html && (!flags.isOuterFooter || urls.logoUrl || options.cardLayout)) {
html = '<div class="' + footerClass + '">' + html; html = '<div class="' + footerClass + '">' + html;
//cardFooter //cardFooter
@ -1217,7 +1214,6 @@ import { appRouter } from '../appRouter';
const forceName = imgInfo.forceName; const forceName = imgInfo.forceName;
const showTitle = options.showTitle === 'auto' ? true : (options.showTitle || item.Type === 'PhotoAlbum' || item.Type === 'Folder');
const overlayText = options.overlayText; const overlayText = options.overlayText;
let cardImageContainerClass = 'cardImageContainer'; let cardImageContainerClass = 'cardImageContainer';
@ -1265,7 +1261,7 @@ import { appRouter } from '../appRouter';
logoUrl = null; logoUrl = null;
footerCssClass = progressHtml ? 'innerCardFooter fullInnerCardFooter' : 'innerCardFooter'; footerCssClass = progressHtml ? 'innerCardFooter fullInnerCardFooter' : 'innerCardFooter';
innerCardFooter += getCardFooterText(item, apiClient, options, showTitle, forceName, overlayText, imgUrl, footerCssClass, progressHtml, logoUrl, false); innerCardFooter += getCardFooterText(item, apiClient, options, footerCssClass, progressHtml, { forceName, overlayText, isOuterFooter: false }, { imgUrl, logoUrl });
footerOverlayed = true; footerOverlayed = true;
} else if (progressHtml) { } else if (progressHtml) {
innerCardFooter += '<div class="innerCardFooter fullInnerCardFooter innerCardFooterClear">'; innerCardFooter += '<div class="innerCardFooter fullInnerCardFooter innerCardFooterClear">';
@ -1292,7 +1288,7 @@ import { appRouter } from '../appRouter';
logoUrl = null; logoUrl = null;
} }
outerCardFooter = getCardFooterText(item, apiClient, options, showTitle, forceName, overlayText, imgUrl, footerCssClass, progressHtml, logoUrl, true); outerCardFooter = getCardFooterText(item, apiClient, options, footerCssClass, progressHtml, { forceName, overlayText, isOuterFooter: true }, { imgUrl, logoUrl });
} }
if (outerCardFooter && !options.cardLayout) { if (outerCardFooter && !options.cardLayout) {

View file

@ -345,7 +345,9 @@ function Guide(options) {
} }
apiClient.getLiveTvPrograms(programQuery).then(function (programsResult) { apiClient.getLiveTvPrograms(programQuery).then(function (programsResult) {
renderGuide(context, date, channelsResult.Items, programsResult.Items, renderOptions, apiClient, scrollToTimeMs, focusToTimeMs, startTimeOfDayMs, focusProgramOnRender); const guideOptions = { focusProgramOnRender, scrollToTimeMs, focusToTimeMs, startTimeOfDayMs };
renderGuide(context, date, channelsResult.Items, programsResult.Items, renderOptions, guideOptions, apiClient);
hideLoading(); hideLoading();
}); });
@ -667,7 +669,7 @@ function Guide(options) {
return (channelIndex * 10000000) + (start.getTime() / 60000); return (channelIndex * 10000000) + (start.getTime() / 60000);
} }
function renderGuide(context, date, channels, programs, renderOptions, apiClient, scrollToTimeMs, focusToTimeMs, startTimeOfDayMs, focusProgramOnRender) { function renderGuide(context, date, channels, programs, renderOptions, guideOptions, apiClient) {
programs.sort(function (a, b) { programs.sort(function (a, b) {
return getProgramSortOrder(a, channels) - getProgramSortOrder(b, channels); return getProgramSortOrder(a, channels) - getProgramSortOrder(b, channels);
}); });
@ -689,11 +691,11 @@ function Guide(options) {
items = {}; items = {};
renderPrograms(context, date, channels, programs, renderOptions); renderPrograms(context, date, channels, programs, renderOptions);
if (focusProgramOnRender) { if (guideOptions.focusProgramOnRender) {
focusProgram(context, itemId, channelRowId, focusToTimeMs, startTimeOfDayMs); focusProgram(context, itemId, channelRowId, guideOptions.focusToTimeMs, guideOptions.startTimeOfDayMs);
} }
scrollProgramGridToTimeMs(context, scrollToTimeMs, startTimeOfDayMs); scrollProgramGridToTimeMs(context, guideOptions.scrollToTimeMs, guideOptions.startTimeOfDayMs);
} }
function scrollProgramGridToTimeMs(context, scrollToTimeMs, startTimeOfDayMs) { function scrollProgramGridToTimeMs(context, scrollToTimeMs, startTimeOfDayMs) {

View file

@ -96,7 +96,7 @@ import template from './imageeditor.template.html';
return apiClient.getScaledImageUrl(item.Id || item.ItemId, options); return apiClient.getScaledImageUrl(item.Id || item.ItemId, options);
} }
function getCardHtml(image, index, numImages, apiClient, imageProviders, imageSize, tagName, enableFooterButtons) { function getCardHtml(image, apiClient, options) {
// TODO move card creation code to Card component // TODO move card creation code to Card component
let html = ''; let html = '';
@ -106,7 +106,7 @@ import template from './imageeditor.template.html';
cssClass += ' backdropCard backdropCard-scalable'; cssClass += ' backdropCard backdropCard-scalable';
if (tagName === 'button') { if (options.tagName === 'button') {
cssClass += ' btnImageCard'; cssClass += ' btnImageCard';
if (layoutManager.tv) { if (layoutManager.tv) {
@ -122,7 +122,7 @@ import template from './imageeditor.template.html';
html += '<div class="' + cssClass + '"'; html += '<div class="' + cssClass + '"';
} }
html += ' data-id="' + currentItem.Id + '" data-serverid="' + apiClient.serverId() + '" data-index="' + index + '" data-numimages="' + numImages + '" data-imagetype="' + image.ImageType + '" data-providers="' + imageProviders.length + '"'; html += ' data-id="' + currentItem.Id + '" data-serverid="' + apiClient.serverId() + '" data-index="' + options.index + '" data-numimages="' + options.numImages + '" data-imagetype="' + image.ImageType + '" data-providers="' + options.imageProviders.length + '"';
html += '>'; html += '>';
@ -132,7 +132,7 @@ import template from './imageeditor.template.html';
html += '<div class="cardContent">'; html += '<div class="cardContent">';
const imageUrl = getImageUrl(currentItem, apiClient, image.ImageType, image.ImageIndex, { maxWidth: imageSize }); const imageUrl = getImageUrl(currentItem, apiClient, image.ImageType, image.ImageIndex, { maxWidth: options.imageSize });
html += '<div class="cardImageContainer" style="background-image:url(\'' + imageUrl + '\');background-position:center center;background-size:contain;"></div>'; html += '<div class="cardImageContainer" style="background-image:url(\'' + imageUrl + '\');background-position:center center;background-size:contain;"></div>';
@ -151,23 +151,23 @@ import template from './imageeditor.template.html';
} }
html += '</div>'; html += '</div>';
if (enableFooterButtons) { if (options.enableFooterButtons) {
html += '<div class="cardText cardTextCentered">'; html += '<div class="cardText cardTextCentered">';
if (image.ImageType === 'Backdrop') { if (image.ImageType === 'Backdrop') {
if (index > 0) { if (options.index > 0) {
html += '<button type="button" is="paper-icon-button-light" class="btnMoveImage autoSize" data-imagetype="' + image.ImageType + '" data-index="' + image.ImageIndex + '" data-newindex="' + (image.ImageIndex - 1) + '" title="' + globalize.translate('MoveLeft') + '"><span class="material-icons chevron_left"></span></button>'; html += '<button type="button" is="paper-icon-button-light" class="btnMoveImage autoSize" data-imagetype="' + image.ImageType + '" data-index="' + image.ImageIndex + '" data-newindex="' + (image.ImageIndex - 1) + '" title="' + globalize.translate('MoveLeft') + '"><span class="material-icons chevron_left"></span></button>';
} else { } else {
html += '<button type="button" is="paper-icon-button-light" class="autoSize" disabled title="' + globalize.translate('MoveLeft') + '"><span class="material-icons chevron_left" aria-hidden="true"></span></button>'; html += '<button type="button" is="paper-icon-button-light" class="autoSize" disabled title="' + globalize.translate('MoveLeft') + '"><span class="material-icons chevron_left" aria-hidden="true"></span></button>';
} }
if (index < numImages - 1) { if (options.index < options.numImages - 1) {
html += '<button type="button" is="paper-icon-button-light" class="btnMoveImage autoSize" data-imagetype="' + image.ImageType + '" data-index="' + image.ImageIndex + '" data-newindex="' + (image.ImageIndex + 1) + '" title="' + globalize.translate('MoveRight') + '"><span class="material-icons chevron_right" aria-hidden="true"></span></button>'; html += '<button type="button" is="paper-icon-button-light" class="btnMoveImage autoSize" data-imagetype="' + image.ImageType + '" data-index="' + image.ImageIndex + '" data-newindex="' + (image.ImageIndex + 1) + '" title="' + globalize.translate('MoveRight') + '"><span class="material-icons chevron_right" aria-hidden="true"></span></button>';
} else { } else {
html += '<button type="button" is="paper-icon-button-light" class="autoSize" disabled title="' + globalize.translate('MoveRight') + '"><span class="material-icons chevron_right" aria-hidden="true"></span></button>'; html += '<button type="button" is="paper-icon-button-light" class="autoSize" disabled title="' + globalize.translate('MoveRight') + '"><span class="material-icons chevron_right" aria-hidden="true"></span></button>';
} }
} else { } else {
if (imageProviders.length) { if (options.imageProviders.length) {
html += '<button type="button" is="paper-icon-button-light" data-imagetype="' + image.ImageType + '" class="btnSearchImages autoSize" title="' + globalize.translate('Search') + '"><span class="material-icons search" aria-hidden="true"></span></button>'; html += '<button type="button" is="paper-icon-button-light" data-imagetype="' + image.ImageType + '" class="btnSearchImages autoSize" title="' + globalize.translate('Search') + '"><span class="material-icons search" aria-hidden="true"></span></button>';
} }
} }
@ -178,7 +178,7 @@ import template from './imageeditor.template.html';
html += '</div>'; html += '</div>';
html += '</div>'; html += '</div>';
html += '</' + tagName + '>'; html += '</' + options.tagName + '>';
return html; return html;
} }
@ -226,7 +226,8 @@ import template from './imageeditor.template.html';
for (let i = 0, length = images.length; i < length; i++) { for (let i = 0, length = images.length; i < length; i++) {
const image = images[i]; const image = images[i];
html += getCardHtml(image, i, length, apiClient, imageProviders, imageSize, tagName, enableFooterButtons); const options = { index: i, numImages: length, imageProviders, imageSize, tagName, enableFooterButtons };
html += getCardHtml(image, apiClient, options);
} }
elem.innerHTML = html; elem.innerHTML = html;

View file

@ -299,20 +299,20 @@ function getAudioMaxValues(deviceProfile) {
} }
let startingPlaySession = new Date().getTime(); let startingPlaySession = new Date().getTime();
function getAudioStreamUrl(item, transcodingProfile, directPlayContainers, maxBitrate, apiClient, maxAudioSampleRate, maxAudioBitDepth, maxAudioBitrate, startPosition) { function getAudioStreamUrl(item, transcodingProfile, directPlayContainers, apiClient, startPosition, maxValues) {
const url = 'Audio/' + item.Id + '/universal'; const url = 'Audio/' + item.Id + '/universal';
startingPlaySession++; startingPlaySession++;
return apiClient.getUrl(url, { return apiClient.getUrl(url, {
UserId: apiClient.getCurrentUserId(), UserId: apiClient.getCurrentUserId(),
DeviceId: apiClient.deviceId(), DeviceId: apiClient.deviceId(),
MaxStreamingBitrate: maxAudioBitrate || maxBitrate, MaxStreamingBitrate: maxValues.maxAudioBitrate || maxValues.maxBitrate,
Container: directPlayContainers, Container: directPlayContainers,
TranscodingContainer: transcodingProfile.Container || null, TranscodingContainer: transcodingProfile.Container || null,
TranscodingProtocol: transcodingProfile.Protocol || null, TranscodingProtocol: transcodingProfile.Protocol || null,
AudioCodec: transcodingProfile.AudioCodec, AudioCodec: transcodingProfile.AudioCodec,
MaxAudioSampleRate: maxAudioSampleRate, MaxAudioSampleRate: maxValues.maxAudioSampleRate,
MaxAudioBitDepth: maxAudioBitDepth, MaxAudioBitDepth: maxValues.maxAudioBitDepth,
api_key: apiClient.accessToken(), api_key: apiClient.accessToken(),
PlaySessionId: startingPlaySession, PlaySessionId: startingPlaySession,
StartTimeTicks: startPosition || 0, StartTimeTicks: startPosition || 0,
@ -344,7 +344,7 @@ function getAudioStreamUrlFromDeviceProfile(item, deviceProfile, maxBitrate, api
const maxValues = getAudioMaxValues(deviceProfile); const maxValues = getAudioMaxValues(deviceProfile);
return getAudioStreamUrl(item, transcodingProfile, directPlayContainers, maxBitrate, apiClient, maxValues.maxAudioSampleRate, maxValues.maxAudioBitDepth, maxValues.maxAudioBitrate, startPosition); return getAudioStreamUrl(item, transcodingProfile, directPlayContainers, apiClient, startPosition, { maxBitrate, ...maxValues });
} }
function getStreamUrls(items, deviceProfile, maxBitrate, apiClient, startPosition) { function getStreamUrls(items, deviceProfile, maxBitrate, apiClient, startPosition) {
@ -377,7 +377,7 @@ function getStreamUrls(items, deviceProfile, maxBitrate, apiClient, startPositio
let streamUrl; let streamUrl;
if (item.MediaType === 'Audio' && !itemHelper.isLocalItem(item)) { if (item.MediaType === 'Audio' && !itemHelper.isLocalItem(item)) {
streamUrl = getAudioStreamUrl(item, audioTranscodingProfile, audioDirectPlayContainers, maxBitrate, apiClient, maxValues.maxAudioSampleRate, maxValues.maxAudioBitDepth, maxValues.maxAudioBitrate, startPosition); streamUrl = getAudioStreamUrl(item, audioTranscodingProfile, audioDirectPlayContainers, apiClient, startPosition, { maxBitrate, ...maxValues });
} }
streamUrls.push(streamUrl || ''); streamUrls.push(streamUrl || '');
@ -408,27 +408,12 @@ function setStreamUrls(items, deviceProfile, maxBitrate, apiClient, startPositio
}); });
} }
function getPlaybackInfo(player, function getPlaybackInfo(player, apiClient, item, deviceProfile, mediaSourceId, liveStreamId, options) {
apiClient,
item,
deviceProfile,
maxBitrate,
startPosition,
isPlayback,
mediaSourceId,
audioStreamIndex,
subtitleStreamIndex,
liveStreamId,
enableDirectPlay,
enableDirectStream,
allowVideoStreamCopy,
allowAudioStreamCopy,
secondarySubtitleStreamIndex) {
if (!itemHelper.isLocalItem(item) && item.MediaType === 'Audio' && !player.useServerPlaybackInfoForAudio) { if (!itemHelper.isLocalItem(item) && item.MediaType === 'Audio' && !player.useServerPlaybackInfoForAudio) {
return Promise.resolve({ return Promise.resolve({
MediaSources: [ MediaSources: [
{ {
StreamUrl: getAudioStreamUrlFromDeviceProfile(item, deviceProfile, maxBitrate, apiClient, startPosition), StreamUrl: getAudioStreamUrlFromDeviceProfile(item, deviceProfile, options.maxBitrate, apiClient, options.startPosition),
Id: item.Id, Id: item.Id,
MediaStreams: [], MediaStreams: [],
RunTimeTicks: item.RunTimeTicks RunTimeTicks: item.RunTimeTicks
@ -446,10 +431,10 @@ function getPlaybackInfo(player,
const query = { const query = {
UserId: apiClient.getCurrentUserId(), UserId: apiClient.getCurrentUserId(),
StartTimeTicks: startPosition || 0 StartTimeTicks: options.startPosition || 0
}; };
if (isPlayback) { if (options.isPlayback) {
query.IsPlayback = true; query.IsPlayback = true;
query.AutoOpenLiveStream = true; query.AutoOpenLiveStream = true;
} else { } else {
@ -457,27 +442,26 @@ function getPlaybackInfo(player,
query.AutoOpenLiveStream = false; query.AutoOpenLiveStream = false;
} }
if (audioStreamIndex != null) { if (options.audioStreamIndex != null) {
query.AudioStreamIndex = audioStreamIndex; query.AudioStreamIndex = options.audioStreamIndex;
} }
if (subtitleStreamIndex != null) { if (options.subtitleStreamIndex != null) {
query.SubtitleStreamIndex = subtitleStreamIndex; query.SubtitleStreamIndex = options.subtitleStreamIndex;
} }
if (secondarySubtitleStreamIndex != null) { if (options.secondarySubtitleStreamIndex != null) {
query.SecondarySubtitleStreamIndex = secondarySubtitleStreamIndex; query.SecondarySubtitleStreamIndex = options.secondarySubtitleStreamIndex;
} }
if (enableDirectPlay != null) { if (options.enableDirectPlay != null) {
query.EnableDirectPlay = enableDirectPlay; query.EnableDirectPlay = options.enableDirectPlay;
} }
if (options.enableDirectStream != null) {
if (enableDirectStream != null) { query.EnableDirectStream = options.enableDirectStream;
query.EnableDirectStream = enableDirectStream;
} }
if (allowVideoStreamCopy != null) { if (options.allowVideoStreamCopy != null) {
query.AllowVideoStreamCopy = allowVideoStreamCopy; query.AllowVideoStreamCopy = options.allowVideoStreamCopy;
} }
if (allowAudioStreamCopy != null) { if (options.allowAudioStreamCopy != null) {
query.AllowAudioStreamCopy = allowAudioStreamCopy; query.AllowAudioStreamCopy = options.allowAudioStreamCopy;
} }
if (mediaSourceId) { if (mediaSourceId) {
query.MediaSourceId = mediaSourceId; query.MediaSourceId = mediaSourceId;
@ -485,8 +469,8 @@ function getPlaybackInfo(player,
if (liveStreamId) { if (liveStreamId) {
query.LiveStreamId = liveStreamId; query.LiveStreamId = liveStreamId;
} }
if (maxBitrate) { if (options.maxBitrate) {
query.MaxStreamingBitrate = maxBitrate; query.MaxStreamingBitrate = options.maxBitrate;
} }
if (player.enableMediaProbe && !player.enableMediaProbe(item)) { if (player.enableMediaProbe && !player.enableMediaProbe(item)) {
query.EnableMediaProbe = false; query.EnableMediaProbe = false;
@ -537,7 +521,7 @@ function getOptimalMediaSource(apiClient, item, versions) {
}); });
} }
function getLiveStream(player, apiClient, item, playSessionId, deviceProfile, maxBitrate, startPosition, mediaSource, audioStreamIndex, subtitleStreamIndex) { function getLiveStream(player, apiClient, item, playSessionId, deviceProfile, mediaSource, options) {
const postData = { const postData = {
DeviceProfile: deviceProfile, DeviceProfile: deviceProfile,
OpenToken: mediaSource.OpenToken OpenToken: mediaSource.OpenToken
@ -545,19 +529,19 @@ function getLiveStream(player, apiClient, item, playSessionId, deviceProfile, ma
const query = { const query = {
UserId: apiClient.getCurrentUserId(), UserId: apiClient.getCurrentUserId(),
StartTimeTicks: startPosition || 0, StartTimeTicks: options.startPosition || 0,
ItemId: item.Id, ItemId: item.Id,
PlaySessionId: playSessionId PlaySessionId: playSessionId
}; };
if (maxBitrate) { if (options.maxBitrate) {
query.MaxStreamingBitrate = maxBitrate; query.MaxStreamingBitrate = options.maxBitrate;
} }
if (audioStreamIndex != null) { if (options.audioStreamIndex != null) {
query.AudioStreamIndex = audioStreamIndex; query.AudioStreamIndex = options.audioStreamIndex;
} }
if (subtitleStreamIndex != null) { if (options.subtitleStreamIndex != null) {
query.SubtitleStreamIndex = subtitleStreamIndex; query.SubtitleStreamIndex = options.subtitleStreamIndex;
} }
// lastly, enforce player overrides for special situations // lastly, enforce player overrides for special situations
@ -1737,7 +1721,19 @@ class PlaybackManager {
const currentPlayOptions = currentItem.playOptions || getDefaultPlayOptions(); const currentPlayOptions = currentItem.playOptions || getDefaultPlayOptions();
getPlaybackInfo(player, apiClient, currentItem, deviceProfile, maxBitrate, ticks, true, currentMediaSource.Id, audioStreamIndex, subtitleStreamIndex, liveStreamId, params.EnableDirectPlay, params.EnableDirectStream, params.AllowVideoStreamCopy, params.AllowAudioStreamCopy).then(function (result) { const options = {
maxBitrate,
startPosition: ticks,
isPlayback: true,
audioStreamIndex,
subtitleStreamIndex,
enableDirectPlay: params.EnableDirectPlay,
enableDirectStream: params.EnableDirectStream,
allowVideoStreamCopy: params.AllowVideoStreamCopy,
allowAudioStreamCopy: params.AllowAudioStreamCopy
};
getPlaybackInfo(player, apiClient, currentItem, deviceProfile, currentMediaSource.Id, liveStreamId, options).then(function (result) {
if (validatePlaybackInfoResult(self, result)) { if (validatePlaybackInfoResult(self, result)) {
currentMediaSource = result.MediaSources[0]; currentMediaSource = result.MediaSources[0];
@ -2303,17 +2299,17 @@ class PlaybackManager {
}, reject); }, reject);
} }
function sendPlaybackListToPlayer(player, items, deviceProfile, maxBitrate, apiClient, startPositionTicks, mediaSourceId, audioStreamIndex, subtitleStreamIndex, startIndex) { function sendPlaybackListToPlayer(player, items, deviceProfile, apiClient, mediaSourceId, options) {
return setStreamUrls(items, deviceProfile, maxBitrate, apiClient, startPositionTicks).then(function () { return setStreamUrls(items, deviceProfile, options.maxBitrate, apiClient, options.startPosition).then(function () {
loading.hide(); loading.hide();
return player.play({ return player.play({
items: items, items,
startPositionTicks: startPositionTicks || 0, startPositionTicks: options.startPosition || 0,
mediaSourceId: mediaSourceId, mediaSourceId,
audioStreamIndex: audioStreamIndex, audioStreamIndex: options.audioStreamIndex,
subtitleStreamIndex: subtitleStreamIndex, subtitleStreamIndex: options.subtitleStreamIndex,
startIndex: startIndex startIndex: options.startIndex
}); });
}); });
} }
@ -2474,15 +2470,27 @@ class PlaybackManager {
const mediaSourceId = playOptions.mediaSourceId; const mediaSourceId = playOptions.mediaSourceId;
const audioStreamIndex = playOptions.audioStreamIndex; const audioStreamIndex = playOptions.audioStreamIndex;
const subtitleStreamIndex = playOptions.subtitleStreamIndex; const subtitleStreamIndex = playOptions.subtitleStreamIndex;
const options = {
maxBitrate,
startPosition,
isPlayback: null,
audioStreamIndex,
subtitleStreamIndex,
startIndex: playOptions.startIndex,
enableDirectPlay: null,
enableDirectStream: null,
allowVideoStreamCopy: null,
allowAudioStreamCopy: null
};
if (player && !enableLocalPlaylistManagement(player)) { if (player && !enableLocalPlaylistManagement(player)) {
return sendPlaybackListToPlayer(player, playOptions.items, deviceProfile, maxBitrate, apiClient, startPosition, mediaSourceId, audioStreamIndex, subtitleStreamIndex, playOptions.startIndex); return sendPlaybackListToPlayer(player, playOptions.items, deviceProfile, apiClient, mediaSourceId, options);
} }
// this reference was only needed by sendPlaybackListToPlayer // this reference was only needed by sendPlaybackListToPlayer
playOptions.items = null; playOptions.items = null;
return getPlaybackMediaSource(player, apiClient, deviceProfile, maxBitrate, item, startPosition, mediaSourceId, audioStreamIndex, subtitleStreamIndex).then(async (mediaSource) => { return getPlaybackMediaSource(player, apiClient, deviceProfile, item, mediaSourceId, options).then(async (mediaSource) => {
const user = await apiClient.getCurrentUser(); const user = await apiClient.getCurrentUser();
autoSetNextTracks(prevSource, mediaSource, user.Configuration.RememberAudioSelections, user.Configuration.RememberSubtitleSelections); autoSetNextTracks(prevSource, mediaSource, user.Configuration.RememberAudioSelections, user.Configuration.RememberSubtitleSelections);
@ -2540,7 +2548,20 @@ class PlaybackManager {
const maxBitrate = getSavedMaxStreamingBitrate(ServerConnections.getApiClient(item.ServerId), mediaType); const maxBitrate = getSavedMaxStreamingBitrate(ServerConnections.getApiClient(item.ServerId), mediaType);
return player.getDeviceProfile(item).then(function (deviceProfile) { return player.getDeviceProfile(item).then(function (deviceProfile) {
return getPlaybackMediaSource(player, apiClient, deviceProfile, maxBitrate, item, startPosition, options.mediaSourceId, options.audioStreamIndex, options.subtitleStreamIndex).then(function (mediaSource) { const mediaOptions = {
maxBitrate,
startPosition,
isPlayback: null,
audioStreamIndex: options.audioStreamIndex,
subtitleStreamIndex: options.subtitleStreamIndex,
startIndex: null,
enableDirectPlay: null,
enableDirectStream: null,
allowVideoStreamCopy: null,
allowAudioStreamCopy: null
};
return getPlaybackMediaSource(player, apiClient, deviceProfile, item, options.mediaSourceId, mediaOptions).then(function (mediaSource) {
return createStreamInfo(apiClient, item.MediaType, item, mediaSource, startPosition, player); return createStreamInfo(apiClient, item.MediaType, item, mediaSource, startPosition, player);
}); });
}); });
@ -2560,7 +2581,19 @@ class PlaybackManager {
const maxBitrate = getSavedMaxStreamingBitrate(ServerConnections.getApiClient(item.ServerId), mediaType); const maxBitrate = getSavedMaxStreamingBitrate(ServerConnections.getApiClient(item.ServerId), mediaType);
return player.getDeviceProfile(item).then(function (deviceProfile) { return player.getDeviceProfile(item).then(function (deviceProfile) {
return getPlaybackInfo(player, apiClient, item, deviceProfile, maxBitrate, startPosition, false, null, null, null, null).then(function (playbackInfoResult) { const mediaOptions = {
maxBitrate,
startPosition,
isPlayback: true,
audioStreamIndex: null,
subtitleStreamIndex: null,
enableDirectPlay: null,
enableDirectStream: null,
allowVideoStreamCopy: null,
allowAudioStreamCopy: null
};
return getPlaybackInfo(player, apiClient, item, deviceProfile, null, null, mediaOptions).then(function (playbackInfoResult) {
return playbackInfoResult.MediaSources; return playbackInfoResult.MediaSources;
}); });
}); });
@ -2701,13 +2734,18 @@ class PlaybackManager {
return tracks; return tracks;
} }
function getPlaybackMediaSource(player, apiClient, deviceProfile, maxBitrate, item, startPosition, mediaSourceId, audioStreamIndex, subtitleStreamIndex) { function getPlaybackMediaSource(player, apiClient, deviceProfile, item, mediaSourceId, options) {
return getPlaybackInfo(player, apiClient, item, deviceProfile, maxBitrate, startPosition, true, mediaSourceId, audioStreamIndex, subtitleStreamIndex, null).then(function (playbackInfoResult) { options.isPlayback = true;
return getPlaybackInfo(player, apiClient, item, deviceProfile, mediaSourceId, null, options).then(function (playbackInfoResult) {
if (validatePlaybackInfoResult(self, playbackInfoResult)) { if (validatePlaybackInfoResult(self, playbackInfoResult)) {
return getOptimalMediaSource(apiClient, item, playbackInfoResult.MediaSources).then(function (mediaSource) { return getOptimalMediaSource(apiClient, item, playbackInfoResult.MediaSources).then(function (mediaSource) {
if (mediaSource) { if (mediaSource) {
if (mediaSource.RequiresOpening && !mediaSource.LiveStreamId) { if (mediaSource.RequiresOpening && !mediaSource.LiveStreamId) {
return getLiveStream(player, apiClient, item, playbackInfoResult.PlaySessionId, deviceProfile, maxBitrate, startPosition, mediaSource, null, null).then(function (openLiveStreamResult) { options.audioStreamIndex = null;
options.subtitleStreamIndex = null;
return getLiveStream(player, apiClient, item, playbackInfoResult.PlaySessionId, deviceProfile, mediaSource, options).then(function (openLiveStreamResult) {
return supportsDirectPlay(apiClient, item, openLiveStreamResult.MediaSource).then(function (result) { return supportsDirectPlay(apiClient, item, openLiveStreamResult.MediaSource).then(function (result) {
openLiveStreamResult.MediaSource.enableDirectPlay = result; openLiveStreamResult.MediaSource.enableDirectPlay = result;
return openLiveStreamResult.MediaSource; return openLiveStreamResult.MediaSource;

View file

@ -12,7 +12,10 @@ const userDataMethods = {
markFavorite: markFavorite markFavorite: markFavorite
}; };
function getUserDataButtonHtml(method, itemId, serverId, buttonCssClass, iconCssClass, icon, tooltip, style) { function getUserDataButtonHtml(method, itemId, serverId, icon, tooltip, style, classes) {
let buttonCssClass = classes.buttonCssClass;
let iconCssClass = classes.iconCssClass;
if (style === 'fab-mini') { if (style === 'fab-mini') {
style = 'fab'; style = 'fab';
buttonCssClass = buttonCssClass ? (buttonCssClass + ' mini') : 'mini'; buttonCssClass = buttonCssClass ? (buttonCssClass + ' mini') : 'mini';
@ -96,7 +99,7 @@ function getIconsHtml(options) {
} }
const iconCssClass = options.iconCssClass; const iconCssClass = options.iconCssClass;
const classes = { buttonCssClass: btnCssClass, iconCssClass: iconCssClass };
const serverId = item.ServerId; const serverId = item.ServerId;
if (includePlayed !== false) { if (includePlayed !== false) {
@ -104,18 +107,21 @@ function getIconsHtml(options) {
if (itemHelper.canMarkPlayed(item)) { if (itemHelper.canMarkPlayed(item)) {
if (userData.Played) { if (userData.Played) {
html += getUserDataButtonHtml('markPlayed', itemId, serverId, btnCssClass + ' btnUserDataOn', iconCssClass, 'check', tooltipPlayed, style); const buttonCssClass = classes.buttonCssClass + ' btnUserDataOn';
html += getUserDataButtonHtml('markPlayed', itemId, serverId, 'check', tooltipPlayed, style, { buttonCssClass, ...classes });
} else { } else {
html += getUserDataButtonHtml('markPlayed', itemId, serverId, btnCssClass, iconCssClass, 'check', tooltipPlayed, style); html += getUserDataButtonHtml('markPlayed', itemId, serverId, 'check', tooltipPlayed, style, classes);
} }
} }
} }
const tooltipFavorite = globalize.translate('Favorite'); const tooltipFavorite = globalize.translate('Favorite');
if (userData.IsFavorite) { if (userData.IsFavorite) {
html += getUserDataButtonHtml('markFavorite', itemId, serverId, btnCssClass + ' btnUserData btnUserDataOn', iconCssClass, 'favorite', tooltipFavorite, style); const buttonCssClass = classes.buttonCssClass + ' btnUserData btnUserDataOn';
html += getUserDataButtonHtml('markFavorite', itemId, serverId, 'favorite', tooltipFavorite, style, { buttonCssClass, ...classes });
} else { } else {
html += getUserDataButtonHtml('markFavorite', itemId, serverId, btnCssClass + ' btnUserData', iconCssClass, 'favorite', tooltipFavorite, style); classes.buttonCssClass += ' btnUserData';
html += getUserDataButtonHtml('markFavorite', itemId, serverId, 'favorite', tooltipFavorite, style, classes);
} }
return html; return html;