mirror of
https://github.com/fazo96/ipfs-boards
synced 2025-01-10 12:24:20 +01:00
refactored all code to comply with new code style
This commit is contained in:
parent
307605a404
commit
78c659e123
@ -10,113 +10,113 @@ Needs to be browserified to work in the browser
|
||||
var EventEmitter = require('wolfy87-eventemitter')
|
||||
var asyncjs = require('async')
|
||||
|
||||
function asObj(str,done){
|
||||
if(str.toString) str = str.toString()
|
||||
if(typeof str === 'string'){
|
||||
function asObj (str, done) {
|
||||
if (str.toString) str = str.toString()
|
||||
if (typeof str === 'string') {
|
||||
var obj
|
||||
try {
|
||||
obj = JSON.parse(str)
|
||||
} catch (e) {
|
||||
console.log('error parsing:',str,'Error:',e)
|
||||
return done(e,undefined)
|
||||
console.log('error parsing:', str, 'Error:', e)
|
||||
return done(e, undefined)
|
||||
}
|
||||
done(null,obj)
|
||||
done(null, obj)
|
||||
} else {
|
||||
console.log('not string:',str)
|
||||
done('not string: '+str,undefined)
|
||||
console.log('not string:', str)
|
||||
done('not string: ' + str, undefined)
|
||||
}
|
||||
}
|
||||
|
||||
function replyAsObj(res,isJson,done){
|
||||
if(res.readable){
|
||||
function replyAsObj (res, isJson, done) {
|
||||
if (res.readable) {
|
||||
// Is a stream
|
||||
console.log('got stream')
|
||||
res.setEncoding('utf8')
|
||||
var data = ''
|
||||
res.on('data',d => {
|
||||
console.log('got stream data:',d)
|
||||
res.on('data', d => {
|
||||
console.log('got stream data:', d)
|
||||
data += d
|
||||
})
|
||||
res.on('end',() => {
|
||||
if(isJson) {
|
||||
asObj(data,done)
|
||||
res.on('end', () => {
|
||||
if (isJson) {
|
||||
asObj(data, done)
|
||||
} else {
|
||||
done(null,data)
|
||||
done(null, data)
|
||||
}
|
||||
})
|
||||
} else if(res.split || res.toString){
|
||||
//console.log('got string or buffer:',res)
|
||||
if(res.toString) res = res.toString()
|
||||
} 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)
|
||||
if (isJson) {
|
||||
asObj(res, done)
|
||||
} else {
|
||||
done(null,res)
|
||||
done(null, res)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function BoardsAPI(ipfs){
|
||||
function BoardsAPI (ipfs) {
|
||||
this.ipfs = ipfs
|
||||
this.version = 'ipfs:boards:version:dev'
|
||||
this.baseurl = '/ipfs-boards-profile/'
|
||||
this.users = [] // list of IPNS names
|
||||
this.resolvingIPNS = {}
|
||||
this.ee = new EventEmitter()
|
||||
if(localStorage !== undefined){
|
||||
if (window && window.localStorage !== undefined) {
|
||||
// Use localStorage to store the IPNS cache
|
||||
var stored = localStorage.getItem('ipfs-boards-user-cache')
|
||||
var stored = window.localStorage.getItem('ipfs-boards-user-cache')
|
||||
try {
|
||||
this.users = JSON.parse(stored)
|
||||
if(this.users === null || this.users === undefined || !this.users.indexOf || !this.users.push){
|
||||
if (this.users === null || this.users === undefined || !this.users.indexOf || !this.users.push) {
|
||||
this.users = []
|
||||
}
|
||||
} catch(e){
|
||||
} catch (e) {
|
||||
this.users = []
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BoardsAPI.prototype.backupCache = function(){
|
||||
if(localStorage !== undefined){
|
||||
BoardsAPI.prototype.backupCache = function () {
|
||||
if (window && window.localStorage !== undefined) {
|
||||
// Use localStorage to store the IPNS cache
|
||||
localStorage.setItem('ipfs-boards-user-cache',JSON.stringify(this.users))
|
||||
window.localStorage.setItem('ipfs-boards-user-cache', JSON.stringify(this.users))
|
||||
}
|
||||
}
|
||||
|
||||
// Rewrote this to use event emitters. Should also add periodic rechecking
|
||||
BoardsAPI.prototype.resolveIPNS = function(n,handler){
|
||||
if(handler && handler.apply) this.ee.on(n,handler)
|
||||
if(!this.resolvingIPNS[n]){
|
||||
BoardsAPI.prototype.resolveIPNS = function (n, handler) {
|
||||
if (handler && handler.apply) this.ee.on(n, handler)
|
||||
if (!this.resolvingIPNS[n]) {
|
||||
this.resolvingIPNS[n] = true
|
||||
this.ipfs.name.resolve(n,(err,r) => {
|
||||
this.ipfs.name.resolve(n, (err, r) => {
|
||||
delete this.resolvingIPNS[n]
|
||||
if(err){
|
||||
if (err) {
|
||||
// Communicate error
|
||||
this.ee.emit('error',err)
|
||||
this.ee.emit('error', err)
|
||||
} else {
|
||||
var url = r.Path
|
||||
if(url === undefined){
|
||||
console.log('Could not resolve',n)
|
||||
this.ee.emit('error',r.Message)
|
||||
} else if(this.users.indexOf(n) < 0){ // new find
|
||||
this.isUserProfile(url,(isit,err) => {
|
||||
if(isit){
|
||||
console.log(n,'is a user')
|
||||
this.ee.emit(n,url)
|
||||
if(this.users.indexOf(n) < 0){
|
||||
this.ee.emit('user',n,url)
|
||||
if (url === undefined) {
|
||||
console.log('Could not resolve', n)
|
||||
this.ee.emit('error', r.Message)
|
||||
} else if (this.users.indexOf(n) < 0) { // new find
|
||||
this.isUserProfile(url, (isit, err) => {
|
||||
if (isit) {
|
||||
console.log(n, 'is a user')
|
||||
this.ee.emit(n, url)
|
||||
if (this.users.indexOf(n) < 0) {
|
||||
this.ee.emit('user', n, url)
|
||||
this.users.push(n)
|
||||
this.backupCache()
|
||||
}
|
||||
} else {
|
||||
console.log(n,'not a valid profile:',err)
|
||||
this.ee.emit(n,undefined,'not a valid profile: '+err)
|
||||
console.log(n, 'not a valid profile:', err)
|
||||
this.ee.emit(n, undefined, 'not a valid profile: ' + err)
|
||||
}
|
||||
return true // Remove from listeners
|
||||
})
|
||||
} else { // Already known
|
||||
this.ee.emit(n,url)
|
||||
this.ee.emit(n, url)
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -124,44 +124,44 @@ BoardsAPI.prototype.resolveIPNS = function(n,handler){
|
||||
return this.ee
|
||||
}
|
||||
|
||||
BoardsAPI.prototype.isUserProfile = function(addr,done){
|
||||
if(addr === undefined) return console.log('Asked to check if undefined is a profile')
|
||||
this.ipfs.cat(addr+this.baseurl+'ipfs-boards-version.txt',(err,r) => {
|
||||
if(err) return done(false,err)
|
||||
replyAsObj(r,false,(_,res) => {
|
||||
if(!res || !res.trim){
|
||||
console.log('Could not read version from',addr)
|
||||
BoardsAPI.prototype.isUserProfile = function (addr, done) {
|
||||
if (addr === undefined) return console.log('Asked to check if undefined is a profile')
|
||||
this.ipfs.cat(addr + this.baseurl + 'ipfs-boards-version.txt', (err, r) => {
|
||||
if (err) return done(false, err)
|
||||
replyAsObj(r, false, (_, res) => {
|
||||
if (!res || !res.trim) {
|
||||
console.log('Could not read version from', addr)
|
||||
} else {
|
||||
var v = res.trim()
|
||||
console.log('Version in profile snapshot',addr,'is',v)
|
||||
if(v === this.version){
|
||||
console.log('Version in profile snapshot', addr, 'is', v)
|
||||
if (v === this.version) {
|
||||
done(true)
|
||||
} else {
|
||||
done(false,'version mismatch: is "'+v+'" but should be "'+this.version+'"')
|
||||
done(false, 'version mismatch: is "' + v + '" but should be "' + this.version + '"')
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
BoardsAPI.prototype.searchUsers = function(){
|
||||
BoardsAPI.prototype.searchUsers = function () {
|
||||
// Look at our peers
|
||||
this.ipfs.swarm.peers((err,r) => {
|
||||
if(err) return console.log(err)
|
||||
replyAsObj(r,true,(e,reply) => {
|
||||
if(e){
|
||||
this.ee.emit('error',e)
|
||||
return console.log('There was an error while getting swarm peers:',e)
|
||||
this.ipfs.swarm.peers((err, r) => {
|
||||
if (err) return console.log(err)
|
||||
replyAsObj(r, true, (e, reply) => {
|
||||
if (e) {
|
||||
this.ee.emit('error', e)
|
||||
return console.log('There was an error while getting swarm peers:', e)
|
||||
}
|
||||
console.log('Checking',reply.Strings.length,'peers')
|
||||
//reply.Strings.forEach(item => {
|
||||
console.log('Checking', reply.Strings.length, 'peers')
|
||||
// reply.Strings.forEach(item => {
|
||||
var f = (item, done) => {
|
||||
var ss = item.split('/')
|
||||
var n = ss[ss.length-1]
|
||||
this.ee.once(n,(res,err) => done(err))
|
||||
var n = ss[ss.length - 1]
|
||||
this.ee.once(n, (res, err) => done(err))
|
||||
this.resolveIPNS(n)
|
||||
}
|
||||
asyncjs.eachSeries(reply.Strings,f.bind(this))
|
||||
asyncjs.eachSeries(reply.Strings, f.bind(this))
|
||||
})
|
||||
})
|
||||
// Look for who has the correct version file, they probably have a profile
|
||||
@ -178,33 +178,33 @@ BoardsAPI.prototype.searchUsers = function(){
|
||||
return this.ee
|
||||
}
|
||||
|
||||
BoardsAPI.prototype.getProfile = function(userID,done){
|
||||
this.resolveIPNS(userID,(url,err) => {
|
||||
if(err){
|
||||
this.ee.emit('error',err)
|
||||
done(err,null)
|
||||
BoardsAPI.prototype.getProfile = function (userID, done) {
|
||||
this.resolveIPNS(userID, (url, err) => {
|
||||
if (err) {
|
||||
this.ee.emit('error', err)
|
||||
done(err, null)
|
||||
} else {
|
||||
// Download actual profile
|
||||
this.ipfs.cat(url+this.baseurl+'profile.json',(err2,res) => {
|
||||
if(err2){
|
||||
this.ee.emit('error',err2)
|
||||
done(err2,null)
|
||||
this.ipfs.cat(url + this.baseurl + 'profile.json', (err2, res) => {
|
||||
if (err2) {
|
||||
this.ee.emit('error', err2)
|
||||
done(err2, null)
|
||||
} else {
|
||||
// TODO: JSON parse error handling
|
||||
var p = JSON.parse(res.toString())
|
||||
this.ee.emit('profile for '+userID,p)
|
||||
done(null,p)
|
||||
this.ee.emit('profile for ' + userID, p)
|
||||
done(null, p)
|
||||
}
|
||||
})
|
||||
// Get other info
|
||||
this.ipfs.ls(url+this.baseurl+'boards/',(err2,res) => {
|
||||
if(!err2){
|
||||
this.ipfs.ls(url + this.baseurl + 'boards/', (err2, res) => {
|
||||
if (!err2) {
|
||||
var l = res.Objects[0].Links.map(i => {
|
||||
return { name: i.Name, hash: i.Hash }
|
||||
})
|
||||
this.ee.emit('boards for '+userID,l)
|
||||
this.ee.emit('boards for ' + userID, l)
|
||||
} else {
|
||||
this.ee.emit('error',err2)
|
||||
this.ee.emit('error', err2)
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -213,51 +213,58 @@ BoardsAPI.prototype.getProfile = function(userID,done){
|
||||
return this.ee
|
||||
}
|
||||
|
||||
BoardsAPI.prototype.getBoardSettings = function(userID,board){
|
||||
if(!userID){
|
||||
return console.log('Invalid USERID',userID)
|
||||
BoardsAPI.prototype.getBoardSettings = function (userID, board) {
|
||||
if (!userID) {
|
||||
return console.log('Invalid USERID', userID)
|
||||
}
|
||||
if(!board){
|
||||
return console.log('Invalid BOARD',board)
|
||||
if (!board) {
|
||||
return console.log('Invalid BOARD', board)
|
||||
}
|
||||
this.resolveIPNS(userID,(r,e) => {
|
||||
if(e){
|
||||
this.ee.emit('error',e)
|
||||
this.resolveIPNS(userID, (r, e) => {
|
||||
if (e) {
|
||||
this.ee.emit('error', e)
|
||||
} else {
|
||||
var url = r+this.baseurl+'boards/'+board+'/settings.json'
|
||||
this.ipfs.cat(url,(err,resp) => {
|
||||
var url = r + this.baseurl + 'boards/' + board + '/settings.json'
|
||||
this.ipfs.cat(url, (err, resp) => {
|
||||
// TODO: error handling json conversion
|
||||
var settings = JSON.parse(resp.toString())
|
||||
if(err){
|
||||
this.ee.emit('error',err)
|
||||
if (err) {
|
||||
this.ee.emit('error', err)
|
||||
} else {
|
||||
// SETTINGS file is here, need to parse it a little bit
|
||||
this.ee.emit('settings for '+board+'@'+userID,settings,r)
|
||||
if(settings.whitelist == true){
|
||||
this.ee.emit('settings for ' + board + '@' + userID, settings, r)
|
||||
if (settings.whitelist === true) {
|
||||
// Get the whitelist
|
||||
var url = r+this.baseurl+'boards/'+board+'/whitelist'
|
||||
this.ipfs.cat(url,(err,res) => {
|
||||
if(err){
|
||||
this.ee.emit('error',err)
|
||||
var url = r + this.baseurl + 'boards/' + board + '/whitelist'
|
||||
this.ipfs.cat(url, (err, res) => {
|
||||
if (err) {
|
||||
this.ee.emit('error', err)
|
||||
// Emit an empty whitelist.
|
||||
this.ee.emit('whitelist for '+board+'@'+userID,[])
|
||||
} else replyAsObj(res,false,(err,whitelist) => {
|
||||
// Send whitelist
|
||||
var w = whitelist.split(' ').map(x => x.trim())
|
||||
this.ee.emit('whitelist for '+board+'@'+userID,w)
|
||||
})
|
||||
this.ee.emit('whitelist for ' + board + '@' + userID, [])
|
||||
} else {
|
||||
replyAsObj(res, false, (err, whitelist) => {
|
||||
if (err) {
|
||||
// Emit an empty whitelist.
|
||||
this.ee.emit('whitelist for ' + board + '@' + userID, [])
|
||||
} else {
|
||||
// Send whitelist
|
||||
var w = whitelist.split(' ').map(x => x.trim())
|
||||
this.ee.emit('whitelist for ' + board + '@' + userID, w)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
if(!settings.whitelist_only && !settings.approval_required && settings.blacklist == true){
|
||||
if (!settings.whitelist_only && !settings.approval_required && settings.blacklist === true) {
|
||||
// Get the blacklist
|
||||
var u = r+this.baseurl+'boards/'+board+'/blacklist'
|
||||
this.ipfs.cat(u,(err,blacklist) => {
|
||||
if(err){
|
||||
this.ee.emit('error',err)
|
||||
var u = r + this.baseurl + 'boards/' + board + '/blacklist'
|
||||
this.ipfs.cat(u, (err, blacklist) => {
|
||||
if (err) {
|
||||
this.ee.emit('error', err)
|
||||
} else {
|
||||
// Send blacklist
|
||||
var w = blacklist.split(' ')
|
||||
this.emit('blacklist for '+board+'@'+userID,w)
|
||||
this.emit('blacklist for ' + board + '@' + userID, w)
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -269,211 +276,218 @@ BoardsAPI.prototype.getBoardSettings = function(userID,board){
|
||||
return this.ee
|
||||
}
|
||||
|
||||
BoardsAPI.prototype.downloadPost = function(hash,adminID,board,op,done){
|
||||
console.log('Downloading post',hash)
|
||||
this.ipfs.cat(hash,(err2,r) => {
|
||||
if(err2){
|
||||
this.ee.emit('error',err2)
|
||||
console.log('Could not download post',hash,'of',board+'@'+adminID)
|
||||
if(done && done.apply) done(err2)
|
||||
BoardsAPI.prototype.downloadPost = function (hash, adminID, board, op, done) {
|
||||
console.log('Downloading post', hash)
|
||||
this.ipfs.cat(hash, (err2, r) => {
|
||||
if (err2) {
|
||||
this.ee.emit('error', err2)
|
||||
console.log('Could not download post', hash, 'of', board + '@' + adminID)
|
||||
if (done && done.apply) done(err2)
|
||||
} else {
|
||||
replyAsObj(r,true,(err,post) => {
|
||||
replyAsObj(r, true, (err, post) => {
|
||||
if (err) return
|
||||
// TODO: add JSON parsing error handling
|
||||
post.hash = hash
|
||||
if(op) post.op = op // Inject op
|
||||
if(board){
|
||||
if(adminID) this.ee.emit('post in '+board+'@'+adminID,post,hash)
|
||||
else this.ee.emit('post in '+board,post,hash)
|
||||
if (op) post.op = op // Inject op
|
||||
if (board) {
|
||||
if (adminID) this.ee.emit('post in ' + board + '@' + adminID, post, hash)
|
||||
else this.ee.emit('post in ' + board, post, hash)
|
||||
}
|
||||
this.ee.emit(hash,post,adminID,board)
|
||||
if(done && done.apply) done(null,post)
|
||||
this.ee.emit(hash, post, adminID, board)
|
||||
if (done && done.apply) done(null, post)
|
||||
})
|
||||
}
|
||||
})
|
||||
return this.ee
|
||||
}
|
||||
|
||||
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)
|
||||
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)
|
||||
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){
|
||||
BoardsAPI.prototype.getAllowedContentProducers = function (adminID, board, options) {
|
||||
if (!options) return
|
||||
this.ee.on('settings for ' + board + '@' + adminID, function (settings, addr) {
|
||||
// Get stuff based on settings
|
||||
if(settings.approval_required == true){
|
||||
if (settings.approval_required === true) {
|
||||
// Get approved posts list
|
||||
if(options.posts) this.retrieveListOfApproved('posts',addr,adminID,board)
|
||||
if (options.posts) this.retrieveListOfApproved('posts', addr, adminID, board)
|
||||
// Get approved comments list
|
||||
if(options.comments) this.retrieveListOfApproved('comments',addr,adminID,board)
|
||||
} else if(settings.whitelist_only == true){
|
||||
if (options.comments) this.retrieveListOfApproved('comments', addr, adminID, board)
|
||||
} else if (settings.whitelist_only === true) {
|
||||
// TODO: emit all whitelisted users
|
||||
} else if(settings.blacklist == true){
|
||||
} else if (settings.blacklist === true) {
|
||||
// TODO: emit all users not in the blacklist
|
||||
}
|
||||
})
|
||||
this.getBoardSettings(adminID,board)
|
||||
this.getBoardSettings(adminID, board)
|
||||
return this.ee
|
||||
}
|
||||
|
||||
BoardsAPI.prototype.getPostsInBoard = function(adminID,board){
|
||||
if(adminID){
|
||||
this.ee.on('approved posts for '+board+'@'+adminID,ret => {
|
||||
BoardsAPI.prototype.getPostsInBoard = function (adminID, board) {
|
||||
if (adminID) {
|
||||
this.ee.on('approved posts for ' + board + '@' + adminID, ret => {
|
||||
// Automatically download approved posts
|
||||
ret.forEach(item => this.downloadPost(item.hash,adminID,board))
|
||||
ret.forEach(item => this.downloadPost(item.hash, adminID, board))
|
||||
})
|
||||
this.ee.on('whitelist for '+board+'@'+adminID, whitelist => {
|
||||
this.ee.on('whitelist for ' + board + '@' + adminID, whitelist => {
|
||||
// download posts for each user in whitelist
|
||||
whitelist.forEach(item => {
|
||||
this.getUserPostListInBoard(item,board,(err,postList) => {
|
||||
postList.forEach( i => this.downloadPost(i.hash,adminID,board,item))
|
||||
this.getUserPostListInBoard(item, board, (err, postList) => {
|
||||
if (err) return
|
||||
postList.forEach(i => this.downloadPost(i.hash, adminID, board, item))
|
||||
})
|
||||
})
|
||||
})
|
||||
// Get allowed content and content producers
|
||||
this.getAllowedContentProducers(adminID,board,{ posts: true })
|
||||
this.getAllowedContentProducers(adminID, board, { posts: true })
|
||||
// Get the admin's posts
|
||||
this.getUserPostListInBoard(adminID,board,(err,res) => {
|
||||
if(err){
|
||||
this.getUserPostListInBoard(adminID, board, (err, res) => {
|
||||
if (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))
|
||||
})
|
||||
} else {
|
||||
// TODO: Download all posts in board from everyone
|
||||
// Download my posts
|
||||
this.getUserPostListInBoard(this.id,board,(err,res) => {
|
||||
if(err){
|
||||
this.getUserPostListInBoard(this.id, board, (err, res) => {
|
||||
if (err) {
|
||||
console.log(err)
|
||||
} else res.forEach(item => this.downloadPost(item.hash,undefined,board,this.id))
|
||||
} else res.forEach(item => this.downloadPost(item.hash, undefined, board, this.id))
|
||||
})
|
||||
}
|
||||
return this.ee
|
||||
}
|
||||
|
||||
BoardsAPI.prototype.getUserPostListInBoard = function(user,board,done){
|
||||
this.resolveIPNS(user,(url,err) => {
|
||||
if(err){
|
||||
this.ee.emit('error',err)
|
||||
BoardsAPI.prototype.getUserPostListInBoard = function (user, board, done) {
|
||||
this.resolveIPNS(user, (url, err) => {
|
||||
if (err) {
|
||||
this.ee.emit('error', err)
|
||||
done(err)
|
||||
} else this.ipfs.ls(url+this.baseurl+'posts/'+board,(e,r) => {
|
||||
if(e){
|
||||
this.ee.emit('error',e)
|
||||
done(e)
|
||||
} else if(r && !r.split){
|
||||
console.log('Found',r.Objects[0].Links.length,'posts in',board,'at',user)
|
||||
this.ee.emit('post count',board,user,r.Objects[0].Links.length)
|
||||
var l = r.Objects[0].Links.map(i => {
|
||||
return { date: i.Name, hash: i.Hash }
|
||||
})
|
||||
done(null,l)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.ipfs.ls(url + this.baseurl + 'posts/' + board, (e, r) => {
|
||||
if (e) {
|
||||
this.ee.emit('error', e)
|
||||
done(e)
|
||||
} else if (r && !r.split) {
|
||||
console.log('Found', r.Objects[0].Links.length, 'posts in', board, 'at', user)
|
||||
this.ee.emit('post count', board, user, r.Objects[0].Links.length)
|
||||
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
|
||||
}
|
||||
|
||||
BoardsAPI.prototype.downloadComment = function(hash,adminID,board,target,done){
|
||||
if(!done && typeof target == 'function'){
|
||||
BoardsAPI.prototype.downloadComment = function (hash, adminID, board, target, done) {
|
||||
if (!done && typeof target === 'function') {
|
||||
done = target
|
||||
target = undefined
|
||||
}
|
||||
console.log('target',target)
|
||||
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(err2)
|
||||
console.log('target', target)
|
||||
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(err2)
|
||||
} else {
|
||||
// TODO: add JSON parsing error handling
|
||||
var cmnt = JSON.parse(r.toString())
|
||||
cmnt.hash = hash
|
||||
if(target){
|
||||
if (target) {
|
||||
cmnt.original_parent = cmnt.parent
|
||||
cmnt.parent = target
|
||||
}
|
||||
this.ee.emit(hash,cmnt,adminID,board)
|
||||
this.ee.emit('comment for '+(target || cmnt.parent),cmnt)
|
||||
if(done) done(null,cmnt)
|
||||
this.ee.emit(hash, cmnt, adminID, board)
|
||||
this.ee.emit('comment for ' + (target || cmnt.parent), cmnt)
|
||||
if (done) done(null, cmnt)
|
||||
}
|
||||
})
|
||||
return this.ee
|
||||
}
|
||||
|
||||
BoardsAPI.prototype.getCommentsFor = function(parent,board,adminID,target){
|
||||
if(!parent || !board || !adminID){
|
||||
return console.log('malformed arguments:',parent,board,adminID)
|
||||
BoardsAPI.prototype.getCommentsFor = function (parent, board, adminID, target) {
|
||||
if (!parent || !board || !adminID) {
|
||||
return console.log('malformed arguments:', parent, board, adminID)
|
||||
}
|
||||
// figure out if there's a previous version of the item
|
||||
this.ipfs.cat(parent, (err,res) => {
|
||||
if(err){
|
||||
this.ee.emit('error',err)
|
||||
this.ipfs.cat(parent, (err, res) => {
|
||||
if (err) {
|
||||
this.ee.emit('error', err)
|
||||
} else {
|
||||
replyAsObj(res,true,(err2,obj) => {
|
||||
if(err2){
|
||||
this.ee.emit('error',err2)
|
||||
} else if(typeof obj.previous == 'string'){
|
||||
replyAsObj(res, true, (err2, obj) => {
|
||||
if (err2) {
|
||||
this.ee.emit('error', err2)
|
||||
} else if (typeof obj.previous === 'string') {
|
||||
// Also get comments for the previous version of the parent!
|
||||
this.getCommentsFor(obj.previous,board,adminID,parent)
|
||||
this.getCommentsFor(obj.previous, board, adminID, parent)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
// get the admin's comments
|
||||
this.getUserCommentList(parent,adminID,(err,res) => {
|
||||
if(!err){
|
||||
res.forEach(item => this.downloadComment(item.hash,adminID,board,target))
|
||||
this.getUserCommentList(parent, adminID, (err, res) => {
|
||||
if (!err) {
|
||||
res.forEach(item => this.downloadComment(item.hash, adminID, board, target))
|
||||
}
|
||||
})
|
||||
// Download comments from whitelisted
|
||||
this.ee.on('whitelist for '+board+'@'+adminID, whitelist => {
|
||||
this.ee.on('whitelist for ' + board + '@' + adminID, whitelist => {
|
||||
// download posts for each user in whitelist
|
||||
whitelist.forEach(item => {
|
||||
this.getUserCommentList(parent,item,(err,res) => {
|
||||
res.forEach(i => this.downloadComment(i.hash,adminID,board,target))
|
||||
this.getUserCommentList(parent, item, (err, res) => {
|
||||
if (err) return
|
||||
res.forEach(i => this.downloadComment(i.hash, adminID, board, target))
|
||||
})
|
||||
})
|
||||
})
|
||||
// Handle approved comments
|
||||
this.ee.on('approved comments for '+board+'@'+adminID,ret => {
|
||||
ret.forEach(item => this.downloadComment(item.hash,adminID,board,target))
|
||||
this.ee.on('approved comments for ' + board + '@' + adminID, ret => {
|
||||
ret.forEach(item => this.downloadComment(item.hash, adminID, board, target))
|
||||
})
|
||||
this.getAllowedContentProducers(adminID,board,{ comments: true })
|
||||
this.getAllowedContentProducers(adminID, board, { comments: true })
|
||||
}
|
||||
|
||||
BoardsAPI.prototype.getUserCommentList = function(parent,user,done){
|
||||
if(!parent || !user){
|
||||
return console.log('Malformed arguments:',parent,user)
|
||||
BoardsAPI.prototype.getUserCommentList = function (parent, user, done) {
|
||||
if (!parent || !user) {
|
||||
return console.log('Malformed arguments:', parent, user)
|
||||
}
|
||||
this.resolveIPNS(user,(url,err) => {
|
||||
if(err){
|
||||
this.ee.emit('error',err)
|
||||
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){
|
||||
if(r.Objects && r.Objects[0]){ // If this is not true, then there are no comments
|
||||
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)
|
||||
} 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) {
|
||||
if (r.Objects && r.Objects[0]) { // If this is not true, then there are no comments
|
||||
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
|
||||
@ -482,41 +496,41 @@ BoardsAPI.prototype.getUserCommentList = function(parent,user,done){
|
||||
// API for publishing content and managing to be done later...
|
||||
|
||||
// Initialize API
|
||||
BoardsAPI.prototype.init = function(done){
|
||||
if(this.isInit) return
|
||||
this.ipfs.id( (err, res) => {
|
||||
if(err){
|
||||
console.log('Error while getting OWN ID:',err)
|
||||
this.ee.emit('error',err)
|
||||
this.ee.emit('init',err)
|
||||
if(done && done.apply) done(err)
|
||||
} else if(res.ID){
|
||||
console.log('I am',res.ID)
|
||||
BoardsAPI.prototype.init = function (done) {
|
||||
if (this.isInit) return
|
||||
this.ipfs.id((err, res) => {
|
||||
if (err) {
|
||||
console.log('Error while getting OWN ID:', err)
|
||||
this.ee.emit('error', err)
|
||||
this.ee.emit('init', err)
|
||||
if (done && done.apply) done(err)
|
||||
} else if (res.ID) {
|
||||
console.log('I am', res.ID)
|
||||
this.id = res.ID
|
||||
this.resolveIPNS(res.ID)
|
||||
console.log('Version is',this.version)
|
||||
this.ipfs.add(new Buffer('ipfs:boards:version:'+this.version),{n: true},(err2,r) => {
|
||||
if(err2){
|
||||
this.ee.emit('error',err2)
|
||||
console.log('Error while calculating version hash:',err2)
|
||||
this.ee.emit('init',err2)
|
||||
if(done && done.apply) done(err2)
|
||||
console.log('Version is', this.version)
|
||||
this.ipfs.add(new Buffer('ipfs:boards:version:' + this.version), {n: true}, (err2, r) => {
|
||||
if (err2) {
|
||||
this.ee.emit('error', err2)
|
||||
console.log('Error while calculating version hash:', err2)
|
||||
this.ee.emit('init', err2)
|
||||
if (done && done.apply) done(err2)
|
||||
} else {
|
||||
if(r && r.Hash) this.version_hash = r.Hash
|
||||
if(r && r[0] && r[0].Hash) this.version_hash = r[0].Hash
|
||||
console.log('Version hash is',this.version_hash)
|
||||
this.ipfs.version((err,res) => {
|
||||
if(err){
|
||||
this.ee.emit('error',err)
|
||||
this.ee.emit('init',err)
|
||||
console.log('Error while getting ipfs version:',err)
|
||||
if(done && done.apply) done(err)
|
||||
if (r && r.Hash) this.version_hash = r.Hash
|
||||
if (r && r[0] && r[0].Hash) this.version_hash = r[0].Hash
|
||||
console.log('Version hash is', this.version_hash)
|
||||
this.ipfs.version((err, res) => {
|
||||
if (err) {
|
||||
this.ee.emit('error', err)
|
||||
this.ee.emit('init', err)
|
||||
console.log('Error while getting ipfs version:', err)
|
||||
if (done && done.apply) done(err)
|
||||
} else {
|
||||
this.ipfs_version = res.Version
|
||||
console.log('IPFS Version is',res.Version)
|
||||
this.ee.emit('init',undefined)
|
||||
console.log('IPFS Version is', res.Version)
|
||||
this.ee.emit('init', undefined)
|
||||
this.isInit = true
|
||||
if(done && done.apply) done(null)
|
||||
if (done && done.apply) done(null)
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -525,15 +539,15 @@ BoardsAPI.prototype.init = function(done){
|
||||
})
|
||||
}
|
||||
|
||||
BoardsAPI.prototype.getEventEmitter = function(){
|
||||
BoardsAPI.prototype.getEventEmitter = function () {
|
||||
return this.ee
|
||||
}
|
||||
|
||||
BoardsAPI.prototype.getUsers = function(){
|
||||
BoardsAPI.prototype.getUsers = function () {
|
||||
return this.users
|
||||
}
|
||||
|
||||
BoardsAPI.prototype.getMyID = function(){
|
||||
BoardsAPI.prototype.getMyID = function () {
|
||||
return this.id
|
||||
}
|
||||
|
||||
|
@ -3,8 +3,6 @@ var ReactDOM = require('react-dom')
|
||||
var Router = require('react-router').Router
|
||||
var Route = require('react-router').Route
|
||||
var IndexRoute = require('react-router').IndexRoute
|
||||
var Redirect = require('react-router').Redirect
|
||||
var Link = require('react-router').Link
|
||||
|
||||
// Load CSS
|
||||
require('normalize.css')
|
||||
@ -14,11 +12,9 @@ require('raleway.css')
|
||||
|
||||
// Load Components
|
||||
|
||||
var opt = require('options.jsx').get()
|
||||
var boardsWrapper = require('boardsapiwrapper.js')
|
||||
var boards = new boardsWrapper()
|
||||
var BoardsWrapper = require('boardsapiwrapper.js')
|
||||
var boards = new BoardsWrapper()
|
||||
var Icon = require('icon.jsx')
|
||||
var GetIPFS = require('getipfs.jsx')
|
||||
|
||||
// Load pages
|
||||
|
||||
@ -33,25 +29,25 @@ var CommentPage = require('commentpage.jsx')(boards)
|
||||
// Define Main Components
|
||||
|
||||
var Container = React.createClass({
|
||||
render: function(){
|
||||
return ( <div className="container app">{this.props.children}</div> )
|
||||
render () {
|
||||
return (<div className="container app">{this.props.children}</div>)
|
||||
}
|
||||
})
|
||||
|
||||
var App = React.createClass({
|
||||
render: function(){
|
||||
return ( <div><Navbar /><Container>{this.props.children}</Container></div> )
|
||||
render () {
|
||||
return (<div><Navbar /><Container>{this.props.children}</Container></div>)
|
||||
}
|
||||
})
|
||||
|
||||
// Static pages
|
||||
|
||||
var Static = React.createClass({
|
||||
html: function(){
|
||||
html () {
|
||||
return { __html: this.props.content }
|
||||
},
|
||||
render: function(){
|
||||
if(this.props.content){
|
||||
render () {
|
||||
if (this.props.content) {
|
||||
return <div className={this.props.className} dangerouslySetInnerHTML={this.html()} />
|
||||
} else {
|
||||
return <NotFound />
|
||||
@ -60,13 +56,13 @@ var Static = React.createClass({
|
||||
})
|
||||
|
||||
var Homepage = React.createClass({
|
||||
render: function(){
|
||||
render () {
|
||||
return <Static className="homepage" content={require('landing.md')} />
|
||||
}
|
||||
})
|
||||
|
||||
var NotFound = React.createClass({
|
||||
render: function(){
|
||||
render () {
|
||||
return (<div className="text-center">
|
||||
<h1><Icon name="ban"/></h1>
|
||||
<p>Sorry, there's nothing here!</p>
|
||||
|
@ -1,11 +1,11 @@
|
||||
var BoardsAPI = function(){
|
||||
var BoardsAPI = function () {
|
||||
this.done = false
|
||||
this.fa = []
|
||||
this.boards
|
||||
require.ensure(['options.jsx','ipfs-api','boards-api.js'], _ => {
|
||||
require.ensure(['options.jsx', 'ipfs-api', 'boards-api.js'], _ => {
|
||||
var opt = require('options.jsx').get()
|
||||
var BoardsAPI = require('boards-api.js')
|
||||
var ipfs = require('ipfs-api')(opt.addr || 'localhost',opt.port || 5001)
|
||||
var ipfs = require('ipfs-api')(opt.addr || 'localhost', opt.port || 5001)
|
||||
this.boards = new BoardsAPI(ipfs)
|
||||
this.boards.init()
|
||||
this.done = true
|
||||
@ -14,9 +14,9 @@ var BoardsAPI = function(){
|
||||
})
|
||||
}
|
||||
|
||||
BoardsAPI.prototype.use = function(f){
|
||||
if(!f || !f.apply || !f.call) return console.log('Non-function tried to use API:',f)
|
||||
if(this.done){
|
||||
BoardsAPI.prototype.use = function (f) {
|
||||
if (!f || !f.apply || !f.call) return console.log('Non-function tried to use API:', f)
|
||||
if (this.done) {
|
||||
f(this.boards)
|
||||
} else {
|
||||
this.fa.push(f)
|
||||
|
@ -2,34 +2,36 @@ var React = require('react')
|
||||
var Icon = require('icon.jsx')
|
||||
|
||||
module.exports = React.createClass({
|
||||
getInitialState: function(){
|
||||
getInitialState: function () {
|
||||
return { moment: false, text: '...' }
|
||||
},
|
||||
componentDidMount: function(){
|
||||
require.ensure(['moment'],_ => {
|
||||
if(this.isMounted()){
|
||||
componentDidMount: function () {
|
||||
require.ensure(['moment'], _ => {
|
||||
if (this.isMounted()) {
|
||||
var moment = require('moment')
|
||||
this.setState({
|
||||
moment: moment,
|
||||
interval: setInterval(this.upDate,60*1000),
|
||||
interval: setInterval(this.upDate, 60 * 1000),
|
||||
text: moment.unix(this.props.date).fromNow()
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
upDate: function(){
|
||||
if(this.isMounted())
|
||||
upDate: function () {
|
||||
if (this.isMounted()) {
|
||||
this.setState({ text: this.state.moment.unix(this.props.date).fromNow() })
|
||||
else
|
||||
} else {
|
||||
clearInterval(this.state.interval)
|
||||
}
|
||||
},
|
||||
getDate: function(){
|
||||
if(this.state.moment)
|
||||
getDate: function () {
|
||||
if (this.state.moment) {
|
||||
return this.state.text
|
||||
else
|
||||
} else {
|
||||
return <Icon name="refresh" className="fa-spin" />
|
||||
}
|
||||
},
|
||||
render: function(){
|
||||
render: function () {
|
||||
return <div className="inline"><Icon name="clock-o" className={this.props.className} /> {this.getDate()}</div>
|
||||
}
|
||||
})
|
||||
|
@ -6,33 +6,33 @@ var Link = require('react-router').Link
|
||||
var UserID = require('userID.jsx')
|
||||
|
||||
var Comment = React.createClass({
|
||||
getInitialState: function(){
|
||||
getInitialState: function () {
|
||||
return { moment: false }
|
||||
},
|
||||
componentDidMount: function(){
|
||||
require.ensure(['moment'],_ => {
|
||||
if(this.isMounted()) this.setState({ moment: require('moment') })
|
||||
componentDidMount: function () {
|
||||
require.ensure(['moment'], _ => {
|
||||
if (this.isMounted()) this.setState({ moment: require('moment') })
|
||||
})
|
||||
},
|
||||
getPermalink: function(){
|
||||
if(this.props.adminID && this.props.board && this.props.post && this.props.comment.hash){
|
||||
getPermalink: function () {
|
||||
if (this.props.adminID && this.props.board && this.props.post && this.props.comment.hash) {
|
||||
return <div className="inline not-first">
|
||||
<Icon name="code" /> <Link to={'/@'+this.props.adminID+'/'+this.props.board+'/'+this.props.post+'/'+this.props.comment.hash}>Permalink</Link>
|
||||
<Icon name="code" /> <Link to={'/@' + this.props.adminID + '/' + this.props.board + '/' + this.props.post + '/' + this.props.comment.hash}>Permalink</Link>
|
||||
</div>
|
||||
}
|
||||
},
|
||||
getParentlink: function(){
|
||||
if(this.props.showParent && this.props.comment.parent && this.props.comment.parent !== this.props.post){
|
||||
getParentlink: function () {
|
||||
if (this.props.showParent && this.props.comment.parent && this.props.comment.parent !== this.props.post) {
|
||||
return <div className="inline not-first">
|
||||
<Icon name="level-up" /> <Link to={'/@'+this.props.adminID+'/'+this.props.board+'/'+this.props.post+'/'+this.props.comment.parent}>Parent</Link>
|
||||
<Icon name="level-up" /> <Link to={'/@' + this.props.adminID + '/' + this.props.board + '/' + this.props.post + '/' + this.props.comment.parent}>Parent</Link>
|
||||
</div>
|
||||
}
|
||||
},
|
||||
getComments: function(){
|
||||
getComments: function () {
|
||||
return <Comments className="shifted" parent={this.props.comment.hash} post={this.props.post} adminID={this.props.adminID} board={this.props.board} api={this.props.api} />
|
||||
},
|
||||
render: function(){
|
||||
if(this.props.comment){
|
||||
render: function () {
|
||||
if (this.props.comment) {
|
||||
return <div className="comment"><hr/>
|
||||
<div className="icons">
|
||||
<UserID id={this.props.comment.op} api={this.props.api} />
|
||||
@ -49,32 +49,33 @@ var Comment = React.createClass({
|
||||
})
|
||||
|
||||
var Comments = React.createClass({
|
||||
getInitialState: function(){
|
||||
getInitialState: function () {
|
||||
return { comments: [] }
|
||||
},
|
||||
componentDidMount: function(){
|
||||
componentDidMount: function () {
|
||||
var boards = this.props.api
|
||||
if(boards){
|
||||
boards.getEventEmitter().on('comment for '+this.props.parent,cmnt => {
|
||||
if(this.isMounted()) this.setState({ comments: this.state.comments.concat(cmnt) })
|
||||
if (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)
|
||||
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)
|
||||
if (!err && this.isMounted()) {
|
||||
boards.getCommentsFor(this.props.parent, this.props.board, this.props.adminID)
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
getComments: function(){
|
||||
if(this.state.comments.length > 0){
|
||||
return this.state.comments.map(cmnt => (<Comment key={cmnt.hash} comment={cmnt} post={this.props.post} adminID={this.props.adminID} board={this.props.board} api={this.props.api} />) )
|
||||
getComments: function () {
|
||||
if (this.state.comments.length > 0) {
|
||||
return this.state.comments.map(cmnt => (<Comment key={cmnt.hash} comment={cmnt} post={this.props.post} adminID={this.props.adminID} board={this.props.board} api={this.props.api} />))
|
||||
}
|
||||
else return <div></div>
|
||||
},
|
||||
render: function(){
|
||||
return <div className={this.props.className+' comments'} >{this.getComments()}</div>
|
||||
render: function () {
|
||||
return <div className={this.props.className + ' comments'} >{this.getComments()}</div>
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -2,10 +2,10 @@ var React = require('react')
|
||||
require('font-awesome.min.css')
|
||||
|
||||
module.exports = React.createClass({
|
||||
class: function(){
|
||||
return 'fa fa-'+this.props.name+' '+this.props.className
|
||||
class: function () {
|
||||
return 'fa fa-' + this.props.name + ' ' + this.props.className
|
||||
},
|
||||
render: function(){
|
||||
return ( <i className={this.class()}></i> )
|
||||
render: function () {
|
||||
return (<i className={this.class()}></i>)
|
||||
}
|
||||
})
|
||||
|
@ -1,17 +1,17 @@
|
||||
var React = require('react')
|
||||
|
||||
module.exports = React.createClass({
|
||||
getInitialState: function(){
|
||||
getInitialState: function () {
|
||||
return { lib: false }
|
||||
},
|
||||
componentDidMount: function(){
|
||||
require.ensure(['react-markdown'],_ => {
|
||||
if(this.isMounted()) this.setState({ MarkdownLib: require('react-markdown') })
|
||||
componentDidMount: function () {
|
||||
require.ensure(['react-markdown'], _ => {
|
||||
if (this.isMounted()) this.setState({ MarkdownLib: require('react-markdown') })
|
||||
})
|
||||
},
|
||||
renderIfApplicable: function(){
|
||||
if(this.props.source){
|
||||
if(this.state.MarkdownLib){
|
||||
renderIfApplicable: function () {
|
||||
if (this.props.source) {
|
||||
if (this.state.MarkdownLib) {
|
||||
var MarkdownLib = this.state.MarkdownLib
|
||||
return <MarkdownLib source={this.props.source} skipHtml={true} />
|
||||
} else {
|
||||
@ -19,7 +19,7 @@ module.exports = React.createClass({
|
||||
}
|
||||
} else return <p>...</p>
|
||||
},
|
||||
render: function(){
|
||||
render: function () {
|
||||
return this.renderIfApplicable()
|
||||
}
|
||||
})
|
||||
|
@ -2,17 +2,17 @@ var React = require('react')
|
||||
var Icon = require('icon.jsx')
|
||||
var Link = require('react-router').Link
|
||||
|
||||
module.exports = function(boardsAPI){
|
||||
module.exports = function (boardsAPI) {
|
||||
return React.createClass({
|
||||
getInitialState: function(){
|
||||
getInitialState: function () {
|
||||
return { api: false, loading: true }
|
||||
},
|
||||
componentDidMount(){
|
||||
componentDidMount () {
|
||||
boardsAPI.use(boards => {
|
||||
if(boards.isInit) this.setState({ api: true })
|
||||
boards.getEventEmitter().on('init',err => {
|
||||
if(!this.isMounted()) return
|
||||
if(err){
|
||||
if (boards.isInit) this.setState({ api: true })
|
||||
boards.getEventEmitter().on('init', err => {
|
||||
if (!this.isMounted()) return
|
||||
if (err) {
|
||||
this.setState({ loading: false, api: false })
|
||||
} else {
|
||||
this.setState({ api: true })
|
||||
@ -20,19 +20,19 @@ module.exports = function(boardsAPI){
|
||||
})
|
||||
})
|
||||
},
|
||||
extraButtons: function(){
|
||||
if(this.state.api){
|
||||
extraButtons: function () {
|
||||
if (this.state.api) {
|
||||
return <span>
|
||||
<Link className="nounderline" to="/@me"><Icon name="user" className="fa-2x light"/></Link>
|
||||
<Link className="nounderline" to="/users"><Icon name="globe" className="fa-2x light"/></Link>
|
||||
</span>
|
||||
} else if(this.state.loading){
|
||||
} else if (this.state.loading) {
|
||||
return <Icon name="refresh" className="fa-2x fa-spin light"/>
|
||||
} else {
|
||||
return <Link className="nounderline" to="/users"><Icon name="ban" className="fa-2x light"/></Link>
|
||||
}
|
||||
},
|
||||
render: function(){
|
||||
render: function () {
|
||||
return (
|
||||
<div className="navbar">
|
||||
<div className="container">
|
||||
|
@ -1,12 +1,13 @@
|
||||
module.exports = {
|
||||
get: function(){
|
||||
var opt, s = localStorage.getItem('ipfs-boards-settings')
|
||||
get: function () {
|
||||
var opt
|
||||
var s = window.localStorage.getItem('ipfs-boards-settings')
|
||||
try {
|
||||
opt = JSON.parse(s)
|
||||
} catch(e){
|
||||
} catch (e) {
|
||||
// Do nothing
|
||||
}
|
||||
if(opt === null || opt === undefined) opt = { addr: 'localhost', port: 5001 }
|
||||
if (opt === null || opt === undefined) opt = { addr: 'localhost', port: 5001 }
|
||||
return opt
|
||||
}
|
||||
}
|
||||
|
@ -6,26 +6,26 @@ var Clock = require('clock.jsx')
|
||||
var UserID = require('userID.jsx')
|
||||
|
||||
module.exports = React.createClass({
|
||||
getInitialState: function(){
|
||||
getInitialState: function () {
|
||||
return { moment: false }
|
||||
},
|
||||
componentDidMount: function(){
|
||||
require.ensure(['moment'],_ => {
|
||||
if(this.isMounted()) this.setState({ moment: require('moment') })
|
||||
componentDidMount: function () {
|
||||
require.ensure(['moment'], _ => {
|
||||
if (this.isMounted()) this.setState({ moment: require('moment') })
|
||||
})
|
||||
},
|
||||
postLink: function(){
|
||||
if(this.props.post.op){
|
||||
if(this.props.board){
|
||||
return '/@'+this.props.post.op+'/'+this.props.board+'/'+this.props.post.hash
|
||||
postLink: function () {
|
||||
if (this.props.post.op) {
|
||||
if (this.props.board) {
|
||||
return '/@' + this.props.post.op + '/' + this.props.board + '/' + this.props.post.hash
|
||||
} else {
|
||||
return '/@'+this.props.post.op+'/post/'+this.props.post.hash
|
||||
return '/@' + this.props.post.op + '/post/' + this.props.post.hash
|
||||
}
|
||||
} else {
|
||||
return '/post/'+this.props.post.hash
|
||||
return '/post/' + this.props.post.hash
|
||||
}
|
||||
},
|
||||
render: function(){
|
||||
render: function () {
|
||||
return <div key={this.props.post.title} className="post">
|
||||
<div className="content">
|
||||
<h5>{this.props.post.title}</h5><hr/>
|
||||
|
@ -4,51 +4,57 @@ var Icon = require('icon.jsx')
|
||||
var Post = require('post.jsx')
|
||||
|
||||
module.exports = React.createClass({
|
||||
getInitialState: function(){
|
||||
getInitialState: function () {
|
||||
return { posts: [], api: false }
|
||||
},
|
||||
sortFn: function(a,b){
|
||||
sortFn: function (a, b) {
|
||||
return (b.date || 0) - (a.date || 0)
|
||||
},
|
||||
init: function(boards){
|
||||
if(this.state.init) return
|
||||
init: function (boards) {
|
||||
if (this.state.init) return
|
||||
this.setState({ api: true })
|
||||
boards.getPostsInBoard(this.props.admin,this.props.board)
|
||||
.on('post in '+this.props.board+(this.props.admin?'@'+this.props.admin:''),(post,hash) => {
|
||||
if(!this.isMounted()) return true
|
||||
var onPost = (post, hash) => {
|
||||
if (!this.isMounted()) return true
|
||||
var now = (new Date()).getTime()
|
||||
var posts = this.state.posts
|
||||
if(post.date === undefined || post.date <= 0){
|
||||
if (post.date === undefined || post.date <= 0) {
|
||||
posts.push(post)
|
||||
} else if(post.date <= now){
|
||||
var i = sortedIndex(posts,post,(p) => now-p.date || now)
|
||||
posts.splice(i,0,post)
|
||||
} else if (post.date <= now) {
|
||||
var i = sortedIndex(posts, post, (p) => now - p.date || now)
|
||||
posts.splice(i, 0, post)
|
||||
} else {
|
||||
console.log('Post discarded cause date in the future:',post)
|
||||
console.log('Post discarded cause date in the future:', post)
|
||||
}
|
||||
this.setState({ posts })
|
||||
})
|
||||
}
|
||||
boards.getEventEmitter().on('post in ' + this.props.board + (this.props.admin ? '@' + this.props.admin : ''), onPost)
|
||||
boards.getPostsInBoard(this.props.admin, this.props.board)
|
||||
this.setState({ init: true })
|
||||
},
|
||||
componentDidMount: function(){
|
||||
componentDidMount: function () {
|
||||
var boards = this.props.api
|
||||
if(boards){
|
||||
if(boards.isInit) this.init(boards)
|
||||
else boards.getEventEmitter().on('init',err => {
|
||||
if(!err && this.isMounted()) this.init(boards)
|
||||
})
|
||||
if (boards) {
|
||||
if (boards.isInit) {
|
||||
this.init(boards)
|
||||
} else {
|
||||
boards.getEventEmitter().on('init', err => {
|
||||
if (!err && this.isMounted()) this.init(boards)
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
getPosts: function(){
|
||||
if(this.state.posts.length > 0 || this.state.api){
|
||||
getPosts: function () {
|
||||
if (this.state.posts.length > 0 || this.state.api) {
|
||||
return this.state.posts.map(post => {
|
||||
return <Post key={post.hash} board={this.props.board} admin={this.props.admin} post={post} api={this.props.api} />
|
||||
})
|
||||
} else return <div className="center-block text-center">
|
||||
<Icon name="refresh" className="fa-3x center-block light fa-spin" />
|
||||
</div>
|
||||
} else {
|
||||
return <div className="center-block text-center">
|
||||
<Icon name="refresh" className="fa-3x center-block light fa-spin" />
|
||||
</div>
|
||||
}
|
||||
},
|
||||
render: function(){
|
||||
render: function () {
|
||||
return (
|
||||
<div className="postList">
|
||||
{this.getPosts()}
|
||||
|
@ -3,49 +3,50 @@ var Icon = require('icon.jsx')
|
||||
var Link = require('react-router').Link
|
||||
|
||||
module.exports = React.createClass({
|
||||
getInitialState: function(){
|
||||
getInitialState: function () {
|
||||
return { }
|
||||
},
|
||||
componentDidMount: function(){
|
||||
componentDidMount: function () {
|
||||
var boards = this.props.api
|
||||
if(boards){
|
||||
if(boards.isInit){
|
||||
if (boards) {
|
||||
if (boards.isInit) {
|
||||
this.getProfile(boards)
|
||||
}
|
||||
boards.getEventEmitter().on('init',err => {
|
||||
if(!err && this.isMounted()) this.getProfile(boards)
|
||||
else console.log('ERR INIT',err)
|
||||
boards.getEventEmitter().on('init', err => {
|
||||
if (!err && this.isMounted()) this.getProfile(boards)
|
||||
else console.log('ERR INIT', err)
|
||||
})
|
||||
}
|
||||
},
|
||||
getProfile: function(boards){
|
||||
if(this.props.id === undefined) return
|
||||
boards.getProfile(this.props.id, (err,res) => {
|
||||
if(!this.isMounted()) return true
|
||||
if(err){
|
||||
console.log('Error while resolving user badge:',err)
|
||||
getProfile: function (boards) {
|
||||
if (this.props.id === undefined) return
|
||||
boards.getProfile(this.props.id, (err, res) => {
|
||||
if (!this.isMounted()) return true
|
||||
if (err) {
|
||||
console.log('Error while resolving user badge:', err)
|
||||
} else {
|
||||
this.setState({ name: res.name || 'Unknown Name' })
|
||||
}
|
||||
})
|
||||
},
|
||||
getContent: function(){
|
||||
if(this.state.name){
|
||||
getContent: function () {
|
||||
if (this.state.name) {
|
||||
return (<Icon name="user" />)
|
||||
} else {
|
||||
return '@'
|
||||
}
|
||||
},
|
||||
render: function(){
|
||||
if(this.props.id === undefined || this.props.id === 'undefined')
|
||||
render: function () {
|
||||
if (this.props.id === undefined || this.props.id === 'undefined') {
|
||||
return <div className="user-id">
|
||||
<Icon name="ban" /> Unknown User
|
||||
</div>
|
||||
else
|
||||
} else {
|
||||
return (<div className="user-id">
|
||||
<Link className="light nounderline" to={'/@'+this.props.id}>
|
||||
<Link className="light nounderline" to={'/@' + this.props.id}>
|
||||
{this.getContent()}{this.state.name || this.props.id}
|
||||
</Link>
|
||||
</div>)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -1,17 +1,15 @@
|
||||
var React = require('react')
|
||||
var Markdown = require('markdown.jsx')
|
||||
var Link = require('react-router').Link
|
||||
var Icon = require('icon.jsx')
|
||||
var UserID = require('userID.jsx')
|
||||
var PostList = require('postlist.jsx')
|
||||
var GetIPFS = require('getipfs.jsx')
|
||||
|
||||
module.exports = function(boardsAPI){
|
||||
module.exports = function (boardsAPI) {
|
||||
return React.createClass({
|
||||
getInitialState: function(){
|
||||
getInitialState: function () {
|
||||
return { name: this.props.params.boardname, api: false, whitelist: [] }
|
||||
},
|
||||
componentDidMount: function(){
|
||||
componentDidMount: function () {
|
||||
boardsAPI.use(boards => {
|
||||
/*
|
||||
When a component inside the component being rendered by the router also needs
|
||||
@ -20,44 +18,45 @@ module.exports = function(boardsAPI){
|
||||
when the root component mounts) works as a cheap, horrible workaround
|
||||
*/
|
||||
boards.init()
|
||||
if(!this.isMounted()) return
|
||||
if (!this.isMounted()) return
|
||||
var ee = boards.getEventEmitter()
|
||||
ee.on('init',err => {
|
||||
if(!err && this.isMounted()){
|
||||
ee.on('init', err => {
|
||||
if (!err && this.isMounted()) {
|
||||
this.init(boards)
|
||||
}
|
||||
})
|
||||
if(this.props.params.userid){
|
||||
ee.on('whitelist for '+this.props.params.boardname+'@'+this.props.params.userid,(whitelist) => {
|
||||
if(this.isMounted())
|
||||
if (this.props.params.userid) {
|
||||
ee.on('whitelist for ' + this.props.params.boardname + '@' + this.props.params.userid, (whitelist) => {
|
||||
if (this.isMounted()) {
|
||||
this.setState({ whitelist })
|
||||
else return true
|
||||
} else return true
|
||||
})
|
||||
ee.on('settings for '+this.props.params.boardname+'@'+this.props.params.userid, (res) => {
|
||||
if(!this.isMounted()) return true
|
||||
if(res) this.setState({ name: res.fullname, description: res.description })
|
||||
ee.on('settings for ' + this.props.params.boardname + '@' + this.props.params.userid, (res) => {
|
||||
if (!this.isMounted()) return true
|
||||
if (res) this.setState({ name: res.fullname, description: res.description })
|
||||
})
|
||||
} else {
|
||||
this.setState({ description: 'All the messages posted in __#'+this.props.params.boardname+'__' })
|
||||
this.setState({ description: 'All the messages posted in __#' + this.props.params.boardname + '__' })
|
||||
}
|
||||
if(boards.isInit || this.state.api){
|
||||
if (boards.isInit || this.state.api) {
|
||||
this.init(boards)
|
||||
}
|
||||
})
|
||||
},
|
||||
init: function(boards){
|
||||
if(!this.state.init){
|
||||
if(this.props.params.userid)
|
||||
boards.getBoardSettings(this.props.params.userid,this.props.params.boardname)
|
||||
init: function (boards) {
|
||||
if (!this.state.init) {
|
||||
if (this.props.params.userid) {
|
||||
boards.getBoardSettings(this.props.params.userid, this.props.params.boardname)
|
||||
}
|
||||
this.setState({ init: true, api: true, boards: boards })
|
||||
}
|
||||
},
|
||||
render: function(){
|
||||
if(this.state.api){
|
||||
render: function () {
|
||||
if (this.state.api) {
|
||||
return (<div className="board">
|
||||
<h2>{this.state.name}</h2>
|
||||
<Markdown source={this.state.description} skipHtml={true} />
|
||||
{this.props.params.userid?<h5><UserID id={this.props.params.userid} api={this.state.boards} /></h5>:<p></p>}
|
||||
{this.props.params.userid ? <h5><UserID id={this.props.params.userid} api={this.state.boards} /></h5> : <p></p>}
|
||||
<div className="whitelist">
|
||||
{this.state.whitelist.map(i => <UserID id={i} key={i} api={this.state.boards} />)}
|
||||
</div>
|
||||
|
@ -3,55 +3,57 @@ var Link = require('react-router').Link
|
||||
var Icon = require('icon.jsx')
|
||||
var UserID = require('userID.jsx')
|
||||
var GetIPFS = require('getipfs.jsx')
|
||||
var Post = require('post.jsx')
|
||||
var Comment = require('comment.jsx').Comment
|
||||
|
||||
module.exports = function(boardsAPI){
|
||||
module.exports = function (boardsAPI) {
|
||||
return React.createClass({
|
||||
getInitialState: function(){
|
||||
getInitialState: function () {
|
||||
return { parent: false, api: false }
|
||||
},
|
||||
componentDidMount: function(){
|
||||
componentDidMount: function () {
|
||||
boardsAPI.use(boards => {
|
||||
boards.init()
|
||||
boards.getEventEmitter().on('init', err => {
|
||||
if(!err && this.isMounted()){
|
||||
if (!err && this.isMounted()) {
|
||||
this.init(boards)
|
||||
}
|
||||
})
|
||||
if(this.isMounted() && boards.isInit){
|
||||
if (this.isMounted() && boards.isInit) {
|
||||
this.init(boards)
|
||||
}
|
||||
})
|
||||
},
|
||||
componentWillReceiveProps: function(nextProps) {
|
||||
boardsAPI.use(boards => this.downloadComment(boards,nextProps))
|
||||
componentWillReceiveProps: function (nextProps) {
|
||||
boardsAPI.use(boards => this.downloadComment(boards, nextProps))
|
||||
},
|
||||
downloadComment: function(boards,props){
|
||||
downloadComment: function (boards, props) {
|
||||
this.setState({ comment: false })
|
||||
boards.downloadComment(props.params.commenthash,props.params.userid,props.params.boardname, (err,comment) => {
|
||||
if(err){
|
||||
this.setState({ comment: { title: 'Error', text: err.Message || err.Error }})
|
||||
boards.downloadComment(props.params.commenthash, props.params.userid, props.params.boardname, (err, comment) => {
|
||||
if (err) {
|
||||
this.setState({
|
||||
comment: { title: 'Error', text: err.Message || err.Error }
|
||||
})
|
||||
} else {
|
||||
this.setState({ comment })
|
||||
}
|
||||
})
|
||||
},
|
||||
init: function(boards){
|
||||
if(this.state.init) return
|
||||
init: function (boards) {
|
||||
if (this.state.init) return
|
||||
this.setState({ api: true, boards: boards })
|
||||
this.downloadComment(boards,this.props)
|
||||
this.downloadComment(boards, this.props)
|
||||
},
|
||||
getContext: function(){
|
||||
if(this.props.params.userid){
|
||||
if(this.props.params.boardname)
|
||||
return <div>Comment by <UserID id={this.props.params.userid} api={this.state.boards} /> in <Link to={'@'+this.props.params.userid+'/'+this.props.params.boardname}>#{this.props.params.boardname}</Link> to <Link to={'/@'+this.props.params.userid+'/'+this.props.params.boardname+'/'+this.props.params.posthash }>{this.props.params.posthash}</Link></div>
|
||||
else
|
||||
getContext: function () {
|
||||
if (this.props.params.userid) {
|
||||
if (this.props.params.boardname) {
|
||||
return <div>Comment by <UserID id={this.props.params.userid} api={this.state.boards} /> in <Link to={'@' + this.props.params.userid + '/' + this.props.params.boardname}>#{this.props.params.boardname}</Link> to <Link to={'/@' + this.props.params.userid + '/' + this.props.params.boardname + '/' + this.props.params.posthash }>{this.props.params.posthash}</Link></div>
|
||||
} else {
|
||||
return <div>Comment by <UserID id={this.props.params.userid} api={this.state.boards} /></div>
|
||||
}
|
||||
} else return <div><h6 className="light">You are viewing a single comment</h6></div>
|
||||
},
|
||||
showComment: function(){
|
||||
if(this.state.comment){
|
||||
showComment: function () {
|
||||
if (this.state.comment) {
|
||||
return <Comment comment={this.state.comment} post={this.props.params.posthash} adminID={this.props.params.userid} board={this.props.params.boardname} showParent={true} api={this.state.boards} />
|
||||
} else {
|
||||
return <div className="center-block text-center find-content">
|
||||
@ -60,15 +62,17 @@ module.exports = function(boardsAPI){
|
||||
</div>
|
||||
}
|
||||
},
|
||||
render: function(){
|
||||
if(this.state.api)
|
||||
render: function () {
|
||||
if (this.state.api) {
|
||||
return <div className="comment-page">
|
||||
<div className="text-center">
|
||||
{this.getContext()}
|
||||
</div>
|
||||
{this.showComment()}
|
||||
</div>
|
||||
else return <GetIPFS api={this.state.boards} />
|
||||
} else {
|
||||
return <GetIPFS api={this.state.boards} />
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -3,19 +3,19 @@ var Link = require('react-router').Link
|
||||
var Icon = require('icon.jsx')
|
||||
|
||||
module.exports = React.createClass({
|
||||
getInitialState: function(){
|
||||
getInitialState: function () {
|
||||
return { connected: false, error: false, long: false }
|
||||
},
|
||||
componentDidMount: function(){
|
||||
componentDidMount: function () {
|
||||
var boards = this.props.api
|
||||
if(boards){
|
||||
if(!this.isMounted()) return
|
||||
if(boards.isInit){
|
||||
if (boards) {
|
||||
if (!this.isMounted()) return
|
||||
if (boards.isInit) {
|
||||
this.setState({ connected: true })
|
||||
} else {
|
||||
boards.getEventEmitter().on('init', err => {
|
||||
if(!this.isMounted()) return
|
||||
if(err){
|
||||
if (!this.isMounted()) return
|
||||
if (err) {
|
||||
this.setState({ error: true })
|
||||
} else {
|
||||
this.setState({ connected: true })
|
||||
@ -24,15 +24,15 @@ module.exports = React.createClass({
|
||||
}
|
||||
} else this.startTimer()
|
||||
},
|
||||
startTimer: function(){
|
||||
startTimer: function () {
|
||||
setTimeout(_ => {
|
||||
console.log('Connection to go-ipfs has timed out (probably due to CORS)')
|
||||
if(this.isMounted()) this.setState({ long: true })
|
||||
if (this.isMounted()) this.setState({ long: true })
|
||||
}, 5000)
|
||||
},
|
||||
render: function(){
|
||||
render: function () {
|
||||
var opt = require('options.jsx').get()
|
||||
if(this.state.error || this.state.long){
|
||||
if (this.state.error || this.state.long) {
|
||||
return (
|
||||
<div className="">
|
||||
<h1><Icon name="ban"/> Connection to IPFS not available</h1>
|
||||
@ -51,7 +51,7 @@ module.exports = React.createClass({
|
||||
</ul>
|
||||
<p>Still can't fix it? <a href="https://github.com/fazo96/ipfs-board/issues">File a issue on GitHub</a>, we'll be happy to help!</p>
|
||||
</div>
|
||||
)} else if(this.state.connected){
|
||||
) } else if (this.state.connected) {
|
||||
return <div class="text-center">
|
||||
<h1><Icon name="check" /></h1>
|
||||
<h5 class="light">You're connected!</h5>
|
||||
|
@ -5,51 +5,54 @@ var GetIPFS = require('getipfs.jsx')
|
||||
var Post = require('post.jsx')
|
||||
var Comments = require('comment.jsx').Comments
|
||||
|
||||
module.exports = function(boardsAPI){
|
||||
module.exports = function (boardsAPI) {
|
||||
return React.createClass({
|
||||
getInitialState: function(){
|
||||
getInitialState: function () {
|
||||
return { post: { title: '...', text: '...' }, api: false }
|
||||
},
|
||||
componentDidMount: function(){
|
||||
componentDidMount: function () {
|
||||
boardsAPI.use(boards => {
|
||||
boards.init()
|
||||
boards.getEventEmitter().on('init', err => {
|
||||
if(!err && this.isMounted()){
|
||||
if (!err && this.isMounted()) {
|
||||
this.init(boards)
|
||||
}
|
||||
})
|
||||
if(this.isMounted() && boards.isInit){
|
||||
if (this.isMounted() && boards.isInit) {
|
||||
this.init(boards)
|
||||
}
|
||||
})
|
||||
},
|
||||
componentWillReceiveProps: function(nextProps) {
|
||||
boardsAPI.use(boards => this.downloadPost(boards,nextProps))
|
||||
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 }})
|
||||
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){
|
||||
if(this.state.init) return
|
||||
init: function (boards) {
|
||||
if (this.state.init) return
|
||||
this.setState({ api: true, boards: boards })
|
||||
this.downloadPost(boards,this.props)
|
||||
this.downloadPost(boards, this.props)
|
||||
},
|
||||
getContext: function(){
|
||||
if(this.props.params.userid){
|
||||
if(this.props.params.boardname)
|
||||
return <div>Posted by <UserID id={this.props.params.userid} api={this.state.boards} /> in <Link to={'@'+this.props.params.userid+'/'+this.props.params.boardname}>#{this.props.params.boardname}</Link></div>
|
||||
else
|
||||
getContext: function () {
|
||||
if (this.props.params.userid) {
|
||||
if (this.props.params.boardname) {
|
||||
return <div>Posted by <UserID id={this.props.params.userid} api={this.state.boards} /> 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} api={this.state.boards} /></div>
|
||||
}
|
||||
} else return <div><h6 className="light">You are viewing a single post</h6></div>
|
||||
},
|
||||
render: function(){
|
||||
if(this.state.api)
|
||||
render: function () {
|
||||
if (this.state.api) {
|
||||
return <div className="post-page">
|
||||
<div className="text-center">
|
||||
{this.getContext()}
|
||||
@ -57,7 +60,9 @@ module.exports = function(boardsAPI){
|
||||
<Post post={this.state.post} board={this.props.params.boardname} 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>
|
||||
else return <GetIPFS api={this.state.boards} />
|
||||
} else {
|
||||
return <GetIPFS api={this.state.boards} />
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -4,42 +4,42 @@ var Link = require('react-router').Link
|
||||
var Icon = require('icon.jsx')
|
||||
var GetIPFS = require('getipfs.jsx')
|
||||
|
||||
module.exports = function(boardsAPI){
|
||||
module.exports = function (boardsAPI) {
|
||||
return React.createClass({
|
||||
getInitialState: function(){
|
||||
getInitialState: function () {
|
||||
return { name: '...', boards: [], api: false }
|
||||
},
|
||||
componentDidMount: function(){
|
||||
componentDidMount: function () {
|
||||
boardsAPI.use(boards => {
|
||||
if(boards.isInit){
|
||||
if (boards.isInit) {
|
||||
this.setState({ api: boards, id: boards.id })
|
||||
this.init(boards)
|
||||
}
|
||||
var ee = boards.getEventEmitter()
|
||||
ee.on('init',err => {
|
||||
if(!err && this.isMounted()){
|
||||
ee.on('init', err => {
|
||||
if (!err && this.isMounted()) {
|
||||
this.setState({ api: boards, id: boards.id })
|
||||
this.init(boards)
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
componentWillReceiveProps: function(nextProps) {
|
||||
boardsAPI.use(boards => this.downloadProfile(boards,nextProps))
|
||||
componentWillReceiveProps: function (nextProps) {
|
||||
boardsAPI.use(boards => this.downloadProfile(boards, nextProps))
|
||||
},
|
||||
downloadProfile: function(boards,props){
|
||||
downloadProfile: function (boards, props) {
|
||||
var ee = boards.getEventEmitter()
|
||||
var uid = props.params.userid
|
||||
if(uid === 'me') uid = boards.id
|
||||
ee.on('boards for '+uid,l => {
|
||||
if (uid === 'me') uid = boards.id
|
||||
ee.on('boards for ' + uid, l => {
|
||||
var u2id = props.params.userid
|
||||
if(u2id === 'me') u2id = boards.id
|
||||
if(!this.isMounted() || u2id !== uid) return true
|
||||
if (u2id === 'me') u2id = boards.id
|
||||
if (!this.isMounted() || u2id !== uid) return true
|
||||
this.setState({ boards: l })
|
||||
})
|
||||
boards.getProfile(uid,(err,res) => {
|
||||
if(!this.isMounted()) return true
|
||||
if(err){
|
||||
boards.getProfile(uid, (err, res) => {
|
||||
if (!this.isMounted()) return true
|
||||
if (err) {
|
||||
this.setState({
|
||||
name: <Icon name="ban" />,
|
||||
description: err
|
||||
@ -49,19 +49,17 @@ module.exports = function(boardsAPI){
|
||||
}
|
||||
})
|
||||
},
|
||||
init: function(boards){
|
||||
if(this.state.init) return
|
||||
var ee = boards.getEventEmitter()
|
||||
if(boards.isInit || this.state.api){
|
||||
var uid = this.props.params.userid
|
||||
this.downloadProfile(boards,this.props)
|
||||
init: function (boards) {
|
||||
if (this.state.init) return
|
||||
if (boards.isInit || this.state.api) {
|
||||
this.downloadProfile(boards, this.props)
|
||||
this.setState({ init: true })
|
||||
}
|
||||
},
|
||||
linkToEditor: function(){
|
||||
linkToEditor: function () {
|
||||
var uid = this.props.params.userid
|
||||
if(uid === 'me' && this.state.id) uid = this.state.id
|
||||
if(uid === this.state.id){
|
||||
if (uid === 'me' && this.state.id) uid = this.state.id
|
||||
if (uid === this.state.id) {
|
||||
return <div>
|
||||
<h6>This is your profile</h6>
|
||||
<hr/>
|
||||
@ -69,10 +67,10 @@ module.exports = function(boardsAPI){
|
||||
}
|
||||
return ''
|
||||
},
|
||||
render: function(){
|
||||
if(this.state.api){
|
||||
render: function () {
|
||||
if (this.state.api) {
|
||||
var uid = this.props.params.userid
|
||||
if(uid === 'me') uid = this.state.id
|
||||
if (uid === 'me') uid = this.state.id
|
||||
return (<div className="profile">
|
||||
{this.linkToEditor()}
|
||||
<h1>{this.state.name}</h1>
|
||||
@ -80,8 +78,8 @@ module.exports = function(boardsAPI){
|
||||
<hr/>
|
||||
<div className="light breaker">@{uid}</div>
|
||||
{this.state.boards.map(n => {
|
||||
return <h6 className="light" key={uid+'/'+n.name}>
|
||||
<Link to={'/@'+uid+'/'+n.name}># {n.name}</Link>
|
||||
return <h6 className="light" key={uid + '/' + n.name}>
|
||||
<Link to={'/@' + uid + '/' + n.name}># {n.name}</Link>
|
||||
</h6>
|
||||
})}
|
||||
</div>)
|
||||
|
@ -1,57 +1,57 @@
|
||||
var React = require('react')
|
||||
var Icon = require('icon.jsx')
|
||||
|
||||
module.exports = function(boardsAPI){
|
||||
module.exports = function (boardsAPI) {
|
||||
return React.createClass({
|
||||
getDefaults: function(){
|
||||
getDefaults: function () {
|
||||
return { addr: 'localhost', port: 5001, api: false }
|
||||
},
|
||||
getInitialState: function(){
|
||||
getInitialState: function () {
|
||||
boardsAPI.use(boards => {
|
||||
if(boards.isInit && this.isMounted()) this.setState({ api: true })
|
||||
if (boards.isInit && this.isMounted()) this.setState({ api: true })
|
||||
boards.getEventEmitter().on('init', err => {
|
||||
if(!err && this.isMounted()) this.setState({ api: true })
|
||||
if (!err && this.isMounted()) this.setState({ api: true })
|
||||
})
|
||||
})
|
||||
var s = localStorage.getItem('ipfs-boards-settings')
|
||||
var s = window.localStorage.getItem('ipfs-boards-settings')
|
||||
var obj = this.getDefaults()
|
||||
try {
|
||||
obj = JSON.parse(s)
|
||||
} catch(e){
|
||||
localStorage.removeItem('ipfs-boards-settings')
|
||||
} catch (e) {
|
||||
window.localStorage.removeItem('ipfs-boards-settings')
|
||||
}
|
||||
return obj || this.getDefaults()
|
||||
},
|
||||
save: function(){
|
||||
if(isNaN(this.state.port) || parseInt(this.state.port) > 65535 || parseInt(this.state.port) < 1){
|
||||
alert('Port number invalid')
|
||||
save: function () {
|
||||
if (isNaN(this.state.port) || parseInt(this.state.port, 10) > 65535 || parseInt(this.state.port, 10) < 1) {
|
||||
window.alert('Port number invalid')
|
||||
} else {
|
||||
localStorage.setItem('ipfs-boards-settings',JSON.stringify({
|
||||
window.localStorage.setItem('ipfs-boards-settings', JSON.stringify({
|
||||
addr: this.state.addr,
|
||||
port: parseInt(this.state.port)
|
||||
port: parseInt(this.state.port, 10)
|
||||
}))
|
||||
window.location.reload(false)
|
||||
}
|
||||
},
|
||||
setDefaults: function(){
|
||||
setDefaults: function () {
|
||||
this.setState(this.getDefaults())
|
||||
},
|
||||
onChange: function(event){
|
||||
if(event.target.id === 'nodeAddress'){
|
||||
onChange: function (event) {
|
||||
if (event.target.id === 'nodeAddress') {
|
||||
this.setState({ addr: event.target.value })
|
||||
} else {
|
||||
this.setState({ port: event.target.value })
|
||||
}
|
||||
},
|
||||
isOK: function(){
|
||||
if(this.state.api){
|
||||
isOK: function () {
|
||||
if (this.state.api) {
|
||||
return <div className="itsok light">
|
||||
<h5><Icon name="check" /> It's OK</h5>
|
||||
<p>You're connected to IPFS</p>
|
||||
</div>
|
||||
}
|
||||
},
|
||||
render: function(){
|
||||
render: function () {
|
||||
return (
|
||||
<div className="settings">
|
||||
<h2><Icon name="cog"/> Settings</h2>
|
||||
@ -77,5 +77,4 @@ module.exports = function(boardsAPI){
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
@ -3,41 +3,41 @@ var Icon = require('icon.jsx')
|
||||
var GetIPFS = require('getipfs.jsx')
|
||||
var UserID = require('userID.jsx')
|
||||
|
||||
module.exports = function(boardsAPI){
|
||||
module.exports = function (boardsAPI) {
|
||||
return React.createClass({
|
||||
getInitialState: function(){
|
||||
getInitialState: function () {
|
||||
return { users: [], api: false }
|
||||
},
|
||||
componentDidMount: function(){
|
||||
componentDidMount: function () {
|
||||
boardsAPI.use(boards => {
|
||||
boards.init()
|
||||
if(boards.isInit){
|
||||
if(this.isMounted()){
|
||||
if (boards.isInit) {
|
||||
if (this.isMounted()) {
|
||||
this.init(boards)
|
||||
}
|
||||
}
|
||||
var ee = boards.getEventEmitter()
|
||||
ee.on('init', e => {
|
||||
if(!e && this.isMounted()){
|
||||
if (!e && this.isMounted()) {
|
||||
this.init(boards)
|
||||
}
|
||||
})
|
||||
ee.on('user',(id) => {
|
||||
if(id === undefined || id === 'undefined') console.log('found undefined user???')
|
||||
if(this.isMounted() && this.state.users.indexOf(id) < 0){
|
||||
ee.on('user', (id) => {
|
||||
if (id === undefined || id === 'undefined') console.log('found undefined user???')
|
||||
if (this.isMounted() && this.state.users.indexOf(id) < 0) {
|
||||
this.setState({ users: this.state.users.concat(id) })
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
init: function(boards){
|
||||
if(this.isMounted() && !this.state.init){
|
||||
init: function (boards) {
|
||||
if (this.isMounted() && !this.state.init) {
|
||||
this.setState({ users: boards.getUsers(), api: true, init: true, boards: boards })
|
||||
boards.searchUsers()
|
||||
}
|
||||
},
|
||||
render: function(){
|
||||
if(this.state.api){
|
||||
render: function () {
|
||||
if (this.state.api) {
|
||||
return <div>
|
||||
<h1><Icon name="users" /> Users</h1>
|
||||
<p>Found <b>{this.state.users.length}</b> users</p>
|
||||
|
@ -5,9 +5,9 @@ var HtmlWebpackPlugin = require('html-webpack-plugin')
|
||||
// Most of the config was copied from js-ipfs-api's webpack configuration
|
||||
|
||||
var config = {
|
||||
entry: path.join(__dirname,'webapp','app.jsx'),
|
||||
entry: path.join(__dirname, 'webapp', 'app.jsx'),
|
||||
output: {
|
||||
path: path.join(__dirname,'webapp','dist'),
|
||||
path: path.join(__dirname, 'webapp', 'dist'),
|
||||
filename: 'app.js'
|
||||
},
|
||||
resolve: {
|
||||
@ -23,7 +23,8 @@ var config = {
|
||||
eslint: {
|
||||
configFile: './.eslintrc',
|
||||
failOnWarning: true,
|
||||
failOnError: true
|
||||
failOnError: true,
|
||||
fix: true
|
||||
},
|
||||
module: {
|
||||
preLoaders: [
|
||||
@ -35,15 +36,15 @@ var config = {
|
||||
],
|
||||
loaders: [
|
||||
{ test: /\.(ttf|eot|svg|woff(2?))(\?v=\d+\.\d+\.\d+)?$/, loader: 'file' },
|
||||
{ test: /\.css$/, loaders: ['style','css'] },
|
||||
{ test: /\.md$/, loaders: ['html','markdown'] },
|
||||
{ test: /\.css$/, loaders: ['style', 'css'] },
|
||||
{ test: /\.md$/, loaders: ['html', 'markdown'] },
|
||||
{ test: /\.json$/, loader: 'json' },
|
||||
{
|
||||
test: /\.jsx?$/,
|
||||
exclude: /(node_modules|bower_components)/,
|
||||
loader: 'babel',
|
||||
query: {
|
||||
presets: ['es2015','react'],
|
||||
presets: ['es2015', 'react'],
|
||||
plugins: addTransformRuntime([])
|
||||
}
|
||||
},
|
||||
@ -74,11 +75,11 @@ var config = {
|
||||
// Optimization
|
||||
new webpack.optimize.OccurenceOrderPlugin(),
|
||||
new webpack.optimize.DedupePlugin(),
|
||||
new webpack.optimize.UglifyJsPlugin({
|
||||
compress: {
|
||||
warnings: false
|
||||
}
|
||||
})
|
||||
new webpack.optimize.UglifyJsPlugin({
|
||||
compress: {
|
||||
warnings: false
|
||||
}
|
||||
})
|
||||
]
|
||||
}
|
||||
|
||||
@ -95,15 +96,15 @@ config.devServer = {
|
||||
contentBase: config.output.path
|
||||
}
|
||||
|
||||
function addTransformRuntime(l){
|
||||
if(process.env.os != 'Windows_NT'){
|
||||
// Workaround for babel6 bug on windows
|
||||
// https://phabricator.babeljs.io/T6670
|
||||
// https://phabricator.babeljs.io/T2954
|
||||
// Disabling uglify on windows does the trick
|
||||
return l.concat('transform-runtime')
|
||||
}
|
||||
return l
|
||||
function addTransformRuntime (l) {
|
||||
if (process.env.os !== 'Windows_NT') {
|
||||
// Workaround for babel6 bug on windows
|
||||
// https://phabricator.babeljs.io/T6670
|
||||
// https://phabricator.babeljs.io/T2954
|
||||
// Disabling uglify on windows does the trick
|
||||
return l.concat('transform-runtime')
|
||||
}
|
||||
return l
|
||||
}
|
||||
|
||||
module.exports = config
|
||||
|
Loading…
Reference in New Issue
Block a user