1
0
mirror of https://github.com/fazo96/ipfs-boards synced 2025-01-10 12:24:20 +01:00

implemented limited mode

This commit is contained in:
Enrico Fasoli 2015-12-19 17:43:55 +01:00
parent e58349f14f
commit 6bbd1377ec
9 changed files with 109 additions and 71 deletions

View File

@ -261,7 +261,10 @@ BoardsAPI.prototype.deleteComment = function (hash, parent, done) {
BoardsAPI.prototype.cat = function (path, done) {
if (this.limited) {
// Download via gateway
if (path.indexOf('/ipfs/') !== 0) path = '/ipfs/' + path
if (path.indexOf('Qm') === 0) {
path = '/ipfs/' + path
}
console.log('Downloading via Gateway: ', path)
wreck.get(path, (err, res, payload) => {
console.log('GET:', err, res, payload)
if (payload.toString) payload = payload.toString()
@ -291,8 +294,13 @@ BoardsAPI.prototype.backupCache = function () {
}
// Rewrote this to use event emitters. Should also add periodic rechecking
// TODO: maybe drop this entirely? We can cat and ls IPNS names now.
BoardsAPI.prototype.resolveIPNS = function (n, handler) {
if (handler && handler.apply) this.ee.on(n, handler)
if (this.limited) {
// In limited mode, don't solve addresses
return this.ee.emit(n, '/ipns/' + n)
}
if (!this.resolvingIPNS[n]) {
this.resolvingIPNS[n] = true
this.ipfs.name.resolve(n, (err, r) => {
@ -333,7 +341,7 @@ BoardsAPI.prototype.resolveIPNS = function (n, handler) {
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) => {
this.cat(addr + this.baseurl + 'ipfs-boards-version.txt', (err, r) => {
if (err) return done(false, err)
replyAsObj(r, false, (_, res) => {
if (!res || !res.trim) {
@ -392,7 +400,7 @@ BoardsAPI.prototype.getProfile = function (userID, done) {
done(err, null)
} else {
// Download actual profile
this.ipfs.cat(url + this.baseurl + 'profile.json', (err2, res) => {
this.cat(url + this.baseurl + 'profile.json', (err2, res) => {
if (err2) {
this.ee.emit('error', err2)
done(err2, null)
@ -410,7 +418,7 @@ BoardsAPI.prototype.getProfile = function (userID, done) {
}
})
// Get other info
this.ipfs.ls(url + this.baseurl + 'boards/', (err2, res) => {
this.ls(url + this.baseurl + 'boards/', (err2, res) => {
if (!err2) {
var l = res.Objects[0].Links.map(i => {
return { name: i.Name, hash: i.Hash }
@ -438,7 +446,7 @@ BoardsAPI.prototype.getBoardSettings = function (userID, board, done) {
this.ee.emit('error', e)
} else {
var url = r + this.baseurl + 'boards/' + board + '/settings.json'
this.ipfs.cat(url, (err, resp) => {
this.cat(url, (err, resp) => {
var settings
try {
settings = JSON.parse(resp.toString())
@ -457,7 +465,7 @@ BoardsAPI.prototype.getBoardSettings = function (userID, board, done) {
if (settings.whitelist === true) {
// Get the whitelist
var url = r + this.baseurl + 'boards/' + board + '/whitelist'
this.ipfs.cat(url, (err, res) => {
this.cat(url, (err, res) => {
if (err) {
this.ee.emit('error', err)
// Emit an empty whitelist.
@ -479,7 +487,7 @@ BoardsAPI.prototype.getBoardSettings = function (userID, board, done) {
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) => {
this.cat(u, (err, blacklist) => {
if (err) {
this.ee.emit('error', err)
} else {
@ -510,7 +518,7 @@ BoardsAPI.prototype.downloadPost = function (hash, adminID, board, op, done) {
done = op
op = undefined
}
this.ipfs.cat(hash, (err2, r) => {
this.cat(hash, (err2, r) => {
if (err2) {
this.ee.emit('error', err2)
console.log('Could not download post', hash, 'of', board + '@' + adminID)
@ -537,7 +545,7 @@ BoardsAPI.prototype.downloadPost = function (hash, adminID, board, op, done) {
BoardsAPI.prototype.retrieveListOfApproved = function (what, addr, adminID, board) {
var a = addr + this.baseurl + 'boards/' + board + '/approved/' + what + '/'
this.ipfs.ls(a, (err, res) => {
this.ls(a, (err, res) => {
if (err) {
this.ee.emit('error', err)
} else {
@ -609,7 +617,7 @@ BoardsAPI.prototype.getUserPostListInBoard = function (user, board, done) {
this.ee.emit('error', err)
done(err)
} else {
this.ipfs.ls(url + this.baseurl + 'posts/' + board, (e, r) => {
this.ls(url + this.baseurl + 'posts/' + board, (e, r) => {
if (e) {
this.ee.emit('error', e)
done(e)
@ -634,7 +642,7 @@ BoardsAPI.prototype.downloadComment = function (hash, adminID, board, target, do
target = undefined
}
console.log('target', target)
this.ipfs.cat(hash, (err2, r) => {
this.cat(hash, (err2, r) => {
if (err2) {
this.ee.emit('error', err2)
console.log('Could not download comment', hash, 'of', board + '@' + adminID)
@ -660,7 +668,7 @@ BoardsAPI.prototype.getCommentsFor = function (parent, board, adminID, target) {
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) => {
this.cat(parent, (err, res) => {
if (err) {
this.ee.emit('error', err)
} else {
@ -706,7 +714,7 @@ BoardsAPI.prototype.getUserCommentList = function (parent, user, done) {
this.ee.emit('error', err)
done(err)
} else {
this.ipfs.ls(url + this.baseurl + 'comments/' + parent, (e, r) => {
this.ls(url + this.baseurl + 'comments/' + parent, (e, r) => {
if (e) {
this.ee.emit('error', e)
done(e)
@ -728,7 +736,7 @@ BoardsAPI.prototype.getUserCommentList = function (parent, user, done) {
BoardsAPI.prototype.isRunningFromGateway = function () {
if (!window) return false
return window.location.pathname.indexOf('/ipfs/') === 0
return window.location.pathname.indexOf('/ipfs/') === 0 || window.location.pathname.indexOf('/ipns/') === 0
}
BoardsAPI.prototype.isNode = function () {

View File

@ -53,29 +53,40 @@ var Comments = React.createClass({
return { comments: [] }
},
componentDidMount () {
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.isInit && this.isMounted()) {
if (this.props.api) this.init(this.props.api)
},
componentWillReceiveProps (props) {
if (props.api) this.init(props.api)
},
init (boards) {
boards.getEventEmitter().on('comment for ' + this.props.parent, cmnt => {
if (this.isMounted()) this.setState({ comments: this.state.comments.concat(cmnt) })
})
boards.getEventEmitter().on('init', (err, limited) => {
if (!this.isMounted()) return
if (!err) {
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 (limited) this.setState({ limited })
})
if (boards.isInit) {
boards.getCommentsFor(this.props.parent, this.props.board, this.props.adminID)
}
if (boards.limited) this.setState({ limited: true })
},
getComments () {
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>
} else return <div></div>
},
render () {
return <div className={this.props.className + ' comments'} >{this.getComments()}</div>
if (this.state.limited) {
return <div className="text-center">
<p>Comments can't be displayed in limited mode</p>
</div>
} else {
return <div className={this.props.className + ' comments'} >{this.getComments()}</div>
}
}
})

View File

@ -10,12 +10,12 @@ module.exports = function (boardsAPI) {
componentDidMount () {
boardsAPI.use(boards => {
if (boards.isInit) this.setState({ api: true, userid: boards.getMyID() })
boards.getEventEmitter().on('init', err => {
boards.getEventEmitter().on('init', (err, limited) => {
if (!this.isMounted()) return
if (err) {
this.setState({ loading: false, api: false })
this.setState({ loading: false, api: false, limited })
} else {
this.setState({ api: true, userid: boards.getMyID() })
this.setState({ api: true, userid: boards.getMyID(), limited })
}
})
})
@ -28,6 +28,8 @@ module.exports = function (boardsAPI) {
</span>
} else if (this.state.loading) {
return <Icon name="refresh" className="fa-2x fa-spin light"/>
} else if (this.state.limited) {
return <Link className="nounderline" to="/status"><Icon name="exclamation-triangle" className="fa-2x light"/></Link>
} else {
return <Link className="nounderline" to="/status"><Icon name="ban" className="fa-2x light"/></Link>
}

View File

@ -5,6 +5,7 @@ var Link = require('react-router').Link
var Clock = require('clock.jsx')
var UserID = require('userID.jsx')
var { Error } = require('status-components.jsx')
var Comments = require('comment.jsx').Comments
module.exports = React.createClass({
getInitialState () {
@ -12,10 +13,10 @@ module.exports = React.createClass({
},
componentDidMount () {
if (this.props.api) {
this.props.api.getEventEmitter().on('init', err => {
if (!err) this.init(this.props)
this.props.api.getEventEmitter().on('init', (err, limited) => {
if (!err || limited) this.init(this.props)
})
if (this.props.api.isInit) this.init(this.props)
if (this.props.api.isInit || this.props.api.limited) this.init(this.props)
}
},
componentWillReceiveProps (props) {
@ -80,6 +81,9 @@ module.exports = React.createClass({
}
},
render () {
return <div className="post">{this.getContent()}</div>
return <div>
<div className="post">{this.getContent()}</div>
<Comments parent={this.props.hash} post={this.props.hash} api={this.props.api} adminID={this.props.adminID} board={this.props.board} />
</div>
}
})

View File

@ -5,7 +5,7 @@ var Post = require('post.jsx')
module.exports = React.createClass({
getInitialState () {
return { posts: [], api: false }
return { posts: [] }
},
sortFn (a, b) {
return (b.date || 0) - (a.date || 0)
@ -16,9 +16,6 @@ module.exports = React.createClass({
}
},
init (boards, props) {
if (this.state.init) return
props = props || this.props
this.setState({ api: true })
var onPost = (hash, date, post) => {
if (!this.isMounted()) return true
var now = (new Date()).getTime()
@ -33,18 +30,29 @@ module.exports = React.createClass({
}*/
this.setState({ posts })
}
props = props || this.props
boards.getEventEmitter().on('post in ' + props.board + (props.admin ? '@' + props.admin : ''), onPost)
boards.getPostsInBoard(props.admin, props.board)
this.setState({ init: true })
this.setState({ api: boards, limited: boards.limited })
if (boards.isInit) {
boards.getPostsInBoard(props.admin, props.board)
} else {
boards.getEventEmitter().on('init', (err, limited) => {
if (!err) {
boards.getPostsInBoard(props.admin, props.board)
} else {
this.setState({ limited })
}
})
}
},
componentDidMount () {
var boards = this.props.api
if (boards) {
if (boards.isInit) {
if (boards.isInit || boards.limited) {
this.init(boards)
} else {
boards.getEventEmitter().on('init', err => {
if (!err && this.isMounted()) this.init(boards)
boards.getEventEmitter().on('init', (err, limited) => {
if ((!err || limited) && this.isMounted()) this.init(boards)
})
}
}
@ -61,10 +69,15 @@ module.exports = React.createClass({
}
},
render () {
return (
<div className="postList">
if (this.state.limited) {
return <div className="text-center">
<h5 className="light"><Icon name="ban" /></h5>
<p>Posts in a board can't be shown in limited mode. Sorry!</p>
</div>
} else {
return <div className="postList">
{this.getPosts()}
</div>
)
}
}
})

View File

@ -16,10 +16,12 @@ module.exports = React.createClass({
props = props || this.props
var boards = props.api
if (boards) {
boards.getEventEmitter().on('init', err => {
if (!err && this.isMounted()) this.getProfile(boards)
boards.getEventEmitter().on('init', (err, limited) => {
if ((!err || limited) && this.isMounted()) {
this.getProfile(boards)
}
})
if (boards.isInit) {
if (boards.isInit || boards.limited) {
this.getProfile(boards)
}
}

View File

@ -16,8 +16,8 @@ module.exports = function (boardsAPI) {
boardsAPI.use(boards => {
if (!this.isMounted()) return
var ee = boards.getEventEmitter()
ee.on('init', err => {
if (!err && this.isMounted()) {
ee.on('init', (err, limited) => {
if ((!err || limited) && this.isMounted()) {
this.init(boards)
}
})
@ -46,13 +46,17 @@ module.exports = function (boardsAPI) {
var props = newProps || this.props
if (!props.params.userid) return
boards.getBoardSettings(props.params.userid, props.params.boardname)
this.setState({ loading: true, init: true, api: true, userid: boards.getMyID(), boards: boards })
this.setState({ loading: true, init: true, api: boards, userid: boards.getMyID(), limited: boards.limited })
},
toolbox () {
return <div className="iconbar text-center">
<Link to={'/edit/board/' + this.props.params.boardname} ><Icon name="edit" className="fa-2x light" /></Link>
<Link to={'/edit/board/' + this.props.params.boardname + '/post'} ><Icon name="plus" className="fa-2x light" /></Link>
</div>
if (this.state.limited) {
return <div className="text-center">Toolbox not available in limited mode<hr/></div>
} else {
return <div className="iconbar text-center">
<Link to={'/edit/board/' + this.props.params.boardname} ><Icon name="edit" className="fa-2x light" /></Link>
<Link to={'/edit/board/' + this.props.params.boardname + '/post'} ><Icon name="plus" className="fa-2x light" /></Link>
</div>
}
},
render () {
if (this.state.api) {
@ -66,16 +70,16 @@ module.exports = function (boardsAPI) {
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.api} /></h5> : <p></p>}
<div className="whitelist">
{this.state.whitelist.map(i => <UserID id={i} key={i} api={this.state.boards} />)}
{this.state.whitelist.map(i => <UserID id={i} key={i} api={this.state.api} />)}
</div>
<hr />
{this.toolbox()}
<PostList board={this.props.params.boardname} admin={this.props.params.userid} api={this.state.boards} />
<PostList board={this.props.params.boardname} admin={this.props.params.userid} api={this.state.api} />
</div>)
}
} else return <GetIPFS api={this.state.boards} />
} else return <GetIPFS api={this.state.api} />
}
})
}

View File

@ -3,7 +3,6 @@ var Link = require('react-router').Link
var UserID = require('userID.jsx')
var GetIPFS = require('getipfs.jsx')
var Post = require('post.jsx')
var Comments = require('comment.jsx').Comments
module.exports = function (boardsAPI) {
return React.createClass({
@ -31,7 +30,6 @@ module.exports = function (boardsAPI) {
{this.getContext()}
</div>
<Post hash={this.props.params.posthash} board={this.props.params.boardname} api={this.state.api} />
<Comments parent={this.props.params.posthash} board={this.props.params.boardname} adminID={this.props.params.userid} post={this.props.params.posthash} api={this.state.boards} />
</div>
} else {
return <GetIPFS api={this.state.boards} />

View File

@ -12,12 +12,12 @@ module.exports = function (boardsAPI) {
},
componentDidMount () {
boardsAPI.use(boards => {
if (boards.isInit) {
if (boards.isInit || boards.limited) {
this.init(boards)
}
var ee = boards.getEventEmitter()
ee.on('init', err => {
if (!err && this.isMounted()) {
ee.on('init', (err, limited) => {
if ((!err || limited) && this.isMounted()) {
this.init(boards)
}
})
@ -30,10 +30,8 @@ module.exports = function (boardsAPI) {
downloadProfile (boards, props) {
var ee = boards.getEventEmitter()
var uid = props.params.userid
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
this.setState({ boards: l })
})
@ -48,12 +46,11 @@ module.exports = function (boardsAPI) {
},
init (boards) {
if (this.state.init) return
this.setState({ init: true, api: boards, id: boards.id })
this.setState({ init: true, api: boards, id: boards.id, limited: boards.limited })
this.downloadProfile(boards, this.props)
},
linkToEditor () {
var uid = this.props.params.userid
if (uid === 'me' && this.state.id) uid = this.state.id
if (uid === this.state.id) {
return <div className="your-profile">
<h6>This is your profile</h6>
@ -76,7 +73,6 @@ module.exports = function (boardsAPI) {
return <Loading title="Downloading Profile">{this.getEditButton()}</Loading>
} else {
var uid = this.props.params.userid
if (uid === 'me') uid = this.state.id
return (<div className="profile">
{this.linkToEditor()}
<h1>{this.state.name}</h1>