import * as userSettings from 'scripts/settings/userSettings'; import datetime from 'scripts/datetime'; import globalize from 'lib/globalize'; import itemHelper from '../itemHelper'; import { ItemKind } from 'types/base/models/item-kind'; import { ItemMediaKind } from 'types/base/models/item-media-kind'; import { ItemStatus } from 'types/base/models/item-status'; import type { NullableNumber, NullableString } from 'types/base/common/shared/types'; import type { ItemDto } from 'types/base/models/item-dto'; import type { MiscInfo } from 'types/mediaInfoItem'; import { PrimaryInfoOpts } from './type'; function shouldShowFolderRuntime( itemType: ItemKind, itemMediaType: ItemMediaKind ): boolean { return ( itemType === ItemKind.MusicAlbum || itemMediaType === ItemMediaKind.MusicArtist || itemType === ItemKind.Playlist || itemMediaType === ItemMediaKind.Playlist || itemMediaType === ItemMediaKind.MusicGenre ); } function addTrackCountOrItemCount( showFolderRuntime: boolean, itemSongCount: NullableNumber, itemChildCount: NullableNumber, itemRunTimeTicks: NullableNumber, itemType: ItemKind, addMiscInfo: (val: MiscInfo) => void ): void { if (showFolderRuntime) { const count = itemSongCount ?? itemChildCount; if (count) { addMiscInfo({ text: globalize.translate('TrackCount', count) }); } if (itemRunTimeTicks) { addMiscInfo({ text: datetime.getDisplayDuration(itemRunTimeTicks) }); } } else if (itemType === ItemKind.PhotoAlbum || itemType === ItemKind.BoxSet) { const count = itemChildCount; if (count) { addMiscInfo({ text: globalize.translate('ItemCount', count) }); } } } function addOriginalAirDateInfo( itemType: ItemKind, itemMediaType: ItemMediaKind, showOriginalAirDateInfo: boolean, itemPremiereDate: NullableString, addMiscInfo: (val: MiscInfo) => void ): void { if ( itemPremiereDate && (itemType === ItemKind.Episode || itemMediaType === ItemMediaKind.Photo) && showOriginalAirDateInfo ) { try { //don't modify date to locale if episode. Only Dates (not times) are stored, or editable in the edit metadata dialog const date = datetime.parseISO8601Date( itemPremiereDate, itemType !== ItemKind.Episode ); addMiscInfo({ text: datetime.toLocaleDateString(date) }); } catch (e) { console.error('error parsing date:', itemPremiereDate); } } } function addSeriesTimerInfo( itemType: ItemKind, itemRecordAnyTime: boolean | undefined, itemStartDate: NullableString, itemRecordAnyChannel: boolean | undefined, itemChannelName: NullableString, addMiscInfo: (val: MiscInfo) => void ): void { if (itemType === ItemKind.SeriesTimer) { if (itemRecordAnyTime) { addMiscInfo({ text: globalize.translate('Anytime') }); } else { addMiscInfo({ text: datetime.getDisplayTime(itemStartDate) }); } if (itemRecordAnyChannel) { addMiscInfo({ text: globalize.translate('AllChannels') }); } else { addMiscInfo({ text: itemChannelName ?? globalize.translate('OneChannel') }); } } } function addProgramIndicatorInfo( program: ItemDto | undefined, addMiscInfo: (val: MiscInfo) => void ): void { if ( program?.IsLive && userSettings.get('guide-indicator-live') === 'true' ) { addMiscInfo({ text: globalize.translate('Live'), cssClass: 'mediaInfoProgramAttribute liveTvProgram' }); } else if ( program?.IsPremiere && userSettings.get('guide-indicator-premiere') === 'true' ) { addMiscInfo({ text: globalize.translate('Premiere'), cssClass: 'mediaInfoProgramAttribute premiereTvProgram' }); } else if ( program?.IsSeries && !program?.IsRepeat && userSettings.get('guide-indicator-new') === 'true' ) { addMiscInfo({ text: globalize.translate('New'), cssClass: 'mediaInfoProgramAttribute newTvProgram' }); } else if ( program?.IsSeries && program?.IsRepeat && userSettings.get('guide-indicator-repeat') === 'true' ) { addMiscInfo({ text: globalize.translate('Repeat'), cssClass: 'mediaInfoProgramAttribute repeatTvProgram' }); } } function addProgramIndicators( item: ItemDto, showYearInfo: boolean, showEpisodeTitleInfo: boolean, showOriginalAirDateInfo: boolean, showProgramIndicatorInfo: boolean, includeEpisodeTitleIndexNumber: boolean, addMiscInfo: (val: MiscInfo) => void ): void { if (item.Type === ItemKind.Program || item.Type === ItemKind.Timer) { let program = item; if (item.Type === ItemKind.Timer && item.ProgramInfo) { program = item.ProgramInfo; } if (showProgramIndicatorInfo !== false) { addProgramIndicatorInfo(program, addMiscInfo); } addProgramTextInfo( program, showEpisodeTitleInfo, includeEpisodeTitleIndexNumber, showOriginalAirDateInfo, showYearInfo, addMiscInfo ); } } function addProgramTextInfo( program: ItemDto, showEpisodeTitleInfo: boolean, includeEpisodeTitleIndexNumber: boolean, showOriginalAirDateInfo: boolean, showYearInfo: boolean, addMiscInfo: (val: MiscInfo) => void ): void { if ( (program?.IsSeries || program?.EpisodeTitle) && showEpisodeTitleInfo !== false ) { const text = itemHelper.getDisplayName(program, { includeIndexNumber: includeEpisodeTitleIndexNumber }); if (text) { addMiscInfo({ text: text }); } } else if ( program?.ProductionYear && ((program?.IsMovie && showOriginalAirDateInfo !== false) || showYearInfo !== false) ) { addMiscInfo({ text: program.ProductionYear }); } else if (program?.PremiereDate && showOriginalAirDateInfo !== false) { try { const date = datetime.parseISO8601Date(program.PremiereDate); const text = globalize.translate( 'OriginalAirDateValue', datetime.toLocaleDateString(date) ); addMiscInfo({ text: text }); } catch (e) { console.error('error parsing date:', program.PremiereDate); } } } function addStartDateInfo( itemStartDate: NullableString, itemType: ItemKind, addMiscInfo: (val: MiscInfo) => void ): void { if ( itemStartDate && itemType !== ItemKind.Program && itemType !== ItemKind.SeriesTimer && itemType !== ItemKind.Timer ) { try { const date = datetime.parseISO8601Date(itemStartDate); addMiscInfo({ text: datetime.toLocaleDateString(date) }); if (itemType !== ItemKind.Recording) { addMiscInfo({ text: datetime.getDisplayTime(date) }); } } catch (e) { console.error('error parsing date:', itemStartDate); } } } function addSeriesProductionYearInfo( itemProductionYear: NullableNumber, itemType: ItemKind, showYearInfo: boolean, itemStatus: ItemStatus, itemEndDate: NullableString, addMiscInfo: (val: MiscInfo) => void ): void { if (itemProductionYear && showYearInfo && itemType === ItemKind.Series) { if (itemStatus === ItemStatus.Continuing) { addMiscInfo({ text: globalize.translate( 'SeriesYearToPresent', datetime.toLocaleString(itemProductionYear, { useGrouping: false }) ) }); } else { addproductionYearWithEndDate(itemProductionYear, itemEndDate, addMiscInfo); } } } function addproductionYearWithEndDate( itemProductionYear: number, itemEndDate: NullableString, addMiscInfo: (val: MiscInfo) => void ): void { let productionYear = datetime.toLocaleString(itemProductionYear, { useGrouping: false }); if (itemEndDate) { try { const endYear = datetime.toLocaleString( datetime.parseISO8601Date(itemEndDate).getFullYear(), { useGrouping: false } ); /* At this point, text will contain only the start year */ if (endYear !== itemProductionYear) { productionYear += `-${endYear}`; } } catch (e) { console.error('error parsing date:', itemEndDate); } } addMiscInfo({ text: productionYear }); } function addYearInfo( showYearInfo: boolean, itemType: ItemKind, itemMediaType: ItemMediaKind, itemProductionYear: NullableNumber, itemPremiereDate: NullableString, addMiscInfo: (val: MiscInfo) => void ): void { if ( showYearInfo && itemType !== ItemKind.Series && itemType !== ItemKind.Episode && itemType !== ItemKind.Person && itemMediaType !== ItemMediaKind.Photo && itemType !== ItemKind.Program && itemType !== ItemKind.Season ) { if (itemProductionYear) { addMiscInfo({ text: itemProductionYear }); } else if (itemPremiereDate) { try { const text = datetime.toLocaleString( datetime.parseISO8601Date(itemPremiereDate).getFullYear(), { useGrouping: false } ); addMiscInfo({ text: text }); } catch (e) { console.error('error parsing date:', itemPremiereDate); } } } } function addVideo3DFormat( itemVideo3DFormat: NullableString, addMiscInfo: (val: MiscInfo) => void ): void { if (itemVideo3DFormat) { addMiscInfo({ text: '3D' }); } } function addRunTimeInfo( itemRunTimeTicks: NullableNumber, itemType: ItemKind, showFolderRuntime: boolean, showRuntimeInfo: boolean, addMiscInfo: (val: MiscInfo) => void ): void { if ( itemRunTimeTicks && itemType !== ItemKind.Series && itemType !== ItemKind.Program && itemType !== ItemKind.Timer && itemType !== ItemKind.Book && !showFolderRuntime && showRuntimeInfo ) { if (itemType === ItemKind.Audio) { addMiscInfo({ text: datetime.getDisplayRunningTime(itemRunTimeTicks) }); } else { addMiscInfo({ text: datetime.getDisplayDuration(itemRunTimeTicks) }); } } } function addOfficialRatingInfo( itemOfficialRating: NullableString, itemType: ItemKind, showOfficialRatingInfo: boolean, addMiscInfo: (val: MiscInfo) => void ): void { if ( itemOfficialRating && showOfficialRatingInfo && itemType !== ItemKind.Season && itemType !== ItemKind.Episode ) { addMiscInfo({ text: itemOfficialRating, cssClass: 'mediaInfoText mediaInfoOfficialRating' }); } } function addAudioContainer( itemContainer: NullableString, showAudioContainerInfo: boolean, itemType: ItemKind, addMiscInfo: (val: MiscInfo) => void ): void { if ( itemContainer && showAudioContainerInfo && itemType === ItemKind.Audio ) { addMiscInfo({ text: itemContainer }); } } function addPhotoSize( itemMediaType: ItemMediaKind, itemWidth: NullableNumber, itemHeight: NullableNumber, addMiscInfo: (val: MiscInfo) => void ): void { if (itemMediaType === ItemMediaKind.Photo && itemWidth && itemHeight) { const size = `${itemWidth}x${itemHeight}`; addMiscInfo({ text: size }); } } interface UsePrimaryMediaInfoProps extends PrimaryInfoOpts { item: ItemDto; } function usePrimaryMediaInfo({ item, showYearInfo = false, showAudioContainerInfo = false, showEpisodeTitleInfo = false, showOriginalAirDateInfo = false, showRuntimeInfo = false, showProgramIndicatorInfo = false, includeEpisodeTitleIndexNumber = false, showOfficialRatingInfo = false }: UsePrimaryMediaInfoProps) { const { EndDate, Status, StartDate, ProductionYear, Video3DFormat, Type, Width, Height, MediaType, SongCount, RecordAnyTime, RecordAnyChannel, ChannelName, ChildCount, RunTimeTicks, PremiereDate, OfficialRating, Container } = item; const miscInfo: MiscInfo[] = []; const addMiscInfo = (val: MiscInfo) => { if (val) { miscInfo.push(val); } }; const showFolderRuntime = shouldShowFolderRuntime(Type, MediaType); addTrackCountOrItemCount( showFolderRuntime, SongCount, ChildCount, RunTimeTicks, Type, addMiscInfo ); addOriginalAirDateInfo( Type, MediaType, showOriginalAirDateInfo, PremiereDate, addMiscInfo ); addSeriesTimerInfo( Type, RecordAnyTime, StartDate, RecordAnyChannel, ChannelName, addMiscInfo ); addStartDateInfo(StartDate, Type, addMiscInfo); addSeriesProductionYearInfo( ProductionYear, Type, showYearInfo, Status, EndDate, addMiscInfo ); addProgramIndicators( item, showProgramIndicatorInfo, showEpisodeTitleInfo, includeEpisodeTitleIndexNumber, showOriginalAirDateInfo, showYearInfo, addMiscInfo ); addYearInfo( showYearInfo, Type, MediaType, ProductionYear, PremiereDate, addMiscInfo ); addRunTimeInfo( RunTimeTicks, Type, showFolderRuntime, showRuntimeInfo, addMiscInfo ); addOfficialRatingInfo( OfficialRating, Type, showOfficialRatingInfo, addMiscInfo ); addVideo3DFormat(Video3DFormat, addMiscInfo); addPhotoSize(MediaType, Width, Height, addMiscInfo); addAudioContainer(Container, showAudioContainerInfo, Type, addMiscInfo); return miscInfo; } export default usePrimaryMediaInfo;