1
0
forked from notnull/waveform

added comment functionality; comment reducer

This commit is contained in:
notnull 2019-04-01 22:02:38 -04:00
parent fea715168a
commit be8660990b
4 changed files with 151 additions and 57 deletions

View File

@ -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

View File

@ -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)

View File

@ -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'

View 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