Browse files

クライアントへのsend/クライアントからのsend->sae

  • Loading branch information...
1 parent 78d9fd7 commit 945a8d85bb1899bf7a0506b18c178731f7933d69 @motsat committed Aug 8, 2011
Showing with 379 additions and 162 deletions.
  1. +235 −0 :w
  2. +1 −0 mongoschema.js
  3. +54 −23 public/js/objectMediator.js
  4. +41 −129 server.js
  5. +42 −0 test.js
  6. +6 −10 views/index.ejs
View
235 :w
@@ -0,0 +1,235 @@
+// 以下の仲介役
+TaskRenderer = function(config, raphael, mediator)
+{
+ this.o = config.objects;
+ this.v = config.visual;
+ this.raphael = raphael;
+ this.mediator = mediator;
+}
+TaskRenderer.prototype.renderTaskBase = function(str, x, y, attr, editOptions)
+{
+ var v = this.v,
+ rc = this.raphael.rect(x, y, w = v.rectEnd.w, y2 = v.rectEnd.h, v.taskR)
+ .attr($.extend(attr, {'scale':0.1})),
+ tx = this.raphael.text(x + v.font_m.padding_rect.x,
+ y + v.font_m.padding_rect.y, str).
+ attr(v.font_m.attr),
+ onEndAnimation = null;
+ mediator = this.mediator;
+ s = this.raphael.set().push(rc, tx);
+
+ if (editOptions && editOptions.openOnCraeted) {
+ onEndAnimation = function() {mediator.showEditBox(editOptions.task, s)};
+ } else {
+ onEndAnimation = null;
+ }
+
+ rc.animate({'scale':1}, 400, 'bounce', onEndAnimation);
+ rc.node.style.cursor = 'pointer';
+ tx.node.style.cursor = 'pointer';
+ return s;
+
+}
+TaskRenderer.prototype.renderStart = function(x) {
+ var v = this.v;
+ return this.renderTaskBase('スタート' , x, y = v.paper.margin.h, v.rectStart.attr);
+}
+
+TaskRenderer.prototype.renderEnd = function(x, task) {
+ var v = this.v;
+ return this.renderTaskBase(task.end_title, x, y = v.paper.margin.h, v.rectEnd.attr);
+}
+
+TaskRenderer.prototype.renderTaskParent = function(x, y, task, mediator, openOnCraeted){
+ var s = this.renderTaskBase(task.title, x, y, v.rectP.attr, {openOnCraeted:openOnCraeted, task:task}),
+ addImg = this.raphael.image('/images/plus.png', x , y + (v.rectP.h / 2)+10, w = v.icon.w, h = v.icon.h)
+ .click(function() {mediator.addChildTask(task, s)});
+
+ s.click(function(){mediator.showEditBox(task, s)});
+ s.push(addImg);
+
+ var showIcons = function() {addImg.show();},
+ hideIcons = function() {addImg.hide();};
+ return s;
+}
+
+TaskRenderer.prototype.renderTaskChild = function(x, y, task, mediator){
+ var s = this.renderTaskBase(task.title, x, y, v.rectC.attr, {openOnCraeted:true, task:task}),
+ p = this.raphael.path($.sprintf('"M %d %d L %d %d', x, y - v.taskMargin.child.h, x, y + v.rectC.h))
+ .attr($.extend(this.v.pathL.attr,{'scale':0.1}))
+ .animate( {'scale':1}, 100)
+ .toBack();
+ s.push(p);
+ s.click(function(){mediator.showEditBox(task, s)});
+ return s;
+}
+
+TaskRenderer.prototype.renderPath = function(x, mediator){
+ var pathL_y = v.paper.margin.h + (v.rectStart.h / 2);
+
+ return this.raphael.path($.sprintf('"M %d %d L 1000 %d',this.v.paper.margin.w, pathL_y, pathL_y))
+ .attr($.extend(this.v.pathL.attr,{'scale':0.1}))
+ .animate( {'scale':1}, 300)
+ .toBack();
+}
+
+
+ObjectMediator = function() {};
+ObjectMediator.prototype.setUp = function(config, objects) {
+ var socket = new io.Socket(config.server_host,{port:config.port}).connect(),
+ v = config.visual,
+ raphael = Raphael(document.getElementById(config.paper_id),
+ v.paper.w, v.paper.h);
+ this.socket = socket;
+ // test code
+ var hoge = function(){log(this)};
+ socket.on('message', function(msg) {
+ log(this);
+ });
+ this.taskRenderer = new TaskRenderer(config, raphael, this);
+ this.config = config;
+ this.objects = objects;
+ this.shapes = {'start_task' : [],
+ 'tasks' : [],
+ 'end_task' : []};
+ var mediator = this,
+ nextX = v.paper.margin.w;
+
+ this.editingTask = {task:null, shapes:null};
+
+ this.taskRenderer.renderStart(nextX);
+
+ nextX += (v.rectStart.w + v.taskMargin.w);
+ var sets = [];
+ for (var i=0; i < objects.tasks.length; i++) {
+ sets[i] = this.taskRenderer.renderTaskParent(nextX, v.paper.margin.h, objects.tasks[i], this, false) ;
+ pushArrayAt(this.shapes.tasks, i, {parent:sets[i], childs:[]});
+ nextX += (v.rectP.w + v.taskMargin.w);
+ }
+
+ this.shapes.end_task = this.taskRenderer.renderEnd(nextX,objects);
+ this.taskRenderer.renderPath(nextX, mediator)
+ .click(function(evt){mediator.onClickPath(evt)});
+ var saveEditBox = function () {
+ $('#editbox').dialog('close');
+ };
+ // setup editBox
+ var onEnterKeyDown = function (evt){
+ if (evt.keyCode =='13') {
+ $.each(mediator.editingTask.shapes , function(idx, elm) {
+ if (elm.type == 'text') {
+ elm.attr({text:$('#task_title').val()});
+ }
+ });
+ mediator.editingTask.task.title = $('#task_title').val();
+ saveEditBox();
+ }
+ };
+
+ $('#edit_complete').click(saveEditBox);
+ $('#task_title').keydown(onEnterKeyDown);
+ $('#editbox').hide();
+
+ // save_button
+ $('#save_button').click(function (evt) {mediator.onSaveTasks()});
+
+};
+
+ObjectMediator.prototype.onSaveTasks = function()
+{
+ this.socket.send(this.objects);
+}
+ObjectMediator.prototype.addChildTask = function(task, shapes)
+{
+ var v = this.config.visual,
+ newTask = {title:'non title', tasks:[]},
+ startTaskMargin = v.rectStart.w + v.taskMargin.w,
+ x = shapes.getBBox().x + v.taskMargin.child.w,
+ y = shapes.getBBox().y + ((task.tasks.length + 1) * (v.rectP.h + v.taskMargin.child.h)),
+ taskShape = this.taskRenderer.renderTaskChild(x,y, newTask, this);
+
+ task.tasks.push(newTask);
+ var order = this.orderOfParentTask(task);
+ this.shapes.tasks[order].childs.push(taskShape);
+}
+ObjectMediator.prototype.addParentTask = function(x)
+{
+ var v = this.config.visual,
+ num = this.taskNumAtPathX(x),
+ newTask = {title:'non title', tasks:[]},
+ taskShape = this.taskRenderer.renderTaskParent(this.calculateTaskX(num) , v.paper.margin.h, newTask, this, true);
+ //this.objects.tasks = pushArrayAt(this.objects.tasks, num, newTask);
+ //this.shapes.tasks = pushArrayAt(this.shapes.tasks, num, taskShape);
+ pushArrayAt(this.objects.tasks, num, newTask);
+ pushArrayAt(this.shapes.tasks, num, {parent:taskShape, childs:[]});
+ this.moveTaskShapesAt(num + 1); // 追加分以降のものを移動
+}
+ObjectMediator.prototype.calculateTaskX = function(num)
+{
+ var v = this.config.visual,
+ startTaskMargin = v.rectStart.w + v.taskMargin.w;
+ return v.paper.margin.w + startTaskMargin + (num * (v.rectP.w + v.taskMargin.w));
+
+}
+ObjectMediator.prototype.moveRaphaelSets = function(sets, x) {
+
+ for (var n = 0; n < sets.items.length; n++){
+ var item = sets.items[n];
+ if (item.type == 'path') {
+ path = $.extend(true, [], item.attr('path')); // deep copy
+ path[0][1] += v.rectP.w + v.taskMargin.w;
+ path[1][1] += v.rectP.w + v.taskMargin.w;
+
+ item.animate({'path':pathToString(path)}, 500);
+ }
+ var x = item.getBBox().x;
+ item.animate( {'x': x + v.rectP.w + v.taskMargin.w}, 500);
+ }
+
+}
+
+ObjectMediator.prototype.moveTaskShapesAt = function(num)
+{
+ var tasks = this.shapes.tasks,
+ v = this.config.visual;
+ this.moveRaphaelSets(this.shapes.end_task, v.rectP.w + v.taskMargin.w );
+
+ if (tasks.length <= 0 ) {
+ return;
+ }
+
+ for (var i = num; i < tasks.length; i++) {
+ this.moveRaphaelSets(tasks[i].parent, v.rectP.w + v.taskMargin.w );
+ if (0 < tasks[i].childs.length){
+ var childs = tasks[i].childs;
+ for (var z = 0; z < childs.length; z++) {
+ this.moveRaphaelSets(childs[z], v.rectP.w + v.taskMargin.w );
+ }
+ }
+ }
+}
+
+ObjectMediator.prototype.onClickPath = function(evt) {
+ this.addParentTask(evt.x);
+}
+ObjectMediator.prototype.taskNumAtPathX = function(pathX) {
+ // 計算式が適当なので詳細詰め
+ var v = this.config.visual;
+ return parseInt(pathX / (v.taskMargin.w + v.rectP.w))-1;
+}
+
+ObjectMediator.prototype.showEditBox = function(task, shapes) {
+ mediator.editingTask = {task:task, shapes:shapes};
+ $('#task_id').val(task.__id);
+ $('#task_title').val(task.title);
+ $('#task_description').val(task.description);
+ $('#editbox').dialog( { draggable: true });
+
+}
+ObjectMediator.prototype.orderOfParentTask = function(task) {
+ for (var i=0;i < this.objects.tasks.length; i++) {
+ if (this.objects.tasks[i] === task){
+ return i;
+ }
+ }
+}
View
1 mongoschema.js
@@ -5,6 +5,7 @@ var Schema = mongo.Schema;
// ModelのSchema Class定義する
var TaskSchema = new Schema({
title : String,
+ description : String,
is_complete : Boolean
});
View
77 public/js/objectMediator.js
@@ -1,8 +1,8 @@
// 以下の仲介役
TaskRenderer = function(config, raphael, mediator)
{
- this.o = config.objects;
- this.v = config.visual;
+ this.o = config.objects;
+ this.v = config.visual;
this.raphael = raphael;
this.mediator = mediator;
}
@@ -76,35 +76,38 @@ TaskRenderer.prototype.renderPath = function(x, mediator){
ObjectMediator = function() {};
ObjectMediator.prototype.setUp = function(config, objects) {
- var socket = new io.Socket(config.server_host,{port:config.port}),
+ var socket = new io.Socket(config.server_host,{port:config.port}).connect(),
v = config.visual,
raphael = Raphael(document.getElementById(config.paper_id),
- v.paper.w, v.paper.h);
+ v.paper.w, v.paper.h),
+ mediator = this,
+ onMessage = function (msg){mediator.dispatchMessage(msg)};
+ socket.on('message', function(msg) {onMessage(msg)}); // fix me
+
+ this.socket = socket;
this.taskRenderer = new TaskRenderer(config, raphael, this);
this.config = config;
- this.objects = objects;
this.shapes = {'start_task' : [],
'tasks' : [],
'end_task' : []};
- var mediator = this,
- nextX = v.paper.margin.w;
+ var nextX = v.paper.margin.w;
- this.editingTask = {task:null, shapes:null};
+ //this.editingTask = {task:null, shapes:null};
- this.taskRenderer.renderStart(nextX);
+ //this.taskRenderer.renderStart(nextX);
- nextX += (v.rectStart.w + v.taskMargin.w);
- var sets = [];
- for (var i=0; i < objects.tasks.length; i++) {
- sets[i] = this.taskRenderer.renderTaskParent(nextX, v.paper.margin.h, objects.tasks[i], this, false) ;
- pushArrayAt(this.shapes.tasks, i, {parent:sets[i], childs:[]});
- nextX += (v.rectP.w + v.taskMargin.w);
- }
+ //nextX += (v.rectStart.w + v.taskMargin.w);
+ //var sets = [];
+ //for (var i=0; i < objects.tasks.length; i++) {
+ // sets[i] = this.taskRenderer.renderTaskParent(nextX, v.paper.margin.h, objects.tasks[i], this, false) ;
+ // pushArrayAt(this.shapes.tasks, i, {parent:sets[i], childs:[]});
+ // nextX += (v.rectP.w + v.taskMargin.w);
+ //}
- this.shapes.end_task = this.taskRenderer.renderEnd(nextX,objects);
- this.taskRenderer.renderPath(nextX, mediator)
- .click(function(evt){mediator.onClickPath(evt)});
+ //this.shapes.end_task = this.taskRenderer.renderEnd(nextX,objects);
+ //this.taskRenderer.renderPath(nextX, mediator)
+ // .click(function(evt){mediator.onClickPath(evt)});
var saveEditBox = function () {
$('#editbox').dialog('close');
};
@@ -120,15 +123,45 @@ ObjectMediator.prototype.setUp = function(config, objects) {
saveEditBox();
}
};
+
$('#edit_complete').click(saveEditBox);
$('#task_title').keydown(onEnterKeyDown);
$('#editbox').hide();
+
+ // save_button
+ $('#save_button').click(function (evt) {mediator.onSaveTasks()});
+
};
+ObjectMediator.prototype.dispatchMessage = function(msg){
+ this.objects = msg;
+ var mediator = this,
+ nextX = v.paper.margin.w;
+
+ this.editingTask = {task:null, shapes:null};
+
+ this.taskRenderer.renderStart(nextX);
+
+ nextX += (v.rectStart.w + v.taskMargin.w);
+ var sets = [];
+ for (var i=0; i < this.objects.tasks.length; i++) {
+ sets[i] = this.taskRenderer.renderTaskParent(nextX, v.paper.margin.h, this.objects.tasks[i], this, false) ;
+ pushArrayAt(this.shapes.tasks, i, {parent:sets[i], childs:[]});
+ nextX += (v.rectP.w + v.taskMargin.w);
+ }
+
+ this.shapes.end_task = this.taskRenderer.renderEnd(nextX,this.objects);
+ this.taskRenderer.renderPath(nextX, mediator)
+ .click(function(evt){mediator.onClickPath(evt)});
+}
+ObjectMediator.prototype.onSaveTasks = function()
+{
+ this.socket.send(this.objects);
+}
ObjectMediator.prototype.addChildTask = function(task, shapes)
{
var v = this.config.visual,
- newTask = {title:'non title', tasks:[]},
+ newTask = {title:'', tasks:[]},
startTaskMargin = v.rectStart.w + v.taskMargin.w,
x = shapes.getBBox().x + v.taskMargin.child.w,
y = shapes.getBBox().y + ((task.tasks.length + 1) * (v.rectP.h + v.taskMargin.child.h)),
@@ -142,7 +175,7 @@ ObjectMediator.prototype.addParentTask = function(x)
{
var v = this.config.visual,
num = this.taskNumAtPathX(x),
- newTask = {title:'non title', tasks:[]},
+ newTask = {title:'', tasks:[]},
taskShape = this.taskRenderer.renderTaskParent(this.calculateTaskX(num) , v.paper.margin.h, newTask, this, true);
//this.objects.tasks = pushArrayAt(this.objects.tasks, num, newTask);
//this.shapes.tasks = pushArrayAt(this.shapes.tasks, num, taskShape);
@@ -188,9 +221,7 @@ ObjectMediator.prototype.moveTaskShapesAt = function(num)
this.moveRaphaelSets(tasks[i].parent, v.rectP.w + v.taskMargin.w );
if (0 < tasks[i].childs.length){
var childs = tasks[i].childs;
- log(1);
for (var z = 0; z < childs.length; z++) {
- log(2);
this.moveRaphaelSets(childs[z], v.rectP.w + v.taskMargin.w );
}
}
View
170 server.js
@@ -1,158 +1,70 @@
-var mongoose = require('mongoose'),
- schemas = require('./mongoschema').schemas();
+var io = require('socket.io'),
+ express = require('express'),
+ objects = [],
+ mongoose = require('mongoose'),
+ schemas = require('./mongoschema').schemas(),
+ app = express.createServer();
-for (var i=0; i < schemas.length; i++) {
- mongoose.model(schemas[i].name, schemas[i].schema);
-}
-
-//
-//mongoose.connect('mongodb://localhost/gridder',
-// function (err) {
-// if (err) {
-// exitWithError(err);
-// }
-// }
-//}
-//); // mongodb://[hostname]/[dbname]
-//
-//var Task = mongoose.model('Task'); // 定義したときの登録名で呼び出し
-//
-//////// インスタンス生成
-//var task = new Task(
-//{ title : 'hoge title',
-// is_complete : false,
-// parent : []
-//}
-//);
-
-// 1.クライアントがつないできたらsendする。
-// 2.クライアント側はもだったjsonから組み立て
-
-// task.title = 'test title';
-// task.is_complete = false;
-// task.parent = [];
-//
-//
-// //// 埋め込み型カラムはpush()を使う
-// // room.comments.push(
-// // {title: 'comment title1',
-// // body: 'comment body1',
-// // password: 'your password'});
-// //
-// //// pre-hookを定義しているとsave時に定義した関数が走る
-//task.save(function(err) {
-// if (err) {
-// console.log(err);
-// }else {
-// console.log('saved!');
-// }
-//});
-//////
-////// データの取得
-////Room.find({}, function(err, docs) {
-//// //docs.forEach(function(doc){
-//// // console.log(doc);
-//// //});
-////});
-//
-//
-//
-//
-//
-//
-//
-//
-//
-//
-//
-var io = require('socket.io'),
- express = require('express'),
- objects = [],
- ACTION_TYPE = {'REQUEST_CREATE' : 'REQUEST_CREATE', // クライアントからの作成要求
- 'CREATE' : 'CREATE' , // クラインとへの作成指示(REQUEST_CREATE後)
- 'REQUEST_LOCK' : 'REQUEST_LOCK' , // サーバへのロック要求
- 'LOCK' : 'LOCK' , // クラインとへのロック指示(REQUEST_EDIT)要求クライアント以外に送るもの
- 'REQUEST_EDIT' : 'REQUEST_EDIT' , // サーバへの編集要求
- 'EDIT' : 'EDIT' // クライントへの編集指示(REQUEST_EDIT後)
- };
-
-var app = express.createServer();
app.configure(function() {
app.set('views', __dirname + '/views')
.use(express.static(__dirname + '/public'))
.set("view options", { layout: false })
.get('/', function(req, res) {
res.render('index.ejs');
})
- .get('/edit', function(req, res) {
- res.render('edit.ejs');
- })
- .get('/test', function(req, res) {
- res.render('test.ejs');
- })
});
-
app.listen(8000);
-var socket = io.listen(app);
+mongoose.connect('mongodb://localhost/gridder',
+ function (err) {
+ if (err) {
+ exitWithError(err);
+ }
+ }
+);
+for (var i=0; i < schemas.length; i++) {
+ mongoose.model(schemas[i].name, schemas[i].schema);
+}
+var Task = mongoose.model('Task'),
+ socket = io.listen(app);
+
socket.on('connection', function(client) {
- client.on('message', function(msg) {onMessage(msg, client);});
+ sendSavedTask(client);
+ client.on('message', function(msg) {
+ var task = new Task(msg);
+ task.save(function(err) {
+ console.log(err || 'saved');
+ });
+ }
+ );
client.on('disconnect', function() {onDisconnect(client)});
});
-//function addMessage(msg)
-//{
-// msg.id = objects.length + 1;
-// msg.createdAt = nowDate();
-// if (msg.option.color == '') {
-// msg.option.color = 'black';
-// }
-// objects.push(msg);
-//
-// return msg;
-//}
-//
+function sendSavedTask(client)
+{
+ var tmpID = '4e39f035b966906c0e000001';
+ console.log(Task);
+ var myTask = Task.findOne({ '_id': tmpID}, function (err, doc){
+ if (err) {
+ exitWithError(err);
+ }
+ console.log(doc);
+ client.send(doc);
+ });
+
+}
function onDisconnect(client)
{
- msg = {"data" : client. sessionId+"が切断されました",
- "type" : ACTION_TYPE.STGING,
- "option" : {"color" : "red"},
- "createdAt" : nowDate()} ;
}
-//
function onMessage(msg, client)
{
-// switch (msg.action) {
-// case ACTION_TYPE.REQUEST_CREATE:
-// var obj = {"id" : objects.length + 1,
-// "action" : ACTION_TYPE.CREATE,
-// "type" : msg.type,
-// "status" : '',
-// "clientId" : client. sessionId};
-// objects.push(obj);
-// client.send(obj);
-// break;
-// case ACTION_TYPE.REQUEST_LOCK:
-// // fix me
-// var obj = {"action" : ACTION_TYPE.LOCK,
-// "id" : msg.id};
-// break;
-// case ACTION_TYPE.REQUEST_EDIT:
-// var obj = {"action": ACTION_TYPE.EDIT,
-// "attr" : msg.attr,
-// "id" : msg.id};
-// break;
-// }
-// client.broadcast(obj);
+ console.log(msg.tasks);
}
-//
function nowDate()
{
d = new Date();
return d.getFullYear() + "-" + (d.getMonth()+1) + "-" + d.getDate()+ " "+ d.getHours()+':' +d.getMinutes()+':' + d.getSeconds();
}
-//*/
-////}}}
function exitWithError(err)
{
console.log(err);
View
42 test.js
@@ -0,0 +1,42 @@
+console.log('start');
+var mongoose = require('mongoose'),
+ schemas = require('./mongoschema').schemas();
+
+for (var i=0; i < schemas.length; i++) {
+ mongoose.model(schemas[i].name, schemas[i].schema);
+}
+
+// sudo /usr/local/mongo/bin/mongod
+mongoose.connect('mongodb://localhost/gridder',
+ function (err) {
+ if (err) {
+ exitWithError(err);
+ }
+ }
+);
+
+var tasks = [ { __id: '1-1',
+ title: '設計',
+ description: '・デザイン\n・プロトタイプ\n',
+ tasks: [] },
+ { __id: '1-2',
+ title: '大項目2',
+ tasks: [ ]}];
+
+
+
+// mongodb://[hostname]/[dbname]
+////// インスタンス生成
+var task = new Task(
+{ title : 'hoge title',
+ is_complete : false,
+ parent : []
+}
+)
+
+
+function exitWithError(err)
+{
+ console.log(err);
+ process.exit(0);
+};
View
16 views/index.ejs
@@ -51,17 +51,12 @@ function getObjects(){
return {
'title' :'このアプリ完成まで',
'end_title' :'Gridder公開',
- '__id' :'1',
- 'tasks' :[{'__id' :'1-1',
- 'title':'設計',
+ 'tasks' :[{'title':'設計',
'description':'・デザイン\n・プロトタイプ\n',
'tasks':[]},
- {'__id' :'1-2',
- 'title':'大項目2',
- 'tasks':[{'__id' :'1-2-1',
- 'title':'中項目1'},
- {'__id' :'1-2-2',
- 'title':'中項目2'}]}]
+ {'title':'大項目2',
+ 'tasks':[{'title':'中項目1'},
+ {'title':'中項目2'}]}]
};
}
</script>
@@ -70,7 +65,8 @@ function getObjects(){
<div class='header'>
<div class='title'><img width='109px' height='41px' src='/images/Grits.png'/></div>
</div>
-<div class='campus' id='main_boad'></div>
+ <input type='button' id='save_button' value='save'/>
+ <div class='campus' id='main_boad'></div>
<div id='editbox' title='編集'>
<form onSubmit='return false;' id='editform'>
title <br/><input id='task_title' value='' type='text'><br/>

0 comments on commit 945a8d8

Please sign in to comment.