Team chat

pull/1/head
yflory 5 years ago
parent 08b105bc10
commit 81c2df389a

@ -369,12 +369,12 @@
} }
} }
button { button {
height: 54px; height: 54px !important;
border-radius: 0; border-radius: 0;
border: none; border: none;
background-color: darken(@bg-color, 15%); background-color: darken(@bg-color, 15%) !important;
&:hover { &:hover {
background-color: darken(@bg-color, 20%); background-color: darken(@bg-color, 20%) !important;
} }
} }
} }

@ -21,7 +21,7 @@ define([
}; };
var initChannel = function (state, info) { var initChannel = function (state, info) {
console.log('initializing channel for [%s]', info.id); console.debug('initializing channel for [%s]', info.id);
var h, t; var h, t;
if (Array.isArray(info.messages) && info.messages.length) { if (Array.isArray(info.messages) && info.messages.length) {
h = info.messages[info.messages.length -1].sig; h = info.messages[info.messages.length -1].sig;
@ -31,8 +31,9 @@ define([
messages: info.messages || [], messages: info.messages || [],
name: info.name, name: info.name,
isFriendChat: info.isFriendChat, isFriendChat: info.isFriendChat,
needMoreHistory: !info.isPadChat,
isPadChat: info.isPadChat, isPadChat: info.isPadChat,
isTeamChat: info.isTeamChat,
needMoreHistory: !info.isPadChat && !info.isTeamChat,
curvePublic: info.curvePublic, curvePublic: info.curvePublic,
HEAD: h || info.lastKnownHash, HEAD: h || info.lastKnownHash,
TAIL: t || null, TAIL: t || null,
@ -507,7 +508,7 @@ define([
var rightCol = h('span.cp-app-contacts-right-col', [ var rightCol = h('span.cp-app-contacts-right-col', [
h('span.cp-app-contacts-name', [room.name]), h('span.cp-app-contacts-name', [room.name]),
room.isFriendChat ? remove : room.isFriendChat ? remove :
room.isPadChat ? undefined : leaveRoom, (room.isPadChat || room.isTeamChat) ? undefined : leaveRoom,
]); ]);
var friendData = room.isFriendChat ? userlist[0] : {}; var friendData = room.isFriendChat ? userlist[0] : {};
@ -685,7 +686,7 @@ define([
execCommand('GET_USERLIST', {id: id}, function (e, list) { execCommand('GET_USERLIST', {id: id}, function (e, list) {
if (e || list.error) { return void console.error(e || list.error); } if (e || list.error) { return void console.error(e || list.error); }
if (!room.isPadChat && (!Array.isArray(list) || !list.length)) { if (!room.isPadChat && !room.isTeamChat && (!Array.isArray(list) || !list.length)) {
return void console.error("Empty room!"); return void console.error("Empty room!");
} }
debug('userlist: ' + JSON.stringify(list), id); debug('userlist: ' + JSON.stringify(list), id);
@ -714,6 +715,8 @@ define([
var $parentEl; var $parentEl;
if (room.isFriendChat) { if (room.isFriendChat) {
$parentEl = $userlist.find('.cp-app-contacts-friends'); $parentEl = $userlist.find('.cp-app-contacts-friends');
} else if (room.isTeamChat) {
$parentEl = $userlist.find('.cp-app-contacts-padchat'); // XXX
} else if (room.isPadChat) { } else if (room.isPadChat) {
$parentEl = $userlist.find('.cp-app-contacts-padchat'); $parentEl = $userlist.find('.cp-app-contacts-padchat');
} else { } else {
@ -725,7 +728,7 @@ define([
updateStatus(id); updateStatus(id);
if (isApp && room.isPadChat) { if (isApp && (room.isPadChat || room.isTeamChat)) {
$container.removeClass('cp-app-contacts-initializing'); $container.removeClass('cp-app-contacts-initializing');
display(room.id); display(room.id);
} }
@ -816,6 +819,21 @@ define([
}); });
}; };
var onTeamChatReady = function (data) {
var teamChat = common.getTeamChat();
if (data !== teamChat) { return; }
if (state.channels[data]) { return; }
execCommand('GET_ROOMS', {teamChat: data}, function (err, rooms) {
if (err) { return void console.error(err); }
if (!Array.isArray(rooms) || rooms.length !== 1) {
return void console.error('Invalid team chat');
}
var room = rooms[0];
room.name = 'TEAMS'; // XXX
rooms.forEach(initializeRoom);
});
};
var onDisconnect = function () { var onDisconnect = function () {
debug('disconnected'); debug('disconnected');
$messages.find('.cp-app-contacts-input textarea').prop('disabled', true); $messages.find('.cp-app-contacts-input textarea').prop('disabled', true);
@ -841,6 +859,10 @@ define([
onPadChatReady(data); onPadChatReady(data);
return; return;
} }
if (cmd === 'TEAMCHAT_READY') {
onTeamChatReady(data);
return;
}
if (cmd === 'DISCONNECT') { if (cmd === 'DISCONNECT') {
onDisconnect(); onDisconnect();
return; return;

@ -120,7 +120,7 @@ define([
var network = ctx.store.network; var network = ctx.store.network;
console.log('Fetching [%s] messages since [%s]', channel.id, data.lastKnownHash || ''); console.log('Fetching [%s] messages since [%s]', channel.id, data.lastKnownHash || '');
if (channel.isPadChat) { if (channel.isPadChat || channel.isTeamChat) {
// We need to use GET_HISTORY_RANGE to make sure we won't get the full history // We need to use GET_HISTORY_RANGE to make sure we won't get the full history
var txid = Util.uid(); var txid = Util.uid();
initRangeRequest(ctx, txid, channel.id, undefined); initRangeRequest(ctx, txid, channel.id, undefined);
@ -137,8 +137,6 @@ define([
return; return;
} }
// XXX team chat
// Friend chat, intial history // Friend chat, intial history
var proxy = ctx.store.proxy; var proxy = ctx.store.proxy;
var friend = getFriendFromChannel(ctx, channel.id) || {}; var friend = getFriendFromChannel(ctx, channel.id) || {};
@ -165,6 +163,8 @@ define([
friend.lastKnownHash = hash; friend.lastKnownHash = hash;
} else if (channel.isPadChat) { } else if (channel.isPadChat) {
// Nothing to do // Nothing to do
} else if (channel.isTeamChat) {
// Nothing to do
} else { } else {
// TODO room // TODO room
return void cb({error: 'NOT_IMPLEMENTED'}); return void cb({error: 'NOT_IMPLEMENTED'});
@ -453,6 +453,7 @@ define([
id: data.channel, id: data.channel,
isFriendChat: data.isFriendChat, isFriendChat: data.isFriendChat,
isPadChat: data.isPadChat, isPadChat: data.isPadChat,
isTeamChat: data.isTeamChat,
padChan: data.padChan, // Channel ID of the pad linked to this pad chat padChan: data.padChan, // Channel ID of the pad linked to this pad chat
readOnly: data.readOnly, readOnly: data.readOnly,
ready: false, ready: false,
@ -671,6 +672,17 @@ define([
}]); }]);
} }
// Team chat room
if (data && data.teamChat) {
var tCChannel = ctx.channels[data.teamChat];
if (!tCChannel) { return void cb({error: 'NO_SUCH_CHANNEL'}); }
return void cb([{
id: tCChannel.id,
isTeamChat: true,
messages: tCChannel.messages
}]);
}
// Existing friends... // Existing friends...
var rooms = Object.keys(ctx.channels).map(function (id) { var rooms = Object.keys(ctx.channels).map(function (id) {
var r = ctx.channels[id]; var r = ctx.channels[id];
@ -683,6 +695,8 @@ define([
curvePublic = friend.curvePublic; curvePublic = friend.curvePublic;
} else if (r.isPadChat) { } else if (r.isPadChat) {
return; return;
} else if (r.isTeamChat) {
return;
} else { } else {
// TODO room get metadata (name) && lastKnownHash // TODO room get metadata (name) && lastKnownHash
} }
@ -752,6 +766,52 @@ define([
openChannel(ctx, chanData); openChannel(ctx, chanData);
}; };
var openTeamChat = function (ctx, clientId, data, _cb) {
var teams = ctx.store.modules['team'];
var team = teams.getTeam(data.teamId);
if (!team) { return; }
var chatData = team.getChatData();
var chanId = chatData.channel;
var cb = Util.once(Util.mkAsync(function () {
ctx.emit('TEAMCHAT_READY', chanId, [clientId]);
_cb({
channel: chanId
});
}));
var channel = ctx.channels[chanId];
if (channel) {
return void channel.onReady.reg(function () {
if (channel.clients.indexOf(clientId) === -1) {
channel.clients.push(clientId);
}
cb();
});
}
var secret = chatData.secret;
if (secret.keys.cryptKey) {
secret.keys.cryptKey = convertToUint8(secret.keys.cryptKey);
}
var encryptor = Crypto.createEncryptor(secret.keys);
var vKey = (secret.keys && secret.keys.validateKey) || chatData.validateKey;
var chanData = {
teamId: data.teamId,
readOnly: typeof(secret.keys) === "object" && !secret.keys.validateKey,
encryptor: encryptor,
channel: chanId,
isTeamChat: true,
decrypt: function (msg) {
return encryptor.decrypt(msg, vKey);
},
clients: [clientId],
onReady: cb
};
openChannel(ctx, chanData);
};
var clearOwnedChannel = function (ctx, id, cb) { var clearOwnedChannel = function (ctx, id, cb) {
var channel = ctx.clients[id]; var channel = ctx.clients[id];
if (!channel) { return void cb({error: 'NO_CHANNEL'}); } if (!channel) { return void cb({error: 'NO_CHANNEL'}); }
@ -877,6 +937,10 @@ define([
}); });
}; };
messenger.openTeamChat = function (data, cId, cb) {
openTeamChat(ctx, cId, data, cb);
};
messenger.removeClient = function (clientId) { messenger.removeClient = function (clientId) {
removeClient(ctx, clientId); removeClient(ctx, clientId);
}; };
@ -892,6 +956,9 @@ define([
if (cmd === 'GET_USERLIST') { if (cmd === 'GET_USERLIST') {
return void getUserList(ctx, data, cb); return void getUserList(ctx, data, cb);
} }
if (cmd === 'OPEN_TEAM_CHAT') {
return void openTeamChat(ctx, clientId, data, cb);
}
if (cmd === 'OPEN_PAD_CHAT') { if (cmd === 'OPEN_PAD_CHAT') {
return void openPadChat(ctx, clientId, data, cb); return void openPadChat(ctx, clientId, data, cb);
} }

@ -138,6 +138,19 @@ define([
})); }));
}; };
team.getChatData = function () {
var hash = Util.find(proxy, ['metadata', 'chat']);
if (!hash) {
hash = proxy.metadata.chat = Hash.createRandomHash('chat');
}
var secret = Hash.getSecrets('chat', hash);
return {
channel: secret.channel,
secret: secret,
validateKey: secret.keys.validateKey
};
};
team.pin = function (data, cb) { return void cb({error: 'EFORBIDDEN'}); }; team.pin = function (data, cb) { return void cb({error: 'EFORBIDDEN'}); };
team.unpin = function (data, cb) { return void cb({error: 'EFORBIDDEN'}); }; team.unpin = function (data, cb) { return void cb({error: 'EFORBIDDEN'}); };
nThen(function (waitFor) { nThen(function (waitFor) {
@ -276,6 +289,9 @@ define([
var membersSecret = Hash.getSecrets('members'); var membersSecret = Hash.getSecrets('members');
var membersHashes = Hash.getHashes(membersSecret); var membersHashes = Hash.getHashes(membersSecret);
var chatSecret = Hash.getSecrets('chat');
var chatHashes = Hash.getHashes(chatSecret);
var config = { var config = {
network: ctx.store.network, network: ctx.store.network,
channel: secret.channel, channel: secret.channel,
@ -319,6 +335,7 @@ define([
proxy.drive = {}; proxy.drive = {};
// Create metadata // Create metadata
proxy.metadata = { proxy.metadata = {
chat: chatHashes.editHash,
name: name, name: name,
members: membersHashes.viewHash, members: membersHashes.viewHash,
}; };
@ -424,7 +441,7 @@ define([
Object.keys(teams).forEach(function (id) { Object.keys(teams).forEach(function (id) {
ctx.onReadyHandlers[id] = []; ctx.onReadyHandlers[id] = [];
openChannel(ctx, teams[id], id, waitFor(function () { openChannel(ctx, teams[id], id, waitFor(function () {
console.error('team '+id+' ready'); console.debug('Team '+id+' ready');
})); }));
}); });
@ -448,7 +465,6 @@ define([
removeClient(ctx, clientId); removeClient(ctx, clientId);
}; };
team.execCommand = function (clientId, obj, cb) { team.execCommand = function (clientId, obj, cb) {
console.log(obj);
var cmd = obj.cmd; var cmd = obj.cmd;
var data = obj.data; var data = obj.data;
if (cmd === 'SUBSCRIBE') { if (cmd === 'SUBSCRIBE') {
@ -458,6 +474,9 @@ define([
if (cmd === 'LIST_TEAMS') { if (cmd === 'LIST_TEAMS') {
return void cb(store.proxy.teams); return void cb(store.proxy.teams);
} }
if (cmd === 'OPEN_TEAM_CHAT') {
return void ctx.store.messenger.openTeamChat(data, clientId, cb);
}
if (cmd === 'CREATE_TEAM') { if (cmd === 'CREATE_TEAM') {
return void createTeam(ctx, data, clientId, cb); return void createTeam(ctx, data, clientId, cb);
} }

@ -212,6 +212,15 @@ define([
}); });
}; };
// Team Chat
var teamChatChannel;
funcs.setTeamChat = function (channel) {
teamChatChannel = channel;
};
funcs.getTeamChat = function () {
return teamChatChannel;
};
var cursorChannel; var cursorChannel;
// common-ui-elements needs to be able to get the cursor channel to put it in metadata when // common-ui-elements needs to be able to get the cursor channel to put it in metadata when
// importing a template // importing a template

@ -1,5 +1,6 @@
@import (reference) '../../customize/src/less2/include/framework.less'; @import (reference) '../../customize/src/less2/include/framework.less';
@import (reference) '../../customize/src/less2/include/drive.less'; @import (reference) '../../customize/src/less2/include/drive.less';
@import (reference) '../../customize/src/less2/include/messenger.less';
@import (reference) '../../customize/src/less2/include/sidebar-layout.less'; @import (reference) '../../customize/src/less2/include/sidebar-layout.less';
&.cp-app-team { &.cp-app-team {
@ -10,11 +11,20 @@
); );
.drive_main(); .drive_main();
.messenger_main();
.sidebar-layout_main(); .sidebar-layout_main();
#cp-sidebarlayout-container { #cp-sidebarlayout-container {
div#cp-sidebarlayout-rightside.cp-rightside-drive { div#cp-sidebarlayout-rightside.cp-rightside-drive {
padding: 0; padding: 0;
& > .cp-team-chat {
display: flex;
height: 100%;
margin: 0;
.cp-app-contacts-container {
height: 100%;
}
}
& > .cp-team-drive { & > .cp-team-drive {
display: flex; display: flex;
height: 100%; height: 100%;

@ -10,6 +10,7 @@ define([
'/common/proxy-manager.js', '/common/proxy-manager.js',
'/common/hyperscript.js', '/common/hyperscript.js',
'/customize/application_config.js', '/customize/application_config.js',
'/common/messenger-ui.js',
'/customize/messages.js', '/customize/messages.js',
'css!/bower_components/bootstrap/dist/css/bootstrap.min.css', 'css!/bower_components/bootstrap/dist/css/bootstrap.min.css',
@ -27,6 +28,7 @@ define([
ProxyManager, ProxyManager,
h, h,
AppConfig, AppConfig,
MessengerUI,
Messages) Messages)
{ {
var APP = {}; var APP = {};
@ -101,6 +103,9 @@ define([
'members': [ 'members': [
'cp-team-roster' 'cp-team-roster'
], ],
'chat': [
'cp-team-chat'
],
}; };
var create = {}; var create = {};
@ -131,6 +136,7 @@ define([
if (key === 'create') { $category.append($('<span>', {'class': 'fa fa-plus-circle'})); } if (key === 'create') { $category.append($('<span>', {'class': 'fa fa-plus-circle'})); }
if (key === 'back') { $category.append($('<span>', {'class': 'fa fa-arrow-left'})); } if (key === 'back') { $category.append($('<span>', {'class': 'fa fa-arrow-left'})); }
if (key === 'members') { $category.append($('<span>', {'class': 'fa fa-users'})); } if (key === 'members') { $category.append($('<span>', {'class': 'fa fa-users'})); }
if (key === 'chat') { $category.append($('<span>', {'class': 'fa fa-comments'})); }
if (key === 'drive') { $category.append($('<span>', {'class': 'fa fa-hdd-o'})); } if (key === 'drive') { $category.append($('<span>', {'class': 'fa fa-hdd-o'})); }
if (key === active) { if (key === active) {
@ -144,7 +150,7 @@ define([
} }
if (active === key) { return; } if (active === key) { return; }
active = key; active = key;
if (key === 'drive') { if (key === 'drive' || key === 'chat') {
APP.$rightside.addClass('cp-rightside-drive'); APP.$rightside.addClass('cp-rightside-drive');
} else { } else {
APP.$rightside.removeClass('cp-rightside-drive'); APP.$rightside.removeClass('cp-rightside-drive');
@ -326,6 +332,18 @@ define([
loadTeam(common, APP.team, false); loadTeam(common, APP.team, false);
}); });
makeBlock('chat', function (common, cb) {
var container = h('div#cp-app-contacts-container.cp-app-contacts-inapp');
var content = [container];
APP.module.execCommand('OPEN_TEAM_CHAT', {
teamId: APP.team
}, function (obj) {
console.warn(obj);
common.setTeamChat(obj.channel);
MessengerUI.create($(container), common, true);
cb(content);
});
});
var onEvent = function (obj) { var onEvent = function (obj) {
var ev = obj.ev; var ev = obj.ev;

Loading…
Cancel
Save