import React, { useCallback, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { useSelect } from 'App/SelectContext'; import { MOVIE_SEARCH, REFRESH_MOVIE } from 'Commands/commandNames'; import Icon from 'Components/Icon'; import ImdbRating from 'Components/ImdbRating'; import IconButton from 'Components/Link/IconButton'; import SpinnerIconButton from 'Components/Link/SpinnerIconButton'; import MovieTagList from 'Components/MovieTagList'; import RottenTomatoRating from 'Components/RottenTomatoRating'; import RelativeDateCell from 'Components/Table/Cells/RelativeDateCell'; import VirtualTableRowCell from 'Components/Table/Cells/VirtualTableRowCell'; import VirtualTableSelectCell from 'Components/Table/Cells/VirtualTableSelectCell'; import Column from 'Components/Table/Column'; import TmdbRating from 'Components/TmdbRating'; import Tooltip from 'Components/Tooltip/Tooltip'; import TraktRating from 'Components/TraktRating'; import { icons, kinds } from 'Helpers/Props'; import DeleteMovieModal from 'Movie/Delete/DeleteMovieModal'; import MovieDetailsLinks from 'Movie/Details/MovieDetailsLinks'; import EditMovieModal from 'Movie/Edit/EditMovieModal'; import createMovieIndexItemSelector from 'Movie/Index/createMovieIndexItemSelector'; import { Statistics } from 'Movie/Movie'; import MoviePopularityIndex from 'Movie/MoviePopularityIndex'; import MovieTitleLink from 'Movie/MovieTitleLink'; import { executeCommand } from 'Store/Actions/commandActions'; import createUISettingsSelector from 'Store/Selectors/createUISettingsSelector'; import { SelectStateInputProps } from 'typings/props'; import formatRuntime from 'Utilities/Date/formatRuntime'; import formatBytes from 'Utilities/Number/formatBytes'; import firstCharToUpper from 'Utilities/String/firstCharToUpper'; import translate from 'Utilities/String/translate'; import MovieIndexProgressBar from '../ProgressBar/MovieIndexProgressBar'; import MovieStatusCell from './MovieStatusCell'; import selectTableOptions from './selectTableOptions'; import styles from './MovieIndexRow.css'; interface MovieIndexRowProps { movieId: number; sortKey: string; columns: Column[]; isSelectMode: boolean; } function MovieIndexRow(props: MovieIndexRowProps) { const { movieId, columns, isSelectMode } = props; const { movie, qualityProfile, isRefreshingMovie, isSearchingMovie } = useSelector(createMovieIndexItemSelector(props.movieId)); const { showSearchAction } = useSelector(selectTableOptions); const { movieRuntimeFormat } = useSelector(createUISettingsSelector()); const { monitored, titleSlug, title, collection, studio, status, originalLanguage, originalTitle, added, statistics = {} as Statistics, year, inCinemas, digitalRelease, physicalRelease, releaseDate, runtime, minimumAvailability, path, genres = [], keywords = [], ratings, popularity, certification, tags = [], tmdbId, imdbId, isAvailable, dateConsideredAvailable, hasFile, movieFile, youTubeTrailerId, isSaving = false, } = movie; const { sizeOnDisk = 0, releaseGroups = [] } = statistics; const dispatch = useDispatch(); const [isEditMovieModalOpen, setIsEditMovieModalOpen] = useState(false); const [isDeleteMovieModalOpen, setIsDeleteMovieModalOpen] = useState(false); const [selectState, selectDispatch] = useSelect(); const onRefreshPress = useCallback(() => { dispatch( executeCommand({ name: REFRESH_MOVIE, movieIds: [movieId], }) ); }, [movieId, dispatch]); const onSearchPress = useCallback(() => { dispatch( executeCommand({ name: MOVIE_SEARCH, movieIds: [movieId], }) ); }, [movieId, dispatch]); const onEditMoviePress = useCallback(() => { setIsEditMovieModalOpen(true); }, [setIsEditMovieModalOpen]); const onEditMovieModalClose = useCallback(() => { setIsEditMovieModalOpen(false); }, [setIsEditMovieModalOpen]); const onDeleteMoviePress = useCallback(() => { setIsEditMovieModalOpen(false); setIsDeleteMovieModalOpen(true); }, [setIsDeleteMovieModalOpen]); const onDeleteMovieModalClose = useCallback(() => { setIsDeleteMovieModalOpen(false); }, [setIsDeleteMovieModalOpen]); const onSelectedChange = useCallback( ({ id, value, shiftKey }: SelectStateInputProps) => { selectDispatch({ type: 'toggleSelected', id, isSelected: value, shiftKey, }); }, [selectDispatch] ); return ( <> {isSelectMode ? ( ) : null} {columns.map((column) => { const { name, isVisible } = column; if (!isVisible) { return null; } if (name === 'status') { return ( ); } if (name === 'sortTitle') { return ( ); } if (name === 'collection') { return ( {collection ? collection.title : null} ); } if (name === 'studio') { return ( {studio} ); } if (name === 'originalLanguage') { return ( {originalLanguage.name} ); } if (name === 'originalTitle') { return ( {originalTitle} ); } if (name === 'qualityProfileId') { return ( {qualityProfile?.name ?? ''} ); } if (name === 'added') { return ( // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore ts(2739) ); } if (name === 'year') { return ( {year > 0 ? year : null} ); } if (name === 'inCinemas') { return ( // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore ts(2739) ); } if (name === 'digitalRelease') { return ( // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore ts(2739) ); } if (name === 'physicalRelease') { return ( // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore ts(2739) ); } if (name === 'releaseDate') { return ( // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore ts(2739) ); } if (name === 'runtime') { return ( {formatRuntime(runtime, movieRuntimeFormat)} ); } if (name === 'minimumAvailability') { return ( {translate(firstCharToUpper(minimumAvailability))} ); } if (name === 'path') { return ( {path} ); } if (name === 'sizeOnDisk') { return ( {formatBytes(sizeOnDisk)} ); } if (name === 'genres') { const joinedGenres = genres.join(', '); return ( {joinedGenres} ); } if (name === 'keywords') { const joinedKeywords = keywords.join(', '); const truncatedKeywords = keywords.length > 3 ? `${keywords.slice(0, 3).join(', ')}...` : joinedKeywords; return ( {truncatedKeywords} ); } if (name === 'movieStatus') { return ( ); } if (name === 'tmdbRating') { return ( {ratings.tmdb ? : null} ); } if (name === 'imdbRating') { return ( {ratings.imdb ? : null} ); } if (name === 'rottenTomatoesRating') { return ( {ratings.rottenTomatoes ? ( ) : null} ); } if (name === 'traktRating') { return ( {ratings.trakt ? : null} ); } if (name === 'popularity') { return ( ); } if (name === 'certification') { return ( {certification} ); } if (name === 'releaseGroups') { const joinedReleaseGroups = releaseGroups.join(', '); const truncatedReleaseGroups = releaseGroups.length > 3 ? `${releaseGroups.slice(0, 3).join(', ')}...` : joinedReleaseGroups; return ( {truncatedReleaseGroups} ); } if (name === 'tags') { return ( ); } if (name === 'actions') { return ( } tooltip={ } canFlip={true} kind={kinds.INVERSE} /> {showSearchAction ? ( ) : null} ); } return null; })} ); } export default MovieIndexRow;