diff -r 7b517a54b708 -r 3247fccfbd3f server/src/main/webapp/static/js/corenkan.js --- a/server/src/main/webapp/static/js/corenkan.js Tue Jan 01 09:28:03 2013 +0100 +++ b/server/src/main/webapp/static/js/corenkan.js Mon Jan 14 16:00:07 2013 +0100 @@ -1,27 +1,37 @@ +//TODO add underscore as requirement define([ "dojo", - "coweb/main" -], function(dojo, coweb) { + "dojo/cookie", + "coweb/main", + "rcolor", + "underscore" +], function(dojo, cookie, coweb, RColor, underscore) { var CoRenkan = function() { }; var proto = CoRenkan.prototype; - + + var _ = underscore; + proto.init = function() { console.log("ready callback"); //this.initCollab(); - + var that = this; + var sess = coweb.initSession(); - var that = this; + sess.onStatusChange = function(status) { console.log(status); if(typeof that.onStatusChange === "function") { that.onStatusChange(status); } }; - sess.prepare(); + + sess.prepare().then(function(data) { + console.log("Prepare ok : ", data); + }); this.project = null; }; @@ -32,6 +42,31 @@ this.collab.subscribeSync("user", this, "onRemoteUserChange"); this.collab.subscribeSync("node", this, "onRemoteNodeChange"); this.collab.subscribeSync("edge", this, "onRemoteEdgeChange"); + this.collab.subscribeSync("_roster", this, "onRemoteRosterChange"); + + this.collab.subscribeReady(this, 'onLocalJoin'); + this.collab.subscribeSiteJoin(this, 'onRemoteJoin'); + this.collab.subscribeSiteLeave(this, 'onRemoteLeave'); + }; + + proto.onLocalJoin = function(params) { + console.log("Local join", params); + }; + + + proto.onRemoteJoin = function(params) { + console.log("Remote join", params); + // do nothing + }; + + proto.onRemoteLeave = function(params) { + console.log("Remote leave", params); + + // remove remote site from current_user_list + if(typeof this.renkan === "undefined" || this.renkan == null || typeof this.renkan.current_user_list === "undefined" || this.renkan.current_user_list == null) { + return; + } + }; function prepareValues(obj,c) { @@ -51,7 +86,8 @@ id: obj.id, _type: type, _index: options.index, - _project_id : obj.get("project").get("_id") + _project_id : obj.get("project").get("_id"), + _user_id : (this.project.current_user!=null)?this.project.current_user.id:null }; for(var k in new_values) { values[k] = new_values[k]; @@ -66,7 +102,8 @@ id: obj.id, _type: type, _index: options.index, - _project_id : obj.get("project").id + _project_id : obj.get("project").id, + _user_id : (this.project.current_user!=null)?this.project.current_user.id:null }; this.collab.sendSync(type, values, "delete", options.index); }; @@ -77,19 +114,142 @@ var values = { id: obj.id, _type: type, - _project_id : obj.get("project").id + _project_id : obj.get("project").id, + _user_id : (this.project.current_user!=null)?this.project.current_user.id:null }; _.extend(values,obj.changed); this.collab.sendSync(type, values); } }; + /** + * Called when an abject is changed + * + */ + proto.objectChange = function(event, model, collection, options) { + + console.log("project change all ", event, model, collection, options); + // check that current user is in user list of the project + + if(this.project == null || this.project.current_user == null) { + return; + } + var current_user = this.project.current_user; + + if(this.project.get("users").get(current_user.id) == null) { + var props = current_user.toJSON(); + this.project.addUser(props); + } + + }; + + + proto.setObjects = function(renkan) { + + console.log(cookie("BAYEUX_BROWSER")); + var project = renkan.project; + this.setProject(project); + this.setRenkan(renkan); + + this.initCollab("renkan_" + project.id); + + this.setUser(renkan); + + }; + + proto.setRenkan = function(renkan) { + + console.log("Set Renkan"); + + var that = this; + + renkan.current_user_list.bind("add", function(obj, c, options) { + that.addObjectBind("_roster", obj, c, options); + }); + renkan.current_user_list.bind("remove", function(obj, c, options) { + that.removeObjectBind("_roster", obj, c, options); + }); + renkan.current_user_list.bind("change", function(obj, options) { + that.updateObjectBind("_roster", obj, options); + }); + + renkan.current_user_list.bind("change", function(obj, options) { + console.log("update roster",obj, options); + // get user in project + project = obj.get("project"); + if(project == null) { + console.log("null project return"); + return; + } + user = project.get("users").get(obj.id); + if(user == null) { + console.log("user " + obj.id + " not in project. return"); + return; + } + for(att in obj.changed) { + new_val = obj.changed[att]; + if(user.get("att") != new_val) { + user.set(att, new_val); + } + } + }); + + this.renkan = renkan; + + }; + + proto.setUser = function(renkan) { + console.log("set user : " + cookie("BAYEUX_BROWSER")); + + if(typeof renkan === "undefined" || typeof renkan.project === "undefined" || renkan.project == null) { + return; + } + + var user_id = cookie("BAYEUX_BROWSER"); + var project = renkan.project; + + var puser = project.get("users").get(user_id); + var puser_def = null; + if(puser == null) { + color = new RColor(); + puser_def = { + id: user_id, + title: "anonymous", + project: project, + color: color.get(true, 0.3, 0.99) + }; + } + else { + puser_def = puser.toJSON(); + puser_def.project = project; + } + puser = renkan.current_user_list.push(puser_def); + + project.current_user = puser; + renkan.current_user = puser.id; + + var that = this; + + project.once("all", function(event, model, collection, options){ + that.objectChange(event, model, collection, options); + }); + project.get("nodes").once("all", function(event, model, collection, options){ + that.objectChange(event, model, collection, options); + }); + project.get("edges").once("all", function(event, model, collection, options){ + that.objectChange(event, model, collection, options); + }); + + + }; + proto.setProject = function(project) { console.log("project", project); - - var projectFields = ["title", "description", "uri"]; + + var projectFields = ["title", "description", "uri"]; var that = this; + for(var fieldIndex in projectFields) { (function(fi){ var field = projectFields[fi]; @@ -106,6 +266,7 @@ })(fieldIndex); } + project.get("nodes").bind("add", function(obj, c, options) { that.addObjectBind("node", obj, c, options); }); @@ -144,7 +305,6 @@ this.project = project; - this.initCollab("renkan_" + project.id); }; @@ -159,13 +319,6 @@ if (args.type === "update") { this.onRemoteProjectUpdate(args.value, args.position); } - /*if (args.type === "insert") { - this.onRemoteInsert(value, args.position); - } else if (args.type === "update") { - this.onRemoteUpdate(value, args.position); - } else if (args.type === "delete") { - this.onRemoteDelete(args.position); - }*/ }; @@ -213,8 +366,16 @@ proto.onRemoteEdgeChange = function(args) { this.onRemoteObjectChange("edges", args); }; - - + + /** + * Called when a remote data store for nodes changes in some manner. Dispatches to + * local methods for insert, update, delete handling. + * @param args Cooperative web event + */ + proto.onRemoteRosterChange = function(args) { + this.onRemoteObjectChange(this.renkan.current_user_list, args); + }; + /** * Called when a project attribute changes value in a remote data store. * Updates the attribute value of the item with the same id in the local @@ -242,20 +403,28 @@ /** * Called when an object is inserted in a remote data store. * + * @param field_coll A collection or a string for one of the project collection * @param value Item data sent by remote data store * @param position Which item to update. */ - proto.onRemoteObjectInsert = function(field, values, position) { + proto.onRemoteObjectInsert = function(field_coll, values, position) { + + console.log("Remote ", field_coll ," insert values ", values, "position", position); - console.log("Remote "+ field +" insert values ", values, "position", position); - - var coll = this.project.get(field); + var coll = null; + if(typeof field_coll === "string") { + coll = this.project.get(field_coll); + } + else { + coll = field_coll; + } + var object_id = values['id']; var obj = coll.get(object_id); if(obj != null) { - this.onRemoteObjectUpdate(field, values, coll.indexOf(obj)); + this.onRemoteObjectUpdate(field_coll, values, coll.indexOf(obj)); } else { var add_values = {}; @@ -264,7 +433,7 @@ add_values[fieldname] = values[fieldname]; } } - switch(field) { + switch(field_coll) { case "nodes": this.project.addNode(add_values, {at:position}); break; @@ -274,7 +443,12 @@ case "users": this.project.addUser(add_values, {at:position}); break; + default: + add_values.project = this.project; + coll.push(add_values, {at:position}); + break; } + } }; @@ -284,18 +458,26 @@ * Updates the attribute value of the item with the same id in the local * data store. * - * @param field The collection field + * @param field_coll A collection or a string for one of the project collection * @param value Item data sent by remote data store * @param position Which item to update. */ - proto.onRemoteObjectUpdate = function(field, values, position) { + proto.onRemoteObjectUpdate = function(field_coll, values, position) { + + console.log("Remote ", field_coll ," update values ", values, "position", position); - console.log("Remote "+ field +" update values ", values, "position", position); + var coll = null; + if(typeof field_coll === "string") { + coll = this.project.get(field_coll); + } + else { + coll = field_coll; + } var object_id = values['id']; if(this.project != null) { - var obj = this.project.get(field).get(object_id); + var obj = coll.get(object_id); if(obj != null) { var changed_val = {}; for(var fieldname in values) { @@ -311,11 +493,20 @@ /** * Called when a object is deleted in a remote data store. * + * @param field_coll A collection or a string for one of the project collection * @param position Which item to update. */ - proto.onRemoteObjectDelete = function(field, position) { - console.log("Remote "+ field +" delete position", position); - this.project.get(field).remove(this.project.get(field).at(position)); + proto.onRemoteObjectDelete = function(field_coll, position) { + console.log("Remote ", field_coll," delete position", position); + var coll = null; + if(typeof field_coll === "string") { + coll = this.project.get(field); + } + else { + coll = field_coll; + } + + coll.remove(coll.at(position)); };