From 82d70763bb07b59de59345f0d5ab31814c2f88e4 Mon Sep 17 00:00:00 2001 From: grafixeyehero Date: Thu, 22 Aug 2024 01:01:59 +0300 Subject: [PATCH] Add Secondary Media Info --- src/components/mediainfo/MediaInfoItem.tsx | 30 +++-- .../mediainfo/SecondaryMediaInfo.tsx | 55 ++++++++ src/components/mediainfo/type.ts | 9 ++ .../mediainfo/useSecondaryMediaInfo.tsx | 124 ++++++++++++++++++ src/types/mediaInfoItem.ts | 10 +- 5 files changed, 218 insertions(+), 10 deletions(-) create mode 100644 src/components/mediainfo/SecondaryMediaInfo.tsx create mode 100644 src/components/mediainfo/useSecondaryMediaInfo.tsx diff --git a/src/components/mediainfo/MediaInfoItem.tsx b/src/components/mediainfo/MediaInfoItem.tsx index 8eeb7307ca..545414c37a 100644 --- a/src/components/mediainfo/MediaInfoItem.tsx +++ b/src/components/mediainfo/MediaInfoItem.tsx @@ -1,24 +1,38 @@ import React, { type FC } from 'react'; import Box from '@mui/material/Box'; +import Link from '@mui/material/Link'; import classNames from 'classnames'; import type { MiscInfo } from 'types/mediaInfoItem'; interface MediaInfoItemProps { className?: string; - miscInfo?: MiscInfo ; + miscInfo: MiscInfo ; } const MediaInfoItem: FC = ({ className, miscInfo }) => { - const cssClass = classNames( - 'mediaInfoItem', - className, - miscInfo?.cssClass - ); + const { text, textAction, cssClass } = miscInfo; + + const renderText = () => { + if (textAction) { + return ( + + {textAction.title} + + ); + } else { + return text; + } + }; return ( - - {miscInfo?.text} + + {renderText()} ); }; diff --git a/src/components/mediainfo/SecondaryMediaInfo.tsx b/src/components/mediainfo/SecondaryMediaInfo.tsx new file mode 100644 index 0000000000..dae138cef4 --- /dev/null +++ b/src/components/mediainfo/SecondaryMediaInfo.tsx @@ -0,0 +1,55 @@ +import React, { type FC } from 'react'; +import classNames from 'classnames'; +import Box from '@mui/material/Box'; +import useSecondaryMediaInfo from './useSecondaryMediaInfo'; +import useIndicator from 'components/indicators/useIndicator'; +import MediaInfoItem from './MediaInfoItem'; +import type { ItemDto } from 'types/base/models/item-dto'; +import { MiscInfo } from 'types/mediaInfoItem'; +import type { SecondaryInfoOpts } from './type'; + +interface SecondaryMediaInfoProps extends SecondaryInfoOpts { + className?: string; + infoclass?: string; + item: ItemDto; + showTimerIndicatorInfo?: boolean; +} + +const SecondaryMediaInfo: FC = ({ + className, + infoclass, + item, + showProgramTimeInfo, + showStartDateInfo, + showChannelNumberInfo, + showChannelInfo, + channelInteractive, + showTimerIndicatorInfo = false +}) => { + const miscInfo = useSecondaryMediaInfo({ + item, + showProgramTimeInfo, + showStartDateInfo, + showChannelNumberInfo, + showChannelInfo, + channelInteractive + }); + + const indicator = useIndicator(item); + + const cssClass = classNames(className); + + const renderMediaInfo = (info: MiscInfo, index: number) => ( + + ); + + return ( + + {miscInfo.map((info, index) => renderMediaInfo(info, index))} + + {showTimerIndicatorInfo !== false && indicator.getTimerIndicator()} + + ); +}; + +export default SecondaryMediaInfo; diff --git a/src/components/mediainfo/type.ts b/src/components/mediainfo/type.ts index 0e20bf1394..ab5bf19422 100644 --- a/src/components/mediainfo/type.ts +++ b/src/components/mediainfo/type.ts @@ -14,3 +14,12 @@ export interface PrimaryInfoOpts { showVideo3DFormatInfo?: boolean; showPhotoSizeInfo?: boolean; } + +export interface SecondaryInfoOpts { + showProgramTimeInfo?: boolean; + showStartDateInfo?: boolean; + showEndDateInfo?: boolean; + showChannelNumberInfo?: boolean; + showChannelInfo?: boolean; + channelInteractive?: boolean; +} diff --git a/src/components/mediainfo/useSecondaryMediaInfo.tsx b/src/components/mediainfo/useSecondaryMediaInfo.tsx new file mode 100644 index 0000000000..c7bbb0d708 --- /dev/null +++ b/src/components/mediainfo/useSecondaryMediaInfo.tsx @@ -0,0 +1,124 @@ +import datetime from 'scripts/datetime'; +import { appRouter } from 'components/router/appRouter'; +import type { NullableString } from 'types/base/common/shared/types'; +import type { ItemDto } from 'types/base/models/item-dto'; +import type { MiscInfo } from 'types/mediaInfoItem'; +import { ItemKind } from 'types/base/models/item-kind'; +import type { SecondaryInfoOpts } from './type'; + +function addProgramTime( + showProgramTimeInfo: boolean, + showStartDateInfo: boolean, + showEndDateInfo: boolean, + itemStartDate: NullableString, + itemEndDate: NullableString, + addMiscInfo: (val: MiscInfo) => void +): void { + let programTimeText = ''; + let date; + + if (showProgramTimeInfo && itemStartDate) { + try { + date = datetime.parseISO8601Date(itemStartDate); + + if (showStartDateInfo) { + programTimeText += datetime.toLocaleDateString(date, { + weekday: 'short', + month: 'short', + day: 'numeric' + }); + } + + programTimeText += ` ${datetime.getDisplayTime(date)}`; + + if (showEndDateInfo && itemEndDate) { + date = datetime.parseISO8601Date(itemEndDate); + programTimeText += ` - ${datetime.getDisplayTime(date)}`; + } + addMiscInfo({ text: programTimeText }); + } catch (e) { + console.error('error parsing date:', itemStartDate); + } + } +} + +function addChannelNumber( + showChannelNumberInfo: boolean, + itemChannelNumber: NullableString, + addMiscInfo: (val: MiscInfo) => void +): void { + if (showChannelNumberInfo && itemChannelNumber) { + addMiscInfo({ + text: `CH ${itemChannelNumber}` + }); + } +} + +const addChannelName = ( + showChannelInfo: boolean, + channelInteractive: boolean, + item: ItemDto, + addMiscInfo: (val: MiscInfo) => void +) => { + if (showChannelInfo && item.ChannelName) { + if (channelInteractive && item.ChannelId) { + const url = appRouter.getRouteUrl({ + ServerId: item.ServerId, + Type: ItemKind.TvChannel, + Name: item.ChannelName, + Id: item.ChannelId + }); + + addMiscInfo({ + textAction: { + url, + title: item.ChannelName + } + }); + } else { + addMiscInfo({ text: item.ChannelName }); + } + } +}; + +interface UseSecondaryMediaInfoProps extends SecondaryInfoOpts { + item: ItemDto; +} + +function useSecondaryMediaInfo({ + item, + showProgramTimeInfo = false, + showStartDateInfo = false, + showEndDateInfo = false, + showChannelNumberInfo = false, + showChannelInfo = false, + channelInteractive = false +}: UseSecondaryMediaInfoProps) { + const { EndDate, StartDate, ChannelNumber } = item; + + const miscInfo: MiscInfo[] = []; + + if (item.Type === ItemKind.Program) { + const addMiscInfo = (val: MiscInfo) => { + if (val) { + miscInfo.push(val); + } + }; + + addProgramTime( + showProgramTimeInfo, + showStartDateInfo, + showEndDateInfo, + StartDate, + EndDate, + addMiscInfo + ); + + addChannelNumber(showChannelNumberInfo, ChannelNumber, addMiscInfo); + + addChannelName(showChannelInfo, channelInteractive, item, addMiscInfo); + } + return miscInfo; +} + +export default useSecondaryMediaInfo; diff --git a/src/types/mediaInfoItem.ts b/src/types/mediaInfoItem.ts index 3620fad620..e8c3dc168d 100644 --- a/src/types/mediaInfoItem.ts +++ b/src/types/mediaInfoItem.ts @@ -1,4 +1,10 @@ -export interface MiscInfo { - text?: string | number; +interface TextAction { + url: string; + title: string; + cssClass?: string; +} +export interface MiscInfo { + text?: string | number; + textAction?: TextAction; cssClass?: string; }