diff --git a/.eslintrc.js b/.eslintrc.js index 3928729cb4..0e35c8c6b8 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -73,6 +73,7 @@ module.exports = { 'padded-blocks': ['error', 'never'], 'prefer-const': ['error', { 'destructuring': 'all' }], '@typescript-eslint/prefer-for-of': ['error'], + '@typescript-eslint/prefer-optional-chain': ['error'], 'quotes': ['error', 'single', { 'avoidEscape': true, 'allowTemplateLiterals': false }], 'radix': ['error'], '@typescript-eslint/semi': ['error'], diff --git a/src/components/backdrop/backdrop.js b/src/components/backdrop/backdrop.js index 4cd481827f..46655777ff 100644 --- a/src/components/backdrop/backdrop.js +++ b/src/components/backdrop/backdrop.js @@ -37,7 +37,7 @@ class Backdrop { parent.appendChild(backdropImage); if (!enableAnimation()) { - if (existingBackdropImage && existingBackdropImage.parentNode) { + if (existingBackdropImage?.parentNode) { existingBackdropImage.parentNode.removeChild(existingBackdropImage); } internalBackdrop(true); @@ -51,7 +51,7 @@ class Backdrop { if (backdropImage === self.currentAnimatingElement) { self.currentAnimatingElement = null; } - if (existingBackdropImage && existingBackdropImage.parentNode) { + if (existingBackdropImage?.parentNode) { existingBackdropImage.parentNode.removeChild(existingBackdropImage); } }; diff --git a/src/components/cardbuilder/cardBuilder.js b/src/components/cardbuilder/cardBuilder.js index 5ad759002d..d5b19c0210 100644 --- a/src/components/cardbuilder/cardBuilder.js +++ b/src/components/cardbuilder/cardBuilder.js @@ -546,7 +546,7 @@ function getCardImageUrl(item, apiClient, options, shape) { imgType = 'Backdrop'; imgTag = item.ParentBackdropImageTags[0]; itemId = item.ParentBackdropItemId; - } else if (item.ImageTags && item.ImageTags.Primary && (item.Type !== 'Episode' || item.ChildCount !== 0)) { + } else if (item.ImageTags?.Primary && (item.Type !== 'Episode' || item.ChildCount !== 0)) { imgType = 'Primary'; imgTag = item.ImageTags.Primary; height = width && primaryImageAspectRatio ? Math.round(width / primaryImageAspectRatio) : null; @@ -591,10 +591,10 @@ function getCardImageUrl(item, apiClient, options, shape) { } else if (item.Type === 'Season' && item.ImageTags && item.ImageTags.Thumb) { imgType = 'Thumb'; imgTag = item.ImageTags.Thumb; - } else if (item.BackdropImageTags && item.BackdropImageTags.length) { + } else if (item.BackdropImageTags?.length) { imgType = 'Backdrop'; imgTag = item.BackdropImageTags[0]; - } else if (item.ImageTags && item.ImageTags.Thumb) { + } else if (item.ImageTags?.Thumb) { imgType = 'Thumb'; imgTag = item.ImageTags.Thumb; } else if (item.SeriesThumbImageTag && options.inheritThumb !== false) { @@ -605,7 +605,7 @@ function getCardImageUrl(item, apiClient, options, shape) { imgType = 'Thumb'; imgTag = item.ParentThumbImageTag; itemId = item.ParentThumbItemId; - } else if (item.ParentBackdropImageTags && item.ParentBackdropImageTags.length && options.inheritThumb !== false) { + } else if (item.ParentBackdropImageTags?.length && options.inheritThumb !== false) { imgType = 'Backdrop'; imgTag = item.ParentBackdropImageTags[0]; itemId = item.ParentBackdropItemId; @@ -634,7 +634,7 @@ function getCardImageUrl(item, apiClient, options, shape) { return { imgUrl: imgUrl, - blurhash: (blurHashes[imgType] || {})[imgTag], + blurhash: blurHashes[imgType]?.[imgTag], forceName: forceName, coverImage: coverImage }; @@ -1422,7 +1422,7 @@ function buildCard(index, item, apiClient, options) { className += ' card-withuserdata'; } - const positionTicksData = item.UserData && item.UserData.PlaybackPositionTicks ? (' data-positionticks="' + item.UserData.PlaybackPositionTicks + '"') : ''; + const positionTicksData = item.UserData?.PlaybackPositionTicks ? (' data-positionticks="' + item.UserData.PlaybackPositionTicks + '"') : ''; const collectionIdData = options.collectionId ? (' data-collectionid="' + options.collectionId + '"') : ''; const playlistIdData = options.playlistId ? (' data-playlistid="' + options.playlistId + '"') : ''; const mediaTypeData = item.MediaType ? (' data-mediatype="' + item.MediaType + '"') : ''; diff --git a/src/components/cardbuilder/chaptercardbuilder.js b/src/components/cardbuilder/chaptercardbuilder.js index 4a359cd9f4..21535adc89 100644 --- a/src/components/cardbuilder/chaptercardbuilder.js +++ b/src/components/cardbuilder/chaptercardbuilder.js @@ -26,7 +26,7 @@ function buildChapterCardsHtml(item, chapters, options) { } } - const mediaStreams = ((item.MediaSources || [])[0] || {}).MediaStreams || []; + const mediaStreams = (item.MediaSources || [])[0]?.MediaStreams || []; const videoStream = mediaStreams.filter(({ Type }) => { return Type === 'Video'; })[0] || {}; diff --git a/src/components/guide/guide.js b/src/components/guide/guide.js index 907de76b88..9384ba2056 100644 --- a/src/components/guide/guide.js +++ b/src/components/guide/guide.js @@ -675,12 +675,12 @@ function Guide(options) { }); const activeElement = document.activeElement; - const itemId = activeElement && activeElement.getAttribute ? activeElement.getAttribute('data-id') : null; + const itemId = activeElement?.getAttribute ? activeElement.getAttribute('data-id') : null; let channelRowId = null; if (activeElement) { channelRowId = dom.parentWithClass(activeElement, 'channelPrograms'); - channelRowId = channelRowId && channelRowId.getAttribute ? channelRowId.getAttribute('data-channelid') : null; + channelRowId = channelRowId?.getAttribute ? channelRowId.getAttribute('data-channelid') : null; } renderChannelHeaders(context, channels, apiClient); diff --git a/src/components/homesections/homesections.js b/src/components/homesections/homesections.js index d5da017e2d..2bb9bb7928 100644 --- a/src/components/homesections/homesections.js +++ b/src/components/homesections/homesections.js @@ -76,7 +76,7 @@ export function loadSections(elem, apiClient, user, userSettings) { }); } else { let noLibDescription; - if (user['Policy'] && user['Policy']['IsAdministrator']) { + if (user.Policy?.IsAdministrator) { noLibDescription = globalize.translate('NoCreatedLibraries', '
', ''); } else { noLibDescription = globalize.translate('AskAdminToCreateLibrary'); diff --git a/src/components/htmlMediaHelper.js b/src/components/htmlMediaHelper.js index 124caa5e0a..f46885c79d 100644 --- a/src/components/htmlMediaHelper.js +++ b/src/components/htmlMediaHelper.js @@ -68,7 +68,7 @@ export function handleHlsJsMediaError(instance, reject) { let now = Date.now(); - if (window.performance && window.performance.now) { + if (window.performance?.now) { now = performance.now(); // eslint-disable-line compat/compat } diff --git a/src/components/imageUploader/imageUploader.js b/src/components/imageUploader/imageUploader.js index c2c70d32ec..c016075ba2 100644 --- a/src/components/imageUploader/imageUploader.js +++ b/src/components/imageUploader/imageUploader.js @@ -41,7 +41,7 @@ function onFileReaderError(evt) { function setFiles(page, files) { const file = files[0]; - if (!file || !file.type.match('image.*')) { + if (!file?.type.match('image.*')) { page.querySelector('#imageOutput').innerHTML = ''; page.querySelector('#fldUpload').classList.add('hide'); currentFile = null; diff --git a/src/components/images/imageLoader.js b/src/components/images/imageLoader.js index beb4bb31a5..178312a314 100644 --- a/src/components/images/imageLoader.js +++ b/src/components/images/imageLoader.js @@ -9,7 +9,7 @@ worker.addEventListener( 'message', ({ data: { pixels, hsh, width, height } }) => { const elems = targetDic[hsh]; - if (elems && elems.length) { + if (elems?.length) { for (const elem of elems) { drawBlurhash(elem, pixels, width, height); } diff --git a/src/components/indicators/indicators.js b/src/components/indicators/indicators.js index 9abfffd8e1..ec21ae3e7f 100644 --- a/src/components/indicators/indicators.js +++ b/src/components/indicators/indicators.js @@ -12,7 +12,7 @@ export function enableProgressIndicator(item) { export function getProgressHtml(pct, options) { let containerClass = 'itemProgressBar'; - if (options && options.containerClass) { + if (options?.containerClass) { containerClass += ' ' + options.containerClass; } @@ -21,7 +21,7 @@ export function getProgressHtml(pct, options) { function getAutoTimeProgressHtml(pct, options, isRecording, start, end) { let containerClass = 'itemProgressBar'; - if (options && options.containerClass) { + if (options?.containerClass) { containerClass += ' ' + options.containerClass; } @@ -36,7 +36,7 @@ function getAutoTimeProgressHtml(pct, options, isRecording, start, end) { export function getProgressBarHtml(item, options) { let pct; if (enableProgressIndicator(item) && item.Type !== 'Recording') { - const userData = options && options.userData ? options.userData : item.UserData; + const userData = options?.userData ? options.userData : item.UserData; if (userData) { pct = userData.PlayedPercentage; @@ -90,7 +90,7 @@ export function getPlayedIndicatorHtml(item) { } export function getChildCountIndicatorHtml(item, options) { - const minCount = options && options.minCount ? options.minCount : 0; + const minCount = options?.minCount ? options.minCount : 0; if (item.ChildCount && item.ChildCount > minCount) { return '
' + datetime.toLocaleString(item.ChildCount) + '
'; diff --git a/src/components/itemHelper.js b/src/components/itemHelper.js index b051fc74c4..ed5982051f 100644 --- a/src/components/itemHelper.js +++ b/src/components/itemHelper.js @@ -117,7 +117,7 @@ export function canEdit(user, item) { } export function isLocalItem(item) { - return item && item.Id && typeof item.Id === 'string' && item.Id.indexOf('local') === 0; + return item?.Id && typeof item.Id === 'string' && item.Id.indexOf('local') === 0; } export function canIdentify (user, item) { diff --git a/src/components/itemMediaInfo/itemMediaInfo.js b/src/components/itemMediaInfo/itemMediaInfo.js index 0eb1348760..a6ce545ee0 100644 --- a/src/components/itemMediaInfo/itemMediaInfo.js +++ b/src/components/itemMediaInfo/itemMediaInfo.js @@ -61,7 +61,7 @@ function getMediaSourceHtml(user, item, version) { if (version.Container) { html += `${createAttribute(globalize.translate('MediaInfoContainer'), version.Container)}
`; } - if (version.Formats && version.Formats.length) { + if (version.Formats?.length) { html += `${createAttribute(globalize.translate('MediaInfoFormat'), version.Formats.join(','))}
`; } if (version.Path && user && user.Policy.IsAdministrator) { diff --git a/src/components/itemidentifier/itemidentifier.js b/src/components/itemidentifier/itemidentifier.js index b1aa1a1b9b..a999f11086 100644 --- a/src/components/itemidentifier/itemidentifier.js +++ b/src/components/itemidentifier/itemidentifier.js @@ -79,7 +79,7 @@ function searchForIdentificationResults(page) { SearchInfo: lookupInfo }; - if (currentItem && currentItem.Id) { + if (currentItem?.Id) { lookupInfo.ItemId = currentItem.Id; } else { lookupInfo.IncludeDisabledProviders = true; diff --git a/src/components/itemsrefresher.js b/src/components/itemsrefresher.js index 4a784b91c9..5bac0621fa 100644 --- a/src/components/itemsrefresher.js +++ b/src/components/itemsrefresher.js @@ -134,7 +134,7 @@ class ItemsRefresher { } } - if (this.needsRefresh || (options && options.refresh)) { + if (this.needsRefresh || (options?.refresh)) { return this.refreshItems(); } diff --git a/src/components/libraryoptionseditor/libraryoptionseditor.js b/src/components/libraryoptionseditor/libraryoptionseditor.js index 9f25b6c3e6..36ee3c7978 100644 --- a/src/components/libraryoptionseditor/libraryoptionseditor.js +++ b/src/components/libraryoptionseditor/libraryoptionseditor.js @@ -495,7 +495,7 @@ function setImageFetchersIntoOptions(parent, options) { } function setImageOptionsIntoOptions(options) { - const originalTypeOptions = (currentLibraryOptions || {}).TypeOptions || []; + const originalTypeOptions = currentLibraryOptions?.TypeOptions || []; for (const originalTypeOption of originalTypeOptions) { let typeOptions = getTypeOptions(options, originalTypeOption.Type); diff --git a/src/components/listview/listview.js b/src/components/listview/listview.js index a6a588dc66..d35bdc3527 100644 --- a/src/components/listview/listview.js +++ b/src/components/listview/listview.js @@ -86,7 +86,7 @@ function getImageUrl(item, size) { type: 'Primary' }; - if (item.ImageTags && item.ImageTags.Primary) { + if (item.ImageTags?.Primary) { options.tag = item.ImageTags.Primary; itemId = item.Id; } else if (item.AlbumId && item.AlbumPrimaryImageTag) { @@ -235,7 +235,7 @@ export function getListViewHtml(options) { const playlistItemId = item.PlaylistItemId ? (` data-playlistitemid="${item.PlaylistItemId}"`) : ''; - const positionTicksData = item.UserData && item.UserData.PlaybackPositionTicks ? (` data-positionticks="${item.UserData.PlaybackPositionTicks}"`) : ''; + const positionTicksData = item.UserData?.PlaybackPositionTicks ? (` data-positionticks="${item.UserData.PlaybackPositionTicks}"`) : ''; const collectionIdData = options.collectionId ? (` data-collectionid="${options.collectionId}"`) : ''; const playlistIdData = options.playlistId ? (` data-playlistid="${options.playlistId}"`) : ''; const mediaTypeData = item.MediaType ? (` data-mediatype="${item.MediaType}"`) : ''; diff --git a/src/components/mediaLibraryEditor/mediaLibraryEditor.js b/src/components/mediaLibraryEditor/mediaLibraryEditor.js index 5a4b3727ab..72bedb2d11 100644 --- a/src/components/mediaLibraryEditor/mediaLibraryEditor.js +++ b/src/components/mediaLibraryEditor/mediaLibraryEditor.js @@ -93,7 +93,7 @@ function onListItemClick(e) { if (listItem) { const index = parseInt(listItem.getAttribute('data-index'), 10); - const pathInfos = (currentOptions.library.LibraryOptions || {}).PathInfos || []; + const pathInfos = currentOptions.library.LibraryOptions?.PathInfos || []; const pathInfo = index == null ? {} : pathInfos[index] || {}; const originalPath = pathInfo.Path || (index == null ? null : currentOptions.library.Locations[index]); const btnRemovePath = dom.parentWithClass(e.target, 'btnRemovePath'); @@ -139,7 +139,7 @@ function refreshLibraryFromServer(page) { } function renderLibrary(page, options) { - let pathInfos = (options.library.LibraryOptions || {}).PathInfos || []; + let pathInfos = options.library.LibraryOptions?.PathInfos || []; if (!pathInfos.length) { pathInfos = options.library.Locations.map(p => { diff --git a/src/components/metadataEditor/metadataEditor.js b/src/components/metadataEditor/metadataEditor.js index b21c615cdd..9c15d316b7 100644 --- a/src/components/metadataEditor/metadataEditor.js +++ b/src/components/metadataEditor/metadataEditor.js @@ -759,7 +759,7 @@ function fillItemInfo(context, item, parentalRatingOptions) { context.querySelector('#txtName').value = item.Name || ''; context.querySelector('#txtOriginalName').value = item.OriginalTitle || ''; context.querySelector('#txtOverview').value = item.Overview || ''; - context.querySelector('#txtTagline').value = (item.Taglines && item.Taglines.length ? item.Taglines[0] : ''); + context.querySelector('#txtTagline').value = (item.Taglines?.length ? item.Taglines[0] : ''); context.querySelector('#txtSortName').value = item.ForcedSortName || ''; context.querySelector('#txtCommunityRating').value = item.CommunityRating || ''; @@ -826,7 +826,7 @@ function fillItemInfo(context, item, parentalRatingOptions) { context.querySelector('#txtAirTime').value = item.AirTime || ''; - const placeofBirth = item.ProductionLocations && item.ProductionLocations.length ? item.ProductionLocations[0] : ''; + const placeofBirth = item.ProductionLocations?.length ? item.ProductionLocations[0] : ''; context.querySelector('#txtPlaceOfBirth').value = placeofBirth; context.querySelector('#txtOriginalAspectRatio').value = item.AspectRatio || ''; diff --git a/src/components/nowPlayingBar/nowPlayingBar.js b/src/components/nowPlayingBar/nowPlayingBar.js index d0fbd7e6b4..239b366a31 100644 --- a/src/components/nowPlayingBar/nowPlayingBar.js +++ b/src/components/nowPlayingBar/nowPlayingBar.js @@ -233,7 +233,7 @@ function bindEvents(elem) { positionSlider.getBubbleText = function (value) { const state = lastPlayerState; - if (!state || !state.NowPlayingItem || !currentRuntimeTicks) { + if (!state?.NowPlayingItem || !currentRuntimeTicks) { return '--:--'; } @@ -476,7 +476,7 @@ function imageUrl(item, options) { options = options || {}; options.type = options.type || 'Primary'; - if (item.ImageTags && item.ImageTags[options.type]) { + if (item.ImageTags?.[options.type]) { options.tag = item.ImageTags[options.type]; return ServerConnections.getApiClient(item.ServerId).getScaledImageUrl(item.PrimaryImageItemId || item.Id, options); } diff --git a/src/components/playback/mediasession.js b/src/components/playback/mediasession.js index 3bfe44e37d..d7d2dcabbe 100644 --- a/src/components/playback/mediasession.js +++ b/src/components/playback/mediasession.js @@ -35,7 +35,7 @@ function seriesImageUrl(item, options = {}) { function imageUrl(item, options = {}) { options.type = options.type || 'Primary'; - if (item.ImageTags && item.ImageTags[options.type]) { + if (item.ImageTags?.[options.type]) { options.tag = item.ImageTags[options.type]; return ServerConnections.getApiClient(item.ServerId).getScaledImageUrl(item.Id, options); diff --git a/src/components/playback/nowplayinghelper.js b/src/components/playback/nowplayinghelper.js index a2b72ca84f..7c5dccaf35 100644 --- a/src/components/playback/nowplayinghelper.js +++ b/src/components/playback/nowplayinghelper.js @@ -23,7 +23,7 @@ export function getNowPlayingNames(nowPlayingItem, includeNonNameInfo) { let bottomText = ''; - if (nowPlayingItem.ArtistItems && nowPlayingItem.ArtistItems.length) { + if (nowPlayingItem.ArtistItems?.length) { bottomItem = { Id: nowPlayingItem.ArtistItems[0].Id, Name: nowPlayingItem.ArtistItems[0].Name, @@ -34,7 +34,7 @@ export function getNowPlayingNames(nowPlayingItem, includeNonNameInfo) { bottomText = nowPlayingItem.ArtistItems.map(function (a) { return a.Name; }).join(', '); - } else if (nowPlayingItem.Artists && nowPlayingItem.Artists.length) { + } else if (nowPlayingItem.Artists?.length) { bottomText = nowPlayingItem.Artists.join(', '); } else if (nowPlayingItem.SeriesName || nowPlayingItem.Album) { bottomText = topText; diff --git a/src/components/playback/playbackmanager.js b/src/components/playback/playbackmanager.js index 77cdb4b6d5..308acd79f5 100644 --- a/src/components/playback/playbackmanager.js +++ b/src/components/playback/playbackmanager.js @@ -163,12 +163,12 @@ function backdropImageUrl(apiClient, item, options) { options.quality = 100; } - if (item.BackdropImageTags && item.BackdropImageTags.length) { + if (item.BackdropImageTags?.length) { options.tag = item.BackdropImageTags[0]; return apiClient.getScaledImageUrl(item.Id, options); } - if (item.ParentBackdropImageTags && item.ParentBackdropImageTags.length) { + if (item.ParentBackdropImageTags?.length) { options.tag = item.ParentBackdropImageTags[0]; return apiClient.getScaledImageUrl(item.ParentBackdropItemId, options); } @@ -773,7 +773,7 @@ class PlaybackManager { self.setActivePlayer = function (player, targetInfo) { if (player === 'localplayer' || player.name === 'localplayer') { - if (self._currentPlayer && self._currentPlayer.isLocalPlayer) { + if (self._currentPlayer?.isLocalPlayer) { return; } setCurrentPlayerInternal(null, null); @@ -795,7 +795,7 @@ class PlaybackManager { self.trySetActivePlayer = function (player, targetInfo) { if (player === 'localplayer' || player.name === 'localplayer') { - if (self._currentPlayer && self._currentPlayer.isLocalPlayer) { + if (self._currentPlayer?.isLocalPlayer) { return; } return; @@ -967,7 +967,7 @@ class PlaybackManager { return player.isPlaying(); } - return player != null && player.currentSrc() != null; + return player?.currentSrc() != null; }; self.isPlayingMediaType = function (mediaType, player) { @@ -989,7 +989,7 @@ class PlaybackManager { self.isPlayingLocally = function (mediaTypes, player) { player = player || self._currentPlayer; - if (!player || !player.isLocalPlayer) { + if (!player?.isLocalPlayer) { return false; } @@ -1068,7 +1068,7 @@ class PlaybackManager { self.setAspectRatio = function (val, player) { player = player || self._currentPlayer; - if (player && player.setAspectRatio) { + if (player?.setAspectRatio) { player.setAspectRatio(val); } }; @@ -1076,7 +1076,7 @@ class PlaybackManager { self.getSupportedAspectRatios = function (player) { player = player || self._currentPlayer; - if (player && player.getSupportedAspectRatios) { + if (player?.getSupportedAspectRatios) { return player.getSupportedAspectRatios(); } @@ -1086,7 +1086,7 @@ class PlaybackManager { self.getAspectRatio = function (player) { player = player || self._currentPlayer; - if (player && player.getAspectRatio) { + if (player?.getAspectRatio) { return player.getAspectRatio(); } }; @@ -1131,7 +1131,7 @@ class PlaybackManager { self.getSupportedPlaybackRates = function (player) { player = player || self._currentPlayer; - if (player && player.getSupportedPlaybackRates) { + if (player?.getSupportedPlaybackRates) { return player.getSupportedPlaybackRates(); } return []; @@ -1351,7 +1351,7 @@ class PlaybackManager { self.getMaxStreamingBitrate = function (player) { player = player || self._currentPlayer; - if (player && player.getMaxStreamingBitrate) { + if (player?.getMaxStreamingBitrate) { return player.getMaxStreamingBitrate(); } @@ -1370,7 +1370,7 @@ class PlaybackManager { self.enableAutomaticBitrateDetection = function (player) { player = player || self._currentPlayer; - if (player && player.enableAutomaticBitrateDetection) { + if (player?.enableAutomaticBitrateDetection) { return player.enableAutomaticBitrateDetection(); } @@ -1386,7 +1386,7 @@ class PlaybackManager { self.setMaxStreamingBitrate = function (options, player) { player = player || self._currentPlayer; - if (player && player.setMaxStreamingBitrate) { + if (player?.setMaxStreamingBitrate) { return player.setMaxStreamingBitrate(options); } @@ -1443,7 +1443,7 @@ class PlaybackManager { document.webkitCancelFullscreen(); } else { const elem = document.querySelector('video'); - if (elem && elem.webkitEnterFullscreen) { + if (elem?.webkitEnterFullscreen) { elem.webkitEnterFullscreen(); } } @@ -2078,7 +2078,7 @@ class PlaybackManager { const mediaSource = self.currentMediaSource(player); - if (mediaSource && mediaSource.RunTimeTicks) { + if (mediaSource?.RunTimeTicks) { return mediaSource.RunTimeTicks; } @@ -2614,7 +2614,7 @@ class PlaybackManager { if (mediaSource.MediaStreams && player.useFullSubtitleUrls) { mediaSource.MediaStreams.forEach(stream => { - if (stream.DeliveryUrl && stream.DeliveryUrl.startsWith('/')) { + if (stream.DeliveryUrl?.startsWith('/')) { stream.DeliveryUrl = apiClient.getUrl(stream.DeliveryUrl); } }); @@ -3444,7 +3444,7 @@ class PlaybackManager { const streamInfo = getPlayerData(player).streamInfo; - if (streamInfo && streamInfo.started && !streamInfo.ended) { + if (streamInfo?.started && !streamInfo.ended) { reportPlayback(self, state, player, reportPlaylist, serverId, 'reportPlaybackProgress', progressEventName); } @@ -3515,7 +3515,7 @@ class PlaybackManager { const nextItem = this._playQueueManager.getNextItemInfo(); - if (!nextItem || !nextItem.item) { + if (!nextItem?.item) { return Promise.reject(); } @@ -3656,7 +3656,7 @@ class PlaybackManager { async playTrailers(item) { const player = this._currentPlayer; - if (player && player.playTrailers) { + if (player?.playTrailers) { return player.playTrailers(item); } @@ -3668,7 +3668,7 @@ class PlaybackManager { items = await apiClient.getLocalTrailers(apiClient.getCurrentUserId(), item.Id); } - if (!items || !items.length) { + if (!items?.length) { items = (item.RemoteTrailers || []).map((t) => { return { Name: t.Name || (item.Name + ' Trailer'), @@ -3750,7 +3750,7 @@ class PlaybackManager { } setPlaybackRate(value, player = this._currentPlayer) { - if (player && player.setPlaybackRate) { + if (player?.setPlaybackRate) { player.setPlaybackRate(value); // Save the new playback rate in the browser session, to restore when playing a new video. @@ -3759,7 +3759,7 @@ class PlaybackManager { } getPlaybackRate(player = this._currentPlayer) { - if (player && player.getPlaybackRate) { + if (player?.getPlaybackRate) { return player.getPlaybackRate(); } @@ -3767,7 +3767,7 @@ class PlaybackManager { } instantMix(item, player = this._currentPlayer) { - if (player && player.instantMix) { + if (player?.instantMix) { return player.instantMix(item); } @@ -3788,7 +3788,7 @@ class PlaybackManager { } shuffle(shuffleItem, player = this._currentPlayer) { - if (player && player.shuffle) { + if (player?.shuffle) { return player.shuffle(shuffleItem); } @@ -3805,7 +3805,7 @@ class PlaybackManager { const mediaSource = this.currentMediaSource(player); - const mediaStreams = (mediaSource || {}).MediaStreams || []; + const mediaStreams = mediaSource?.MediaStreams || []; return mediaStreams.filter(function (s) { return s.Type === 'Audio'; }).sort(itemHelper.sortTracks); @@ -3821,7 +3821,7 @@ class PlaybackManager { const mediaSource = this.currentMediaSource(player); - const mediaStreams = (mediaSource || {}).MediaStreams || []; + const mediaStreams = mediaSource?.MediaStreams || []; return mediaStreams.filter(function (s) { return s.Type === 'Subtitle'; }).sort(itemHelper.sortTracks); @@ -3960,7 +3960,7 @@ class PlaybackManager { } displayContent(options, player = this._currentPlayer) { - if (player && player.displayContent) { + if (player?.displayContent) { player.displayContent(options); } } diff --git a/src/components/playback/playbackorientation.js b/src/components/playback/playbackorientation.js index a4bd8324c6..b581801f9e 100644 --- a/src/components/playback/playbackorientation.js +++ b/src/components/playback/playbackorientation.js @@ -1,4 +1,3 @@ - import { playbackManager } from './playbackmanager'; import layoutManager from '../layoutManager'; import Events from '../../utils/events.ts'; @@ -19,7 +18,7 @@ Events.on(playbackManager, 'playbackstart', function (e, player) { if (isLocalVideo && layoutManager.mobile) { /* eslint-disable-next-line compat/compat */ - const lockOrientation = window.screen.lockOrientation || window.screen.mozLockOrientation || window.screen.msLockOrientation || (window.screen.orientation && window.screen.orientation.lock); + const lockOrientation = window.screen.lockOrientation || window.screen.mozLockOrientation || window.screen.msLockOrientation || (window.screen.orientation?.lock); if (lockOrientation) { try { @@ -40,7 +39,7 @@ Events.on(playbackManager, 'playbackstart', function (e, player) { Events.on(playbackManager, 'playbackstop', function (e, playbackStopInfo) { if (orientationLocked && !playbackStopInfo.nextMediaType) { /* eslint-disable-next-line compat/compat */ - const unlockOrientation = window.screen.unlockOrientation || window.screen.mozUnlockOrientation || window.screen.msUnlockOrientation || (window.screen.orientation && window.screen.orientation.unlock); + const unlockOrientation = window.screen.unlockOrientation || window.screen.mozUnlockOrientation || window.screen.msUnlockOrientation || (window.screen.orientation?.unlock); if (unlockOrientation) { try { diff --git a/src/components/playback/playersettingsmenu.js b/src/components/playback/playersettingsmenu.js index da3be20970..e0acde509b 100644 --- a/src/components/playback/playersettingsmenu.js +++ b/src/components/playback/playersettingsmenu.js @@ -248,7 +248,7 @@ export function show(options) { const player = options.player; const currentItem = playbackManager.currentItem(player); - if (!currentItem || !currentItem.ServerId) { + if (!currentItem?.ServerId) { return showWithUser(options, player, null); } diff --git a/src/components/playback/playmethodhelper.js b/src/components/playback/playmethodhelper.js index 1e7002b45d..5c9511adbc 100644 --- a/src/components/playback/playmethodhelper.js +++ b/src/components/playback/playmethodhelper.js @@ -3,9 +3,9 @@ export function getDisplayPlayMethod(session) { return null; } - if (session.TranscodingInfo && session.TranscodingInfo.IsVideoDirect && session.TranscodingInfo.IsAudioDirect) { + if (session.TranscodingInfo?.IsVideoDirect && session.TranscodingInfo.IsAudioDirect) { return 'Remux'; - } else if (session.TranscodingInfo && session.TranscodingInfo.IsVideoDirect) { + } else if (session.TranscodingInfo?.IsVideoDirect) { return 'DirectStream'; } else if (session.PlayState.PlayMethod === 'Transcode') { return 'Transcode'; diff --git a/src/components/playerstats/playerstats.js b/src/components/playerstats/playerstats.js index d03db1ef71..2d34723721 100644 --- a/src/components/playerstats/playerstats.js +++ b/src/components/playerstats/playerstats.js @@ -166,7 +166,7 @@ function getTranscodingStats(session, player, displayPlayMethod) { value: session.TranscodingInfo.Framerate + ' fps' }); } - if (session.TranscodingInfo.TranscodeReasons && session.TranscodingInfo.TranscodeReasons.length) { + if (session.TranscodingInfo.TranscodeReasons?.length) { sessionStats.push({ label: globalize.translate('LabelReasonForTranscoding'), value: session.TranscodingInfo.TranscodeReasons.map(translateReason).join('
') diff --git a/src/components/recordingcreator/recordingcreator.js b/src/components/recordingcreator/recordingcreator.js index 7fd8b5fc5a..7bee9dccc7 100644 --- a/src/components/recordingcreator/recordingcreator.js +++ b/src/components/recordingcreator/recordingcreator.js @@ -170,7 +170,7 @@ function showEditor(itemId, serverId) { Events.off(currentRecordingFields, 'recordingchanged', onRecordingChanged); executeCloseAction(closeAction, itemId, serverId); - if (currentRecordingFields && currentRecordingFields.hasChanged()) { + if (currentRecordingFields?.hasChanged()) { resolve(); } else { reject(); diff --git a/src/components/remotecontrol/remotecontrol.js b/src/components/remotecontrol/remotecontrol.js index 9f8822405b..b790edded4 100644 --- a/src/components/remotecontrol/remotecontrol.js +++ b/src/components/remotecontrol/remotecontrol.js @@ -119,7 +119,7 @@ function imageUrl(item, options) { options = options || {}; options.type = options.type || 'Primary'; - if (item.ImageTags && item.ImageTags[options.type]) { + if (item.ImageTags?.[options.type]) { options.tag = item.ImageTags[options.type]; return ServerConnections.getApiClient(item.ServerId).getScaledImageUrl(item.PrimaryImageItemId || item.Id, options); } @@ -800,7 +800,7 @@ export default function () { positionSlider.getBubbleText = function (value) { const state = lastPlayerState; - if (!state || !state.NowPlayingItem || !currentRuntimeTicks) { + if (!state?.NowPlayingItem || !currentRuntimeTicks) { return '--:--'; } diff --git a/src/components/router/appRouter.js b/src/components/router/appRouter.js index 7c0d8e86c1..dd049df622 100644 --- a/src/components/router/appRouter.js +++ b/src/components/router/appRouter.js @@ -320,7 +320,7 @@ class AppRouter { path: ctx.path }; }).catch((result) => { - if (!result || !result.cancelled) { + if (!result?.cancelled) { onNewViewNeeded(); } }); @@ -402,7 +402,7 @@ class AppRouter { const isCurrentRouteStartup = this.currentRouteInfo ? this.currentRouteInfo.route.startup : true; const shouldExitApp = ctx.isBack && route.isDefaultRoute && isCurrentRouteStartup; - if (!shouldExitApp && (!apiClient || !apiClient.isLoggedIn()) && !route.anonymous) { + if (!shouldExitApp && (!apiClient?.isLoggedIn()) && !route.anonymous) { console.debug('[appRouter] route does not allow anonymous access: redirecting to login'); this.#beginConnectionWizard(); return; @@ -416,7 +416,7 @@ class AppRouter { return; } - if (apiClient && apiClient.isLoggedIn()) { + if (apiClient?.isLoggedIn()) { console.debug('[appRouter] user is authenticated'); if (route.roles) { diff --git a/src/components/shortcuts.js b/src/components/shortcuts.js index 3b308b06d9..7dc840e8b6 100644 --- a/src/components/shortcuts.js +++ b/src/components/shortcuts.js @@ -33,7 +33,7 @@ function playAllFromHere(card, serverId, queue) { } const itemsContainer = dom.parentWithClass(card, 'itemsContainer'); - if (itemsContainer && itemsContainer.fetchData) { + if (itemsContainer?.fetchData) { const queryOptions = queue ? { StartIndex: startIndex } : {}; return itemsContainer.fetchData(queryOptions).then(result => { diff --git a/src/components/slideshow/slideshow.js b/src/components/slideshow/slideshow.js index 5ec641b683..20307c9d18 100644 --- a/src/components/slideshow/slideshow.js +++ b/src/components/slideshow/slideshow.js @@ -41,7 +41,7 @@ function getImageUrl(item, options, apiClient) { return apiClient.getScaledImageUrl(item, options); } - if (item.ImageTags && item.ImageTags[options.type]) { + if (item.ImageTags?.[options.type]) { options.tag = item.ImageTags[options.type]; return apiClient.getScaledImageUrl(item.Id, options); } @@ -70,7 +70,7 @@ function getBackdropImageUrl(item, options, apiClient) { options.quality = 100; } - if (item.BackdropImageTags && item.BackdropImageTags.length) { + if (item.BackdropImageTags?.length) { options.tag = item.BackdropImageTags[0]; return apiClient.getScaledImageUrl(item.Id, options); } @@ -87,7 +87,7 @@ function getImgUrl(item, user) { const apiClient = ServerConnections.getApiClient(item.ServerId); const imageOptions = {}; - if (item.BackdropImageTags && item.BackdropImageTags.length) { + if (item.BackdropImageTags?.length) { return getBackdropImageUrl(item, imageOptions, apiClient); } else { if (item.MediaType === 'Photo' && user && user.Policy.EnableContentDownloading) { diff --git a/src/components/tabbedview/tabbedview.js b/src/components/tabbedview/tabbedview.js index 8c865ec9f6..2bb85db8c3 100644 --- a/src/components/tabbedview/tabbedview.js +++ b/src/components/tabbedview/tabbedview.js @@ -65,7 +65,7 @@ class TabbedView { const previousIndex = e.detail.previousIndex; const previousTabController = previousIndex == null ? null : self.tabControllers[previousIndex]; - if (previousTabController && previousTabController.onPause) { + if (previousTabController?.onPause) { previousTabController.onPause(); } @@ -93,7 +93,7 @@ class TabbedView { if (!currentTabController) { mainTabsManager.selectedTabIndex(this.initialTabIndex); - } else if (currentTabController && currentTabController.onResume) { + } else if (currentTabController?.onResume) { currentTabController.onResume({}); } } @@ -101,7 +101,7 @@ class TabbedView { onPause() { const currentTabController = this.currentTabController; - if (currentTabController && currentTabController.onPause) { + if (currentTabController?.onPause) { currentTabController.onPause(); } } diff --git a/src/components/themeMediaPlayer.js b/src/components/themeMediaPlayer.js index 9dea2a7770..bad76612ce 100644 --- a/src/components/themeMediaPlayer.js +++ b/src/components/themeMediaPlayer.js @@ -86,7 +86,7 @@ document.addEventListener('viewshow', function (e) { const state = e.detail.state || {}; const item = state.item; - if (item && item.ServerId) { + if (item?.ServerId) { loadThemeMedia(item); return; } diff --git a/src/components/viewManager/ViewManagerPage.tsx b/src/components/viewManager/ViewManagerPage.tsx index 98cf0dcb01..8795e9edd2 100644 --- a/src/components/viewManager/ViewManagerPage.tsx +++ b/src/components/viewManager/ViewManagerPage.tsx @@ -47,7 +47,7 @@ const ViewManagerPage: FunctionComponent = ({ viewManager.tryRestoreView(viewOptions) .catch(async (result?: RestoreViewFailResponse) => { - if (!result || !result.cancelled) { + if (!result?.cancelled) { const [ controllerFactory, viewHtml ] = await Promise.all([ import(/* webpackChunkName: "[request]" */ `../../controllers/${controller}`), import(/* webpackChunkName: "[request]" */ `../../controllers/${view}`) diff --git a/src/controllers/dashboard/dashboard.js b/src/controllers/dashboard/dashboard.js index 95912a55d6..372000a685 100644 --- a/src/controllers/dashboard/dashboard.js +++ b/src/controllers/dashboard/dashboard.js @@ -47,7 +47,7 @@ function showPlaybackInfo(btn, session) { text.push(globalize.translate('MediaIsBeingConverted')); text.push(DashboardPage.getSessionNowPlayingStreamInfo(session)); - if (session.TranscodingInfo && session.TranscodingInfo.TranscodeReasons && session.TranscodingInfo.TranscodeReasons.length) { + if (session.TranscodingInfo?.TranscodeReasons?.length) { text.push('
'); text.push(globalize.translate('LabelReasonForTranscoding')); session.TranscodingInfo.TranscodeReasons.forEach(function (transcodeReason) { @@ -90,7 +90,7 @@ function showOptionsMenu(btn, session) { }); } - if (session.TranscodingInfo && session.TranscodingInfo.TranscodeReasons && session.TranscodingInfo.TranscodeReasons.length) { + if (session.TranscodingInfo?.TranscodeReasons?.length) { menuItems.push({ name: globalize.translate('ViewPlaybackInfo'), id: 'transcodinginfo' @@ -402,7 +402,7 @@ window.DashboardPage = { } else if (displayPlayMethod === 'DirectStream') { html += globalize.translate('DirectStreaming'); } else if (displayPlayMethod === 'Transcode') { - if (session.TranscodingInfo && session.TranscodingInfo.Framerate) { + if (session.TranscodingInfo?.Framerate) { html += `${globalize.translate('Framerate')}: ${session.TranscodingInfo.Framerate}fps`; } @@ -481,7 +481,7 @@ window.DashboardPage = { let topText = escapeHtml(itemHelper.getDisplayName(nowPlayingItem)); let bottomText = ''; - if (nowPlayingItem.Artists && nowPlayingItem.Artists.length) { + if (nowPlayingItem.Artists?.length) { bottomText = topText; topText = escapeHtml(nowPlayingItem.Artists[0]); } else { @@ -493,7 +493,7 @@ window.DashboardPage = { } } - if (nowPlayingItem.ImageTags && nowPlayingItem.ImageTags.Logo) { + if (nowPlayingItem.ImageTags?.Logo) { imgUrl = ApiClient.getScaledImageUrl(nowPlayingItem.Id, { tag: nowPlayingItem.ImageTags.Logo, maxHeight: 24, @@ -571,7 +571,7 @@ window.DashboardPage = { const btnSessionPlayPauseIcon = btnSessionPlayPause.querySelector('.material-icons'); btnSessionPlayPauseIcon.classList.remove('play_arrow', 'pause'); - btnSessionPlayPauseIcon.classList.add(session.PlayState && session.PlayState.IsPaused ? 'play_arrow' : 'pause'); + btnSessionPlayPauseIcon.classList.add(session.PlayState?.IsPaused ? 'play_arrow' : 'pause'); row.querySelector('.sessionNowPlayingTime').innerText = DashboardPage.getSessionNowPlayingTime(session); row.querySelector('.sessionUserName').innerHTML = DashboardPage.getUsersHtml(session); @@ -620,7 +620,7 @@ window.DashboardPage = { getNowPlayingImageUrl: function (item) { /* Screen width is multiplied by 0.2, as the there is currently no way to get the width of elements that aren't created yet. */ - if (item && item.BackdropImageTags && item.BackdropImageTags.length) { + if (item?.BackdropImageTags?.length) { return ApiClient.getScaledImageUrl(item.Id, { maxWidth: Math.round(dom.getScreenWidth() * 0.20), type: 'Backdrop', @@ -628,7 +628,7 @@ window.DashboardPage = { }); } - if (item && item.ParentBackdropImageTags && item.ParentBackdropImageTags.length) { + if (item?.ParentBackdropImageTags?.length) { return ApiClient.getScaledImageUrl(item.ParentBackdropItemId, { maxWidth: Math.round(dom.getScreenWidth() * 0.20), type: 'Backdrop', @@ -636,7 +636,7 @@ window.DashboardPage = { }); } - if (item && item.BackdropImageTag) { + if (item?.BackdropImageTag) { return ApiClient.getScaledImageUrl(item.BackdropItemId, { maxWidth: Math.round(dom.getScreenWidth() * 0.20), type: 'Backdrop', @@ -644,7 +644,7 @@ window.DashboardPage = { }); } - const imageTags = (item || {}).ImageTags || {}; + const imageTags = item?.ImageTags || {}; if (item && imageTags.Thumb) { return ApiClient.getScaledImageUrl(item.Id, { @@ -654,7 +654,7 @@ window.DashboardPage = { }); } - if (item && item.ParentThumbImageTag) { + if (item?.ParentThumbImageTag) { return ApiClient.getScaledImageUrl(item.ParentThumbItemId, { maxWidth: Math.round(dom.getScreenWidth() * 0.20), type: 'Thumb', @@ -662,7 +662,7 @@ window.DashboardPage = { }); } - if (item && item.ThumbImageTag) { + if (item?.ThumbImageTag) { return ApiClient.getScaledImageUrl(item.ThumbItemId, { maxWidth: Math.round(dom.getScreenWidth() * 0.20), type: 'Thumb', @@ -678,7 +678,7 @@ window.DashboardPage = { }); } - if (item && item.PrimaryImageTag) { + if (item?.PrimaryImageTag) { return ApiClient.getScaledImageUrl(item.PrimaryImageItemId, { maxWidth: Math.round(dom.getScreenWidth() * 0.20), type: 'Primary', @@ -686,7 +686,7 @@ window.DashboardPage = { }); } - if (item && item.AlbumPrimaryImageTag) { + if (item?.AlbumPrimaryImageTag) { return ApiClient.getScaledImageUrl(item.AlbumId, { maxWidth: Math.round(dom.getScreenWidth() * 0.20), type: 'Primary', diff --git a/src/controllers/dashboard/dlna/profile.js b/src/controllers/dashboard/dlna/profile.js index dd3e3ad957..47583f2510 100644 --- a/src/controllers/dashboard/dlna/profile.js +++ b/src/controllers/dashboard/dlna/profile.js @@ -415,7 +415,7 @@ function renderContainerProfiles(page, profiles) { html += ''; html += '

' + globalize.translate('ValueContainer', profile.Container || allText) + '

'; - if (profile.Conditions && profile.Conditions.length) { + if (profile.Conditions?.length) { html += '

'; html += globalize.translate('ValueConditions', profile.Conditions.map(function (c) { return c.Property; @@ -487,7 +487,7 @@ function renderCodecProfiles(page, profiles) { html += ''; html += '

' + globalize.translate('ValueCodec', profile.Codec || allText) + '

'; - if (profile.Conditions && profile.Conditions.length) { + if (profile.Conditions?.length) { html += '

'; html += globalize.translate('ValueConditions', profile.Conditions.map(function (c) { return c.Property; @@ -567,7 +567,7 @@ function renderResponseProfiles(page, profiles) { } } - if (profile.Conditions && profile.Conditions.length) { + if (profile.Conditions?.length) { html += '

'; html += globalize.translate('ValueConditions', profile.Conditions.map(function (c) { return c.Property; diff --git a/src/controllers/itemDetails/index.js b/src/controllers/itemDetails/index.js index ee1703bd15..37f5d3108a 100644 --- a/src/controllers/itemDetails/index.js +++ b/src/controllers/itemDetails/index.js @@ -406,7 +406,7 @@ function renderName(item, container, context) { if (item.AlbumArtists) { parentNameHtml.push(getArtistLinksHtml(item.AlbumArtists, item.ServerId, context)); parentNameLast = true; - } else if (item.ArtistItems && item.ArtistItems.length && item.Type === 'MusicVideo') { + } else if (item.ArtistItems?.length && item.Type === 'MusicVideo') { parentNameHtml.push(getArtistLinksHtml(item.ArtistItems, item.ServerId, context)); parentNameLast = true; } else if (item.SeriesName && item.Type === 'Episode') { @@ -475,7 +475,7 @@ function renderName(item, container, context) { } function setTrailerButtonVisibility(page, item) { - if ((item.LocalTrailerCount || item.RemoteTrailers && item.RemoteTrailers.length) && playbackManager.getSupportedCommands().indexOf('PlayTrailers') !== -1) { + if ((item.LocalTrailerCount || item.RemoteTrailers?.length) && playbackManager.getSupportedCommands().indexOf('PlayTrailers') !== -1) { hideAll(page, 'btnPlayTrailer', true); } else { hideAll(page, 'btnPlayTrailer'); @@ -505,7 +505,7 @@ function renderDetailPageBackdrop(page, item, apiClient) { let hasbackdrop = false; const itemBackdropElement = page.querySelector('#itemBackdrop'); - if (item.BackdropImageTags && item.BackdropImageTags.length) { + if (item.BackdropImageTags?.length) { imgUrl = apiClient.getScaledImageUrl(item.Id, { type: 'Backdrop', maxWidth: dom.getScreenWidth(), @@ -523,7 +523,7 @@ function renderDetailPageBackdrop(page, item, apiClient) { }); imageLoader.lazyImage(itemBackdropElement, imgUrl); hasbackdrop = true; - } else if (item.ImageTags && item.ImageTags.Primary) { + } else if (item.ImageTags?.Primary) { imgUrl = apiClient.getScaledImageUrl(item.Id, { type: 'Primary', maxWidth: dom.getScreenWidth(), @@ -660,7 +660,7 @@ function logoImageUrl(item, apiClient, options) { options = options || {}; options.type = 'Logo'; - if (item.ImageTags && item.ImageTags.Logo) { + if (item.ImageTags?.Logo) { options.tag = item.ImageTags.Logo; return apiClient.getScaledImageUrl(item.Id, options); } @@ -1054,7 +1054,7 @@ function renderMiscInfo(page, item) { function renderTagline(page, item) { const taglineElement = page.querySelector('.tagline'); - if (item.Taglines && item.Taglines.length) { + if (item.Taglines?.length) { taglineElement.classList.remove('hide'); taglineElement.innerHTML = '' + escapeHtml(item.Taglines[0]) + ''; } else { @@ -1263,7 +1263,7 @@ function renderSeriesAirTime(page, item) { return; } let html = ''; - if (item.AirDays && item.AirDays.length) { + if (item.AirDays?.length) { if (item.AirDays.length == 7) { html += 'daily'; } else { diff --git a/src/controllers/livetv/livetvsuggested.js b/src/controllers/livetv/livetvsuggested.js index f06508611f..d8325f7a2b 100644 --- a/src/controllers/livetv/livetvsuggested.js +++ b/src/controllers/livetv/livetvsuggested.js @@ -229,7 +229,7 @@ export default function (view, params) { function onTabChange(evt) { const previousTabController = tabControllers[parseInt(evt.detail.previousIndex, 10)]; - if (previousTabController && previousTabController.onHide) { + if (previousTabController?.onHide) { previousTabController.onHide(); } @@ -388,7 +388,7 @@ export default function (view, params) { inputManager.on(window, onInputCommand); }); view.addEventListener('viewbeforehide', function () { - if (currentTabController && currentTabController.onHide) { + if (currentTabController?.onHide) { currentTabController.onHide(); } diff --git a/src/controllers/playback/video/index.js b/src/controllers/playback/video/index.js index cb237d3466..0feb6e3752 100644 --- a/src/controllers/playback/video/index.js +++ b/src/controllers/playback/video/index.js @@ -666,7 +666,7 @@ export default function (view) { if (item.Type === 'TvChannel') { const program = item.CurrentProgram; - if (program && program.EndDate) { + if (program?.EndDate) { try { const endDate = datetime.parseISO8601Date(program.EndDate); @@ -1685,7 +1685,7 @@ export default function (view) { ticks *= value; const item = currentItem; - if (item && item.Chapters && item.Chapters.length && item.Chapters[0].ImageTag) { + if (item?.Chapters?.length && item.Chapters[0].ImageTag) { const html = getChapterBubbleHtml(ServerConnections.getApiClient(item.ServerId), item, item.Chapters, ticks); if (html) { diff --git a/src/elements/emby-input/emby-input.js b/src/elements/emby-input/emby-input.js index 1b7067cef8..81b0c3b3ee 100644 --- a/src/elements/emby-input/emby-input.js +++ b/src/elements/emby-input/emby-input.js @@ -12,7 +12,7 @@ if (Object.getOwnPropertyDescriptor && Object.defineProperty) { const descriptor = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value'); // descriptor returning null in webos - if (descriptor && descriptor.configurable) { + if (descriptor?.configurable) { const baseSetMethod = descriptor.set; descriptor.set = function (value) { baseSetMethod.call(this, value); diff --git a/src/elements/emby-itemscontainer/emby-itemscontainer.js b/src/elements/emby-itemscontainer/emby-itemscontainer.js index d34cc25438..b951fa7d2f 100644 --- a/src/elements/emby-itemscontainer/emby-itemscontainer.js +++ b/src/elements/emby-itemscontainer/emby-itemscontainer.js @@ -37,7 +37,7 @@ function onContextMenu(e) { const card = dom.parentWithAttribute(target, 'data-id'); // check for serverId, it won't be present on selectserver - if (card && card.getAttribute('data-serverid')) { + if (card?.getAttribute('data-serverid')) { inputManager.handleCommand('menu', { sourceElement: card }); @@ -357,7 +357,7 @@ ItemsContainerPrototype.resume = function (options) { } } - if (this.needsRefresh || (options && options.refresh)) { + if (this.needsRefresh || (options?.refresh)) { return this.refreshItems(); } diff --git a/src/elements/emby-playstatebutton/emby-playstatebutton.js b/src/elements/emby-playstatebutton/emby-playstatebutton.js index 6e7756d902..6bc43b461a 100644 --- a/src/elements/emby-playstatebutton/emby-playstatebutton.js +++ b/src/elements/emby-playstatebutton/emby-playstatebutton.js @@ -132,7 +132,7 @@ EmbyPlaystateButtonPrototype.setItem = function (item) { this.setAttribute('data-serverid', item.ServerId); this.setAttribute('data-type', item.Type); - const played = item.UserData && item.UserData.Played; + const played = item.UserData?.Played; setState(this, played); bindEvents(this); } else { diff --git a/src/elements/emby-slider/emby-slider.js b/src/elements/emby-slider/emby-slider.js index 16c52f5863..ec93e61fd6 100644 --- a/src/elements/emby-slider/emby-slider.js +++ b/src/elements/emby-slider/emby-slider.js @@ -14,7 +14,7 @@ let supportsValueSetOverride = false; if (Object.getOwnPropertyDescriptor && Object.defineProperty) { const descriptor = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value'); // descriptor returning null in webos - if (descriptor && descriptor.configurable) { + if (descriptor?.configurable) { supportsValueSetOverride = true; } } @@ -167,7 +167,7 @@ function setMarker(range, valueMarker, marker, valueProgress) { } function updateMarkers(range, currentValue) { - if (range.markerInfo && range.markerInfo.length && range.markerElements && range.markerElements.length) { + if (range.markerInfo?.length && range.markerElements?.length) { for (let i = 0, length = range.markerElements.length; i < length; i++) { if (range.markerInfo.length > i) { setMarker(range, mapFractionToValue(range, range.markerInfo[i].progress), range.markerElements[i], currentValue); diff --git a/src/elements/emby-textarea/emby-textarea.js b/src/elements/emby-textarea/emby-textarea.js index 5f0ddba73e..d186398a06 100644 --- a/src/elements/emby-textarea/emby-textarea.js +++ b/src/elements/emby-textarea/emby-textarea.js @@ -74,7 +74,7 @@ if (Object.getOwnPropertyDescriptor && Object.defineProperty) { const descriptor = Object.getOwnPropertyDescriptor(HTMLTextAreaElement.prototype, 'value'); // descriptor returning null in webos - if (descriptor && descriptor.configurable) { + if (descriptor?.configurable) { const baseSetMethod = descriptor.set; descriptor.set = function (value) { baseSetMethod.call(this, value); diff --git a/src/legacy/focusPreventScroll.js b/src/legacy/focusPreventScroll.js index ad2f12a4b7..f21cce2d40 100644 --- a/src/legacy/focusPreventScroll.js +++ b/src/legacy/focusPreventScroll.js @@ -33,7 +33,7 @@ if (HTMLElement.prototype.nativeFocus === undefined) { this.nativeFocus(); // Restore window scroll if preventScroll - if (options && options.preventScroll) { + if (options?.preventScroll) { window.scroll(scrollX, scrollY); } }; diff --git a/src/libraries/navdrawer/navdrawer.js b/src/libraries/navdrawer/navdrawer.js index 539682a076..ef6dd1e04f 100644 --- a/src/libraries/navdrawer/navdrawer.js +++ b/src/libraries/navdrawer/navdrawer.js @@ -131,7 +131,7 @@ class NavDrawer { if (this.isPeeking) { this.onMenuTouchMove(e); } else { - if (((getTouches(e)[0] || {}).clientX || 0) <= options.handleSize) { + if ((getTouches(e)[0]?.clientX || 0) <= options.handleSize) { this.isPeeking = true; if (e.type === 'touchstart') { diff --git a/src/plugins/bookPlayer/plugin.js b/src/plugins/bookPlayer/plugin.js index 8924d06951..6418d84e6b 100644 --- a/src/plugins/bookPlayer/plugin.js +++ b/src/plugins/bookPlayer/plugin.js @@ -384,7 +384,7 @@ export class BookPlayer { } canPlayItem(item) { - return item.Path && item.Path.endsWith('epub'); + return item.Path?.endsWith('epub'); } } diff --git a/src/plugins/chromecastPlayer/plugin.js b/src/plugins/chromecastPlayer/plugin.js index 693836b172..569e347cd2 100644 --- a/src/plugins/chromecastPlayer/plugin.js +++ b/src/plugins/chromecastPlayer/plugin.js @@ -103,7 +103,7 @@ class CastPlayer { return; } - if (!chrome.cast || !chrome.cast.isAvailable) { + if (!chrome.cast?.isAvailable) { setTimeout(this.initializeCastPlayer.bind(this), 1000); return; } @@ -322,14 +322,14 @@ class CastPlayer { const session = player.session; - if (session && session.receiver && session.receiver.friendlyName) { + if (session?.receiver?.friendlyName) { receiverName = session.receiver.friendlyName; } let apiClient; - if (message.options && message.options.ServerId) { + if (message.options?.ServerId) { apiClient = ServerConnections.getApiClient(message.options.ServerId); - } else if (message.options && message.options.items && message.options.items.length) { + } else if (message.options?.items?.length) { apiClient = ServerConnections.getApiClient(message.options.items[0].ServerId); } else { apiClient = ServerConnections.currentApiClient(); @@ -350,7 +350,7 @@ class CastPlayer { message.maxBitrate = bitrateSetting; } - if (message.options && message.options.items) { + if (message.options?.items) { message.subtitleAppearance = userSettings.getSubtitleAppearanceSettings(); message.subtitleBurnIn = appSettings.get('subtitleburnin') || ''; } @@ -451,10 +451,10 @@ function onVolumeDownKeyDown() { } function normalizeImages(state) { - if (state && state.NowPlayingItem) { + if (state?.NowPlayingItem) { const item = state.NowPlayingItem; - if ((!item.ImageTags || !item.ImageTags.Primary) && item.PrimaryImageTag) { + if ((!item.ImageTags?.Primary) && item.PrimaryImageTag) { item.ImageTags = item.ImageTags || {}; item.ImageTags.Primary = item.PrimaryImageTag; } @@ -599,7 +599,7 @@ class ChromecastPlayer { getTargets() { const targets = []; - if (this._castPlayer && this._castPlayer.hasReceivers) { + if (this._castPlayer?.hasReceivers) { targets.push(this.getCurrentTargetInfo()); } @@ -612,7 +612,7 @@ class ChromecastPlayer { const castPlayer = this._castPlayer; - if (castPlayer.session && castPlayer.session.receiver && castPlayer.session.receiver.friendlyName) { + if (castPlayer.session?.receiver?.friendlyName) { appName = castPlayer.session.receiver.friendlyName; } diff --git a/src/plugins/htmlAudioPlayer/plugin.js b/src/plugins/htmlAudioPlayer/plugin.js index a7c7be0c15..2d0c6cceb1 100644 --- a/src/plugins/htmlAudioPlayer/plugin.js +++ b/src/plugins/htmlAudioPlayer/plugin.js @@ -413,7 +413,7 @@ class HtmlAudioPlayer { const mediaElement = this._mediaElement; if (mediaElement) { const seekable = mediaElement.seekable; - if (seekable && seekable.length) { + if (seekable?.length) { let start = seekable.start(0); let end = seekable.end(0); diff --git a/src/plugins/htmlVideoPlayer/plugin.js b/src/plugins/htmlVideoPlayer/plugin.js index c2a1e9d002..b2410ed0ec 100644 --- a/src/plugins/htmlVideoPlayer/plugin.js +++ b/src/plugins/htmlVideoPlayer/plugin.js @@ -1010,7 +1010,7 @@ export class HtmlVideoPlayer { } if (elem.videoWidth === 0 && elem.videoHeight === 0) { - const mediaSource = (this._currentPlayOptions || {}).mediaSource; + const mediaSource = this._currentPlayOptions?.mediaSource; // Only trigger this if there is media info // Avoid triggering in situations where it might not actually have a video stream (audio only live tv channel) @@ -1536,7 +1536,7 @@ export class HtmlVideoPlayer { } } - if (selectedTrackEvent && selectedTrackEvent.Text) { + if (selectedTrackEvent?.Text) { subtitleTextElement.innerHTML = DOMPurify.sanitize( normalizeTrackEventText(selectedTrackEvent.Text, true)); subtitleTextElement.classList.remove('hide'); @@ -1812,7 +1812,7 @@ export class HtmlVideoPlayer { Windows.UI.ViewManagement.ApplicationView.getForCurrentView().tryEnterViewModeAsync(Windows.UI.ViewManagement.ApplicationViewMode.default); } } else { - if (video && video.webkitSupportsPresentationMode && typeof video.webkitSetPresentationMode === 'function') { + if (video?.webkitSupportsPresentationMode && typeof video.webkitSetPresentationMode === 'function') { video.webkitSetPresentationMode(isEnabled ? 'picture-in-picture' : 'inline'); } } @@ -1891,7 +1891,7 @@ export class HtmlVideoPlayer { const mediaElement = this.#mediaElement; if (mediaElement) { const seekable = mediaElement.seekable; - if (seekable && seekable.length) { + if (seekable?.length) { let start = seekable.start(0); let end = seekable.end(0); diff --git a/src/plugins/logoScreensaver/plugin.js b/src/plugins/logoScreensaver/plugin.js index fc999ccccf..9cd0e1a445 100644 --- a/src/plugins/logoScreensaver/plugin.js +++ b/src/plugins/logoScreensaver/plugin.js @@ -25,7 +25,7 @@ export default function () { const elem = document.querySelector('.logoScreenSaverImage'); - if (elem && elem.animate) { + if (elem?.animate) { const random = randomInt(0, animations.length - 1); animations[random](elem, 1); diff --git a/src/plugins/pdfPlayer/plugin.js b/src/plugins/pdfPlayer/plugin.js index 00625c2776..6a14a4a684 100644 --- a/src/plugins/pdfPlayer/plugin.js +++ b/src/plugins/pdfPlayer/plugin.js @@ -312,7 +312,7 @@ export class PdfPlayer { } canPlayItem(item) { - return item.Path && item.Path.endsWith('pdf'); + return item.Path?.endsWith('pdf'); } } diff --git a/src/plugins/sessionPlayer/plugin.js b/src/plugins/sessionPlayer/plugin.js index 98e0e843ab..6feef63575 100644 --- a/src/plugins/sessionPlayer/plugin.js +++ b/src/plugins/sessionPlayer/plugin.js @@ -157,7 +157,7 @@ function subscribeToPlayerUpdates(instance) { } function normalizeImages(state, apiClient) { - if (state && state.NowPlayingItem) { + if (state?.NowPlayingItem) { const item = state.NowPlayingItem; if (!item.ImageTags || !item.ImageTags.Primary && item.PrimaryImageTag) { diff --git a/src/scripts/autocast.js b/src/scripts/autocast.js index 854403b4da..9ed7de5df7 100644 --- a/src/scripts/autocast.js +++ b/src/scripts/autocast.js @@ -12,7 +12,7 @@ export function enable(enabled) { if (enabled) { const currentPlayerInfo = playbackManager.getPlayerInfo(); - if (currentPlayerInfo && currentPlayerInfo.id) { + if (currentPlayerInfo?.id) { localStorage.setItem('autocastPlayerId', currentPlayerInfo.id); } } else { diff --git a/src/scripts/browserDeviceProfile.js b/src/scripts/browserDeviceProfile.js index c4623718bc..98be70a9b1 100644 --- a/src/scripts/browserDeviceProfile.js +++ b/src/scripts/browserDeviceProfile.js @@ -3,7 +3,7 @@ import * as userSettings from './settings/userSettings'; import browser from './browser'; function canPlayH264(videoTestElement) { - return !!(videoTestElement.canPlayType && videoTestElement.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"').replace(/no/, '')); + return !!(videoTestElement.canPlayType?.('video/mp4; codecs="avc1.42E01E, mp4a.40.2"').replace(/no/, '')); } function canPlayHevc(videoTestElement, options) { diff --git a/src/scripts/dom.js b/src/scripts/dom.js index 9488c7e16d..dadd3b4fe4 100644 --- a/src/scripts/dom.js +++ b/src/scripts/dom.js @@ -15,7 +15,7 @@ export function parentWithAttribute(elem, name, value) { while ((value ? elem.getAttribute(name) !== value : !elem.getAttribute(name))) { elem = elem.parentNode; - if (!elem || !elem.getAttribute) { + if (!elem?.getAttribute) { return null; } } diff --git a/src/scripts/gamepadtokey.js b/src/scripts/gamepadtokey.js index 847ef02a52..cfd6e3790c 100644 --- a/src/scripts/gamepadtokey.js +++ b/src/scripts/gamepadtokey.js @@ -349,7 +349,7 @@ function isGamepadConnected() { const gamepads = navigator.getGamepads(); /* eslint-disable-line compat/compat */ for (let i = 0, len = gamepads.length; i < len; i++) { const gamepad = gamepads[i]; - if (gamepad && gamepad.connected) { + if (gamepad?.connected) { return true; } } diff --git a/src/scripts/globalize.js b/src/scripts/globalize.js index 256207acec..21260e2be4 100644 --- a/src/scripts/globalize.js +++ b/src/scripts/globalize.js @@ -37,7 +37,7 @@ function getDefaultLanguage() { if (navigator.userLanguage) { return navigator.userLanguage; } - if (navigator.languages && navigator.languages.length) { + if (navigator.languages?.length) { return navigator.languages[0]; } @@ -217,12 +217,12 @@ function translateKey(key) { function translateKeyFromModule(key, module) { let dictionary = getDictionary(module, getCurrentLocale()); - if (dictionary && dictionary[key]) { + if (dictionary?.[key]) { return dictionary[key]; } dictionary = getDictionary(module, fallbackCulture); - if (dictionary && dictionary[key]) { + if (dictionary?.[key]) { return dictionary[key]; } diff --git a/src/scripts/libraryMenu.js b/src/scripts/libraryMenu.js index c49a8336d3..b77dfa92e1 100644 --- a/src/scripts/libraryMenu.js +++ b/src/scripts/libraryMenu.js @@ -71,7 +71,7 @@ function renderHeader() { } function getCurrentApiClient() { - if (currentUser && currentUser.localUser) { + if (currentUser?.localUser) { return ServerConnections.getApiClient(currentUser.localUser.ServerId); } @@ -127,7 +127,7 @@ function updateUserInHeader(user) { let hasImage; - if (user && user.name) { + if (user?.name) { if (user.imageUrl) { const url = user.imageUrl; updateHeaderUserButton(url); @@ -143,7 +143,7 @@ function updateUserInHeader(user) { updateHeaderUserButton(null); } - if (user && user.localUser) { + if (user?.localUser) { if (headerHomeButton) { headerHomeButton.classList.remove('hide'); } @@ -322,7 +322,7 @@ function refreshLibraryInfoInDrawer(user) { // libraries are added here html += '

'; - if (user.localUser && user.localUser.Policy.IsAdministrator) { + if (user.localUser?.Policy.IsAdministrator) { html += '
'; html += '

'; html += globalize.translate('HeaderAdmin'); diff --git a/src/scripts/screensavermanager.js b/src/scripts/screensavermanager.js index c63d530685..a187da6ae2 100644 --- a/src/scripts/screensavermanager.js +++ b/src/scripts/screensavermanager.js @@ -94,7 +94,7 @@ function ScreenSaverManager() { let isLoggedIn; const apiClient = ServerConnections.currentApiClient(); - if (apiClient && apiClient.isLoggedIn()) { + if (apiClient?.isLoggedIn()) { isLoggedIn = true; } diff --git a/src/utils/fetchLocal.ts b/src/utils/fetchLocal.ts index cec934028f..8191e846e7 100644 --- a/src/utils/fetchLocal.ts +++ b/src/utils/fetchLocal.ts @@ -33,7 +33,7 @@ export default async function fetchLocal(url: string, options?: FetchOptions) { xhr.open('GET', url); - if (options && options.cache) { + if (options?.cache) { xhr.setRequestHeader('Cache-Control', options.cache); }