diff -r 7e132e2a48ca -r 267d67791e05 server/src/main/webapp/static/js/corenkan.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server/src/main/webapp/static/js/corenkan.js Tue Dec 25 21:29:11 2012 +0100 @@ -0,0 +1,306 @@ +define([ + "dojo", + "coweb/main" +], function(dojo, coweb) { + + var CoRenkan = function() { + }; + + var proto = CoRenkan.prototype; + + proto.init = function() { + console.log("ready callback"); + + //this.initCollab(); + + var sess = coweb.initSession(); + var that = this; + sess.onStatusChange = function(status) { + console.log(status); + if(typeof that.onStatusChange === "function") { + that.onStatusChange(status); + } + }; + sess.prepare(); + this.project = null; + + }; + + proto.initCollab = function(id) { + this.collab = coweb.initCollab({id : id}); + this.collab.subscribeSync("project", this, "onRemoteProjectChange"); + }; + + function prepareValues(obj,c) { + values = {}; + for(var fieldname in c.changes) { + if(c.changes[fieldname]) { + values[fieldname] = obj.get(fieldname); + } + } + return values; + } + + proto.addObjectBind = function(type, obj, c, options) { + console.log("add " + type,obj, c, options, this.project.toJSON()); + var values = obj.toJSON(); + var new_values = { + id: obj.id, + _type: type, + _index: options.index, + _project_id : obj.get("project").get("_id") + }; + for(var k in new_values) { + values[k] = new_values[k]; + } + console.log("add values : ", values); + this.collab.sendSync(type, values, "insert", options.index); + }; + + proto.removeObjectBind = function(type, obj, c, options) { + console.log("delete " + type,obj, c, options); + var values = { + id: obj.id, + _type: type, + _index: options.index, + _project_id : obj.get("project").id + }; + this.collab.sendSync(type, values, "delete", options.index); + }; + + proto.updateObjectBind = function(type, obj, options) { + console.log("change " + type,obj, options); + if(obj.hasChanged()) { + var values = { + id: obj.id, + _type: type, + _project_id : obj.get("project").id + }; + _.extend(values,obj.changed); + this.collab.sendSync(type, values); + } + }; + + proto.setProject = function(project) { + + console.log("project", project); + + var projectFields = ["title", "description", "uri"]; + var that = this; + for(var fieldIndex in projectFields) { + (function(fi){ + var field = projectFields[fi]; + project.bind("change:"+field, function(obj, c) { + console.log(c); + values = { + id: obj.id, + type: "project", + project_id: obj.id + }; + values[field] = c; + that.collab.sendSync("project", values); + }); + })(fieldIndex); + } + + project.get("nodes").bind("add", function(obj, c, options) { + that.addObjectBind("node", obj, c, options); + }); + + project.get("nodes").bind("remove", function(obj, c, options) { + that.removeObjectBind("node", obj, c, options); + }); + + project.get("nodes").bind("change", function(obj, options) { + that.updateObjectBind("node", obj, options); + }); + + project.get("users").bind("add", function(obj, c, options) { + that.addObjectBind("user", obj, c, options); + }); + + project.get("users").bind("remove", function(obj, c, options) { + that.removeObjectBind("user", obj, c, options); + }); + + project.get("users").bind("change", function(obj, options) { + that.updateObjectBind("user", obj, options); + }); + + project.get("edges").bind("add", function(obj, c, options) { + that.addObjectBind("edge", obj, c, options); + }); + + project.get("edges").bind("remove", function(obj, c, options) { + that.removeObjectBind("edge", obj, c, options); + }); + + project.get("edges").bind("change", function(obj, options) { + that.updateObjectBind("edge", obj, options); + }); + + + this.project = project; + this.initCollab("renkan_" + project.id); + }; + + + /** + * Called when a remote data store for project changes in some manner. Dispatches to + * local methods for insert, update, delete handling. + * TODO: manage project list change on server + * @param args Cooperative web event + */ + proto.onRemoteProjectChange = function(args) { + console.log("Remote project change", args); + 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); + }*/ + }; + + + /** + * 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.onRemoteObjectChange = function(field, args) { + console.log("Remote "+ field +" change",args); + if (args.type === "insert") { + this.onRemoteObjectInsert(field, args.value, args.position); + } else if (args.type === "update") { + this.onRemoteNodeUpdate(field, args.value, args.position); + } else if (args.type === "delete") { + this.onRemoteNodeDelete(field, args.position); + } + }; + + + /** + * 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.onRemoteNodeChange = function(args) { + this.onRemoteObjectChange("nodes", 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.onRemoteUserChange = function(args) { + this.onRemoteObjectChange("users", 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.onRemoteUserChange = function(args) { + this.onRemoteObjectChange("edges", 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 + * data store. + * + * @param value Item data sent by remote data store + * @param position Which item to update. + */ + proto.onRemoteProjectUpdate = function(values, position) { + var project_id = values['id']; + if(typeof(project_id) === "undefined") { + return; + } + + if(this.project != null && project_id == this.project.id) { + for(var fieldname in values) { + if(fieldname != "id" && fieldname != "type") { + this.project.set(fieldname, values[fieldname]); + } + } + } + + }; + + /** + * Called when an object is inserted in a remote data store. + * + * @param value Item data sent by remote data store + * @param position Which item to update. + */ + proto.onRemoteObjectInsert = function(field, values, position) { + + var coll = this.project.get(field); + var object_id = values['id']; + + var obj = coll.get(object_id); + + if(obj != null) { + this.onRemoteObjectUpdate(field, values, coll.indexOf(obj)); + } + else { + this.project.get(field).add(values, {at:position}); + } + + }; + + /** + * Called when a object attribute changes value in a remote data store. + * Updates the attribute value of the item with the same id in the local + * data store. + * + * @param field The collection field + * @param value Item data sent by remote data store + * @param position Which item to update. + */ + proto.onRemoteObjectUpdate = function(field, values, position) { + + var object_id = values['id']; + + if(this.project != null) { + for(var obj in this.project.get(field)) { + if(obj.id == object_id) { + for(var fieldname in values) { + if(fieldname != "id" && fieldname != "type") { + obj.set(fieldname, values[fieldname]); + } + } + } + } + } + }; + + /** + * Called when a object is deleted in a remote data store. + * + * @param position Which item to update. + */ + proto.onRemoteObjectDelete = function(field, position) { + this.project.get(field).remove(this.project.get(field).at(position)); + }; + + + var app = new CoRenkan(); + dojo.ready(function() { + app.init(); + }); + + + return { + app: app + }; +}); \ No newline at end of file