mirror of
https://github.com/fazo96/ipfs-boards
synced 2025-01-25 14:54:19 +01:00
board viewing is ok now
This commit is contained in:
parent
0f71407040
commit
5a71c39bb9
15
PROTOCOL.md
15
PROTOCOL.md
@ -37,10 +37,21 @@ publication, containing:
|
||||
- votes
|
||||
- _board name(s)_
|
||||
- _vote(s)_ - named with their parent object uri
|
||||
- name - stores the user's screen name (maybe store it in profile?)
|
||||
- profile.json - user's additional profile data
|
||||
- profile.json - user's profile data, like name, email, etc
|
||||
- ipfs-boards-version.txt - used to store compatibility information
|
||||
|
||||
#### Board settings
|
||||
|
||||
{
|
||||
"whitelist": true,
|
||||
"blacklist": false,
|
||||
"approval_required": true,
|
||||
"fullname": "The Full Name Can Be Long With Spaces",
|
||||
"description": "A very Long Full Description with Spaces"
|
||||
}
|
||||
|
||||
The blacklist and whitelist should contain just IDs separated by spaces.
|
||||
|
||||
#### Post
|
||||
|
||||
{
|
||||
|
21
README.md
21
README.md
@ -25,10 +25,12 @@ Image and discussion boards, forums and the like have many problems:
|
||||
This project was conceived to solve that. With the help of modern web technologies, the IPFS and IPNS protocols
|
||||
and some optional cache servers, we can solve these problems and create a true universal platform which can act as:
|
||||
|
||||
- Discussion board
|
||||
- Discussion board, like reddit or 4chan
|
||||
- Blog with dynamic comments
|
||||
- Wiki
|
||||
- File Sharing platform
|
||||
- E-Learning platform
|
||||
- (Maybe) Forum (not sure because it would require some changes, but maybe)
|
||||
- (Maybe) E-Learning platform
|
||||
|
||||
With security, control, reliability, rock solid stability, fully distributed
|
||||
architecture or, optionally, none of these!
|
||||
@ -41,20 +43,21 @@ See `FAQ.md`
|
||||
|
||||
See `PROTOCOL.md`
|
||||
|
||||
## Prototype
|
||||
## Demo / Prototype
|
||||
|
||||
It's being worked on, but it doesn't have:
|
||||
It's being worked on, but __it doesn't have__:
|
||||
|
||||
- Write ability in web app (only a small cli to validate and publish a folder)
|
||||
- Read only web app (only a small cli to publish stuff, without a comfortable UI)
|
||||
- Aggregation (only the admin can post)
|
||||
- Advanced customization, control, user profile
|
||||
- Media support
|
||||
- Votes
|
||||
|
||||
Maybe it will have:
|
||||
|
||||
- No backend needed (for read only access)
|
||||
- Comments
|
||||
- Actually nice user interface
|
||||
|
||||
Ability to publish stuff in the browser won't be implemented until go-ipfs 0.4
|
||||
is ready. It will probably be ready before the new year, but we're not sure.
|
||||
You will be able to publish your blog/pages/profile using a CLI though
|
||||
|
||||
## Components
|
||||
|
||||
|
@ -36,7 +36,7 @@ function replyAsObj(res,isJson,done){
|
||||
}
|
||||
})
|
||||
} else {
|
||||
console.log('got string:',res)
|
||||
//console.log('got string:',res)
|
||||
// Is a string
|
||||
if(isJson){
|
||||
asObj(res,done)
|
||||
@ -55,10 +55,13 @@ function BoardsAPI(ipfs){
|
||||
}
|
||||
|
||||
// This function works but needs a little rethinking.
|
||||
// TODO: convert it to emitters and periodically check. Emit events if the IPNS updates
|
||||
// TODO: this SUCKS and is SLOW. NEEDS TO BE FIXED
|
||||
BoardsAPI.prototype.resolveIPNS = function(n,done){
|
||||
var cached = this.users[n]
|
||||
//console.log('Cached is',cached)
|
||||
if(cached){
|
||||
console.log('Returning cached',n,'is',this.users[n])
|
||||
//console.log('Returning cached',n,'is',this.users[n])
|
||||
done(null,cached)
|
||||
}
|
||||
this.ipfs.name.resolve(n,(err,r) => {
|
||||
@ -66,10 +69,13 @@ BoardsAPI.prototype.resolveIPNS = function(n,done){
|
||||
if(err){
|
||||
done(err)
|
||||
} else if(!cached){
|
||||
//console.log('oldcache',this.users)
|
||||
//console.log('Setting cache for',n,'to',r.Path)
|
||||
this.users[n] = r.Path
|
||||
done(err,r.Path)
|
||||
} else if(cached !== r.Path){
|
||||
// Update cache
|
||||
//console.log('Setting cache for',n,'from',this.users[n],'to',r.Path)
|
||||
this.users[n] = r.Path
|
||||
}
|
||||
})
|
||||
@ -133,7 +139,6 @@ BoardsAPI.prototype.getProfile = function(userID,done){
|
||||
} else {
|
||||
// Download actual profile
|
||||
this.ipfs.cat(url+'/profile.json',(err2,res) => {
|
||||
console.log('got something')
|
||||
if(err2){
|
||||
done(err2,null)
|
||||
} else {
|
||||
@ -156,43 +161,36 @@ BoardsAPI.prototype.getProfile = function(userID,done){
|
||||
return ee
|
||||
}
|
||||
|
||||
BoardsAPI.prototype.getName = function(userID,done){
|
||||
this.ipfs.cat(userID+'/name',(err,res) => {
|
||||
if(err){
|
||||
done(err,null)
|
||||
} else {
|
||||
replyAsObj(res,false,done)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
BoardsAPI.prototype.getBoardSettings = function(userID,board,done){
|
||||
var url = userID+'/boards/'+board+'/settings.json'
|
||||
console.log('Getting Board Settings:',url)
|
||||
this.ipfs.cat(url,function(err,res){
|
||||
console.log('Done')
|
||||
if(err){
|
||||
done(err,{})
|
||||
this.resolveIPNS(userID,(e,r) => {
|
||||
if(e){
|
||||
done(e)
|
||||
} else {
|
||||
replyAsObj(res,true,done)
|
||||
var url = r+'/boards/'+board+'/settings.json'
|
||||
this.ipfs.cat(url,(err,res) => {
|
||||
if(err){
|
||||
done(err)
|
||||
} else {
|
||||
// It's already json...
|
||||
done(err,res)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
BoardsAPI.prototype.getPostsInBoard = function(adminID,board){
|
||||
var ee = new EventEmitter()
|
||||
/*
|
||||
this.getBoardSettings(administratorID,board,(err,res) => {
|
||||
// NEEDS: board settings structure definition
|
||||
// For now we only list admin's posts
|
||||
})
|
||||
*/
|
||||
this.getUserPostListInBoard(adminID,board,(err,res) =>{
|
||||
var ee = this.getUserPostListInBoard(adminID,board,(err,res) =>{
|
||||
if(err){
|
||||
console.log(err)
|
||||
} else res.forEach(item => {
|
||||
this.ipfs.cat(item.hash,(err2,r) => {
|
||||
console.log('got something')
|
||||
if(err2){
|
||||
console.log('Could not download post',item,'of',board+'@'+adminID)
|
||||
} else {
|
||||
@ -206,6 +204,7 @@ BoardsAPI.prototype.getPostsInBoard = function(adminID,board){
|
||||
}
|
||||
|
||||
BoardsAPI.prototype.getUserPostListInBoard = function(user,board,done){
|
||||
var ee = new EventEmitter()
|
||||
this.resolveIPNS(user,(err,url) => {
|
||||
if(err){
|
||||
done(err)
|
||||
@ -214,6 +213,7 @@ BoardsAPI.prototype.getUserPostListInBoard = function(user,board,done){
|
||||
done(e)
|
||||
} else if(r && !r.split){
|
||||
console.log('Found',r.Objects[0].Links.length,'posts in',board,'at',user)
|
||||
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 }
|
||||
})
|
||||
@ -221,6 +221,7 @@ BoardsAPI.prototype.getUserPostListInBoard = function(user,board,done){
|
||||
}
|
||||
})
|
||||
})
|
||||
return ee
|
||||
}
|
||||
|
||||
BoardsAPI.prototype.getCommentsFor = function(parent,done){
|
||||
|
@ -29,9 +29,10 @@ var Homepage = React.createClass({
|
||||
render: function(){
|
||||
return (
|
||||
<div>
|
||||
<h3>Hello</h3>
|
||||
<h3>Welcome to the IPFS Boards Prototype</h3>
|
||||
<p>Not much is implemented...</p>
|
||||
<p>You can try <Link to="@QmXnfA41SXMX3tqFD4kjED7ehyvgTsuAho86TkEoTbZdpw">Opening a Profile</Link> though :)</p>
|
||||
<p>You can try <Link to="@QmXnfA41SXMX3tqFD4kjED7ehyvgTsuAho86TkEoTbZdpw">Opening my Profile</Link> though :)</p>
|
||||
<p>More information about the project on <a href="https://github.com/fazo96/ipfs-board">GitHub</a></p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@ -102,8 +103,8 @@ var PostList = React.createClass({
|
||||
return (
|
||||
<div className="postList">
|
||||
{this.state.posts.map(post => {
|
||||
return (<div className="post">
|
||||
<h5 key={post.title}>{post.title}</h5>
|
||||
return (<div key={post.title} className="post">
|
||||
<h5>{post.title}</h5>
|
||||
<p>{post.text}</p>
|
||||
</div>)
|
||||
})}
|
||||
@ -112,13 +113,44 @@ var PostList = React.createClass({
|
||||
}
|
||||
})
|
||||
|
||||
var Board = React.createClass({
|
||||
var UserID = React.createClass({
|
||||
getInitialState: function(){
|
||||
return { name: '@'+this.props.id }
|
||||
},
|
||||
componentDidMount: function(){
|
||||
boards.getProfile(this.props.id, (err,res) => {
|
||||
if(!err) {
|
||||
this.setState({ name: '@'+res.name.trim() })
|
||||
}
|
||||
})
|
||||
},
|
||||
render: function(){
|
||||
return (<div className="board">
|
||||
<h2>{this.props.params.boardname}</h2>
|
||||
<Link to={'/@'+this.props.params.userid}>
|
||||
<h5 className="light">@{this.props.params.userid}</h5>
|
||||
<Link to={'/@'+this.props.id}>
|
||||
<h5 className="light">{this.state.name}</h5>
|
||||
</Link>
|
||||
</div>)
|
||||
}
|
||||
})
|
||||
|
||||
var Board = React.createClass({
|
||||
getInitialState: function(){
|
||||
return { name: '# '+this.props.params.boardname }
|
||||
},
|
||||
componentDidMount: function(){
|
||||
boards.getBoardSettings(this.props.params.userid,this.props.params.boardname, (err,res) => {
|
||||
if(err) {
|
||||
console.log('Huh? Invalid board settings?',err)
|
||||
} else {
|
||||
console.log('Found name:',res.fullname)
|
||||
this.setState({ name: '# '+res.fullname.trim() })
|
||||
}
|
||||
})
|
||||
},
|
||||
render: function(){
|
||||
return (<div className="board">
|
||||
<h2>{this.state.name}</h2>
|
||||
<UserID id={this.props.params.userid} />
|
||||
<PostList board={this.props.params.boardname} admin={this.props.params.userid}/>
|
||||
</div>)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user