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

Merge pull request #5850 from grafixeyehero/move-reusable-component

Move reusable Text Lines component to common file
This commit is contained in:
Bill Thornton 2024-08-20 16:31:17 -04:00 committed by GitHub
commit 3e8592e29e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 172 additions and 103 deletions

View file

@ -0,0 +1,74 @@
import React, { type FC, type PropsWithChildren } from 'react';
import classNames from 'classnames';
import Typography from '@mui/material/Typography';
import Box from '@mui/material/Box';
import useTextLines from './useTextLines';
import type { ItemDto } from 'types/base/models/item-dto';
import type { TextLine, TextLineOpts } from './types';
interface TextWrapperProps {
isHeading?: boolean;
isLargeStyle?: boolean;
className?: string;
}
const TextWrapper: FC<PropsWithChildren<TextWrapperProps>> = ({
isHeading,
isLargeStyle,
className,
children
}) => {
if (isHeading) {
return (
<Typography className={classNames('primary', className)} variant={isLargeStyle ? 'h1' : 'h3'}>
{children}
</Typography>
);
} else {
return (
<Box className={classNames('secondary', className )}>
{children}
</Box>
);
}
};
interface TextLinesProps {
item: ItemDto;
textLineOpts?: TextLineOpts;
isLargeStyle?: boolean;
className?: string;
textClassName?: string;
}
const TextLines: FC<TextLinesProps> = ({
item,
textLineOpts,
isLargeStyle,
className,
textClassName
}) => {
const { textLines } = useTextLines({ item, textLineOpts });
const renderTextlines = (text: TextLine, index: number) => {
return (
<TextWrapper
key={index}
isHeading={index === 0}
isLargeStyle={isLargeStyle}
className={textClassName}
>
<bdi>{text.title}</bdi>
</TextWrapper>
);
};
return (
<Box className={className}>
{textLines?.map((text, index) => renderTextlines(text, index))}
</Box>
);
};
export default TextLines;

View file

@ -0,0 +1,18 @@
export interface TextLine {
title?: string;
cssClass?: string;
}
export interface TextLineOpts {
showProgramDateTime?: boolean;
showProgramTime?: boolean;
showChannel?: boolean;
showTitle?: boolean;
showParentTitle?: boolean;
showIndexNumber?: boolean;
parentTitleWithTitle?: boolean;
showArtist?: boolean;
showCurrentProgram?: boolean;
includeIndexNumber?: boolean;
includeParentInfoInTitle?: boolean;
}

View file

@ -0,0 +1,160 @@
import itemHelper from '../../itemHelper';
import datetime from 'scripts/datetime';
import type { ItemDto } from 'types/base/models/item-dto';
import type { TextLine, TextLineOpts } from './types';
import { ItemKind } from 'types/base/models/item-kind';
function getParentTitle(
item: ItemDto,
showParentTitle: boolean | undefined,
parentTitleWithTitle: boolean | undefined,
displayName: string | null | undefined
) {
let parentTitle;
if (showParentTitle) {
if (item.Type === ItemKind.Season || item.Type === ItemKind.Episode) {
parentTitle = item.SeriesName;
} else if (item.IsSeries || (item.EpisodeTitle && item.Name)) {
parentTitle = item.Name;
}
}
if (showParentTitle && parentTitleWithTitle) {
if (displayName && parentTitle) {
parentTitle += ' - ';
}
parentTitle = (parentTitle ?? '') + displayName;
}
return parentTitle;
}
function getNameOrIndexWithName(
item: ItemDto,
showIndexNumber?: boolean,
includeParentInfoInTitle?: boolean,
includeIndexNumber?: boolean
) {
let displayName = itemHelper.getDisplayName(item, {
includeParentInfo: includeParentInfoInTitle,
includeIndexNumber
});
if (showIndexNumber && item.IndexNumber != null) {
displayName = `${item.IndexNumber}. ${displayName}`;
}
return displayName;
}
interface UseTextLinesProps {
item: ItemDto;
textLineOpts?: TextLineOpts;
}
function useTextLines({ item, textLineOpts = {} }: UseTextLinesProps) {
const {
showTitle,
showProgramDateTime,
showProgramTime,
showChannel,
showParentTitle,
showIndexNumber,
parentTitleWithTitle,
showArtist,
showCurrentProgram,
includeParentInfoInTitle,
includeIndexNumber
} = textLineOpts;
const textLines: TextLine[] = [];
const addTextLine = (textLine: TextLine) => {
if (textLine) {
textLines.push(textLine);
}
};
const addProgramDateTime = () => {
if (showProgramDateTime) {
const programDateTime = datetime.toLocaleString(
datetime.parseISO8601Date(item.StartDate),
{
weekday: 'long',
month: 'short',
day: 'numeric',
hour: 'numeric',
minute: '2-digit'
}
);
addTextLine({ title: programDateTime });
}
};
const addProgramTime = () => {
if (showProgramTime) {
const programTime = datetime.getDisplayTime(
datetime.parseISO8601Date(item.StartDate)
);
addTextLine({ title: programTime });
}
};
const addChannelName = () => {
if (showChannel && item.ChannelName) {
addTextLine({ title: item.ChannelName });
}
};
const displayName = getNameOrIndexWithName(item, showIndexNumber, includeParentInfoInTitle, includeIndexNumber);
const parentTitle = getParentTitle(item, showParentTitle, parentTitleWithTitle, displayName );
const addParentTitle = () => {
if (parentTitle) {
addTextLine({ title: parentTitle });
}
};
const addDisplayName = () => {
if (displayName && !parentTitleWithTitle && showTitle !== false) {
addTextLine({ title: displayName });
}
};
const addAlbumArtistOrArtists = () => {
if (item.IsFolder && showArtist !== false) {
if (item.AlbumArtist && item.Type === ItemKind.MusicAlbum) {
addTextLine({ title: item.AlbumArtist });
}
} else if (showArtist) {
const artistItems = item.ArtistItems;
if (artistItems && item.Type !== ItemKind.MusicAlbum) {
const artists = artistItems.map((a) => a.Name).join(', ');
addTextLine({ title: artists });
}
}
};
const addCurrentProgram = () => {
if (item.Type === ItemKind.TvChannel && item.CurrentProgram && showCurrentProgram !== false) {
const currentProgram = itemHelper.getDisplayName(item.CurrentProgram, {
includeParentInfo: includeParentInfoInTitle,
includeIndexNumber
});
addTextLine({ title: currentProgram });
}
};
addProgramDateTime();
addProgramTime();
addChannelName();
addParentTitle();
addDisplayName();
addAlbumArtistOrArtists();
addCurrentProgram();
return {
textLines
};
}
export default useTextLines;