1
0
mirror of https://github.com/fazo96/ipfs-boards synced 2025-01-26 15:04:19 +01:00

implemented new Post component

This commit is contained in:
Enrico Fasoli 2015-12-17 22:19:21 +01:00
parent 0bf9dcca1f
commit 086e6da860
4 changed files with 76 additions and 61 deletions

View File

@ -10,7 +10,6 @@ Needs to be browserified to work in the browser
var EventEmitter = require('wolfy87-eventemitter') var EventEmitter = require('wolfy87-eventemitter')
var asyncjs = require('async') var asyncjs = require('async')
var semver = require('semver') var semver = require('semver')
var moment = require('moment')
function asObj (str, done) { function asObj (str, done) {
if (str.toString) str = str.toString() if (str.toString) str = str.toString()
@ -168,7 +167,7 @@ BoardsAPI.prototype.createBoard = function (board, done) {
BoardsAPI.prototype.createPost = function (post, board, done) { BoardsAPI.prototype.createPost = function (post, board, done) {
try { try {
post.date = moment().unix() post.date = (new Date()).getTime()
post.op = this.id post.op = this.id
var post_str = JSON.stringify(post) var post_str = JSON.stringify(post)
} catch (e) { } catch (e) {
@ -423,9 +422,18 @@ BoardsAPI.prototype.getBoardSettings = function (userID, board, done) {
} }
BoardsAPI.prototype.downloadPost = function (hash, adminID, board, op, done) { BoardsAPI.prototype.downloadPost = function (hash, adminID, board, op, done) {
if (typeof adminID === 'function') done = adminID if (typeof adminID === 'function') {
if (typeof board === 'function') done = board done = adminID
if (typeof op === 'function') done = op adminID = undefined
}
if (typeof board === 'function') {
done = board
board = undefined
}
if (typeof op === 'function') {
done = op
op = undefined
}
console.log('Downloading post', hash) console.log('Downloading post', hash)
this.ipfs.cat(hash, (err2, r) => { this.ipfs.cat(hash, (err2, r) => {
if (err2) { if (err2) {
@ -439,11 +447,11 @@ BoardsAPI.prototype.downloadPost = function (hash, adminID, board, op, done) {
post.hash = hash post.hash = hash
if (op) post.op = op // Inject op if (op) post.op = op // Inject op
if (board) { if (board) {
if (adminID) this.ee.emit('post in ' + board + '@' + adminID, post, hash) if (adminID) this.ee.emit('post in ' + board + '@' + adminID, hash, post.date, post)
else this.ee.emit('post in ' + board, post, hash) else this.ee.emit('post in ' + board, hash, post.date, post)
} }
this.ee.emit(hash, post, adminID, board) this.ee.emit(hash, post, adminID, board)
if (done && done.apply) done(null, post) if (done && done.apply) done(null, hash, post.date, post)
}) })
} }
}) })
@ -484,17 +492,19 @@ BoardsAPI.prototype.getAllowedContentProducers = function (adminID, board, optio
return this.ee return this.ee
} }
BoardsAPI.prototype.getPostsInBoard = function (adminID, board) { BoardsAPI.prototype.getPostsInBoard = function (adminID, board, opt) {
opt = opt || {}
var emitPost = i => this.ee.emit('post in ' + board + '@' + adminID, i.hash, i.date)
if (adminID) { if (adminID) {
this.ee.on('approved posts for ' + board + '@' + adminID, ret => { this.ee.on('approved posts for ' + board + '@' + adminID, ret => {
// Automatically download approved posts // Automatically download approved posts
ret.forEach(item => this.downloadPost(item.hash, adminID, board)) ret.forEach(emitPost)
}) })
this.ee.on('whitelist for ' + board + '@' + adminID, whitelist => { this.ee.on('whitelist for ' + board + '@' + adminID, whitelist => {
// download posts for each user in whitelist // download posts for each user in whitelist
whitelist.forEach(item => { whitelist.forEach(item => {
this.getUserPostListInBoard(item, board, (err, postList) => { this.getUserPostListInBoard(item, board, (err, postList) => {
if (!err) postList.forEach(i => this.downloadPost(i.hash, adminID, board, item)) if (!err) postList.forEach(emitPost)
}) })
}) })
}) })
@ -502,7 +512,7 @@ BoardsAPI.prototype.getPostsInBoard = function (adminID, board) {
this.getAllowedContentProducers(adminID, board, { posts: true }) this.getAllowedContentProducers(adminID, board, { posts: true })
// Get the admin's posts // Get the admin's posts
this.getUserPostListInBoard(adminID, board, (err, res) => { this.getUserPostListInBoard(adminID, board, (err, res) => {
if (!err) res.forEach(item => this.downloadPost(item.hash, adminID, board, adminID)) if (!err) res.forEach(emitPost)
}) })
} else { } else {
// TODO: Download all posts in board from everyone // TODO: Download all posts in board from everyone
@ -510,7 +520,7 @@ BoardsAPI.prototype.getPostsInBoard = function (adminID, board) {
this.getUserPostListInBoard(this.id, board, (err, res) => { this.getUserPostListInBoard(this.id, board, (err, res) => {
if (err) { if (err) {
console.log(err) console.log(err)
} else res.forEach(item => this.downloadPost(item.hash, undefined, board, this.id)) } else res.forEach(emitPost)
}) })
} }
return this.ee return this.ee

View File

@ -4,38 +4,58 @@ var Icon = require('icon.jsx')
var Link = require('react-router').Link var Link = require('react-router').Link
var Clock = require('clock.jsx') var Clock = require('clock.jsx')
var UserID = require('userID.jsx') var UserID = require('userID.jsx')
var { Error, Loading } = require('status-components.jsx')
module.exports = React.createClass({ module.exports = React.createClass({
getInitialState: function () { getInitialState () {
return { moment: false } return { loading: true }
}, },
componentDidMount: function () { componentDidMount () {
require.ensure(['moment'], _ => { this.init(this.props)
if (this.isMounted()) this.setState({ moment: require('moment') }) },
componentWillReceiveProps (props) {
this.init(props)
},
init (props) {
var boards = props.api
if (!boards) return this.setState({ error: 'Could not connect to IPFS' })
this.setState({ loading: true })
boards.downloadPost(props.hash, props.adminID, props.board, (err, hash, date, post) => {
this.setState({ error: err, post: post, loading: false })
}) })
}, },
postLink: function () { postLink () {
if (this.props.post.op) { if (this.state.post.op) {
if (this.props.board) { if (this.props.board) {
return '/@' + this.props.post.op + '/' + this.props.board + '/' + this.props.post.hash return '/@' + this.state.post.op + '/' + this.props.board + '/' + this.props.hash
} else { } else {
return '/@' + this.props.post.op + '/post/' + this.props.post.hash return '/@' + this.state.post.op + '/post/' + this.props.hash
} }
} else { } else {
return '/post/' + this.props.post.hash return '/post/' + this.props.hash
} }
}, },
render: function () { getContent () {
return <div key={this.props.post.title} className="post"> if (this.state.error) {
<div className="content"> return <Error className="content" error={this.state.error} />
<h5>{this.props.post.title}</h5><hr/> } else if (this.state.loading) {
<Markdown source={this.props.post.text} /><hr/> return <Loading className="content" title="Downloading post"/>
} else {
return <div className="content">
{ this.state.post.title
? <div><h5>{this.state.post.title}</h5><hr/></div>
: <div />
}
<Markdown source={this.state.post.text} /><hr/>
<div className="icons"> <div className="icons">
<UserID id={this.props.post.op} api={this.props.api} ></UserID> <UserID id={this.state.post.op} api={this.props.api} ></UserID>
<Clock className="not-first" date={this.props.post.date} /> <Clock className="not-first" date={this.state.post.date} />
<Icon name="comments" className="not-first" /> <Link className="nounderline" to={this.postLink()}>View</Link> <Icon name="comments" className="not-first" /> <Link className="nounderline" to={this.postLink()}>View</Link>
</div> </div>
</div> </div>
</div> }
},
render () {
return <div className="post">{this.getContent()}</div>
} }
}) })

View File

@ -13,18 +13,18 @@ module.exports = React.createClass({
init: function (boards) { init: function (boards) {
if (this.state.init) return if (this.state.init) return
this.setState({ api: true }) this.setState({ api: true })
var onPost = (post, hash) => { var onPost = (hash, date, post) => {
if (!this.isMounted()) return true if (!this.isMounted()) return true
var now = (new Date()).getTime() var now = (new Date()).getTime()
var posts = this.state.posts var posts = this.state.posts
if (post.date === undefined || post.date <= 0) { if (date === undefined || date <= 0) {
posts.push(post) posts.push(hash)
} else if (post.date <= now) { } else /* if (date <= now) */ {
var i = sortedIndex(posts, post, (p) => now - p.date || now) var i = sortedIndex(posts, post, (p) => now - date || now)
posts.splice(i, 0, post) posts.splice(i, 0, hash)
} else { } /* else {
console.log('Post discarded cause date in the future:', post) console.log('Post discarded cause date in the future:', hash)
} }*/
this.setState({ posts }) this.setState({ posts })
} }
boards.getEventEmitter().on('post in ' + this.props.board + (this.props.admin ? '@' + this.props.admin : ''), onPost) boards.getEventEmitter().on('post in ' + this.props.board + (this.props.admin ? '@' + this.props.admin : ''), onPost)
@ -45,8 +45,8 @@ module.exports = React.createClass({
}, },
getPosts: function () { getPosts: function () {
if (this.state.posts.length > 0 || this.state.api) { if (this.state.posts.length > 0 || this.state.api) {
return this.state.posts.map(post => { return this.state.posts.map(hash => {
return <Post key={post.hash} board={this.props.board} admin={this.props.admin} post={post} api={this.props.api} /> return <Post key={hash} board={this.props.board} admin={this.props.admin} hash={hash} api={this.props.api} />
}) })
} else { } else {
return <div className="center-block text-center"> return <div className="center-block text-center">

View File

@ -8,11 +8,10 @@ var Comments = require('comment.jsx').Comments
module.exports = function (boardsAPI) { module.exports = function (boardsAPI) {
return React.createClass({ return React.createClass({
getInitialState: function () { getInitialState: function () {
return { post: { title: '...', text: '...' }, api: false } return { }
}, },
componentDidMount: function () { componentDidMount: function () {
boardsAPI.use(boards => { boardsAPI.use(boards => {
boards.init()
boards.getEventEmitter().on('init', err => { boards.getEventEmitter().on('init', err => {
if (!err && this.isMounted()) { if (!err && this.isMounted()) {
this.init(boards) this.init(boards)
@ -21,26 +20,12 @@ module.exports = function (boardsAPI) {
if (this.isMounted() && boards.isInit) { if (this.isMounted() && boards.isInit) {
this.init(boards) this.init(boards)
} }
}) boards.init()
},
componentWillReceiveProps: function (nextProps) {
boardsAPI.use(boards => this.downloadPost(boards, nextProps))
},
downloadPost: function (boards, props) {
boards.downloadPost(props.params.posthash, props.params.userid, props.params.boardname, props.params.userid, (err, post) => {
if (err) {
this.setState({
post: { title: 'Error', text: err.Message || err.Error }
})
} else {
this.setState({ post })
}
}) })
}, },
init: function (boards) { init: function (boards) {
if (this.state.init) return if (this.state.init) return
this.setState({ api: true, boards: boards }) this.setState({ api: boards })
this.downloadPost(boards, this.props)
}, },
getContext: function () { getContext: function () {
if (this.props.params.userid) { if (this.props.params.userid) {
@ -57,7 +42,7 @@ module.exports = function (boardsAPI) {
<div className="text-center"> <div className="text-center">
{this.getContext()} {this.getContext()}
</div> </div>
<Post post={this.state.post} board={this.props.params.boardname} api={this.state.boards} /> <Post hash={this.props.params.posthash} board={this.props.params.boardname} api={this.state.api} />
<Comments parent={this.props.params.posthash} board={this.props.params.boardname} adminID={this.props.params.userid} post={this.props.params.posthash} api={this.state.boards} /> <Comments parent={this.props.params.posthash} board={this.props.params.boardname} adminID={this.props.params.userid} post={this.props.params.posthash} api={this.state.boards} />
</div> </div>
} else { } else {