231 lines
8.3 KiB
JavaScript
Raw Normal View History

import React from "react";
import style from "./Player.module.css"
2020-07-26 18:17:29 +02:00
import {PlyrComponent} from 'plyr-react';
import SideBar, {SideBarItem, SideBarTitle} from "../../elements/SideBar/SideBar";
2020-06-12 15:57:30 +00:00
import Tag from "../../elements/Tag/Tag";
import AddTagPopup from "../../elements/AddTagPopup/AddTagPopup";
import PageTitle, {Line} from "../../elements/PageTitle/PageTitle";
/**
* Player page loads when a video is selected to play and handles the video view
* and actions such as tag adding and liking
*/
class Player extends React.Component {
options = {
controls: [
'play-large', // The large play button in the center
'play', // Play/pause playback
'progress', // The progress bar and scrubber for playback and buffering
'current-time', // The current time of playback
'duration', // The full duration of the media
'mute', // Toggle mute
'volume', // Volume control
'captions', // Toggle captions
'settings', // Settings menu
'airplay', // Airplay (currently Safari only)
'download', // Show a download button with a link to either the current source or a custom URL you specify in your options
'fullscreen', // Toggle fullscreen
]
};
constructor(props, context) {
super(props, context);
this.state = {
sources: null,
movie_id: null,
movie_name: null,
likes: null,
quality: null,
length: null,
tags: [],
suggesttag: [],
popupvisible: false
};
}
componentDidMount() {
this.fetchMovieData();
}
/**
* quick add callback to add tag to db and change gui correctly
* @param tag_id id of tag to add
* @param tag_name name of tag to add
*/
quickAddTag(tag_id, tag_name) {
// save the tag
const updateRequest = new FormData();
updateRequest.append('action', 'addTag');
updateRequest.append('id', tag_id);
updateRequest.append('movieid', this.props.movie_id);
fetch('/api/tags.php', {method: 'POST', body: updateRequest})
.then((response) => response.json()
.then((result) => {
if (result.result !== "success") {
console.error("error occured while writing to db -- todo error handling");
console.error(result.result);
} else {
// update tags if successful
let array = [...this.state.suggesttag]; // make a separate copy of the array
const index = array.map(function (e) {
return e.tag_id;
}).indexOf(tag_id);
if (index !== -1) {
array.splice(index, 1);
this.setState({
tags: [...this.state.tags, {tag_name: tag_name}],
suggesttag: array
});
}
}
}));
}
/**
* generate sidebar with all items
*/
assembleSideBar() {
return (
<SideBar>
<SideBarTitle>Infos:</SideBarTitle>
<Line/>
<SideBarItem><b>{this.state.likes}</b> Likes!</SideBarItem>
{this.state.quality !== 0 ?
<SideBarItem><b>{this.state.quality}p</b> Quality!</SideBarItem> : null}
{this.state.length !== 0 ?
<SideBarItem><b>{Math.round(this.state.length / 60)}</b> Minutes of
length!</SideBarItem> : null}
<Line/>
<SideBarTitle>Tags:</SideBarTitle>
{this.state.tags.map((m) => (
<Tag
key={m.tag_name}
viewbinding={this.props.viewbinding}>{m.tag_name}</Tag>
))}
<Line/>
<SideBarTitle>Tag Quickadd:</SideBarTitle>
{this.state.suggesttag.map((m) => (
<Tag
key={m.tag_name}
onclick={() => {
this.quickAddTag(m.tag_id, m.tag_name);
}}>
{m.tag_name}
</Tag>
))}
</SideBar>
);
}
render() {
return (
2020-06-01 21:36:55 +02:00
<div id='videocontainer'>
<PageTitle
title='Watch'
subtitle={this.state.movie_name}/>
{this.assembleSideBar()}
<div className={style.videowrapper}>
{/* video component is added here */}
{this.state.sources ? <PlyrComponent
className='myvideo'
sources={this.state.sources}
options={this.options}/> :
<div>not loaded yet</div>}
<div className={style.videoactions}>
<button className='btn btn-primary' onClick={() => this.likebtn()}>Like this Video!</button>
2020-06-06 11:48:12 +00:00
<button className='btn btn-info' onClick={() => this.setState({popupvisible: true})}>Give this
Video a Tag
</button>
{this.state.popupvisible ?
<AddTagPopup show={this.state.popupvisible}
2020-06-07 23:27:31 +02:00
onHide={() => {
this.setState({popupvisible: false});
this.fetchMovieData();
}}
2020-06-06 11:48:12 +00:00
movie_id={this.state.movie_id}/> :
null
}
</div>
</div>
<button className={style.closebutton} onClick={() => this.closebtn()}>Close</button>
</div>
);
}
/**
* fetch all the required infos of a video from backend
*/
fetchMovieData() {
const updateRequest = new FormData();
updateRequest.append('action', 'loadVideo');
updateRequest.append('movieid', this.props.movie_id);
fetch('/api/video.php', {method: 'POST', body: updateRequest})
.then((response) => response.json())
.then((result) => {
this.setState({
sources: {
type: 'video',
sources: [
{
src: result.movie_url,
type: 'video/mp4',
size: 1080,
}
],
poster: result.thumbnail
},
2020-06-06 11:48:12 +00:00
movie_id: result.movie_id,
movie_name: result.movie_name,
likes: result.likes,
quality: result.quality,
length: result.length,
tags: result.tags,
suggesttag: result.suggesttag
});
console.log(this.state);
});
}
/**
* click handler for the like btn
*/
likebtn() {
const updateRequest = new FormData();
updateRequest.append('action', 'addLike');
updateRequest.append('movieid', this.props.movie_id);
fetch('/api/video.php', {method: 'POST', body: updateRequest})
2020-06-12 15:57:30 +00:00
.then((response) => response.json()
.then((result) => {
if (result.result === "success") {
// likes +1 --> avoid reload of all data
this.setState({likes: this.state.likes + 1})
2020-06-12 15:57:30 +00:00
} else {
console.error("an error occured while liking");
console.error(result);
2020-06-12 15:57:30 +00:00
}
}));
}
/**
* closebtn click handler
* calls callback to viewbinding to show previous page agains
*/
closebtn() {
2020-06-21 23:08:46 +02:00
this.props.viewbinding.returnToLastElement();
}
}
export default Player;