mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
Add Secondary Media Info
This commit is contained in:
parent
fabfb9b173
commit
82d70763bb
5 changed files with 218 additions and 10 deletions
|
@ -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<MediaInfoItemProps> = ({ className, miscInfo }) => {
|
||||
const cssClass = classNames(
|
||||
'mediaInfoItem',
|
||||
className,
|
||||
miscInfo?.cssClass
|
||||
);
|
||||
const { text, textAction, cssClass } = miscInfo;
|
||||
|
||||
const renderText = () => {
|
||||
if (textAction) {
|
||||
return (
|
||||
<Link
|
||||
className={classNames(textAction.cssClass, className)}
|
||||
href={textAction.url}
|
||||
title={textAction.title}
|
||||
color='inherit'
|
||||
>
|
||||
{textAction.title}
|
||||
</Link>
|
||||
);
|
||||
} else {
|
||||
return text;
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Box className={cssClass}>
|
||||
{miscInfo?.text}
|
||||
<Box className={classNames('mediaInfoItem', cssClass, className)}>
|
||||
{renderText()}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
|
55
src/components/mediainfo/SecondaryMediaInfo.tsx
Normal file
55
src/components/mediainfo/SecondaryMediaInfo.tsx
Normal file
|
@ -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<SecondaryMediaInfoProps> = ({
|
||||
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) => (
|
||||
<MediaInfoItem key={index} className={infoclass} miscInfo={info} />
|
||||
);
|
||||
|
||||
return (
|
||||
<Box className={cssClass}>
|
||||
{miscInfo.map((info, index) => renderMediaInfo(info, index))}
|
||||
|
||||
{showTimerIndicatorInfo !== false && indicator.getTimerIndicator()}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default SecondaryMediaInfo;
|
|
@ -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;
|
||||
}
|
||||
|
|
124
src/components/mediainfo/useSecondaryMediaInfo.tsx
Normal file
124
src/components/mediainfo/useSecondaryMediaInfo.tsx
Normal file
|
@ -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;
|
Loading…
Add table
Add a link
Reference in a new issue