mirror of
https://github.com/fazo96/ipfs-boards
synced 2025-01-10 12:24:20 +01:00
I guess comments are kinda implemented
This commit is contained in:
parent
ce187c3ddc
commit
573303de39
@ -11,6 +11,7 @@ var EventEmitter = require('wolfy87-eventemitter')
|
||||
var asyncjs = require('async')
|
||||
|
||||
function asObj(str,done){
|
||||
if(str.toString) str = str.toString()
|
||||
if(typeof str === 'string'){
|
||||
var obj
|
||||
try {
|
||||
@ -43,8 +44,9 @@ function replyAsObj(res,isJson,done){
|
||||
done(null,data)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
console.log('got string:',res)
|
||||
} else if(res.split || res.toString){
|
||||
console.log('got string or buffer:',res)
|
||||
if(res.toString) res = res.toString()
|
||||
// Is a string
|
||||
if(isJson){
|
||||
asObj(res,done)
|
||||
@ -88,7 +90,7 @@ BoardsAPI.prototype.resolveIPNS = function(n,handler){
|
||||
var cached = this.users[n]
|
||||
if(cached){
|
||||
this.ee.emit(n,cached)
|
||||
console.log(n,'was cached',cached)
|
||||
//console.log(n,'was cached',cached)
|
||||
} else {
|
||||
console.log(n,'not cached')
|
||||
}
|
||||
@ -178,7 +180,6 @@ BoardsAPI.prototype.searchUsers = function(){
|
||||
}
|
||||
|
||||
BoardsAPI.prototype.getProfile = function(userID,done){
|
||||
console.log('profile requested for',userID)
|
||||
this.resolveIPNS(userID,(url,err) => {
|
||||
if(err){
|
||||
this.ee.emit('error',err)
|
||||
@ -282,41 +283,55 @@ BoardsAPI.prototype.downloadPost = function(hash,adminID,board,op,done){
|
||||
return this.ee
|
||||
}
|
||||
|
||||
BoardsAPI.prototype.getPostsInBoard = function(adminID,board){
|
||||
this.getBoardSettings(adminID,board)
|
||||
BoardsAPI.prototype.retrieveListOfApproved = function(what,addr,adminID,board){
|
||||
var a = addr+this.baseurl+'boards/'+board+'/approved/'+what+'/'
|
||||
this.ipfs.ls(a,(err,res) => {
|
||||
if(err){
|
||||
this.ee.emit('error',err)
|
||||
} else {
|
||||
// Send approved posts list
|
||||
var ret = res.Objects[0].Links.map(item => {
|
||||
return { date: item.Name, hash: item.Hash }
|
||||
})
|
||||
this.emit('approved '+what+' for '+board+'@'+adminID,ret)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
BoardsAPI.prototype.getAllowedContentProducers = function(adminID,board,options){
|
||||
if(!options) return
|
||||
this.ee.on('settings for'+board+'@'+adminID,function(settings,addr){
|
||||
// Download posts based on settings
|
||||
// Get stuff based on settings
|
||||
if(settings.approval_required == true){
|
||||
// Get approved posts list
|
||||
var a = addr+this.baseurl+'boards/'+board+'/approved/posts/'
|
||||
this.ipfs.ls(a,(err,res) => {
|
||||
if(err){
|
||||
this.ee.emit('error',err)
|
||||
} else {
|
||||
// Send approved posts list
|
||||
var ret = res.Objects[0].Links.map(item => {
|
||||
return { date: item.Name, hash: item.Hash }
|
||||
})
|
||||
this.emit('approved posts for '+board+'@'+adminID,ret)
|
||||
// Automatically download approved posts
|
||||
ret.forEach(item => this.downloadPost(item.hash,adminID,board))
|
||||
}
|
||||
})
|
||||
if(options.posts) this.retrieveListOfApproved('posts',addr,adminID,board)
|
||||
// Get approved comments list
|
||||
if(options.comments) this.retrieveListOfApproved('comments',addr,adminID,board)
|
||||
if(settings.whitelist == true){
|
||||
// TODO: Download all posts from whitelisted users
|
||||
// TODO: emit all whitelisted users
|
||||
}
|
||||
} else if(settings.whitelist_only == true){
|
||||
// TODO: download all posts from whitelisted users
|
||||
// TODO: emit all whitelisted users
|
||||
} else if(settings.blacklist == true){
|
||||
// TODO: get the blacklist, then start downloading posts from everyone not in the blacklist
|
||||
// TODO: emit all users not in the blacklist
|
||||
}
|
||||
})
|
||||
this.getBoardSettings(adminID,board)
|
||||
return this.ee
|
||||
}
|
||||
|
||||
BoardsAPI.prototype.getPostsInBoard = function(adminID,board){
|
||||
this.ee.on('approved posts for '+board+'@'+adminID,ret => {
|
||||
// Automatically download approved posts
|
||||
ret.forEach(item => this.downloadPost(item.hash,adminID,board))
|
||||
})
|
||||
// Get the admin's posts
|
||||
this.getUserPostListInBoard(adminID,board,(err,res) => {
|
||||
if(err){
|
||||
console.log(err)
|
||||
} else res.forEach(item => this.downloadPost(item.hash,adminID,board,adminID))
|
||||
})
|
||||
this.getAllowedContentProducers(adminID,board,{ posts: true })
|
||||
return this.ee
|
||||
}
|
||||
|
||||
@ -343,9 +358,57 @@ BoardsAPI.prototype.getUserPostListInBoard = function(user,board,done){
|
||||
return this.ee
|
||||
}
|
||||
|
||||
BoardsAPI.prototype.downloadComment = function(hash,adminID,board,done){
|
||||
this.ipfs.cat(hash,(err2,r) => {
|
||||
if(err2){
|
||||
this.ee.emit('error',err2)
|
||||
console.log('Could not download comment',hash,'of',board+'@'+adminID)
|
||||
if(done && done.apply) done(err2)
|
||||
} else {
|
||||
// TODO: add JSON parsing error handling
|
||||
var cmnt = JSON.parse(r.toString())
|
||||
cmnt.hash = hash
|
||||
this.ee.emit(hash,cmnt,adminID,board)
|
||||
this.ee.emit('comment for '+cmnt.parent,cmnt)
|
||||
if(done && done.apply) done(null,cmnt)
|
||||
}
|
||||
})
|
||||
return this.ee
|
||||
}
|
||||
|
||||
BoardsAPI.prototype.getCommentsFor = function(parent,board,adminID){
|
||||
// Create an EventEmitter, start looking and emit an event for every new comment
|
||||
// Consider the rules of @adminID#board
|
||||
this.ee.on('approved comments for '+board+'@'+adminID,ret => {
|
||||
ret.forEach(item => this.downloadComment(item.hash,adminID,board))
|
||||
})
|
||||
// get the admin's comments
|
||||
this.getUserCommentList(parent,adminID,(err,res) => {
|
||||
if(err){
|
||||
console.log(err)
|
||||
} else res.forEach(item => this.downloadComment(item.hash,adminID,board))
|
||||
})
|
||||
this.getAllowedContentProducers(adminID,board,{ comments: true })
|
||||
}
|
||||
|
||||
BoardsAPI.prototype.getUserCommentList = function(parent,user,done){
|
||||
this.resolveIPNS(user,(url,err) => {
|
||||
if(err){
|
||||
this.ee.emit('error',err)
|
||||
done(err)
|
||||
} else this.ipfs.ls(url+this.baseurl+'comments/'+parent,(e,r) => {
|
||||
if(e){
|
||||
this.ee.emit('error',e)
|
||||
done(e)
|
||||
} else if(r && !r.split){
|
||||
console.log('Found',r.Objects[0].Links.length,'comments for',parent,'at',user)
|
||||
var l = r.Objects[0].Links.map(i => {
|
||||
return { date: i.Name, hash: i.Hash }
|
||||
})
|
||||
done(null,l)
|
||||
}
|
||||
})
|
||||
return true // remove myself from listeners
|
||||
})
|
||||
return this.ee
|
||||
}
|
||||
|
||||
// API for publishing content and managing to be done later...
|
||||
|
39
webapp/components/comment.jsx
Normal file
39
webapp/components/comment.jsx
Normal file
@ -0,0 +1,39 @@
|
||||
var React = require('react')
|
||||
var Markdown = require('markdown.jsx')
|
||||
var Icon = require('icon.jsx')
|
||||
|
||||
module.exports = function(boardsAPI){
|
||||
var UserID = require('userID.jsx')(boardsAPI)
|
||||
return React.createClass({
|
||||
getInitialState: function(){
|
||||
return { moment: false }
|
||||
},
|
||||
componentDidMount: function(){
|
||||
require.ensure(['moment'],_ => {
|
||||
if(this.isMounted()) this.setState({ moment: require('moment') })
|
||||
})
|
||||
},
|
||||
getDate: function(){
|
||||
if(this.props.comment.date){
|
||||
if(this.state.moment)
|
||||
return this.state.moment.unix(this.props.comment.date).fromNow()
|
||||
else return '...'
|
||||
} else {
|
||||
return 'Unknown Date'
|
||||
}
|
||||
},
|
||||
render: function(){
|
||||
if(this.props.comment){
|
||||
return <div className="comment"><hr/>
|
||||
<div className="icons">
|
||||
<UserID id={this.props.comment.op} />
|
||||
<Icon name="clock-o" className="not-first"/> {this.getDate()}
|
||||
</div>
|
||||
<Markdown source={this.props.comment.text} />
|
||||
<hr/></div>
|
||||
} else {
|
||||
return <div><hr/>Invalid Comment<hr/></div>
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
30
webapp/components/comments.jsx
Normal file
30
webapp/components/comments.jsx
Normal file
@ -0,0 +1,30 @@
|
||||
var React = require('react')
|
||||
|
||||
module.exports = function(boardsAPI){
|
||||
var Comment = require('comment.jsx')(boardsAPI)
|
||||
return React.createClass({
|
||||
getInitialState: function(){
|
||||
return { comments: [] }
|
||||
},
|
||||
componentDidMount: function(){
|
||||
boardsAPI.use(boards => {
|
||||
boards.getEventEmitter().on('comment for '+this.props.parent,cmnt => {
|
||||
if(this.isMounted()) this.setState({ comments: this.state.comments.concat(cmnt) })
|
||||
})
|
||||
if(boards.isInit && this.isMounted()){
|
||||
boards.getCommentsFor(this.props.parent,this.props.board,this.props.adminID)
|
||||
}
|
||||
boards.getEventEmitter().on('init', err => {
|
||||
if(!err && this.isMounted())
|
||||
boards.getCommentsFor(this.props.parent,this.props.board,this.props.adminID)
|
||||
})
|
||||
})
|
||||
},
|
||||
getComments: function(){
|
||||
return this.state.comments.map(cmnt => (<Comment key={cmnt.hash} comment={cmnt} />) )
|
||||
},
|
||||
render: function(){
|
||||
return <div>{this.getComments()}</div>
|
||||
}
|
||||
})
|
||||
}
|
@ -24,7 +24,6 @@ module.exports = function(boardsAPI){
|
||||
})
|
||||
},
|
||||
postLink: function(){
|
||||
console.log('op',this.props.post.op,'board',this.props.board)
|
||||
if(this.props.post.op){
|
||||
if(this.props.board){
|
||||
return '/@'+this.props.post.op+'/'+this.props.board+'/'+this.props.post.hash
|
||||
@ -39,7 +38,7 @@ module.exports = function(boardsAPI){
|
||||
return <div key={this.props.post.title} className="post">
|
||||
<div className="content">
|
||||
<h5>{this.props.post.title}</h5><hr/>
|
||||
<Markdown source={this.props.post.text} skipHtml={true} /><hr/>
|
||||
<Markdown source={this.props.post.text} /><hr/>
|
||||
<div className="icons">
|
||||
<UserID id={this.props.post.op}></UserID>
|
||||
<Icon name="clock-o" className="not-first"/> {this.getDate()}
|
||||
|
@ -5,6 +5,8 @@ module.exports = function(boardsAPI){
|
||||
var UserID = require('userID.jsx')(boardsAPI)
|
||||
var GetIPFS = require('getipfs.jsx')(boardsAPI)
|
||||
var Post = require('post.jsx')(boardsAPI)
|
||||
var Comments = require('comments.jsx')(boardsAPI)
|
||||
|
||||
return React.createClass({
|
||||
getInitialState: function(){
|
||||
return { post: { title: '...', text: '...' }, api: false }
|
||||
@ -36,7 +38,7 @@ module.exports = function(boardsAPI){
|
||||
getContext(){
|
||||
if(this.props.params.userid){
|
||||
if(this.props.params.boardname)
|
||||
return <div>Posted by <UserID id={this.props.params.userid} /> in <Link to={'@/'+this.props.params.userid+'/'+this.props.params.boardname}>#{this.props.params.boardname}</Link></div>
|
||||
return <div>Posted by <UserID id={this.props.params.userid} /> in <Link to={'@'+this.props.params.userid+'/'+this.props.params.boardname}>#{this.props.params.boardname}</Link></div>
|
||||
else
|
||||
return <div>Posted by <UserID id={this.props.params.userid} /></div>
|
||||
} else return <div><h6 className="light">You are viewing a single post</h6></div>
|
||||
@ -48,6 +50,7 @@ module.exports = function(boardsAPI){
|
||||
{this.getContext()}
|
||||
</div>
|
||||
<Post post={this.state.post} board={this.props.params.boardname} />
|
||||
<Comments parent={this.props.params.posthash} board={this.props.params.boardname} adminID={this.props.params.userid}/>
|
||||
</div>
|
||||
else return <GetIPFS />
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ a:hover {
|
||||
margin: 2rem;
|
||||
}
|
||||
|
||||
.post .icons .fa {
|
||||
.post .icons .fa, .comment .icons .fa {
|
||||
color: #707070;
|
||||
}
|
||||
|
||||
@ -95,6 +95,15 @@ a:hover {
|
||||
display: inline
|
||||
}
|
||||
|
||||
.comment .icons {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.comment .icons .user-id {
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
|
||||
.navbar {
|
||||
border-bottom: 1px solid #eee;
|
||||
display: block;
|
||||
|
Loading…
Reference in New Issue
Block a user