First of all, congratulations for this wonderful project! It is ideal for implementing a public and/or private chat.
BUT, what I miss is the ability to send some local user metadata on connection and/or with the messages.
That will permit to have the ability to display some shiny list of user on-line, or message.
I made an implementation sending (back) JSON messages, resulting something like in the folowing screenshot, BUT it complicate a bit the logic.
So, I need to do something like:
channel.onopen = function (userid) {
console.debug(userid, 'is connected with you.');
setTimeout(function() {
sendUserInfo(userid);
// Enable the input.
chatInput.attr("disabled", false);
chatButton.attr("disabled", false);
chatInput.focus();
}, 5000);
};
channel.onmessage = function(message, userid, latency) {
console.log('Latency:', latency, 'milliseconds');
console.debug('Message from', userid, ':', message);
var data = JSON.parse(message);
if (data.type == 'message') {
addChatMessage(data.message, data.realname, data.picture, 'left');
}
// Further, we will handle only the INFO messages.
else if (data.type != 'info') {
return;
}
if (! chatUsers[userid]) {
chatUsers[userid] = data;
addOnlineUser(userid, data);
//
var text = sprintf("<?= __d('chat', '%s (%s) joined the chat.'); ?>", data.realname, data.username);
addLogMessage(text, 'success');
}
};
function sendUserInfo(userid) {
var value = JSON.stringify({
type: 'info',
username: userInfo.username,
realname: userInfo.realname,
roles: userInfo.roles,
picture: userInfo.picture,
});
console.debug('Sending User info to', userid);
channel.channels[userid].send(value);
}
function sendMessage() {
var message = chatInput.val();
var value = JSON.stringify({
type: 'message',
username: userInfo.username,
realname: userInfo.realname,
picture: userInfo.picture,
message: message
});
channel.send(value);
//
addChatMessage(message, userInfo.realname, userInfo.picture, 'right');
chatInput.val('');
}
IF there would be the ability to specify some metadata for the local User, the code would be greatly simplified and would not be a need to encode in the JSON the messages. For example:
channel.onopen = function (userid, data) {
console.debug(userid, 'is connected with you.');
if (! chatUsers[userid]) {
chatUsers[userid] = data;
addOnlineUser(userid, data);
//
var text = sprintf("<?= __d('chat', '%s (%s) joined the chat.'); ?>", data.realname, data.username);
addLogMessage(text, 'success');
}
// Enable the input.
chatInput.attr("disabled", false);
chatButton.attr("disabled", false);
chatInput.focus();
};
channel.onmessage = function(message, userid, latency, data) {
console.log('Latency:', latency, 'milliseconds');
console.debug('Message from', userid, ':', message);
addChatMessage(data.message, data.realname, data.picture, 'left');
};
function sendMessage() {
var message = chatInput.val();
channel.send(value);
//
addChatMessage(message, userInfo.realname, userInfo.picture, 'right');
chatInput.val('');
}
Where to add that User Medata? I think at beginning, something like:
var channel = new DataChannel();
channel.metadata = {
userid: '<?= $user->id; ?>',
username: '<?= $user->username; ?>',
realname: '<?= $user->realname; ?>',
picture: '<?= $user->picture(); ?>'
};
BTW, in the previous snippet, I used a piece from a PHP application.