mirror of
https://github.com/fazo96/ipfs-boards
synced 2025-03-12 21:48:39 +01:00
improvements, removed @me, added post editing link and post deletion
This commit is contained in:
parent
086e6da860
commit
1a713c8559
@ -207,6 +207,56 @@ BoardsAPI.prototype.createPost = function (post, board, done) {
|
|||||||
], done)
|
], done)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BoardsAPI.prototype.delete = function (opts, done) {
|
||||||
|
var url = '/ipfs-boards-profile/'
|
||||||
|
console.log('Deleting', opts)
|
||||||
|
if (opts.what === 'post') url += 'posts/' + opts.board + '/'
|
||||||
|
if (opts.what === 'comment') url += 'comments/' + opts.parent + '/'
|
||||||
|
if (opts.what === 'comment' || opts.what === 'post') {
|
||||||
|
this.ipfs.files.ls(url, (err, res) => {
|
||||||
|
if (err) return done(err)
|
||||||
|
if (!res || !res.Entries) return done('invalid response')
|
||||||
|
var list = res.Entries
|
||||||
|
for (var item in list) {
|
||||||
|
if (list[item].Hash === opts.hash) {
|
||||||
|
url = url + list[item].Name
|
||||||
|
return this.ipfs.files.rm(url, {}, err => {
|
||||||
|
if (err) return done(err)
|
||||||
|
this.ipfs.files.stat('/', (err, res) => {
|
||||||
|
if (err) return done(err)
|
||||||
|
console.log('Publishing profile...')
|
||||||
|
this.ipfs.name.publish(res.Hash, done)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return done('post does not exist or was already deleted')
|
||||||
|
})
|
||||||
|
} else if (opts.what === 'board' || opts.what === 'profile') {
|
||||||
|
if (opts.what === 'board') {
|
||||||
|
url += 'boards/' + opts.board
|
||||||
|
}
|
||||||
|
this.ipfs.files.rm(url, { r: true }, err => {
|
||||||
|
if (err) return done(err)
|
||||||
|
this.ipfs.files.stat('/', (err, res) => {
|
||||||
|
if (err) return done(err)
|
||||||
|
console.log('Publishing profile...')
|
||||||
|
this.ipfs.name.publish(res.Hash, done)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
done('what?')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BoardsAPI.prototype.deletePost = function (hash, board, done) {
|
||||||
|
this.delete({ what: 'post', hash, board }, done)
|
||||||
|
}
|
||||||
|
|
||||||
|
BoardsAPI.prototype.deleteComment = function (hash, parent, done) {
|
||||||
|
this.delete({ what: 'comment', hash, parent }, done)
|
||||||
|
}
|
||||||
|
|
||||||
BoardsAPI.prototype.backupCache = function () {
|
BoardsAPI.prototype.backupCache = function () {
|
||||||
if (window && window.localStorage !== undefined) {
|
if (window && window.localStorage !== undefined) {
|
||||||
// Use localStorage to store the IPNS cache
|
// Use localStorage to store the IPNS cache
|
||||||
@ -434,7 +484,6 @@ BoardsAPI.prototype.downloadPost = function (hash, adminID, board, op, done) {
|
|||||||
done = op
|
done = op
|
||||||
op = undefined
|
op = undefined
|
||||||
}
|
}
|
||||||
console.log('Downloading post', hash)
|
|
||||||
this.ipfs.cat(hash, (err2, r) => {
|
this.ipfs.cat(hash, (err2, r) => {
|
||||||
if (err2) {
|
if (err2) {
|
||||||
this.ee.emit('error', err2)
|
this.ee.emit('error', err2)
|
||||||
@ -442,8 +491,10 @@ BoardsAPI.prototype.downloadPost = function (hash, adminID, board, op, done) {
|
|||||||
if (done && done.apply) done(err2)
|
if (done && done.apply) done(err2)
|
||||||
} else {
|
} else {
|
||||||
replyAsObj(r, true, (err, post) => {
|
replyAsObj(r, true, (err, post) => {
|
||||||
if (err) return
|
if (err) {
|
||||||
// TODO: add JSON parsing error handling
|
if (done && done.apply) return done(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
post.hash = hash
|
post.hash = hash
|
||||||
if (op) post.op = op // Inject op
|
if (op) post.op = op // Inject op
|
||||||
if (board) {
|
if (board) {
|
||||||
|
@ -9,13 +9,13 @@ module.exports = function (boardsAPI) {
|
|||||||
},
|
},
|
||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
boardsAPI.use(boards => {
|
boardsAPI.use(boards => {
|
||||||
if (boards.isInit) this.setState({ api: true })
|
if (boards.isInit) this.setState({ api: true, userid: boards.getMyID() })
|
||||||
boards.getEventEmitter().on('init', err => {
|
boards.getEventEmitter().on('init', err => {
|
||||||
if (!this.isMounted()) return
|
if (!this.isMounted()) return
|
||||||
if (err) {
|
if (err) {
|
||||||
this.setState({ loading: false, api: false })
|
this.setState({ loading: false, api: false })
|
||||||
} else {
|
} else {
|
||||||
this.setState({ api: true })
|
this.setState({ api: true, userid: boards.getMyID() })
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -23,7 +23,7 @@ module.exports = function (boardsAPI) {
|
|||||||
extraButtons: function () {
|
extraButtons: function () {
|
||||||
if (this.state.api) {
|
if (this.state.api) {
|
||||||
return <span>
|
return <span>
|
||||||
<Link className="nounderline" to="/@me"><Icon name="user" className="fa-2x light"/></Link>
|
<Link className="nounderline" to={'/@' + this.state.userid}><Icon name="user" className="fa-2x light"/></Link>
|
||||||
<Link className="nounderline" to="/users"><Icon name="globe" className="fa-2x light"/></Link>
|
<Link className="nounderline" to="/users"><Icon name="globe" className="fa-2x light"/></Link>
|
||||||
</span>
|
</span>
|
||||||
} else if (this.state.loading) {
|
} else if (this.state.loading) {
|
||||||
|
@ -19,7 +19,7 @@ module.exports = React.createClass({
|
|||||||
init (props) {
|
init (props) {
|
||||||
var boards = props.api
|
var boards = props.api
|
||||||
if (!boards) return this.setState({ error: 'Could not connect to IPFS' })
|
if (!boards) return this.setState({ error: 'Could not connect to IPFS' })
|
||||||
this.setState({ loading: true })
|
this.setState({ loading: true, userid: boards.getMyID() })
|
||||||
boards.downloadPost(props.hash, props.adminID, props.board, (err, hash, date, post) => {
|
boards.downloadPost(props.hash, props.adminID, props.board, (err, hash, date, post) => {
|
||||||
this.setState({ error: err, post: post, loading: false })
|
this.setState({ error: err, post: post, loading: false })
|
||||||
})
|
})
|
||||||
@ -35,6 +35,19 @@ module.exports = React.createClass({
|
|||||||
return '/post/' + this.props.hash
|
return '/post/' + this.props.hash
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
editorLink () {
|
||||||
|
if (this.state.post.op === this.state.userid) {
|
||||||
|
var board = this.props.board || this.state.post.board
|
||||||
|
if (board) {
|
||||||
|
var url = '/edit/board/' + board + '/post/' + this.props.hash
|
||||||
|
return <Link to={url} className="nounderline">
|
||||||
|
<Icon name="edit" className="not-first"/> Edit
|
||||||
|
</Link>
|
||||||
|
} else {
|
||||||
|
return <span/>
|
||||||
|
}
|
||||||
|
} else return <span/>
|
||||||
|
},
|
||||||
getContent () {
|
getContent () {
|
||||||
if (this.state.error) {
|
if (this.state.error) {
|
||||||
return <Error className="content" error={this.state.error} />
|
return <Error className="content" error={this.state.error} />
|
||||||
@ -51,6 +64,7 @@ module.exports = React.createClass({
|
|||||||
<UserID id={this.state.post.op} api={this.props.api} ></UserID>
|
<UserID id={this.state.post.op} api={this.props.api} ></UserID>
|
||||||
<Clock className="not-first" date={this.state.post.date} />
|
<Clock className="not-first" date={this.state.post.date} />
|
||||||
<Icon name="comments" className="not-first" /> <Link className="nounderline" to={this.postLink()}>View</Link>
|
<Icon name="comments" className="not-first" /> <Link className="nounderline" to={this.postLink()}>View</Link>
|
||||||
|
{this.editorLink()}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
@ -16,13 +16,24 @@ var Error = React.createClass({
|
|||||||
|
|
||||||
var Loading = React.createClass({
|
var Loading = React.createClass({
|
||||||
render () {
|
render () {
|
||||||
return <div>
|
// TODO: merge these (duplicated code) and use css to get desired style
|
||||||
<div className="text-center">
|
if (this.props.small) {
|
||||||
<Icon className="center-block fa-spin fa-3x light" name="refresh" />
|
return <div>
|
||||||
<h4 className="top-half-em">{this.props.title}</h4>
|
<div className="text-center">
|
||||||
{ this.props.children }
|
<Icon className="center-block fa-spin fa-2x light" name="refresh" />
|
||||||
|
<h5 className="top-half-em">{this.props.title}</h5>
|
||||||
|
{ this.props.children }
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
} else {
|
||||||
|
return <div>
|
||||||
|
<div className="text-center">
|
||||||
|
<Icon className="center-block fa-spin fa-3x light" name="refresh" />
|
||||||
|
<h4 className="top-half-em">{this.props.title}</h4>
|
||||||
|
{ this.props.children }
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -31,11 +42,23 @@ var Saving = React.createClass({
|
|||||||
return <div>
|
return <div>
|
||||||
<div className="text-center">
|
<div className="text-center">
|
||||||
<Icon className="center-block fa-spin fa-3x light" name="refresh" />
|
<Icon className="center-block fa-spin fa-3x light" name="refresh" />
|
||||||
<h4 className="top-half-em">Publishing...</h4>
|
<h4 className="top-half-em">{ this.props.title || 'Publishing' }</h4>
|
||||||
{ this.props.children }
|
{ this.props.children }
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
module.exports = { Error, Loading, Saving }
|
var Success = React.createClass({
|
||||||
|
render () {
|
||||||
|
return <div>
|
||||||
|
<div className="text-center">
|
||||||
|
<Icon className="center-block fa-3x light" name="check" />
|
||||||
|
<h4 className="top-half-em">{ this.props.title || 'Done' }</h4>
|
||||||
|
{ this.props.children }
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
module.exports = { Error, Loading, Saving, Success }
|
||||||
|
@ -2,7 +2,7 @@ var React = require('react')
|
|||||||
var GetIPFS = require('getipfs.jsx')
|
var GetIPFS = require('getipfs.jsx')
|
||||||
var Icon = require('icon.jsx')
|
var Icon = require('icon.jsx')
|
||||||
var Link = require('react-router').Link
|
var Link = require('react-router').Link
|
||||||
var { Error, Loading, Saving } = require('status-components.jsx')
|
var { Error, Loading, Saving, Success } = require('status-components.jsx')
|
||||||
|
|
||||||
module.exports = function (boardsAPI) {
|
module.exports = function (boardsAPI) {
|
||||||
return React.createClass({
|
return React.createClass({
|
||||||
@ -29,11 +29,12 @@ module.exports = function (boardsAPI) {
|
|||||||
},
|
},
|
||||||
downloadPost (boards) {
|
downloadPost (boards) {
|
||||||
this.setState({ loading: true })
|
this.setState({ loading: true })
|
||||||
boards.downloadPost(this.props.params.posthash, (err, p) => {
|
boards.downloadPost(this.props.params.posthash, (err, hash, date, post) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
this.setState({ error: err, loading: false })
|
this.setState({ error: err, loading: false })
|
||||||
} else {
|
} else {
|
||||||
this.setState({ loading: false, title: p.title, text: p.text })
|
console.log(post)
|
||||||
|
this.setState({ loading: false, title: post.title, text: post.text })
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@ -43,7 +44,7 @@ module.exports = function (boardsAPI) {
|
|||||||
this.setState(obj)
|
this.setState(obj)
|
||||||
},
|
},
|
||||||
skip () {
|
skip () {
|
||||||
this.setState({ loading: false, updating: false, error: false })
|
this.setState({ loading: false, updating: false, error: false, success: false })
|
||||||
},
|
},
|
||||||
refresh () {
|
refresh () {
|
||||||
boardsAPI.use(b => this.downloadPost(b))
|
boardsAPI.use(b => this.downloadPost(b))
|
||||||
@ -61,12 +62,22 @@ module.exports = function (boardsAPI) {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
delete () {
|
||||||
|
this.setState({ deleting: true })
|
||||||
|
boardsAPI.use(boards => {
|
||||||
|
boards.deletePost(this.props.params.posthash, this.props.params.boardname, err => {
|
||||||
|
if (!err) console.log('Post deleted')
|
||||||
|
this.setState({ deleting: false, error: err, success: true })
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
additionalButtons () {
|
additionalButtons () {
|
||||||
if (this.state.api && this.props.params.posthash) {
|
if (this.state.api && this.props.params.posthash) {
|
||||||
var url = '/@' + this.state.api.getMyID() + '/' + this.props.params.boardname + '/' + this.props.params.posthash
|
var url = '/@' + this.state.api.getMyID() + '/' + this.props.params.boardname + '/' + this.props.params.posthash
|
||||||
return <span>
|
return <span>
|
||||||
<button onClick={this.refresh} className="button not-first">Refresh</button>
|
<button onClick={this.refresh} className="button not-first">Refresh</button>
|
||||||
<Link to={url} className="button not-first">View</Link>
|
<Link to={url} className="button not-first">View</Link>
|
||||||
|
<button onClick={this.delete} className="button not-first">Delete</button>
|
||||||
</span>
|
</span>
|
||||||
} else {
|
} else {
|
||||||
return <span></span>
|
return <span></span>
|
||||||
@ -78,6 +89,11 @@ module.exports = function (boardsAPI) {
|
|||||||
return <Error error={this.state.error} >
|
return <Error error={this.state.error} >
|
||||||
<button className="button button-primary center-block" onClick={this.skip}>Continue</button>
|
<button className="button button-primary center-block" onClick={this.skip}>Continue</button>
|
||||||
</Error>
|
</Error>
|
||||||
|
} else if (this.state.deleting) {
|
||||||
|
return <Loading title="Deleting Post">
|
||||||
|
<p>Pressing the Skip button will not abort the Delete operation.</p>
|
||||||
|
<button className="button button-primary center-block" onClick={this.skip}>Skip</button>
|
||||||
|
</Loading>
|
||||||
} else if (this.state.loading) {
|
} else if (this.state.loading) {
|
||||||
return <Loading title="Downloading Post">
|
return <Loading title="Downloading Post">
|
||||||
<button className="button button-primary center-block" onClick={this.skip}>Skip</button>
|
<button className="button button-primary center-block" onClick={this.skip}>Skip</button>
|
||||||
@ -87,10 +103,11 @@ module.exports = function (boardsAPI) {
|
|||||||
<p>Pressing the Skip button will not abort the publish operation.</p>
|
<p>Pressing the Skip button will not abort the publish operation.</p>
|
||||||
<button className="button button-primary center-block" onClick={this.skip}>Skip</button>
|
<button className="button button-primary center-block" onClick={this.skip}>Skip</button>
|
||||||
</Saving>
|
</Saving>
|
||||||
|
} else if (this.state.success) {
|
||||||
|
return <Success title="Post Deleted">
|
||||||
|
<p><b>Note:</b> due to a bug in go-ipfs, you may need to wait up to a minute for changes to appear.</p>
|
||||||
|
</Success>
|
||||||
} else {
|
} else {
|
||||||
if (this.state.userid && this.props.params.boardname) {
|
|
||||||
var boardurl = '/@' + this.state.userid + '/' + this.props.params.boardname
|
|
||||||
}
|
|
||||||
return (
|
return (
|
||||||
<div className="editor">
|
<div className="editor">
|
||||||
<h2><Icon name="pencil" className="light" />
|
<h2><Icon name="pencil" className="light" />
|
||||||
@ -112,7 +129,6 @@ module.exports = function (boardsAPI) {
|
|||||||
</div>
|
</div>
|
||||||
<div className="buttons">
|
<div className="buttons">
|
||||||
<button className="button button-primary" onClick={this.save}>Publish</button>
|
<button className="button button-primary" onClick={this.save}>Publish</button>
|
||||||
{boardurl ? <Link className="button not-first" to={boardurl}>View Board</Link> : <span></span> }
|
|
||||||
{this.additionalButtons()}
|
{this.additionalButtons()}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -36,7 +36,7 @@ module.exports = function (boardsAPI) {
|
|||||||
},
|
},
|
||||||
init (boards) {
|
init (boards) {
|
||||||
if (this.state.init) return
|
if (this.state.init) return
|
||||||
this.setState({ api: boards })
|
this.setState({ api: boards, userid: boards.getMyID() })
|
||||||
this.getProfile(boards)
|
this.getProfile(boards)
|
||||||
},
|
},
|
||||||
handleChange (event) {
|
handleChange (event) {
|
||||||
@ -101,7 +101,7 @@ module.exports = function (boardsAPI) {
|
|||||||
<div className="buttons">
|
<div className="buttons">
|
||||||
<button className="button button-primary" onClick={this.save}>Publish</button>
|
<button className="button button-primary" onClick={this.save}>Publish</button>
|
||||||
<button onClick={this.refresh} className="button not-first">Refresh</button>
|
<button onClick={this.refresh} className="button not-first">Refresh</button>
|
||||||
<Link to='/@me' className="button not-first">View</Link>
|
<Link to={'/@' + this.state.userid} className="button not-first">View</Link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
@ -13,13 +13,11 @@ module.exports = function (boardsAPI) {
|
|||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
boardsAPI.use(boards => {
|
boardsAPI.use(boards => {
|
||||||
if (boards.isInit) {
|
if (boards.isInit) {
|
||||||
this.setState({ api: boards, id: boards.id })
|
|
||||||
this.init(boards)
|
this.init(boards)
|
||||||
}
|
}
|
||||||
var ee = boards.getEventEmitter()
|
var ee = boards.getEventEmitter()
|
||||||
ee.on('init', err => {
|
ee.on('init', err => {
|
||||||
if (!err && this.isMounted()) {
|
if (!err && this.isMounted()) {
|
||||||
this.setState({ api: boards, id: boards.id })
|
|
||||||
this.init(boards)
|
this.init(boards)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -50,10 +48,8 @@ module.exports = function (boardsAPI) {
|
|||||||
},
|
},
|
||||||
init (boards) {
|
init (boards) {
|
||||||
if (this.state.init) return
|
if (this.state.init) return
|
||||||
if (boards.isInit || this.state.api) {
|
this.setState({ init: true, api: boards, id: boards.id })
|
||||||
this.downloadProfile(boards, this.props)
|
this.downloadProfile(boards, this.props)
|
||||||
this.setState({ init: true })
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
linkToEditor () {
|
linkToEditor () {
|
||||||
var uid = this.props.params.userid
|
var uid = this.props.params.userid
|
||||||
|
Loading…
Reference in New Issue
Block a user