forked from notnull/waveform
added comment functionality; comment reducer
This commit is contained in:
parent
fea715168a
commit
be8660990b
@ -1,15 +1,35 @@
|
||||
import React from 'react'
|
||||
import {Card} from 'react-bootstrap'
|
||||
import {Tooltip, Image, Button, Card, Overlay} from 'react-bootstrap'
|
||||
|
||||
const Comment = props => {
|
||||
console.log('comment props:', props)
|
||||
return (
|
||||
<Card style={{position: 'relative', width: '100px', height: '100px', left: props.commentLoc + '%' }}>
|
||||
<Card.Body>
|
||||
{props.parseTime(props.commentSecs)}
|
||||
</Card.Body>
|
||||
</Card>
|
||||
class Example extends React.Component {
|
||||
constructor() {
|
||||
super()
|
||||
this.attachRef = target => this.setState({ target })
|
||||
this.state = {
|
||||
show: false,
|
||||
}
|
||||
this.toggleShow=this.toggleShow.bind(this)
|
||||
}
|
||||
toggleShow() {
|
||||
this.setState({show: !this.state.show})
|
||||
}
|
||||
|
||||
)
|
||||
render() {
|
||||
const { show, target } = this.state
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
className = "comment_icon"
|
||||
ref={this.attachRef}
|
||||
style={{position: 'absolute', top: 180, left: this.props.commentLoc + '%'}}
|
||||
onClick={this.toggleShow} />
|
||||
<Overlay target={target} show={show} placement="bottom" >
|
||||
<Tooltip>
|
||||
{this.props.text}
|
||||
</Tooltip>
|
||||
</Overlay>
|
||||
</>
|
||||
)
|
||||
}
|
||||
}
|
||||
export default Comment
|
||||
export default Example
|
||||
|
@ -5,6 +5,8 @@ const config = require('./audio/loneDigger.json')
|
||||
import ReactAudioPlayer from 'react-audio-player'
|
||||
import CommentPopup from './CommentPopup'
|
||||
import Comment from './Comment'
|
||||
import {fetchAllComments, addComment} from '../../store'
|
||||
import {Container, Row, Col} from 'react-bootstrap'
|
||||
|
||||
const parseTime = secs => {
|
||||
var hours = Math.floor(secs / 3600)
|
||||
@ -18,10 +20,11 @@ const parseTime = secs => {
|
||||
}
|
||||
|
||||
|
||||
class App extends Component {
|
||||
class Player extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
loading: true,
|
||||
playerSize: {},
|
||||
duration: 3*60+49,
|
||||
songSecs: 0,
|
||||
@ -29,22 +32,30 @@ class App extends Component {
|
||||
commentLoc: 0,
|
||||
commentText: '',
|
||||
showPopup: false,
|
||||
showComment: false,
|
||||
showComments: true,
|
||||
comments: [{id: 1, commentSecs: 132}]
|
||||
}
|
||||
this.getCommentSecs = this.getCommentSecs.bind(this)
|
||||
//this.getCommentSecs = this.getCommentSecs.bind(this)
|
||||
this.getPlayerSize = this.getPlayerSize.bind(this)
|
||||
this.submitComment = this.submitComment.bind(this)
|
||||
this.togglePopup = this.togglePopup.bind(this)
|
||||
this.openCommentPopup = this.openCommentPopup.bind(this)
|
||||
this.updateCommentText = this.updateCommentText.bind(this)
|
||||
//this.showComment = this.showComment.bind(this)
|
||||
this.commentID = 3
|
||||
}
|
||||
|
||||
getCommentSecs (commentSecs) {
|
||||
this.setState({commentSecs})
|
||||
async fetchData() {
|
||||
await this.props.fetchComments()
|
||||
await this.setState({loading: false})
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.fetchData()
|
||||
}
|
||||
|
||||
// getCommentSecs (commentSecs) {
|
||||
// this.setState({commentSecs})
|
||||
// }
|
||||
|
||||
getPlayerSize(e) {
|
||||
if(e){
|
||||
this.setState({playerSize: e.getBoundingClientRect()})
|
||||
@ -53,20 +64,16 @@ class App extends Component {
|
||||
}
|
||||
submitComment(e) {
|
||||
e.preventDefault()
|
||||
const commentLoc = (this.state.playerSize.width * this.state.commentSecs) / ( this.state.duration * 100)
|
||||
this.setState({commentLoc})
|
||||
this.togglePopup()
|
||||
this.showComment()
|
||||
console.log(this.state.commentText)
|
||||
this.props.postComment({id: this.commentID, commentSecs: this.state.commentSecs, text: this.state.commentText})
|
||||
this.commentID ++
|
||||
this.setState({showPopup: false, showComments: true})
|
||||
}
|
||||
|
||||
openCommentPopup(commentSecs) {
|
||||
this.togglePopup()
|
||||
this.setState({commentSecs})
|
||||
this.setState({commentSecs, showPopup: true, showComments: false})
|
||||
this.rap.audioEl.pause()
|
||||
}
|
||||
togglePopup() {
|
||||
this.setState({showPopup: !this.state.showPopup})
|
||||
}
|
||||
|
||||
updateCommentText(e) {
|
||||
e.preventDefault()
|
||||
@ -75,37 +82,51 @@ class App extends Component {
|
||||
render() {
|
||||
|
||||
return (
|
||||
<div className="container App">
|
||||
<Container className="App mt-5">
|
||||
<header className="App-header">
|
||||
<h1 className="App-title">Player</h1>
|
||||
</header>
|
||||
<div ref = {this.getPlayerSize} style={{ border: '1px solid red' }}>
|
||||
<Waveform
|
||||
ref = {el => {this.waveform = el}}
|
||||
peaks={config.data}
|
||||
height={200}
|
||||
pos={this.state.songSecs}
|
||||
duration={this.state.duration}
|
||||
onClick={this.openCommentPopup}
|
||||
color="#676767"
|
||||
progressGradientColors={[[0, '#33cccc'], [1, '#aaa']]}
|
||||
/>
|
||||
{this.state.comments.map(comment => <Comment
|
||||
parseTime={parseTime}
|
||||
key = {comment.id}
|
||||
commentSecs = {comment.commentSecs}
|
||||
commentLoc = {(comment.commentSecs / this.state.duration) * 100}
|
||||
/>) }
|
||||
</div>
|
||||
<div ref = {this.getPlayerSize} className = "mb-5">
|
||||
<Row>
|
||||
<Col>
|
||||
<Waveform
|
||||
ref = {el => {this.waveform = el}}
|
||||
peaks={config.data}
|
||||
height={200}
|
||||
pos={this.state.songSecs}
|
||||
duration={this.state.duration}
|
||||
onClick={this.openCommentPopup}
|
||||
color="#676767"
|
||||
progressGradientColors={[[0, '#33cccc'], [1, '#aaa']]}
|
||||
/>
|
||||
|
||||
<ReactAudioPlayer
|
||||
src="/audio/01. Lone Digger.mp3"
|
||||
//autoPlay
|
||||
controls
|
||||
listenInterval={100}
|
||||
ref={(element) => { this.rap = element }}
|
||||
onListen={()=>this.setState({songSecs:this.rap.audioEl.currentTime})}
|
||||
/>
|
||||
{this.state.showComments
|
||||
?
|
||||
this.props.comments.map(comment =>
|
||||
<Comment
|
||||
parseTime={parseTime}
|
||||
key = {comment.id}
|
||||
commentSecs = {comment.commentSecs}
|
||||
commentLoc = {(comment.commentSecs / this.state.duration) * 100}
|
||||
text={comment.text}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
<Row>
|
||||
<Col>
|
||||
<ReactAudioPlayer
|
||||
src="/audio/01. Lone Digger.mp3"
|
||||
//autoPlay
|
||||
controls
|
||||
listenInterval={100}
|
||||
ref={(element) => { this.rap = element }}
|
||||
onListen={()=>this.setState({songSecs:this.rap.audioEl.currentTime})}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
{this.state.showPopup ?
|
||||
<CommentPopup
|
||||
@ -117,10 +138,16 @@ class App extends Component {
|
||||
/>
|
||||
: null
|
||||
}
|
||||
</div>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const mapState = state => state
|
||||
export default connect(mapState)(App)
|
||||
const mapDispatch = dispatch => {
|
||||
return {
|
||||
fetchComments: () => dispatch(fetchAllComments()),
|
||||
postComment: comment => dispatch(addComment(comment))
|
||||
}
|
||||
}
|
||||
export default connect(mapState, mapDispatch)(Player)
|
||||
|
@ -4,9 +4,10 @@ import thunkMiddleware from 'redux-thunk'
|
||||
import {composeWithDevTools} from 'redux-devtools-extension'
|
||||
import episodes from './reducers/episodes'
|
||||
import captions from './reducers/captions'
|
||||
import comments from './reducers/comments'
|
||||
|
||||
|
||||
const reducer = combineReducers({episodes, captions})
|
||||
const reducer = combineReducers({episodes, captions, comments})
|
||||
const middleware = composeWithDevTools(
|
||||
applyMiddleware(thunkMiddleware, createLogger({collapsed: true}))
|
||||
)
|
||||
@ -15,3 +16,4 @@ const store = createStore(reducer, middleware)
|
||||
export default store
|
||||
export * from './reducers/episodes'
|
||||
export * from './reducers/captions'
|
||||
export * from './reducers/comments'
|
||||
|
45
src/store/reducers/comments.js
Normal file
45
src/store/reducers/comments.js
Normal file
@ -0,0 +1,45 @@
|
||||
//import axios from 'axios'
|
||||
|
||||
// ACTION TYPES
|
||||
const GOT_ALL_COMMENTS = 'GOT_ALL_COMMENTS'
|
||||
const ADD_COMMENT = 'ADD_COMMENT'
|
||||
const initialComments = []
|
||||
|
||||
// ACTION CREATORS
|
||||
export const gotAllComments = comments => ({
|
||||
type: GOT_ALL_COMMENTS,
|
||||
comments
|
||||
})
|
||||
|
||||
export const addComment = comment => ({
|
||||
type: ADD_COMMENT,
|
||||
comment
|
||||
})
|
||||
|
||||
|
||||
// THUNK CREATORS
|
||||
const comments = [{id: 1, commentSecs: 132, text: 'This is a comment.'}, {id: 2, commentSecs: 32, text: 'Yooo'}]
|
||||
|
||||
export const fetchAllComments = () => async dispatch => {
|
||||
try {
|
||||
//const res = await axios.get('https://irc.anarchyplanet.org/ircbang/api/v2/comments')
|
||||
//const comments = res.data
|
||||
dispatch(gotAllComments(comments))
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
}
|
||||
}
|
||||
|
||||
// REDUCER
|
||||
const commentReducer = (comments = initialComments, action) => {
|
||||
switch (action.type) {
|
||||
case GOT_ALL_COMMENTS:
|
||||
return action.comments
|
||||
case ADD_COMMENT:
|
||||
return comments.concat(action.comment)
|
||||
default:
|
||||
return comments
|
||||
}
|
||||
}
|
||||
|
||||
export default commentReducer
|
Loading…
x
Reference in New Issue
Block a user