diff --git a/PROTOCOL.md b/PROTOCOL.md index 833db4e..ba71121 100644 --- a/PROTOCOL.md +++ b/PROTOCOL.md @@ -109,7 +109,7 @@ possible for lange texts without duplicating data. #### Versioning - just the version ID written in the version file + ipfs:boards:version:version_name ## Boards diff --git a/lib/boards-api.js b/lib/boards-api.js index 71cc7f6..de9c2c8 100644 --- a/lib/boards-api.js +++ b/lib/boards-api.js @@ -49,7 +49,7 @@ function replyAsObj(res,isJson,done){ function BoardsAPI(ipfs){ this.ipfs = ipfs - this.version = 'dev' + this.version = 'ipfs:boards:version:dev' this.baseurl = '/ipfs-boards-profile/' this.users = {} // userID : profileHash this.resolving_ipns = {} // to check if a resolve is already in progress @@ -81,6 +81,9 @@ BoardsAPI.prototype.resolveIPNS = function(n,handler){ var cached = this.users[n] if(cached){ this.ee.emit(n,cached) + console.log(n,'was cached') + } else { + console.log(n,'not cached') } if(this.resolving_ipns[n] != true){ this.resolving_ipns[n] = true @@ -89,16 +92,22 @@ BoardsAPI.prototype.resolveIPNS = function(n,handler){ // Communicate error this.ee.emit('error',err) } else { - var url = r.Hash - if(this.users[n] != url) this.isUserProfile(r.Hash,isit => { - if(isit == this.version){ + var url = r.Path + if(url === undefined){ + console.log('UNDEFINED URL',r) + } + if(this.users[n] != url) this.isUserProfile(url,(isit,err) => { + if(isit){ console.log(n,'is a user') - if(this.users[n] != url){ - this.users[n] = url - this.ee.emit(n,url) - } + this.users[n] = url + this.ee.emit(n,url) + this.backupCache() + } else { + console.log(n,'not a user') + this.ee.emit(n,undefined,'not a valid profile: '+err) } this.resolving_ipns[n] = false + return true // Remove from listeners }) } }) @@ -109,11 +118,14 @@ 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) => { - if(err) return done(false) + if(err) return done(false,err) replyAsObj(r,false,(_,res) => { var v = res.trim() - console.log('Version for',addr,'is',v) - done(v) + 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+'"') }) }) } @@ -125,10 +137,25 @@ BoardsAPI.prototype.searchUsers = function(){ replyAsObj(r,true,(e,reply) => { console.log('Checking',reply.Strings.length,'peers') reply.Strings.forEach(item => { - this.resolveIPNS(item) + var ss = item.split('/') + var n = ss[ss.length-1] + this.resolveIPNS(n) }) }) }) + // Look for who has the correct version file, they probably have a profile + // Disabled at the moment + /* + this.ipfs.dht.findprovs(this.version_hash, (err,res) => { + if(err){ + console.log('DHT FINDPROVS err',err) + } else if(res.readable){ + console.log('DHT FINDPROVS stream',res) + } else { + console.log('DHT FINDPROVS string',res) + } + }) + */ return this.ee } @@ -146,6 +173,7 @@ BoardsAPI.prototype.getProfile = function(userID,done){ done(err2,null) } else { // It already returns a JSON? + this.ee.emit('profile for '+userID,res) done(null,res) } }) @@ -305,12 +333,13 @@ BoardsAPI.prototype.init = function(done){ this.id = res.ID this.resolveIPNS(res.ID) console.log('Version is',this.version) - this.ipfs.add(new Buffer('ipfs:boards:version:'+this.version),(err2,r) => { + 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) 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) done(null) diff --git a/webapp/app.jsx b/webapp/app.jsx index 6c7bc61..9589934 100644 --- a/webapp/app.jsx +++ b/webapp/app.jsx @@ -102,7 +102,7 @@ var PostList = React.createClass({ var UserID = React.createClass({ getInitialState: function(){ - return { name: '@'+this.props.id } + return { } }, componentDidMount: function(){ boards.getProfile(this.props.id, (err,res) => { @@ -112,10 +112,17 @@ var UserID = React.createClass({ } }) }, + getContent: function(){ + if(this.state.name){ + return () + } else { + return '@' + } + }, render: function(){ return (
- {this.state.name} + {this.getContent()}{this.state.name || this.props.id}
) } @@ -184,21 +191,23 @@ var Profile = React.createClass({ return { name: '...', boards: [] } }, componentDidMount: function(){ - var ee = boards.getProfile(this.props.params.userid, (err,res) => { + console.log('About to ask for profile for',this.props.params.userid) + var ee = boards.getEventEmitter() + ee.on('boards for '+this.props.params.userid,l => { + if(!this.isMounted()) return true + this.setState({ boards: l }) + }) + boards.getProfile(this.props.params.userid,(err,res) => { if(!this.isMounted()) return true if(err){ this.setState({ - name: '?', - error: 'Invalid profile' + name: , + description: err }) } else { this.setState({ name: res.name, description: res.description }) } }) - ee.on('boards for '+this.props.params.userid,l => { - if(!this.isMounted()) return true - this.setState({ boards: l }) - }) }, linkToEditor: function(){ if(this.props.params.userid === boards.id){ @@ -213,7 +222,6 @@ var Profile = React.createClass({ return (
{this.linkToEditor()}

{this.state.name}

-

{this.state.error}


@{this.props.params.userid}
@@ -249,8 +257,25 @@ var Board = React.createClass({ }) var Users = React.createClass({ + getInitialState: function(){ + return { users: [ boards.id ] } + }, + componentDidMount: function(){ + boards.searchUsers().on('user',(id) => { + if(this.isMounted() && this.state.users.indexOf(id) < 0) + this.setState({ users: this.state.users.concat(id) }) + }) + }, render: function(){ - return + return
+

Users

+

Found {this.state.users.length} users, looking for more...

+
    + {this.state.users.map(user => { + return + })} +
+
} })