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')
|
var asyncjs = require('async')
|
||||||
|
|
||||||
function asObj(str,done){
|
function asObj(str,done){
|
||||||
|
if(str.toString) str = str.toString()
|
||||||
if(typeof str === 'string'){
|
if(typeof str === 'string'){
|
||||||
var obj
|
var obj
|
||||||
try {
|
try {
|
||||||
@ -43,8 +44,9 @@ function replyAsObj(res,isJson,done){
|
|||||||
done(null,data)
|
done(null,data)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else if(res.split || res.toString){
|
||||||
console.log('got string:',res)
|
console.log('got string or buffer:',res)
|
||||||
|
if(res.toString) res = res.toString()
|
||||||
// Is a string
|
// Is a string
|
||||||
if(isJson){
|
if(isJson){
|
||||||
asObj(res,done)
|
asObj(res,done)
|
||||||
@ -88,7 +90,7 @@ BoardsAPI.prototype.resolveIPNS = function(n,handler){
|
|||||||
var cached = this.users[n]
|
var cached = this.users[n]
|
||||||
if(cached){
|
if(cached){
|
||||||
this.ee.emit(n,cached)
|
this.ee.emit(n,cached)
|
||||||
console.log(n,'was cached',cached)
|
//console.log(n,'was cached',cached)
|
||||||
} else {
|
} else {
|
||||||
console.log(n,'not cached')
|
console.log(n,'not cached')
|
||||||
}
|
}
|
||||||
@ -178,7 +180,6 @@ BoardsAPI.prototype.searchUsers = function(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
BoardsAPI.prototype.getProfile = function(userID,done){
|
BoardsAPI.prototype.getProfile = function(userID,done){
|
||||||
console.log('profile requested for',userID)
|
|
||||||
this.resolveIPNS(userID,(url,err) => {
|
this.resolveIPNS(userID,(url,err) => {
|
||||||
if(err){
|
if(err){
|
||||||
this.ee.emit('error',err)
|
this.ee.emit('error',err)
|
||||||
@ -282,41 +283,55 @@ BoardsAPI.prototype.downloadPost = function(hash,adminID,board,op,done){
|
|||||||
return this.ee
|
return this.ee
|
||||||
}
|
}
|
||||||
|
|
||||||
BoardsAPI.prototype.getPostsInBoard = function(adminID,board){
|
BoardsAPI.prototype.retrieveListOfApproved = function(what,addr,adminID,board){
|
||||||
this.getBoardSettings(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){
|
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){
|
if(settings.approval_required == true){
|
||||||
// Get approved posts list
|
// Get approved posts list
|
||||||
var a = addr+this.baseurl+'boards/'+board+'/approved/posts/'
|
if(options.posts) this.retrieveListOfApproved('posts',addr,adminID,board)
|
||||||
this.ipfs.ls(a,(err,res) => {
|
// Get approved comments list
|
||||||
if(err){
|
if(options.comments) this.retrieveListOfApproved('comments',addr,adminID,board)
|
||||||
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(settings.whitelist == true){
|
if(settings.whitelist == true){
|
||||||
// TODO: Download all posts from whitelisted users
|
// TODO: emit all whitelisted users
|
||||||
}
|
}
|
||||||
} else if(settings.whitelist_only == true){
|
} else if(settings.whitelist_only == true){
|
||||||
// TODO: download all posts from whitelisted users
|
// TODO: emit all whitelisted users
|
||||||
} else if(settings.blacklist == true){
|
} 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
|
// Get the admin's posts
|
||||||
this.getUserPostListInBoard(adminID,board,(err,res) => {
|
this.getUserPostListInBoard(adminID,board,(err,res) => {
|
||||||
if(err){
|
if(err){
|
||||||
console.log(err)
|
console.log(err)
|
||||||
} else res.forEach(item => this.downloadPost(item.hash,adminID,board,adminID))
|
} else res.forEach(item => this.downloadPost(item.hash,adminID,board,adminID))
|
||||||
})
|
})
|
||||||
|
this.getAllowedContentProducers(adminID,board,{ posts: true })
|
||||||
return this.ee
|
return this.ee
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -343,9 +358,57 @@ BoardsAPI.prototype.getUserPostListInBoard = function(user,board,done){
|
|||||||
return this.ee
|
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){
|
BoardsAPI.prototype.getCommentsFor = function(parent,board,adminID){
|
||||||
// Create an EventEmitter, start looking and emit an event for every new comment
|
this.ee.on('approved comments for '+board+'@'+adminID,ret => {
|
||||||
// Consider the rules of @adminID#board
|
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...
|
// 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(){
|
postLink: function(){
|
||||||
console.log('op',this.props.post.op,'board',this.props.board)
|
|
||||||
if(this.props.post.op){
|
if(this.props.post.op){
|
||||||
if(this.props.board){
|
if(this.props.board){
|
||||||
return '/@'+this.props.post.op+'/'+this.props.board+'/'+this.props.post.hash
|
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">
|
return <div key={this.props.post.title} className="post">
|
||||||
<div className="content">
|
<div className="content">
|
||||||
<h5>{this.props.post.title}</h5><hr/>
|
<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">
|
<div className="icons">
|
||||||
<UserID id={this.props.post.op}></UserID>
|
<UserID id={this.props.post.op}></UserID>
|
||||||
<Icon name="clock-o" className="not-first"/> {this.getDate()}
|
<Icon name="clock-o" className="not-first"/> {this.getDate()}
|
||||||
|
@ -5,6 +5,8 @@ module.exports = function(boardsAPI){
|
|||||||
var UserID = require('userID.jsx')(boardsAPI)
|
var UserID = require('userID.jsx')(boardsAPI)
|
||||||
var GetIPFS = require('getipfs.jsx')(boardsAPI)
|
var GetIPFS = require('getipfs.jsx')(boardsAPI)
|
||||||
var Post = require('post.jsx')(boardsAPI)
|
var Post = require('post.jsx')(boardsAPI)
|
||||||
|
var Comments = require('comments.jsx')(boardsAPI)
|
||||||
|
|
||||||
return React.createClass({
|
return React.createClass({
|
||||||
getInitialState: function(){
|
getInitialState: function(){
|
||||||
return { post: { title: '...', text: '...' }, api: false }
|
return { post: { title: '...', text: '...' }, api: false }
|
||||||
@ -36,7 +38,7 @@ module.exports = function(boardsAPI){
|
|||||||
getContext(){
|
getContext(){
|
||||||
if(this.props.params.userid){
|
if(this.props.params.userid){
|
||||||
if(this.props.params.boardname)
|
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
|
else
|
||||||
return <div>Posted by <UserID id={this.props.params.userid} /></div>
|
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>
|
} else return <div><h6 className="light">You are viewing a single post</h6></div>
|
||||||
@ -48,6 +50,7 @@ module.exports = function(boardsAPI){
|
|||||||
{this.getContext()}
|
{this.getContext()}
|
||||||
</div>
|
</div>
|
||||||
<Post post={this.state.post} board={this.props.params.boardname} />
|
<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>
|
</div>
|
||||||
else return <GetIPFS />
|
else return <GetIPFS />
|
||||||
}
|
}
|
||||||
|
@ -75,7 +75,7 @@ a:hover {
|
|||||||
margin: 2rem;
|
margin: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.post .icons .fa {
|
.post .icons .fa, .comment .icons .fa {
|
||||||
color: #707070;
|
color: #707070;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,6 +95,15 @@ a:hover {
|
|||||||
display: inline
|
display: inline
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.comment .icons {
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comment .icons .user-id {
|
||||||
|
margin-right: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.navbar {
|
.navbar {
|
||||||
border-bottom: 1px solid #eee;
|
border-bottom: 1px solid #eee;
|
||||||
display: block;
|
display: block;
|
||||||
|
Loading…
Reference in New Issue
Block a user