gdq-archive/frontend/components/VideoList.tsx

118 lines
3.4 KiB
TypeScript
Raw Normal View History

2021-01-05 15:25:09 +00:00
/**
* Copyright (C) 2019-2021 Carl Kittelberger <icedream@icedream.pw>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
2020-08-22 20:25:57 +00:00
import React, { ChangeEvent } from 'react';
import FormControl from 'react-bootstrap/FormControl';
import InputGroup from 'react-bootstrap/InputGroup';
import ListGroup from 'react-bootstrap/ListGroup';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { injectIntl, IntlShape } from 'react-intl';
import VideoListItem from './VideoListItem';
import Filter from './Filter';
import { VideoEntry } from '../util/datatypes/VideoList';
interface VideoListProps {
intl: IntlShape,
id: string,
thumbnailServerURL: string,
videos: Array<VideoEntry>,
}
interface VideoListState {
query: string
}
class VideoList extends React.Component<VideoListProps, VideoListState> {
constructor(props: VideoListProps) {
super(props);
this.state = {
query: '',
};
this.onQueryChange = this.onQueryChange.bind(this);
}
onQueryChange({ target }: ChangeEvent<HTMLInputElement>) {
this.setState({
query: target.value,
});
}
render() {
const { query } = this.state;
const {
intl,
id,
thumbnailServerURL,
videos,
} = this.props;
return (
<div>
<InputGroup>
<InputGroup.Prepend>
<InputGroup.Text id="search-prepend">
<FontAwesomeIcon icon="search" />
</InputGroup.Text>
</InputGroup.Prepend>
<FormControl
placeholder={intl.formatMessage({ id: 'VideoList.Search.Placeholder', defaultMessage: 'Type something to search here…' })}
aria-label={intl.formatMessage({ id: 'VideoList.Search.Label', defaultMessage: 'Search' })}
aria-describedby="search-prepend"
value={query}
onChange={this.onQueryChange}
/>
</InputGroup>
<ListGroup>
<Filter
items={videos}
query={query}
keys={['title', 'fileName']}
output={(filteredVideos) => filteredVideos.map(({
item: {
duration,
fileName,
title,
slug,
2020-08-22 20:25:57 +00:00
sourceVideoStart,
sourceVideoEnd,
},
refIndex: index,
}) => (
2021-01-03 17:52:55 +00:00
<VideoListItem
key={index}
duration={duration}
id={id}
thumbnailServerURL={thumbnailServerURL}
fileName={fileName}
slug={slug}
2021-01-03 17:52:55 +00:00
title={title}
sourceVideoStart={sourceVideoStart}
sourceVideoEnd={sourceVideoEnd}
/>
))}
2020-08-22 20:25:57 +00:00
/>
</ListGroup>
</div>
);
}
}
export default injectIntl(VideoList);