added a Chat

This commit is contained in:
Peter 'Pita' Martischka 2011-07-14 16:15:38 +01:00
parent 51c4aff54b
commit 29878e648e
11 changed files with 506 additions and 26 deletions

View file

@ -7,6 +7,7 @@ var AttributePoolFactory = require("../AttributePoolFactory");
var db = require("../db").db;
var async = require("async");
var settings = require('../settings');
var authorManager = require("../AuthorManager");
/**
* Copied from the Etherpad source code. It converts Windows line breaks to Unix line breaks and convert Tabs to spaces
@ -38,6 +39,11 @@ Class('Pad', {
getterName : 'getHeadRevisionNumber'
}, // head
chatHead : {
is: 'rw',
init: -1
}, // chatHead
id : { is : 'r' }
},
@ -52,7 +58,6 @@ Class('Pad', {
appendRevision : function(aChangeset, author)
{
if(!author)
author = '';
@ -77,7 +82,7 @@ Class('Pad', {
}
db.set("pad:"+this.id+":revs:"+newRev, newRevData);
db.set("pad:"+this.id, {atext: this.atext, pool: this.pool.toJsonable(), head: this.head});
db.set("pad:"+this.id, {atext: this.atext, pool: this.pool.toJsonable(), head: this.head, chatHead: this.chatHead});
}, //appendRevision
getRevisionChangeset : function(revNum, callback)
@ -186,6 +191,99 @@ Class('Pad', {
return this.atext.text;
},
appendChatMessage: function(text, userId, time)
{
this.chatHead++;
//save the chat entry in the database
db.set("pad:"+this.id+":chat:"+this.chatHead, {"text": text, "userId": userId, "time": time});
//save the new chat head
db.setSub("pad:"+this.id, ["chatHead"], this.chatHead);
},
getChatMessage: function(entryNum, withName, callback)
{
var _this = this;
var entry;
async.series([
//get the chat entry
function(callback)
{
db.get("pad:"+_this.id+":chat:"+entryNum, function(err, _entry)
{
entry = _entry;
callback(err);
});
},
//add the authorName
function(callback)
{
//skip if we don't need the authorName
if(!withName)
{
callback();
return;
}
//get the authorName
authorManager.getAuthorName(entry.userId, function(err, authorName)
{
entry.userName = authorName;
callback(err);
});
}
], function(err)
{
callback(err, entry);
});
},
getLastChatMessages: function(count, callback)
{
//return an empty array if there are no chat messages
if(this.chatHead == -1)
{
callback(null, []);
return;
}
var _this = this;
//works only if we decrement the amount, for some reason
count--;
//set the startpoint
var start = this.chatHead-count;
if(start < 0)
start = 0;
//set the endpoint
var end = this.chatHead;
//collect the numbers of chat entries and in which order we need them
var neededEntries = [];
var order = 0;
for(var i=start;i<=end; i++)
{
neededEntries.push({entryNum:i, order: order});
order++;
}
//get all entries out of the database
var entries = [];
async.forEach(neededEntries, function(entryObject, callback)
{
_this.getChatMessage(entryObject.entryNum, true, function(err, entry)
{
entries[entryObject.order] = entry;
callback(err);
});
}, function(err)
{
callback(err, entries);
});
},
init : function (callback)
{
var _this = this;
@ -205,6 +303,11 @@ Class('Pad', {
_this.head = value.head;
_this.atext = value.atext;
_this.pool = _this.pool.fromJsonable(value.pool);
if(value.chatHead != null)
_this.chatHead = value.chatHead;
else
_this.chatHead = -1;
}
//this pad doesn't exist, so create it
else

View file

@ -164,6 +164,11 @@ exports.handleMessage = function(client, message)
{
handleUserInfoUpdate(client, message);
}
else if(message.type == "COLLABROOM" &&
message.data.type == "CHAT_MESSAGE")
{
handleChatMessage(client, message);
}
else if(message.type == "COLLABROOM" &&
message.data.type == "CLIENT_MESSAGE" &&
message.data.payload.type == "suggestUserName")
@ -177,6 +182,71 @@ exports.handleMessage = function(client, message)
}
}
/**
* Handles a Chat Message
* @param client the client that send this message
* @param message the message from the client
*/
function handleChatMessage(client, message)
{
var time = new Date().getTime();
var userId = sessioninfos[client.id].author;
var text = message.data.text;
var padId = session2pad[client.id];
var pad;
var userName;
async.series([
//get the pad
function(callback)
{
padManager.getPad(padId, function(err, _pad)
{
pad = _pad;
callback(err);
});
},
function(callback)
{
authorManager.getAuthorName(userId, function(err, _userName)
{
userName = _userName;
callback(err);
});
},
//save the chat message and broadcast it
function(callback)
{
//save the chat message
pad.appendChatMessage(text, userId, time);
var msg = {
type: "COLLABROOM",
data: {
type: "CHAT_MESSAGE",
userId: userId,
userName: userName,
time: time,
text: text
}
};
//broadcast the chat message to everyone on the pad
for(var i in pad2sessions[padId])
{
socketio.sockets.sockets[pad2sessions[padId][i]].json.send(msg);
}
callback();
}
], function(err)
{
if(err) throw err;
});
}
/**
* Handles a handleSuggestUserName, that means a user have suggest a userName for a other user
* @param client the client that send this message
@ -509,6 +579,7 @@ function handleClientReady(client, message)
var pad;
var historicalAuthorData = {};
var readOnlyId;
var chatMessages;
async.series([
//get all authordata of this new user
@ -557,19 +628,36 @@ function handleClientReady(client, message)
], callback);
});
},
//these db requests all need the pad object
function(callback)
{
var authors = pad.getAllAuthors();
//get all author data out of the database
async.forEach(authors, function(authorId, callback)
{
authorManager.getAuthor(authorId, function(err, author)
async.parallel([
//get all author data out of the database
function(callback)
{
historicalAuthorData[authorId] = author;
callback(err);
});
}, callback);
async.forEach(authors, function(authorId, callback)
{
authorManager.getAuthor(authorId, function(err, author)
{
historicalAuthorData[authorId] = author;
callback(err);
});
}, callback);
},
//get the latest chat messages
function(callback)
{
pad.getLastChatMessages(20, function(err, _chatMessages)
{
chatMessages = _chatMessages;
callback(err);
});
}
], callback);
},
function(callback)
{
@ -629,12 +717,7 @@ function handleClientReady(client, message)
"padId": message.padId,
"initialTitle": "Pad: " + message.padId,
"opts": {},
"chatHistory": {
"start": 0,
"historicalAuthorData": historicalAuthorData,
"end": 0,
"lines": []
},
"chatHistory": chatMessages,
"numConnectedUsers": pad2sessions[message.padId].length,
"isProPad": false,
"readOnlyId": readOnlyId,

View file

@ -39,7 +39,7 @@ exports.padJS = function(req, res)
{
res.header("Content-Type","text/javascript");
var jsFiles = ["jquery.min.js", "plugins.js", "undo-xpopup.js", "json2.js", "pad_utils.js", "pad_cookie.js", "pad_editor.js", "pad_editbar.js", "pad_docbar.js", "pad_modals.js", "ace.js", "collab_client.js", "pad_userlist.js", "pad_impexp.js", "pad_savedrevs.js", "pad_connectionstatus.js", "pad2.js"];
var jsFiles = ["jquery.min.js", "plugins.js", "undo-xpopup.js", "json2.js", "pad_utils.js", "pad_cookie.js", "pad_editor.js", "pad_editbar.js", "pad_docbar.js", "pad_modals.js", "ace.js", "collab_client.js", "pad_userlist.js", "pad_impexp.js", "pad_savedrevs.js", "pad_connectionstatus.js", "pad2.js", "jquery-ui-slide.js", "chat.js"];
//minifying is enabled
if(settings.minify)