Add TypeScript support for React components
This commit is contained in:
parent
0dde17fbd7
commit
4d23e79f65
16 changed files with 810 additions and 107 deletions
276
src/components/search/SearchResults.tsx
Normal file
276
src/components/search/SearchResults.tsx
Normal file
|
@ -0,0 +1,276 @@
|
|||
import classNames from 'classnames';
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { FunctionComponent, useEffect, useState } from 'react';
|
||||
|
||||
import globalize from '../../scripts/globalize';
|
||||
import ServerConnections from '../ServerConnections';
|
||||
import SearchResultsRow from './SearchResultsRow';
|
||||
|
||||
type SearchResultsProps = {
|
||||
serverId: string;
|
||||
parentId: string;
|
||||
collectionType: string;
|
||||
query: string;
|
||||
}
|
||||
|
||||
/*
|
||||
* React component to display search result rows for global search and non-live tv library search
|
||||
*/
|
||||
const SearchResults: FunctionComponent<SearchResultsProps> = ({ serverId, parentId, collectionType, query }) => {
|
||||
const [ movies, setMovies ] = useState([]);
|
||||
const [ shows, setShows ] = useState([]);
|
||||
const [ episodes, setEpisodes ] = useState([]);
|
||||
const [ videos, setVideos ] = useState([]);
|
||||
const [ programs, setPrograms ] = useState([]);
|
||||
const [ channels, setChannels ] = useState([]);
|
||||
const [ playlists, setPlaylists ] = useState([]);
|
||||
const [ artists, setArtists ] = useState([]);
|
||||
const [ albums, setAlbums ] = useState([]);
|
||||
const [ songs, setSongs ] = useState([]);
|
||||
const [ photoAlbums, setPhotoAlbums ] = useState([]);
|
||||
const [ photos, setPhotos ] = useState([]);
|
||||
const [ audioBooks, setAudioBooks ] = useState([]);
|
||||
const [ books, setBooks ] = useState([]);
|
||||
const [ people, setPeople ] = useState([]);
|
||||
|
||||
useEffect(() => {
|
||||
const getDefaultParameters = () => ({
|
||||
ParentId: parentId,
|
||||
searchTerm: query,
|
||||
Limit: 24,
|
||||
Fields: 'PrimaryImageAspectRatio,CanDelete,BasicSyncInfo,MediaSourceCount',
|
||||
Recursive: true,
|
||||
EnableTotalRecordCount: false,
|
||||
ImageTypeLimit: 1,
|
||||
IncludePeople: false,
|
||||
IncludeMedia: false,
|
||||
IncludeGenres: false,
|
||||
IncludeStudios: false,
|
||||
IncludeArtists: false
|
||||
});
|
||||
|
||||
const fetchArtists = (apiClient, params = {}) => apiClient?.getArtists(
|
||||
apiClient?.getCurrentUserId(),
|
||||
{
|
||||
...getDefaultParameters(),
|
||||
IncludeArtists: true,
|
||||
...params
|
||||
}
|
||||
);
|
||||
|
||||
const fetchItems = (apiClient, params = {}) => apiClient?.getItems(
|
||||
apiClient?.getCurrentUserId(),
|
||||
{
|
||||
...getDefaultParameters(),
|
||||
IncludeMedia: true,
|
||||
...params
|
||||
}
|
||||
);
|
||||
|
||||
const fetchPeople = (apiClient, params = {}) => apiClient?.getPeople(
|
||||
apiClient?.getCurrentUserId(),
|
||||
{
|
||||
...getDefaultParameters(),
|
||||
IncludePeople: true,
|
||||
...params
|
||||
}
|
||||
);
|
||||
|
||||
const isMovies = () => collectionType === 'movies';
|
||||
|
||||
const isMusic = () => collectionType === 'music';
|
||||
|
||||
const isTVShows = () => collectionType === 'tvshows' || collectionType === 'tv';
|
||||
|
||||
// Reset state
|
||||
setMovies([]);
|
||||
setShows([]);
|
||||
setEpisodes([]);
|
||||
setVideos([]);
|
||||
setPrograms([]);
|
||||
setChannels([]);
|
||||
setPlaylists([]);
|
||||
setArtists([]);
|
||||
setAlbums([]);
|
||||
setSongs([]);
|
||||
setPhotoAlbums([]);
|
||||
setPhotos([]);
|
||||
setAudioBooks([]);
|
||||
setBooks([]);
|
||||
setPeople([]);
|
||||
|
||||
if (query) {
|
||||
// TODO: Remove type casting once we're using a properly typed API client
|
||||
const apiClient = (ServerConnections as any).getApiClient(serverId);
|
||||
|
||||
// Movie libraries
|
||||
if (!collectionType || isMovies()) {
|
||||
// Movies row
|
||||
fetchItems(apiClient, { IncludeItemTypes: 'Movie' })
|
||||
.then(result => setMovies(result.Items));
|
||||
}
|
||||
|
||||
// TV Show libraries
|
||||
if (!collectionType || isTVShows()) {
|
||||
// Shows row
|
||||
fetchItems(apiClient, { IncludeItemTypes: 'Series' })
|
||||
.then(result => setShows(result.Items));
|
||||
// Episodes row
|
||||
fetchItems(apiClient, { IncludeItemTypes: 'Episode' })
|
||||
.then(result => setEpisodes(result.Items));
|
||||
}
|
||||
|
||||
// People are included for Movies and TV Shows
|
||||
if (!collectionType || isMovies() || isTVShows()) {
|
||||
// People row
|
||||
fetchPeople(apiClient).then(result => setPeople(result.Items));
|
||||
}
|
||||
|
||||
// Music libraries
|
||||
if (!collectionType || isMusic()) {
|
||||
// Playlists row
|
||||
fetchItems(apiClient, { IncludeItemTypes: 'Playlist' })
|
||||
.then(results => setPlaylists(results.Items));
|
||||
// Artists row
|
||||
fetchArtists(apiClient).then(result => setArtists(result.Items));
|
||||
// Albums row
|
||||
fetchItems(apiClient, { IncludeItemTypes: 'MusicAlbum' })
|
||||
.then(result => setAlbums(result.Items));
|
||||
// Songs row
|
||||
fetchItems(apiClient, { IncludeItemTypes: 'Audio' })
|
||||
.then(result => setSongs(result.Items));
|
||||
}
|
||||
|
||||
// Other libraries do not support in-library search currently
|
||||
if (!collectionType) {
|
||||
// Videos row
|
||||
fetchItems(apiClient, {
|
||||
MediaTypes: 'Video',
|
||||
ExcludeItemTypes: 'Movie,Episode,TvChannel'
|
||||
}).then(result => setVideos(result.Items));
|
||||
// Programs row
|
||||
fetchItems(apiClient, { IncludeItemTypes: 'LiveTvProgram' })
|
||||
.then(result => setPrograms(result.Items));
|
||||
// Channels row
|
||||
fetchItems(apiClient, { IncludeItemTypes: 'TvChannel' })
|
||||
.then(result => setChannels(result.Items));
|
||||
// Photo Albums row
|
||||
fetchItems(apiClient, { IncludeItemTypes: 'PhotoAlbum' })
|
||||
.then(results => setPhotoAlbums(results.Items));
|
||||
// Photos row
|
||||
fetchItems(apiClient, { IncludeItemTypes: 'Photo' })
|
||||
.then(results => setPhotos(results.Items));
|
||||
// Audio Books row
|
||||
fetchItems(apiClient, { IncludeItemTypes: 'AudioBook' })
|
||||
.then(results => setAudioBooks(results.Items));
|
||||
// Books row
|
||||
fetchItems(apiClient, { IncludeItemTypes: 'Book' })
|
||||
.then(results => setBooks(results.Items));
|
||||
}
|
||||
}
|
||||
}, [collectionType, parentId, query, serverId]);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classNames(
|
||||
'searchResults',
|
||||
'padded-bottom-page',
|
||||
'padded-top',
|
||||
{ 'hide': !query || collectionType === 'livetv' }
|
||||
)}
|
||||
>
|
||||
<SearchResultsRow
|
||||
title={globalize.translate('Movies')}
|
||||
items={movies}
|
||||
cardOptions={{ showYear: true }}
|
||||
/>
|
||||
<SearchResultsRow
|
||||
title={globalize.translate('Shows')}
|
||||
items={shows}
|
||||
cardOptions={{ showYear: true }}
|
||||
/>
|
||||
<SearchResultsRow
|
||||
title={globalize.translate('Episodes')}
|
||||
items={episodes}
|
||||
cardOptions={{
|
||||
coverImage: true,
|
||||
showParentTitle: true
|
||||
}}
|
||||
/>
|
||||
<SearchResultsRow
|
||||
title={globalize.translate('HeaderVideos')}
|
||||
items={videos}
|
||||
cardOptions={{ showParentTitle: true }}
|
||||
/>
|
||||
<SearchResultsRow
|
||||
title={globalize.translate('Programs')}
|
||||
items={programs}
|
||||
cardOptions={{
|
||||
preferThumb: true,
|
||||
inheritThumb: false,
|
||||
showParentTitleOrTitle: true,
|
||||
showTitle: false,
|
||||
coverImage: true,
|
||||
overlayMoreButton: true,
|
||||
showAirTime: true,
|
||||
showAirDateTime: true,
|
||||
showChannelName: true
|
||||
}}
|
||||
/>
|
||||
<SearchResultsRow
|
||||
title={globalize.translate('Channels')}
|
||||
items={channels}
|
||||
cardOptions={{ shape: 'square' }}
|
||||
/>
|
||||
<SearchResultsRow
|
||||
title={globalize.translate('Playlists')}
|
||||
items={playlists}
|
||||
/>
|
||||
<SearchResultsRow
|
||||
title={globalize.translate('Artists')}
|
||||
items={artists}
|
||||
cardOptions={{ coverImage: true }}
|
||||
/>
|
||||
<SearchResultsRow
|
||||
title={globalize.translate('Albums')}
|
||||
items={albums}
|
||||
cardOptions={{ showParentTitle: true }}
|
||||
/>
|
||||
<SearchResultsRow
|
||||
title={globalize.translate('Songs')}
|
||||
items={songs}
|
||||
cardOptions={{ showParentTitle: true }}
|
||||
/>
|
||||
<SearchResultsRow
|
||||
title={globalize.translate('HeaderPhotoAlbums')}
|
||||
items={photoAlbums}
|
||||
/>
|
||||
<SearchResultsRow
|
||||
title={globalize.translate('Photos')}
|
||||
items={photos}
|
||||
/>
|
||||
<SearchResultsRow
|
||||
title={globalize.translate('HeaderAudioBooks')}
|
||||
items={audioBooks}
|
||||
/>
|
||||
<SearchResultsRow
|
||||
title={globalize.translate('Books')}
|
||||
items={books}
|
||||
/>
|
||||
<SearchResultsRow
|
||||
title={globalize.translate('People')}
|
||||
items={people}
|
||||
cardOptions={{ coverImage: true }}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
SearchResults.propTypes = {
|
||||
serverId: PropTypes.string,
|
||||
parentId: PropTypes.string,
|
||||
collectionType: PropTypes.string,
|
||||
query: PropTypes.string
|
||||
};
|
||||
|
||||
export default SearchResults;
|
Loading…
Add table
Add a link
Reference in a new issue