JSX component for api requests
This commit is contained in:
		
							
								
								
									
										48
									
								
								src/elements/APIComponent.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								src/elements/APIComponent.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,48 @@
 | 
				
			|||||||
 | 
					import React from 'react';
 | 
				
			||||||
 | 
					import {APINode, callAPI} from '../utils/Api';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface Props<T> {
 | 
				
			||||||
 | 
					    onLoad?: JSX.Element;
 | 
				
			||||||
 | 
					    render: (data: T, actions: {refresh: () => void}) => JSX.Element;
 | 
				
			||||||
 | 
					    node: APINode;
 | 
				
			||||||
 | 
					    action: string;
 | 
				
			||||||
 | 
					    params?: {[_: string]: string | number | boolean | object};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface State {
 | 
				
			||||||
 | 
					    loaded: boolean;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default class APIComponent<T> extends React.Component<Props<T>, State> {
 | 
				
			||||||
 | 
					    state = {
 | 
				
			||||||
 | 
					        loaded: false
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    data: T | undefined;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    render(): JSX.Element {
 | 
				
			||||||
 | 
					        if (this.state.loaded && this.data !== undefined) {
 | 
				
			||||||
 | 
					            return this.props.render(this.data, {refresh: () => this.loadData()});
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            return this.props.onLoad ? this.props.onLoad : <></>;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    componentDidMount(): void {
 | 
				
			||||||
 | 
					        this.loadData();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    componentDidUpdate(prevProps: Readonly<Props<T>>): void {
 | 
				
			||||||
 | 
					        if (prevProps.params !== this.props.params) {
 | 
				
			||||||
 | 
					            this.loadData();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private loadData(): void {
 | 
				
			||||||
 | 
					        this.setState({loaded: false});
 | 
				
			||||||
 | 
					        callAPI(this.props.node, {action: this.props.action, ...this.props.params}, (result: T) => {
 | 
				
			||||||
 | 
					            this.data = result;
 | 
				
			||||||
 | 
					            this.setState({loaded: true});
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										32
									
								
								src/elements/KeyComponent.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								src/elements/KeyComponent.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,32 @@
 | 
				
			|||||||
 | 
					import React from 'react';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface Props {
 | 
				
			||||||
 | 
					    listenKey: string;
 | 
				
			||||||
 | 
					    onKey: () => void;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default class KeyComponent extends React.Component<Props> {
 | 
				
			||||||
 | 
					    constructor(props: Props) {
 | 
				
			||||||
 | 
					        super(props);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this.handler = this.handler.bind(this);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    render(): JSX.Element {
 | 
				
			||||||
 | 
					        return <>{this.props.children}</>;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    componentDidMount(): void {
 | 
				
			||||||
 | 
					        document.addEventListener('keyup', this.handler);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    componentWillUnmount(): void {
 | 
				
			||||||
 | 
					        document.removeEventListener('keyup', this.handler);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private handler(e: KeyboardEvent): void {
 | 
				
			||||||
 | 
					        if (e.key === this.props.listenKey) {
 | 
				
			||||||
 | 
					            this.props.onKey();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -5,7 +5,7 @@ import VideoContainer from '../../elements/VideoContainer/VideoContainer';
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import style from './HomePage.module.css';
 | 
					import style from './HomePage.module.css';
 | 
				
			||||||
import PageTitle, {Line} from '../../elements/PageTitle/PageTitle';
 | 
					import PageTitle, {Line} from '../../elements/PageTitle/PageTitle';
 | 
				
			||||||
import {APINode, callAPI} from '../../utils/Api';
 | 
					import {APINode} from '../../utils/Api';
 | 
				
			||||||
import {Route, Switch, withRouter} from 'react-router-dom';
 | 
					import {Route, Switch, withRouter} from 'react-router-dom';
 | 
				
			||||||
import {RouteComponentProps} from 'react-router';
 | 
					import {RouteComponentProps} from 'react-router';
 | 
				
			||||||
import SearchHandling from './SearchHandling';
 | 
					import SearchHandling from './SearchHandling';
 | 
				
			||||||
@@ -13,6 +13,8 @@ import {VideoTypes} from '../../types/ApiTypes';
 | 
				
			|||||||
import {DefaultTags} from '../../types/GeneralTypes';
 | 
					import {DefaultTags} from '../../types/GeneralTypes';
 | 
				
			||||||
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
 | 
					import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
 | 
				
			||||||
import {faSortDown} from '@fortawesome/free-solid-svg-icons';
 | 
					import {faSortDown} from '@fortawesome/free-solid-svg-icons';
 | 
				
			||||||
 | 
					import APIComponent from '../../elements/APIComponent';
 | 
				
			||||||
 | 
					import {TagType} from '../../types/VideoTypes';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// eslint-disable-next-line no-shadow
 | 
					// eslint-disable-next-line no-shadow
 | 
				
			||||||
export enum SortBy {
 | 
					export enum SortBy {
 | 
				
			||||||
@@ -26,11 +28,10 @@ export enum SortBy {
 | 
				
			|||||||
interface Props extends RouteComponentProps {}
 | 
					interface Props extends RouteComponentProps {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
interface state {
 | 
					interface state {
 | 
				
			||||||
    sideinfo: VideoTypes.startDataType;
 | 
					 | 
				
			||||||
    subtitle: string;
 | 
					    subtitle: string;
 | 
				
			||||||
    data: VideoTypes.VideoUnloadedType[];
 | 
					 | 
				
			||||||
    selectionnr: number;
 | 
					 | 
				
			||||||
    sortby: string;
 | 
					    sortby: string;
 | 
				
			||||||
 | 
					    sortState: SortBy;
 | 
				
			||||||
 | 
					    tagState: TagType;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@@ -40,71 +41,24 @@ export class HomePage extends React.Component<Props, state> {
 | 
				
			|||||||
    /** keyword variable needed temporary store search keyword */
 | 
					    /** keyword variable needed temporary store search keyword */
 | 
				
			||||||
    keyword = '';
 | 
					    keyword = '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    constructor(props: Props) {
 | 
					    state = {
 | 
				
			||||||
        super(props);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        this.state = {
 | 
					 | 
				
			||||||
            sideinfo: {
 | 
					 | 
				
			||||||
                VideoNr: 0,
 | 
					 | 
				
			||||||
                FullHdNr: 0,
 | 
					 | 
				
			||||||
                HDNr: 0,
 | 
					 | 
				
			||||||
                SDNr: 0,
 | 
					 | 
				
			||||||
                DifferentTags: 0,
 | 
					 | 
				
			||||||
                Tagged: 0
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
        subtitle: 'All Videos',
 | 
					        subtitle: 'All Videos',
 | 
				
			||||||
            data: [],
 | 
					        sortby: 'Date Added',
 | 
				
			||||||
            selectionnr: 0,
 | 
					        sortState: SortBy.date,
 | 
				
			||||||
            sortby: 'Date Added'
 | 
					        tagState: DefaultTags.all
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    sortState = SortBy.date;
 | 
					 | 
				
			||||||
    tagState = DefaultTags.all;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    componentDidMount(): void {
 | 
					 | 
				
			||||||
        // initial get of all videos
 | 
					 | 
				
			||||||
        this.fetchVideoData();
 | 
					 | 
				
			||||||
        this.fetchStartData();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * fetch available videos for specified tag
 | 
					 | 
				
			||||||
     * this function clears all preview elements an reloads gravity with tag
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @param tag tag to fetch videos
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    fetchVideoData(): void {
 | 
					 | 
				
			||||||
        callAPI(
 | 
					 | 
				
			||||||
            APINode.Video,
 | 
					 | 
				
			||||||
            {action: 'getMovies', Tag: this.tagState.TagId, Sort: this.sortState},
 | 
					 | 
				
			||||||
            (result: {Videos: VideoTypes.VideoUnloadedType[]; TagName: string}) => {
 | 
					 | 
				
			||||||
                this.setState({
 | 
					 | 
				
			||||||
                    data: result.Videos,
 | 
					 | 
				
			||||||
                    selectionnr: result.Videos.length
 | 
					 | 
				
			||||||
                });
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * fetch the necessary data for left info box
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    fetchStartData(): void {
 | 
					 | 
				
			||||||
        callAPI(APINode.Video, {action: 'getStartData'}, (result: VideoTypes.startDataType) => {
 | 
					 | 
				
			||||||
            this.setState({sideinfo: result});
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    render(): JSX.Element {
 | 
					    render(): JSX.Element {
 | 
				
			||||||
        return (
 | 
					        return (
 | 
				
			||||||
            <>
 | 
					 | 
				
			||||||
            <Switch>
 | 
					            <Switch>
 | 
				
			||||||
                <Route path='/search/:name'>
 | 
					                <Route path='/search/:name'>
 | 
				
			||||||
                    <SearchHandling />
 | 
					                    <SearchHandling />
 | 
				
			||||||
                </Route>
 | 
					                </Route>
 | 
				
			||||||
                <Route path='/'>
 | 
					                <Route path='/'>
 | 
				
			||||||
                        <PageTitle title='Home Page' subtitle={this.state.subtitle + ' - ' + this.state.selectionnr}>
 | 
					                    <APIComponent
 | 
				
			||||||
 | 
					                        render={(data: {Videos: VideoTypes.VideoUnloadedType[]; TagName: string}): JSX.Element => (
 | 
				
			||||||
 | 
					                            <>
 | 
				
			||||||
 | 
					                                <PageTitle title='Home Page' subtitle={this.state.subtitle + ' - ' + data.Videos.length}>
 | 
				
			||||||
                                    <form
 | 
					                                    <form
 | 
				
			||||||
                                        className={'form-inline ' + style.searchform}
 | 
					                                        className={'form-inline ' + style.searchform}
 | 
				
			||||||
                                        onSubmit={(e): void => {
 | 
					                                        onSubmit={(e): void => {
 | 
				
			||||||
@@ -126,57 +80,60 @@ export class HomePage extends React.Component<Props, state> {
 | 
				
			|||||||
                                    </form>
 | 
					                                    </form>
 | 
				
			||||||
                                </PageTitle>
 | 
					                                </PageTitle>
 | 
				
			||||||
                                <SideBar>
 | 
					                                <SideBar>
 | 
				
			||||||
 | 
					                                    <APIComponent
 | 
				
			||||||
 | 
					                                        render={(sidebardata: VideoTypes.startDataType): JSX.Element => (
 | 
				
			||||||
 | 
					                                            <>
 | 
				
			||||||
                                                <SideBarTitle>Infos:</SideBarTitle>
 | 
					                                                <SideBarTitle>Infos:</SideBarTitle>
 | 
				
			||||||
                                                <Line />
 | 
					                                                <Line />
 | 
				
			||||||
                                                <SideBarItem>
 | 
					                                                <SideBarItem>
 | 
				
			||||||
                                <b>{this.state.sideinfo.VideoNr}</b> Videos Total!
 | 
					                                                    <b>{sidebardata.VideoNr}</b> Videos Total!
 | 
				
			||||||
                                                </SideBarItem>
 | 
					                                                </SideBarItem>
 | 
				
			||||||
                                                <SideBarItem>
 | 
					                                                <SideBarItem>
 | 
				
			||||||
                                <b>{this.state.sideinfo.FullHdNr}</b> FULL-HD Videos!
 | 
					                                                    <b>{sidebardata.FullHdNr}</b> FULL-HD Videos!
 | 
				
			||||||
                                                </SideBarItem>
 | 
					                                                </SideBarItem>
 | 
				
			||||||
                                                <SideBarItem>
 | 
					                                                <SideBarItem>
 | 
				
			||||||
                                <b>{this.state.sideinfo.HDNr}</b> HD Videos!
 | 
					                                                    <b>{sidebardata.HDNr}</b> HD Videos!
 | 
				
			||||||
                                                </SideBarItem>
 | 
					                                                </SideBarItem>
 | 
				
			||||||
                                                <SideBarItem>
 | 
					                                                <SideBarItem>
 | 
				
			||||||
                                <b>{this.state.sideinfo.SDNr}</b> SD Videos!
 | 
					                                                    <b>{sidebardata.SDNr}</b> SD Videos!
 | 
				
			||||||
                                                </SideBarItem>
 | 
					                                                </SideBarItem>
 | 
				
			||||||
                                                <SideBarItem>
 | 
					                                                <SideBarItem>
 | 
				
			||||||
                                <b>{this.state.sideinfo.DifferentTags}</b> different Tags!
 | 
					                                                    <b>{sidebardata.DifferentTags}</b> different Tags!
 | 
				
			||||||
                                                </SideBarItem>
 | 
					                                                </SideBarItem>
 | 
				
			||||||
                                                <Line />
 | 
					                                                <Line />
 | 
				
			||||||
                                                <SideBarTitle>Default Tags:</SideBarTitle>
 | 
					                                                <SideBarTitle>Default Tags:</SideBarTitle>
 | 
				
			||||||
                                                <Tag
 | 
					                                                <Tag
 | 
				
			||||||
                                                    tagInfo={{TagName: 'All', TagId: DefaultTags.all.TagId}}
 | 
					                                                    tagInfo={{TagName: 'All', TagId: DefaultTags.all.TagId}}
 | 
				
			||||||
                                                    onclick={(): void => {
 | 
					                                                    onclick={(): void => {
 | 
				
			||||||
                                    this.tagState = DefaultTags.all;
 | 
					                                                        this.setState({tagState: DefaultTags.all, subtitle: 'All Videos'});
 | 
				
			||||||
                                    this.fetchVideoData();
 | 
					 | 
				
			||||||
                                    this.setState({subtitle: 'All Videos'});
 | 
					 | 
				
			||||||
                                                    }}
 | 
					                                                    }}
 | 
				
			||||||
                                                />
 | 
					                                                />
 | 
				
			||||||
                                                <Tag
 | 
					                                                <Tag
 | 
				
			||||||
                                                    tagInfo={{TagName: 'Full Hd', TagId: DefaultTags.fullhd.TagId}}
 | 
					                                                    tagInfo={{TagName: 'Full Hd', TagId: DefaultTags.fullhd.TagId}}
 | 
				
			||||||
                                                    onclick={(): void => {
 | 
					                                                    onclick={(): void => {
 | 
				
			||||||
                                    this.tagState = DefaultTags.fullhd;
 | 
					                                                        this.setState({tagState: DefaultTags.fullhd, subtitle: 'Full Hd Videos'});
 | 
				
			||||||
                                    this.fetchVideoData();
 | 
					 | 
				
			||||||
                                    this.setState({subtitle: 'Full Hd Videos'});
 | 
					 | 
				
			||||||
                                                    }}
 | 
					                                                    }}
 | 
				
			||||||
                                                />
 | 
					                                                />
 | 
				
			||||||
                                                <Tag
 | 
					                                                <Tag
 | 
				
			||||||
                                                    tagInfo={{TagName: 'Low Quality', TagId: DefaultTags.lowq.TagId}}
 | 
					                                                    tagInfo={{TagName: 'Low Quality', TagId: DefaultTags.lowq.TagId}}
 | 
				
			||||||
                                                    onclick={(): void => {
 | 
					                                                    onclick={(): void => {
 | 
				
			||||||
                                    this.tagState = DefaultTags.lowq;
 | 
					                                                        this.setState({
 | 
				
			||||||
                                    this.fetchVideoData();
 | 
					                                                            tagState: DefaultTags.lowq,
 | 
				
			||||||
                                    this.setState({subtitle: 'Low Quality Videos'});
 | 
					                                                            subtitle: 'Low Quality Videos'
 | 
				
			||||||
 | 
					                                                        });
 | 
				
			||||||
                                                    }}
 | 
					                                                    }}
 | 
				
			||||||
                                                />
 | 
					                                                />
 | 
				
			||||||
                                                <Tag
 | 
					                                                <Tag
 | 
				
			||||||
                                                    tagInfo={{TagName: 'HD', TagId: DefaultTags.hd.TagId}}
 | 
					                                                    tagInfo={{TagName: 'HD', TagId: DefaultTags.hd.TagId}}
 | 
				
			||||||
                                                    onclick={(): void => {
 | 
					                                                    onclick={(): void => {
 | 
				
			||||||
                                    this.tagState = DefaultTags.hd;
 | 
					                                                        this.setState({tagState: DefaultTags.hd, subtitle: 'HD Videos'});
 | 
				
			||||||
                                    this.fetchVideoData();
 | 
					 | 
				
			||||||
                                    this.setState({subtitle: 'HD Videos'});
 | 
					 | 
				
			||||||
                                                    }}
 | 
					                                                    }}
 | 
				
			||||||
                                                />
 | 
					                                                />
 | 
				
			||||||
 | 
					                                            </>
 | 
				
			||||||
 | 
					                                        )}
 | 
				
			||||||
 | 
					                                        node={APINode.Video}
 | 
				
			||||||
 | 
					                                        action='getStartData'
 | 
				
			||||||
 | 
					                                    />
 | 
				
			||||||
                                </SideBar>
 | 
					                                </SideBar>
 | 
				
			||||||
                                <div>
 | 
					                                <div>
 | 
				
			||||||
                                    <span className={style.sortbyLabel}>Sort By: </span>
 | 
					                                    <span className={style.sortbyLabel}>Sort By: </span>
 | 
				
			||||||
@@ -186,20 +143,28 @@ export class HomePage extends React.Component<Props, state> {
 | 
				
			|||||||
                                            <FontAwesomeIcon style={{marginLeft: 3, paddingBottom: 3}} icon={faSortDown} size='1x' />
 | 
					                                            <FontAwesomeIcon style={{marginLeft: 3, paddingBottom: 3}} icon={faSortDown} size='1x' />
 | 
				
			||||||
                                        </span>
 | 
					                                        </span>
 | 
				
			||||||
                                        <div className={style.dropdownContent}>
 | 
					                                        <div className={style.dropdownContent}>
 | 
				
			||||||
                                    <span onClick={(): void => this.onDropDownItemClick(SortBy.date, 'Date Added')}>Date Added</span>
 | 
					                                            <span onClick={(): void => this.onDropDownItemClick(SortBy.date, 'Date Added')}>
 | 
				
			||||||
                                    <span onClick={(): void => this.onDropDownItemClick(SortBy.likes, 'Most likes')}>Most likes</span>
 | 
					                                                Date Added
 | 
				
			||||||
 | 
					                                            </span>
 | 
				
			||||||
 | 
					                                            <span onClick={(): void => this.onDropDownItemClick(SortBy.likes, 'Most likes')}>
 | 
				
			||||||
 | 
					                                                Most likes
 | 
				
			||||||
 | 
					                                            </span>
 | 
				
			||||||
                                            <span onClick={(): void => this.onDropDownItemClick(SortBy.random, 'Random')}>Random</span>
 | 
					                                            <span onClick={(): void => this.onDropDownItemClick(SortBy.random, 'Random')}>Random</span>
 | 
				
			||||||
                                            <span onClick={(): void => this.onDropDownItemClick(SortBy.name, 'Name')}>Name</span>
 | 
					                                            <span onClick={(): void => this.onDropDownItemClick(SortBy.name, 'Name')}>Name</span>
 | 
				
			||||||
                                            <span onClick={(): void => this.onDropDownItemClick(SortBy.length, 'Length')}>Length</span>
 | 
					                                            <span onClick={(): void => this.onDropDownItemClick(SortBy.length, 'Length')}>Length</span>
 | 
				
			||||||
                                        </div>
 | 
					                                        </div>
 | 
				
			||||||
                                    </div>
 | 
					                                    </div>
 | 
				
			||||||
                                </div>
 | 
					                                </div>
 | 
				
			||||||
 | 
					                                <VideoContainer data={data.Videos} />
 | 
				
			||||||
                        <VideoContainer data={this.state.data} />
 | 
					 | 
				
			||||||
                                <div className={style.rightinfo} />
 | 
					                                <div className={style.rightinfo} />
 | 
				
			||||||
 | 
					                            </>
 | 
				
			||||||
 | 
					                        )}
 | 
				
			||||||
 | 
					                        node={APINode.Video}
 | 
				
			||||||
 | 
					                        action='getMovies'
 | 
				
			||||||
 | 
					                        params={{Tag: this.state.tagState.TagId, Sort: this.state.sortState}}
 | 
				
			||||||
 | 
					                    />
 | 
				
			||||||
                </Route>
 | 
					                </Route>
 | 
				
			||||||
            </Switch>
 | 
					            </Switch>
 | 
				
			||||||
            </>
 | 
					 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -209,9 +174,7 @@ export class HomePage extends React.Component<Props, state> {
 | 
				
			|||||||
     * @param name new header title
 | 
					     * @param name new header title
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    onDropDownItemClick(type: SortBy, name: string): void {
 | 
					    onDropDownItemClick(type: SortBy, name: string): void {
 | 
				
			||||||
        this.sortState = type;
 | 
					        this.setState({sortby: name, sortState: type});
 | 
				
			||||||
        this.setState({sortby: name});
 | 
					 | 
				
			||||||
        this.fetchVideoData();
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,15 +4,11 @@ import SideBar, {SideBarTitle} from '../../elements/SideBar/SideBar';
 | 
				
			|||||||
import Tag from '../../elements/Tag/Tag';
 | 
					import Tag from '../../elements/Tag/Tag';
 | 
				
			||||||
import PageTitle from '../../elements/PageTitle/PageTitle';
 | 
					import PageTitle from '../../elements/PageTitle/PageTitle';
 | 
				
			||||||
import VideoContainer from '../../elements/VideoContainer/VideoContainer';
 | 
					import VideoContainer from '../../elements/VideoContainer/VideoContainer';
 | 
				
			||||||
import {APINode, callAPI} from '../../utils/Api';
 | 
					import {APINode} from '../../utils/Api';
 | 
				
			||||||
import {TagType} from '../../types/VideoTypes';
 | 
					import {TagType} from '../../types/VideoTypes';
 | 
				
			||||||
import {VideoTypes} from '../../types/ApiTypes';
 | 
					import {VideoTypes} from '../../types/ApiTypes';
 | 
				
			||||||
import {addKeyHandler, removeKeyHandler} from '../../utils/ShortkeyHandler';
 | 
					import APIComponent from '../../elements/APIComponent';
 | 
				
			||||||
 | 
					import KeyComponent from '../../elements/KeyComponent';
 | 
				
			||||||
interface state {
 | 
					 | 
				
			||||||
    videos: VideoTypes.VideoUnloadedType[];
 | 
					 | 
				
			||||||
    tags: TagType[];
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
interface GetRandomMoviesType {
 | 
					interface GetRandomMoviesType {
 | 
				
			||||||
    Videos: VideoTypes.VideoUnloadedType[];
 | 
					    Videos: VideoTypes.VideoUnloadedType[];
 | 
				
			||||||
@@ -22,46 +18,27 @@ interface GetRandomMoviesType {
 | 
				
			|||||||
/**
 | 
					/**
 | 
				
			||||||
 * Randompage shuffles random viedeopreviews and provides a shuffle btn
 | 
					 * Randompage shuffles random viedeopreviews and provides a shuffle btn
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
class RandomPage extends React.Component<{}, state> {
 | 
					class RandomPage extends React.Component {
 | 
				
			||||||
    readonly LoadNR = 3;
 | 
					    readonly LoadNR = 3;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    constructor(props: {}) {
 | 
					 | 
				
			||||||
        super(props);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        this.state = {
 | 
					 | 
				
			||||||
            videos: [],
 | 
					 | 
				
			||||||
            tags: []
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        this.keypress = this.keypress.bind(this);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    componentDidMount(): void {
 | 
					 | 
				
			||||||
        addKeyHandler(this.keypress);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        this.loadShuffledvideos(this.LoadNR);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    componentWillUnmount(): void {
 | 
					 | 
				
			||||||
        removeKeyHandler(this.keypress);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    render(): JSX.Element {
 | 
					    render(): JSX.Element {
 | 
				
			||||||
        return (
 | 
					        return (
 | 
				
			||||||
            <div>
 | 
					            <div>
 | 
				
			||||||
                <PageTitle title='Random Videos' subtitle='4pc' />
 | 
					                <PageTitle title='Random Videos' subtitle={this.LoadNR + 'pcs'} />
 | 
				
			||||||
 | 
					                <APIComponent
 | 
				
			||||||
 | 
					                    render={(data: GetRandomMoviesType, actions): JSX.Element => (
 | 
				
			||||||
 | 
					                        <KeyComponent listenKey='s' onKey={actions.refresh}>
 | 
				
			||||||
                            <SideBar>
 | 
					                            <SideBar>
 | 
				
			||||||
                                <SideBarTitle>Visible Tags:</SideBarTitle>
 | 
					                                <SideBarTitle>Visible Tags:</SideBarTitle>
 | 
				
			||||||
                    {this.state.tags.map((m) => (
 | 
					                                {data.Tags.map((m) => (
 | 
				
			||||||
                                    <Tag key={m.TagId} tagInfo={m} />
 | 
					                                    <Tag key={m.TagId} tagInfo={m} />
 | 
				
			||||||
                                ))}
 | 
					                                ))}
 | 
				
			||||||
                            </SideBar>
 | 
					                            </SideBar>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                {this.state.videos.length !== 0 ? (
 | 
					                            {data.Videos.length !== 0 ? (
 | 
				
			||||||
                    <VideoContainer data={this.state.videos}>
 | 
					                                <VideoContainer data={data.Videos}>
 | 
				
			||||||
                                    <div className={style.Shufflebutton}>
 | 
					                                    <div className={style.Shufflebutton}>
 | 
				
			||||||
                            <button onClick={(): void => this.shuffleclick()} className={style.btnshuffle}>
 | 
					                                        <button onClick={actions.refresh} className={style.btnshuffle}>
 | 
				
			||||||
                                            Shuffle
 | 
					                                            Shuffle
 | 
				
			||||||
                                        </button>
 | 
					                                        </button>
 | 
				
			||||||
                                    </div>
 | 
					                                    </div>
 | 
				
			||||||
@@ -69,41 +46,15 @@ class RandomPage extends React.Component<{}, state> {
 | 
				
			|||||||
                            ) : (
 | 
					                            ) : (
 | 
				
			||||||
                                <div>No Data found!</div>
 | 
					                                <div>No Data found!</div>
 | 
				
			||||||
                            )}
 | 
					                            )}
 | 
				
			||||||
 | 
					                        </KeyComponent>
 | 
				
			||||||
 | 
					                    )}
 | 
				
			||||||
 | 
					                    node={APINode.Video}
 | 
				
			||||||
 | 
					                    action='getRandomMovies'
 | 
				
			||||||
 | 
					                    params={{Number: this.LoadNR}}
 | 
				
			||||||
 | 
					                />
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * click handler for shuffle btn
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    shuffleclick(): void {
 | 
					 | 
				
			||||||
        this.loadShuffledvideos(this.LoadNR);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * load random videos from backend
 | 
					 | 
				
			||||||
     * @param nr number of videos to load
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    loadShuffledvideos(nr: number): void {
 | 
					 | 
				
			||||||
        callAPI<GetRandomMoviesType>(APINode.Video, {action: 'getRandomMovies', Number: nr}, (result) => {
 | 
					 | 
				
			||||||
            this.setState({videos: []}); // needed to trigger rerender of main videoview
 | 
					 | 
				
			||||||
            this.setState({
 | 
					 | 
				
			||||||
                videos: result.Videos,
 | 
					 | 
				
			||||||
                tags: result.Tags
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * key event handling
 | 
					 | 
				
			||||||
     * @param event keyevent
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    private keypress(event: KeyboardEvent): void {
 | 
					 | 
				
			||||||
        // bind s to shuffle
 | 
					 | 
				
			||||||
        if (event.key === 's') {
 | 
					 | 
				
			||||||
            this.loadShuffledvideos(4);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default RandomPage;
 | 
					export default RandomPage;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user