Compare commits

..

No commits in common. "7f0f856d196f3d0772ff47ef1a420094a841e2ae" and "fa190de4b6cd42f63a58d044a621a3c222ad56e1" have entirely different histories.

5 changed files with 10953 additions and 24872 deletions

35325
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +1,12 @@
{ {
"name": "reddit-slideshow", "name": "reddit-slideshow",
"version": "0.1.6", "version": "0.1.2",
"private": true, "private": true,
"dependencies": { "dependencies": {
"axios": "^0.26.1", "axios": "^0.19.0",
"react": "^16.13.1", "react": "^16.8.6",
"react-dom": "^16.13.1", "react-dom": "^16.8.6",
"react-scripts": "^5.0.0" "react-scripts": "3.1.1"
}, },
"scripts": { "scripts": {
"start": "react-scripts start", "start": "react-scripts start",

View File

@ -1,16 +1,15 @@
import React from "react"; import React from 'react';
import Slide from "../Slide/Slide"; import Slide from '../Slide/Slide';
import "./Layout.css"; import './Layout.css';
import { ReactComponent as PrevSlideSVG } from "../../assets/prevSlide-24px.svg"; import { ReactComponent as PrevSlideSVG } from '../../assets/prevSlide-24px.svg';
import { ReactComponent as NextSlideSVG } from "../../assets/nextSlide-24px.svg"; import { ReactComponent as NextSlideSVG } from '../../assets/nextSlide-24px.svg';
import { ReactComponent as LeftArrowSVG } from "../../assets/leftArrow-24px.svg"; import { ReactComponent as LeftArrowSVG } from '../../assets/leftArrow-24px.svg';
import { ReactComponent as RightArrowSVG } from "../../assets/rightArrow-24px.svg"; import { ReactComponent as RightArrowSVG } from '../../assets/rightArrow-24px.svg';
import { ReactComponent as GithubLogo } from "../../assets/githubLogo.svg"; import { ReactComponent as GithubLogo } from '../../assets/githubLogo.svg';
const layout = (props) => { const layout = (props) => {
const link = props.post ? props.post.link : null; const link = props.post ? props.post.link : null;
const extension = props.post ? props.post.extension : null;
const id = props.post ? props.post.id : null; const id = props.post ? props.post.id : null;
const title = props.post ? props.post.title : null; const title = props.post ? props.post.title : null;
const urlToComments = props.post ? props.post.urlToComments : null; const urlToComments = props.post ? props.post.urlToComments : null;
@ -20,132 +19,67 @@ const layout = (props) => {
// console.log('link', link); // console.log('link', link);
// console.log('post', props.post); // console.log('post', props.post);
const headerClasses = [props.showTitle ? "showTitle" : "hideTitle"]; const headerClasses = [ props.showTitle ? 'showTitle' : 'hideTitle'];
const infoClasses = ["info"]; const infoClasses = ['info'];
infoClasses.push(props.showInfo ? "showInfo" : "hideInfo"); infoClasses.push( props.showInfo ? 'showInfo' : 'hideInfo' );
const uiClasses = ["ui"]; const uiClasses = ['ui'];
uiClasses.push(props.hideUI ? "hideUI" : "showUI"); uiClasses.push( props.hideUI ? 'hideUI' : 'showUI' );
const slideClasses = ["slide"]; const slideClasses = ['slide'];
if (props.hideUI) { if ( props.hideUI ) {
slideClasses.push("hideCursor"); slideClasses.push('hideCursor');
} }
const currentEndedPlayingHandler = () => {
props.currentEndedPlaying();
};
return ( return (
<div className="layout" onTouchStart={props.touchStart} onTouchEnd={props.touchEnd}> <div className="layout" onTouchStart={props.touchStart} onTouchEnd={props.touchEnd}>
<div className={uiClasses.join(" ")}> <div className={ uiClasses.join(' ') }>
<header className={headerClasses.join(" ")}> <header className={headerClasses.join(' ')}>
<h1 className="title">{title}</h1> <h1 className="title">
{props.showTitle ? ( {title}
<LeftArrowSVG </h1>
aria-label="Hide title" { props.showTitle
className="toggleTitleButton toggleButton" ? <LeftArrowSVG aria-label="Hide title" className="toggleTitleButton toggleButton" onClick={props.titleClick}/>
onClick={props.titleClick} : <RightArrowSVG aria-label="Show title" className="toggleTitleButton toggleButton" onClick={props.titleClick}/> }
/>
) : (
<RightArrowSVG
aria-label="Show title"
className="toggleTitleButton toggleButton"
onClick={props.titleClick}
/>
)}
</header> </header>
<NextSlideSVG aria-label="Next" className="navButton nextButton" onClick={props.nextHandler} /> <NextSlideSVG aria-label="Next" className="navButton nextButton" onClick={ props.nextHandler }/>
<PrevSlideSVG aria-label="Previous" className="navButton prevButton" onClick={props.prevHandler} /> <PrevSlideSVG aria-label="Previous" className="navButton prevButton" onClick={ props.prevHandler }/>
<div className={infoClasses.join(" ")}> <div className={infoClasses.join(' ')}>
<div className="infoButtons"> <div className="infoButtons">
<div className="infoRow"> <div className="infoRow">
<a target="_blank" className="infoElement" href={urlToComments} rel="noopener noreferrer"> <a target="_blank" className="infoElement" href= { urlToComments } rel="noopener noreferrer">Comments</a>
Comments <a target="_blank" className="infoElement" href= { link } rel="noopener noreferrer">Direct link</a>
</a>
<a target="_blank" className="infoElement" href={link} rel="noopener noreferrer">
Direct link
</a>
{/*<div className="infoElement"> {/*<div className="infoElement">
<input type="checkbox" id="showNSFW" name="showNSFW" onChange={props.nsfwCheckboxHandler} checked={props.nsfwChecked}/><label htmlFor="showNSFW">NSFW</label> <input type="checkbox" id="showNSFW" name="showNSFW" onChange={props.nsfwCheckboxHandler} checked={props.nsfwChecked}/><label htmlFor="showNSFW">NSFW</label>
</div>*/} </div>*/}
</div> </div>
<div className="infoRow"> <div className="infoRow">
<div className="infoElement"> <div className="infoElement">
<input <input type="checkbox" id="auto" name="auto" onChange={props.autoCheckboxHandler} checked={props.autoPlay}/>
type="checkbox"
id="auto"
name="auto"
onChange={props.autoCheckboxHandler}
checked={props.autoPlay}
/>
<label htmlFor="auto">Auto</label> <label htmlFor="auto">Auto</label>
</div> </div>
<div className="infoElement"> <div className="infoElement">
<input <input type="checkbox" id="hideUI" name="hideUI" onChange={props.hideUICheckboxHandler} checked={props.hideUIChecked}/>
type="checkbox"
id="hideUI"
name="hideUI"
onChange={props.hideUICheckboxHandler}
checked={props.hideUIChecked}
/>
<label htmlFor="hideUI">Hide UI</label> <label htmlFor="hideUI">Hide UI</label>
</div> </div>
</div> </div>
<div className="infoRow">
<div className="infoElement">
<input
type="checkbox"
id="sound"
name="sound"
onChange={props.soundCheckboxHandler}
checked={props.sound}
/>
<label htmlFor="sound">Sound</label>
</div> </div>
</div> { props.showInfo
</div> ? <LeftArrowSVG aria-label="Hide info panel" className="toggleInfoButton toggleButton" onClick={props.infoClick}/>
{props.showInfo ? ( : <RightArrowSVG aria-label="Show info panel" className="toggleInfoButton toggleButton" onClick={props.infoClick}/> }
<LeftArrowSVG
aria-label="Hide info panel"
className="toggleInfoButton toggleButton"
onClick={props.infoClick}
/>
) : (
<RightArrowSVG
aria-label="Show info panel"
className="toggleInfoButton toggleButton"
onClick={props.infoClick}
/>
)}
</div> </div>
<a <a href="https://github.com/ismaelpadilla/reddit-slideshow" aria-label="Source code" target="_blank" rel="noopener noreferrer">
href="https://github.com/ismaelpadilla/reddit-slideshow" <GithubLogo className="githubLogo"/>
aria-label="Source code"
target="_blank"
rel="noopener noreferrer"
>
<GithubLogo className="githubLogo" />
</a> </a>
</div> </div>
{link ? ( { link ? <Slide url={ link } classes={ slideClasses.concat(['current']) } key={ id }/> : null }
<Slide { props.prev !== props.post ? <Slide url={ prevLink } classes={ slideClasses.concat(['prev']) } key={ prevId } /> : null }
url={link}
extension={extension}
classes={slideClasses.concat(["current"])}
key={id}
currentEndedPLaying={currentEndedPlayingHandler}
sound={props.sound}
/>
) : null}
{props.prev !== props.post ? (
<Slide url={prevLink} extension={extension} classes={slideClasses.concat(["prev"])} key={prevId} />
) : null}
</div> </div>
); );
}; };

View File

@ -1,48 +1,49 @@
import React, { useState } from "react"; import React from 'react';
import "./Slide.css"; import './Slide.css'
const Slide = (props) => { const slide = (props) => {
// how many time has the video played?
const [loopCount, setLoopCount] = useState(0);
const fileExt = props.extension; // get file extension
const extPattern = /\.[0-9a-z]+$/i;
if (props.classes.includes("current")) { const match = props.url.match(extPattern);
const fileExt = match ? match[0] : null;
if (props.classes.includes('current')) {
console.log("Attempting to show", props.url); console.log("Attempting to show", props.url);
} }
// console.log (props.classes);
// console.log('extension', fileExt);
const endedHandler = () => { // console.log('domain', domain);
if (props.classes.includes("current")) {
if (loopCount === 1 && props.currentEndedPLaying) { // imgur urls are case sensitive!
props.currentEndedPLaying(); // const afterDomain = props.url.match(/[.0-9a-zA-Z]+$/)[0];
} // console.log('afterdomain', afterDomain);
setLoopCount(loopCount + 1);
}
};
if (fileExt) { if (fileExt) {
// Imgur videos can be linked by using .mp4 extension instead of .gifv // Imgur videos can be linked by using .mp4 extension instead of .gifv
if (fileExt === ".gifv") { if ( fileExt === ".gifv" ) {
return ( return (
<video autoPlay loop muted={!props.sound} className={props.classes.join(" ") + " video"} onPlaying={endedHandler}> <video autoPlay muted loop className= { props.classes.join(' ') + ' video' }>
<source src={props.url.replace(".gifv", ".mp4")} type="video/mp4" /> <source src={ props.url.replace(".gifv", ".mp4") } type="video/mp4"/>
</video> </video>
); );
} else if (fileExt === ".mp4") { } else if ( fileExt === ".mp4" ) {
return ( return (
<video autoPlay loop muted={!props.sound} className={props.classes.join(" ") + " video"} onPlaying={endedHandler}> <video autoPlay muted loop className= { props.classes.join(' ') + ' video' }>
<source src={props.url.replace(".mp4", ".webm")} type="video/webm" /> <source src={ props.url.replace('.mp4', '.webm') } type="video/webm"/>
<source src={props.url} type="video/mp4" /> <source src={ props.url } type="video/mp4"/>
</video> </video>
); );
} }
// Regular picture // Regular picture
const mystyle = { backgroundImage: `url(${props.url})` }; const mystyle= { backgroundImage:`url(${props.url})` };
return <div style={mystyle} className={props.classes.join(" ")} />; return <div style={ mystyle } className= { props.classes.join(' ') } />;
} }
return <div>Something went wrong.</div>; return(
<div>Something went wrong.</div>
);
}; };
export default Slide; export default slide;

View File

@ -1,59 +1,58 @@
import React, { Component } from "react"; import React, { Component } from 'react';
import axios from "axios"; import axios from 'axios';
import Layout from "../components/Layout/Layout"; import Layout from '../components/Layout/Layout';
import "./App.css"; import './App.css';
class App extends Component { class App extends Component {
hideUI = false;
state = { state = {
// request: '/r/pics.json', // request: '/r/pics.json',
request: window.location.pathname + ".json", request: window.location.pathname + '.json',
posts: [], posts: [],
currentPost: -1, currentPost: -1,
prevPost: 0, prevPost: 0,
currentEndedPlaying: false, after: '', // to be sent as a part of a request, see reddit api docs
after: "", // to be sent as a part of a request, see reddit api docs
awaitingResponse: false, awaitingResponse: false,
showTitle: true, // show image title at top left showTitle: true, // show image title at top left
showInfo: true, // show info and buttons at bottom right showInfo: true, // show info and buttons at bottom right
auto: false, // autoplay auto: false, // autoplay
sound: false, hideUI: this.hideUI,
hideUI: false, hideUIChecked: this.hideUI,
hideUIChecked: false,
showNSWF: true, showNSWF: true,
touchStartX: 0, // used for swipe gestures in mobile touchStartX: 0 // used for swipe gestures in mobile
}; };
/** /**
* This makes sure we access the right reddit url based on how the user * This makes sure we access the right reddit url based on how the user
* accesses our website. * accesses our website.
*/ */
componentDidMount = () => { componentDidMount = () => {
// Get initial posts via http, set state // Get initial posts via http, set state
if (!this.state.awaitingResponse) { if ( !this.state.awaitingResponse ) {
this.setState({ awaitingResponse: true }); this.setState( { awaitingResponse: true } );
axios axios.get( this.state.request )
.get(this.state.request) .then(
.then((response) => { response => {
// posts are in response.data.data.children // posts are in response.data.data.children
const after = response.data.data.after; const after = response.data.data.after;
this.getPosts(response.data.data.children) this.getPosts(response.data.data.children).then ( (posts) =>
.then((posts) => { {
// console.log('after', after); // console.log('after', after);
// console.log('reduced posts', posts); // console.log('reduced posts', posts);
this.setState({ this.setState( {
posts: [...posts], posts: [...posts],
after: after, after: after,
currentPost: 0, currentPost: 0,
awaitingResponse: false, awaitingResponse: false
// interval: setInterval(this.nextSlideHandler, 2000) // interval: setInterval(this.nextSlideHandler, 2000)
}); });
if (this.state.auto) { if (this.state.auto) {
this.setState({ interval: setInterval(() => this.nextSlideHandler(false), 5000) }); this.setState({ interval: setInterval(this.nextSlideHandler, 5000) });
} }
// console.log("initialized state", this.state); // console.log("initialized state", this.state);
}) }).catch(function (error) {
.catch(function (error) {
console.log(error); console.log(error);
}); });
}) })
@ -61,9 +60,9 @@ class App extends Component {
console.log(error); console.log(error);
}); });
} }
document.addEventListener("mousemove", this.mouseMoveHandler); document.addEventListener('mousemove', this.mouseMoveHandler);
document.addEventListener("keydown", this.keyDownHandler); document.addEventListener('keydown', this.keyDownHandler);
}; }
/** /**
* Prevent unnecessary rerenders. * Prevent unnecessary rerenders.
@ -74,11 +73,11 @@ class App extends Component {
* the touch start event modifies the state but it doesn't have an impact * the touch start event modifies the state but it doesn't have an impact
* on the elements being shown. * on the elements being shown.
*/ */
if (this.state.touchStartX !== nextState.touchStartX) { if (this.state.touchStartX !== nextState.touchStartX){
return false; return false;
} }
return true; return true;
}; }
/** /**
* Handle key presses. * Handle key presses.
@ -88,9 +87,9 @@ class App extends Component {
if (event.key === "ArrowLeft" || event.code === "KeyA") { if (event.key === "ArrowLeft" || event.code === "KeyA") {
this.prevSlideHandler(); this.prevSlideHandler();
} else if (event.key === "ArrowRight" || event.code === "KeyD") { } else if (event.key === "ArrowRight" || event.code === "KeyD") {
this.nextSlideHandler(true); this.nextSlideHandler();
}
} }
};
/** /**
* Get posts from a server response * Get posts from a server response
@ -105,7 +104,7 @@ class App extends Component {
*/ */
getPosts = (children) => { getPosts = (children) => {
// Filter and map at the same time // Filter and map at the same time
const posts = children.reduce(this.filterPosts, []); const posts = children.reduce( this.filterPosts, [] );
// Update the posts, get urls to gfycat mp4s (see updatePosts fore more info). // Update the posts, get urls to gfycat mp4s (see updatePosts fore more info).
const updatedPosts = this.updatePosts(posts); const updatedPosts = this.updatePosts(posts);
// console.log('updated posts', updatedPosts); // console.log('updated posts', updatedPosts);
@ -126,9 +125,8 @@ class App extends Component {
title: child.data.title, title: child.data.title,
id: child.data.id, id: child.data.id,
nsfw: child.data.over_18, nsfw: child.data.over_18,
urlToComments: "https://www.reddit.com" + child.data.permalink, urlToComments: 'https://www.reddit.com' + child.data.permalink,
link: filteredUrl.url, link: filteredUrl
extension: filteredUrl.extension,
}); });
} }
} }
@ -149,12 +147,12 @@ class App extends Component {
const extPattern = /\.[0-9a-z]+$/i; const extPattern = /\.[0-9a-z]+$/i;
const match = url.match(extPattern); const match = url.match(extPattern);
const fileExt = match ? match[0] : null; const fileExt = match ? match[0] : null;
const supportedExtensions = [".jpg", ".jpeg", ".png", ".bmp", ".gif", ".gifv"]; const supportedExtensions = [".jpg", ".jpeg", ".png", ".bmp",".gif", ".gifv"];
if (domain === "gfycat.com" || supportedExtensions.includes(fileExt)) { if ( domain === "gfycat.com" || supportedExtensions.includes(fileExt) ) {
return { url, extension: fileExt }; return url;
} }
if (domain === "imgur.com") { if ( domain === "imgur.com" ) {
return { url: url + ".jpg", extension: fileExt }; return url + ".jpg";
} }
return null; return null;
}; };
@ -176,7 +174,7 @@ class App extends Component {
const domain = post.link.match(/:\/\/(.+)\//)[1]; const domain = post.link.match(/:\/\/(.+)\//)[1];
// In order to play gfycat videos we must get the mp4 url from the video id // In order to play gfycat videos we must get the mp4 url from the video id
if (domain === "gfycat.com") { if (domain === 'gfycat.com') {
const gfyId = post.link.match(/([.0-9a-zA-Z]+)(-|$)/)[1]; const gfyId = post.link.match(/([.0-9a-zA-Z]+)(-|$)/)[1];
/* /*
* gfyId regex clarification: sometimes gfys have dashes ('-') in their url. * gfyId regex clarification: sometimes gfys have dashes ('-') in their url.
@ -184,31 +182,20 @@ class App extends Component {
*/ */
// Wait until some images are correct so we can render something // Wait until some images are correct so we can render something
if (counter < 3) { if ( counter < 3) {
const response = await axios.get("https://api.gfycat.com/v1/gfycats/" + gfyId); const response = await axios.get( "https://api.gfycat.com/v1/gfycats/" + gfyId );
post.link = response.data.gfyItem.mp4Url; post.link = response.data.gfyItem.mp4Url;
} else { } else {
axios axios.get( "https://api.gfycat.com/v1/gfycats/" + gfyId ).then( (response) =>
.get("https://api.gfycat.com/v1/gfycats/" + gfyId) {
.then((response) => {
post.link = response.data.gfyItem.mp4Url; post.link = response.data.gfyItem.mp4Url;
}) }).catch(function (error) {
.catch(function (error) {
console.log(error); console.log(error);
}); });
} }
const extPattern = /\.[0-9a-z]+$/i;
const match = post.link.match(extPattern);
const fileExt = match ? match[0] : null;
post.extension = fileExt;
if (fileExt === ".gifv" || fileExt === ".mp4") {
post.isVideo = true;
} else {
post.isVideo = false;
}
counter++; counter++;
} }
} };
return posts; return posts;
}; };
@ -216,11 +203,11 @@ class App extends Component {
* Go to previous slide. * Go to previous slide.
*/ */
prevSlideHandler = () => { prevSlideHandler = () => {
if (this.state.currentPost > 0) { if ( this.state.currentPost > 0 ) {
this.setState((prevState, props) => { this.setState( (prevState, props) => {
return { return {
prevPost: prevState.currentPost, prevPost: prevState.currentPost,
currentPost: prevState.currentPost - 1, currentPost: prevState.currentPost -1
}; };
}); });
} }
@ -228,50 +215,40 @@ class App extends Component {
}; };
/** /**
* Handle nextSlide event. If it was fired manually, always go to next slide. * Go to next slide.
* If it was fired automatically and we are playing a video, go to next slide only
* if current video has finished playing.
*/ */
nextSlideHandler = (manual, e) => { nextSlideHandler = () => {
// do nothing if current video didn't end playing if ( this.state.currentPost < this.state.posts.length -1 ) {
const currentIsVideo = this.state.posts[this.state.currentPost].isVideo; this.setState( (prevState, props) => {
if (!manual && currentIsVideo && !this.state.currentEndedPlaying) {
console.log("Current video still playing!");
return;
}
if (this.state.currentPost < this.state.posts.length - 1) {
this.setState((prevState, props) => {
return { return {
prevPost: prevState.currentPost, prevPost: prevState.currentPost,
currentPost: prevState.currentPost + 1, currentPost: prevState.currentPost +1
}; };
}); });
} };
// Load more posts when close to reaching the end // Load more posts when close to reaching the end
if (this.state.currentPost > this.state.posts.length - 4) { if ( this.state.currentPost > this.state.posts.length -4 ) {
if (!this.state.awaitingResponse) { if ( !this.state.awaitingResponse ) {
this.setState({ awaitingResponse: true }); this.setState( { awaitingResponse: true } );
console.log("fetching aditional posts"); console.log('fetching aditional posts');
axios axios.get(this.state.request + '?after=' + this.state.after)
.get(this.state.request + "?after=" + this.state.after) .then(
.then((response) => { response => {
// console.log(response); // posts are in response.data.data.children // console.log(response); // posts are in response.data.data.children
const after = response.data.data.after; const after = response.data.data.after;
this.getPosts(response.data.data.children) this.getPosts(response.data.data.children).then ( (posts) =>
.then((posts) => { {
// console.log('after', after); // console.log('after', after);
// console.log('reduced posts', posts); // console.log('reduced posts', posts);
this.setState((state, props) => { this.setState( (state, props) => {
return { return {
posts: [...state.posts, ...posts], posts: [...state.posts, ...posts],
after: after, after: after,
awaitingResponse: false, awaitingResponse: false
}; }
}); });
}) }).catch(function (error) {
.catch(function (error) {
console.log(error); console.log(error);
}); });
}) })
@ -280,7 +257,6 @@ class App extends Component {
}); });
} }
} }
this.setState({ currentEndedPlaying: false });
console.log("Next"); console.log("Next");
}; };
@ -288,23 +264,23 @@ class App extends Component {
* Hide/show title at the top right. * Hide/show title at the top right.
*/ */
toggleTitleHandler = () => { toggleTitleHandler = () => {
this.setState((state, props) => { this.setState( (state,props) => {
return { return {
showTitle: !state.showTitle, showTitle: ! state.showTitle
}; }
}); } );
}; };
/** /**
* Hide/show info panel at the bottom left. * Hide/show info panel at the bottom left.
*/ */
toggleInfoHandler = () => { toggleInfoHandler = () => {
console.log("toggle info"); console.log('toggle info');
this.setState((state, props) => { this.setState( (state,props) => {
return { return {
showInfo: !state.showInfo, showInfo: ! state.showInfo
}; }
}); } );
}; };
/** /**
@ -314,24 +290,11 @@ class App extends Component {
if (event.target.checked) { if (event.target.checked) {
this.setState({ this.setState({
auto: true, auto: true,
interval: setInterval(() => this.nextSlideHandler(false), 5000), interval: setInterval(this.nextSlideHandler, 5000)
}); });
} else { } else {
this.setState({ auto: false }); this.setState({ auto: false });
clearInterval(this.state.interval); clearInterval( this.state.interval );
}
};
/**
* Handle sound checkbox.
*/
soundCheckboxHandler = (event) => {
if (event.target.checked) {
this.setState({
sound: true
});
} else {
this.setState({ sound: false });
} }
}; };
@ -342,14 +305,14 @@ class App extends Component {
if (event.target.checked) { if (event.target.checked) {
this.setState({ this.setState({
hideUI: true, hideUI: true,
hideUIChecked: true, hideUIChecked: true
}); });
} else { } else {
this.setState({ this.setState({
hideUI: false, hideUI: false,
hideUIChecked: false, hideUIChecked: false
}); });
clearInterval(this.state.interval); clearInterval( this.state.interval );
} }
}; };
@ -358,7 +321,7 @@ class App extends Component {
*/ */
nsfwCheckboxHandler = (event) => { nsfwCheckboxHandler = (event) => {
this.setState({ showNSWF: event.target.checked }); this.setState({ showNSWF: event.target.checked });
}; }
/** /**
* Handle mouse movement. * Handle mouse movement.
@ -366,10 +329,10 @@ class App extends Component {
*/ */
mouseMoveHandler = () => { mouseMoveHandler = () => {
if (this.state.hideUI) { if (this.state.hideUI) {
this.setState({ hideUI: false }); this.setState({ hideUI:false });
setTimeout(this.hideUI, 3000); setTimeout( this.hideUI, 3000);
}
} }
};
/** /**
* Hide UI, this method should be called from the timer created in * Hide UI, this method should be called from the timer created in
@ -378,7 +341,7 @@ class App extends Component {
* after moving the mouse so as not to hide the UI in that case. * after moving the mouse so as not to hide the UI in that case.
*/ */
hideUI = () => { hideUI = () => {
if (this.state.hideUIChecked) { if(this.state.hideUIChecked) {
this.setState({ hideUI: true }); this.setState({ hideUI: true });
} }
}; };
@ -389,53 +352,45 @@ class App extends Component {
*/ */
touchStartHandler = (event) => { touchStartHandler = (event) => {
this.setState({ touchStartX: event.targetTouches[0].clientX }); this.setState({ touchStartX: event.targetTouches[0].clientX });
}; }
/** /**
* On touch end, compare touch position to touch start (saved in state). * On touch end, compare touch position to touch start (saved in state).
* Change slides if both points are far enough. * Change slides if both points are far enough.
*/ */
touchEndHandler = (event) => { touchEndHandler = (event) => {
if (event.changedTouches[0].clientX < this.state.touchStartX - 50) { if ( event.changedTouches[0].clientX < this.state.touchStartX - 50 ) {
this.nextSlideHandler(true); this.nextSlideHandler();
} else if (event.changedTouches[0].clientX > this.state.touchStartX + 50) { } else if ( event.changedTouches[0].clientX > this.state.touchStartX + 50) {
this.prevSlideHandler(); this.prevSlideHandler();
} }
}; }
currentEndedPlayingHandler = () => {
this.setState({ currentEndedPlaying: true });
};
render() { render() {
return ( return (
<div className="App"> <div className="App">
<Layout <Layout className="App"
className="App" post={ this.state.posts.length ? (this.state.posts[ this.state.currentPost ]) : null }
post={this.state.posts.length ? this.state.posts[this.state.currentPost] : null} prev={ this.state.posts.length ? (this.state.posts[ this.state.prevPost ]) : null }
prev={this.state.posts.length ? this.state.posts[this.state.prevPost] : null} prevHandler={ this.prevSlideHandler }
prevHandler={this.prevSlideHandler} nextHandler={ this.nextSlideHandler }
nextHandler={(e) => this.nextSlideHandler(true, e)} showTitle={ this.state.showTitle }
showTitle={this.state.showTitle} showInfo={ this.state.showInfo }
showInfo={this.state.showInfo} titleClick={ this.toggleTitleHandler }
titleClick={this.toggleTitleHandler} infoClick={ this.toggleInfoHandler }
infoClick={this.toggleInfoHandler} autoPlay={ this.state.auto }
autoPlay={this.state.auto} autoCheckboxHandler={ this.autoCheckboxHandler }
autoCheckboxHandler={this.autoCheckboxHandler} hideUI={ this.state.hideUI }
sound={this.state.sound} hideUIChecked={ this.state.hideUIChecked }
soundCheckboxHandler={this.soundCheckboxHandler} hideUICheckboxHandler={ this.hideUICheckboxHandler }
hideUI={this.state.hideUI} nsfwCheckboxHandler={ this.nsfwCheckboxHandler }
hideUIChecked={this.state.hideUIChecked} nsfwChecked={ this.state.showNSWF }
hideUICheckboxHandler={this.hideUICheckboxHandler} touchStart={ this.touchStartHandler }
nsfwCheckboxHandler={this.nsfwCheckboxHandler} touchEnd={ this.touchEndHandler }
nsfwChecked={this.state.showNSWF}
touchStart={this.touchStartHandler}
touchEnd={this.touchEndHandler}
currentEndedPlaying={this.currentEndedPlayingHandler}
/> />
</div> </div>
); );
} };
} }
export default App; export default App;