1
0
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:
Enrico Fasoli 2015-11-14 16:26:03 +01:00
parent 0f71407040
commit 5a71c39bb9
4 changed files with 89 additions and 42 deletions

View File

@ -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
{

View File

@ -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

View File

@ -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){

View File

@ -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>)
}