Merge branch 'staging' of github.com:xwiki-labs/cryptpad into staging
This commit is contained in:
commit
e5cb3250d8
@ -2,6 +2,7 @@
|
|||||||
@import (reference) "./colortheme-all.less";
|
@import (reference) "./colortheme-all.less";
|
||||||
@import (reference) "./tools.less";
|
@import (reference) "./tools.less";
|
||||||
@import (reference) './icon-colors.less';
|
@import (reference) './icon-colors.less';
|
||||||
|
@import (reference) "./avatar.less";
|
||||||
|
|
||||||
.creation_vars(
|
.creation_vars(
|
||||||
@color: @colortheme_default-color,
|
@color: @colortheme_default-color,
|
||||||
@ -62,7 +63,7 @@
|
|||||||
outline: none;
|
outline: none;
|
||||||
width: 700px;
|
width: 700px;
|
||||||
max-width: 90vw;
|
max-width: 90vw;
|
||||||
height: 500px;
|
height: 550px;
|
||||||
max-height: calc(~"100vh - 20px");
|
max-height: calc(~"100vh - 20px");
|
||||||
margin: 50px;
|
margin: 50px;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
@ -175,15 +176,47 @@
|
|||||||
color: @colortheme_form-color;
|
color: @colortheme_form-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cp-creation-team {
|
.cp-creation-teams {
|
||||||
.cp-dropdown-container {
|
display: none !important;
|
||||||
|
.cp-creation-teams-grid {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
padding: 0 2px;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
min-width: 0;
|
}
|
||||||
margin-left: 10px;
|
.cp-creation-team {
|
||||||
margin-right: 10px;
|
.avatar_main(25px);
|
||||||
button, .cp-dropdown-content {
|
width: 140px;
|
||||||
width: 100%;
|
height: 35px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
padding: 5px;
|
||||||
|
cursor: default;
|
||||||
|
font: @colortheme_app-font;
|
||||||
|
color: @colortheme_modal-fg;
|
||||||
|
margin: 0 1px;
|
||||||
|
|
||||||
|
.tools_unselectable();
|
||||||
|
|
||||||
|
&.cp-selected {
|
||||||
|
background-color: @colortheme_alertify-primary;
|
||||||
|
color: @colortheme_alertify-primary-text;
|
||||||
}
|
}
|
||||||
|
.cp-creation-team-avatar {
|
||||||
|
.fa {
|
||||||
|
font-size: 25px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.cp-creation-team-name {
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 18px;
|
||||||
|
}
|
||||||
|
border: 1px solid @colortheme_alertify-primary;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -16,6 +16,7 @@ define(function () {
|
|||||||
tokenKey: 'loginToken',
|
tokenKey: 'loginToken',
|
||||||
displayPadCreationScreen: 'displayPadCreationScreen',
|
displayPadCreationScreen: 'displayPadCreationScreen',
|
||||||
deprecatedKey: 'deprecated',
|
deprecatedKey: 'deprecated',
|
||||||
|
MAX_TEAMS_SLOTS: 3,
|
||||||
// Sub
|
// Sub
|
||||||
plan: 'CryptPad_plan',
|
plan: 'CryptPad_plan',
|
||||||
// Apps
|
// Apps
|
||||||
|
|||||||
@ -81,10 +81,13 @@ define([
|
|||||||
};
|
};
|
||||||
|
|
||||||
Msg.updateMyData = function (store, curve) {
|
Msg.updateMyData = function (store, curve) {
|
||||||
var myData = createData(store.proxy);
|
var myData = createData(store.proxy, false);
|
||||||
if (store.proxy.friends) {
|
if (store.proxy.friends) {
|
||||||
store.proxy.friends.me = myData;
|
store.proxy.friends.me = myData;
|
||||||
}
|
}
|
||||||
|
if (store.modules['team']) {
|
||||||
|
store.modules['team'].updateMyData(myData);
|
||||||
|
}
|
||||||
var todo = function (friend) {
|
var todo = function (friend) {
|
||||||
if (!friend || !friend.notifications) { return; }
|
if (!friend || !friend.notifications) { return; }
|
||||||
myData.channel = friend.channel;
|
myData.channel = friend.channel;
|
||||||
|
|||||||
@ -2881,57 +2881,49 @@ define([
|
|||||||
// Team pad
|
// Team pad
|
||||||
var team;
|
var team;
|
||||||
var teamExists = privateData.teams && Object.keys(privateData.teams).length;
|
var teamExists = privateData.teams && Object.keys(privateData.teams).length;
|
||||||
var $teamBlock;
|
var teamValue;
|
||||||
// storeInTeam can be
|
// storeInTeam can be
|
||||||
// * a team ID ==> store in the team drive, and the team will be the owner
|
// * a team ID ==> store in the team drive, and the team will be the owner
|
||||||
// * -1 ==> store in the user drive, and the user will be the owner
|
// * -1 ==> store in the user drive, and the user will be the owner
|
||||||
// * undefined ==> ask
|
// * undefined ==> ask
|
||||||
if (teamExists && privateData.enableTeams) {
|
if (teamExists && privateData.enableTeams) {
|
||||||
var teamOptions = Object.keys(privateData.teams).map(function (teamId) {
|
var teams = Object.keys(privateData.teams).map(function (id) {
|
||||||
var t = privateData.teams[teamId];
|
var data = privateData.teams[id];
|
||||||
return {
|
var avatar = h('span.cp-creation-team-avatar.cp-avatar');
|
||||||
tag: 'a',
|
UIElements.displayAvatar(common, $(avatar), data.avatar, data.name);
|
||||||
attributes: {
|
return h('div.cp-creation-team', {
|
||||||
'data-value': teamId,
|
'data-id': id,
|
||||||
'href': '#'
|
title: data.name,
|
||||||
},
|
},[
|
||||||
content: Util.fixHTML(t.name)
|
avatar,
|
||||||
};
|
h('span.cp-creation-team-name', data.name)
|
||||||
|
]);
|
||||||
});
|
});
|
||||||
teamOptions.unshift({
|
teams.unshift(h('div.cp-creation-team', {
|
||||||
tag: 'a',
|
'data-id': '-1',
|
||||||
attributes: {
|
title: Messages.settings_cat_drive
|
||||||
'data-value': '-1',
|
}, [
|
||||||
'href': '#'
|
h('span.cp-creation-team-avatar.fa.fa-hdd-o'),
|
||||||
},
|
h('span.cp-creation-team-name', Messages.settings_cat_drive)
|
||||||
content: Messages.settings_cat_drive
|
]));
|
||||||
});
|
team = h('div.cp-creation-teams', [
|
||||||
teamOptions.unshift({
|
|
||||||
tag: 'a',
|
|
||||||
attributes: {
|
|
||||||
'data-value': '',
|
|
||||||
'href': '#'
|
|
||||||
},
|
|
||||||
content: ' '
|
|
||||||
});
|
|
||||||
var teamDropdownConfig = {
|
|
||||||
text: " ", // Button initial text
|
|
||||||
options: teamOptions, // Entries displayed in the menu
|
|
||||||
isSelect: true,
|
|
||||||
common: common
|
|
||||||
};
|
|
||||||
$teamBlock = UIElements.createDropdown(teamDropdownConfig);
|
|
||||||
$teamBlock.find('a').click(function () {
|
|
||||||
var id = $(this).attr('data-value');
|
|
||||||
$teamBlock.setValue(id);
|
|
||||||
});
|
|
||||||
team = h('div.cp-creation-team', [
|
|
||||||
Messages.team_pcsSelectLabel,
|
Messages.team_pcsSelectLabel,
|
||||||
$teamBlock[0],
|
h('div.cp-creation-teams-grid', teams),
|
||||||
createHelper('#', Messages.team_pcsSelectHelp)
|
createHelper('#', Messages.team_pcsSelectHelp)
|
||||||
]);
|
]);
|
||||||
|
var $team = $(team);
|
||||||
|
$team.find('.cp-creation-team').click(function () {
|
||||||
|
if ($(this).hasClass('cp-selected')) {
|
||||||
|
teamValue = undefined;
|
||||||
|
return void $(this).removeClass('cp-selected');
|
||||||
|
}
|
||||||
|
$team.find('.cp-creation-team').removeClass('cp-selected');
|
||||||
|
$(this).addClass('cp-selected');
|
||||||
|
teamValue = $(this).attr('data-id');
|
||||||
|
});
|
||||||
if (privateData.storeInTeam) {
|
if (privateData.storeInTeam) {
|
||||||
$teamBlock.setValue(privateData.storeInTeam);
|
$team.find('[data-id="'+privateData.storeInTeam+'"]').addClass('cp-selected');
|
||||||
|
teamValue = privateData.storeInTeam;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3208,9 +3200,9 @@ define([
|
|||||||
var templateId = $template.data('id') || undefined;
|
var templateId = $template.data('id') || undefined;
|
||||||
// Team
|
// Team
|
||||||
var team;
|
var team;
|
||||||
if ($teamBlock && $teamBlock.getValue()) {
|
if (teamValue) {
|
||||||
team = privateData.teams[$teamBlock.getValue()] || {};
|
team = privateData.teams[teamValue] || {};
|
||||||
team.id = Number($teamBlock.getValue());
|
team.id = Number(teamValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -3746,8 +3738,15 @@ define([
|
|||||||
console.log(err);
|
console.log(err);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var MAX_TEAMS_SLOTS = Constants.MAX_TEAMS_SLOTS;
|
||||||
var todo = function (yes) {
|
var todo = function (yes) {
|
||||||
|
var priv = common.getMetadataMgr().getPrivateData();
|
||||||
|
var numberOfTeams = Object.keys(priv.teams || {}).length;
|
||||||
if (yes) {
|
if (yes) {
|
||||||
|
if (numberOfTeams >= MAX_TEAMS_SLOTS) {
|
||||||
|
return void UI.alert(Messages._getKey('team_maxTeams', [MAX_TEAMS_SLOTS]));
|
||||||
|
}
|
||||||
// ACCEPT
|
// ACCEPT
|
||||||
module.execCommand('JOIN_TEAM', {
|
module.execCommand('JOIN_TEAM', {
|
||||||
team: msg.content.team
|
team: msg.content.team
|
||||||
|
|||||||
@ -321,7 +321,16 @@ define([
|
|||||||
return void cb(true);
|
return void cb(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (invitedTo[content.team.channel]) { return void cb(true); }
|
var invited = invitedTo[content.team.channel];
|
||||||
|
if (invited) {
|
||||||
|
console.log('removing old invitation');
|
||||||
|
cb(false, invited);
|
||||||
|
invitedTo[content.team.channel] = {
|
||||||
|
type: box.type,
|
||||||
|
hash: data.hash
|
||||||
|
};
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var myTeams = Util.find(ctx, ['store', 'proxy', 'teams']) || {};
|
var myTeams = Util.find(ctx, ['store', 'proxy', 'teams']) || {};
|
||||||
var alreadyMember = Object.keys(myTeams).some(function (k) {
|
var alreadyMember = Object.keys(myTeams).some(function (k) {
|
||||||
@ -330,7 +339,10 @@ define([
|
|||||||
});
|
});
|
||||||
if (alreadyMember) { return void cb(true); }
|
if (alreadyMember) { return void cb(true); }
|
||||||
|
|
||||||
invitedTo[content.team.channel] = true;
|
invitedTo[content.team.channel] = {
|
||||||
|
type: box.type,
|
||||||
|
hash: data.hash
|
||||||
|
};
|
||||||
|
|
||||||
cb(false);
|
cb(false);
|
||||||
};
|
};
|
||||||
@ -349,6 +361,10 @@ define([
|
|||||||
return void cb(true);
|
return void cb(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (invitedTo[content.teamChannel] && content.pending) {
|
||||||
|
return void cb(true, invitedTo[content.teamChannel]);
|
||||||
|
}
|
||||||
|
|
||||||
cb(false);
|
cb(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -258,6 +258,11 @@ proxy.mailboxes = {
|
|||||||
hash: hash
|
hash: hash
|
||||||
};
|
};
|
||||||
Handlers.add(ctx, box, message, function (dismissed, toDismiss) {
|
Handlers.add(ctx, box, message, function (dismissed, toDismiss) {
|
||||||
|
if (toDismiss) { // List of other messages to remove
|
||||||
|
dismiss(ctx, toDismiss, '', function () {
|
||||||
|
console.log('Notification handled automatically');
|
||||||
|
});
|
||||||
|
}
|
||||||
if (dismissed) { // This message should be removed
|
if (dismissed) { // This message should be removed
|
||||||
dismiss(ctx, {
|
dismiss(ctx, {
|
||||||
type: type,
|
type: type,
|
||||||
@ -267,11 +272,6 @@ proxy.mailboxes = {
|
|||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (toDismiss) { // List of other messages to remove
|
|
||||||
dismiss(ctx, toDismiss, '', function () {
|
|
||||||
console.log('Notification handled automatically');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
box.content[hash] = msg;
|
box.content[hash] = msg;
|
||||||
showMessage(ctx, type, message, null, function (obj) {
|
showMessage(ctx, type, message, null, function (obj) {
|
||||||
if (!box.ready) { return; }
|
if (!box.ready) { return; }
|
||||||
|
|||||||
@ -477,6 +477,7 @@ define([
|
|||||||
sending: false,
|
sending: false,
|
||||||
messages: [],
|
messages: [],
|
||||||
clients: data.clients || [],
|
clients: data.clients || [],
|
||||||
|
onUserlistUpdate: data.onUserlistUpdate || function () {},
|
||||||
mapId: {},
|
mapId: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -584,10 +585,32 @@ define([
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var getOnlineList = function (ctx, chanId) {
|
||||||
|
var channel = ctx.channels[chanId];
|
||||||
|
if (!channel) { return; }
|
||||||
|
var online = []; // Store online members to avoid duplicates
|
||||||
|
|
||||||
|
// Add ourselves
|
||||||
|
var myData = createData(ctx.store.proxy, false);
|
||||||
|
online.push(myData.curvePublic);
|
||||||
|
|
||||||
|
channel.wc.members.forEach(function (nId) {
|
||||||
|
if (nId === ctx.store.network.historyKeeper) { return; }
|
||||||
|
var data = channel.mapId[nId] || {};
|
||||||
|
if (!data.curvePublic) { return; }
|
||||||
|
if (online.indexOf(data.curvePublic) !== -1) { return; }
|
||||||
|
online.push(data.curvePublic);
|
||||||
|
});
|
||||||
|
return online;
|
||||||
|
};
|
||||||
|
|
||||||
// Display green status if one member is not me
|
// Display green status if one member is not me
|
||||||
var getStatus = function (ctx, chanId, cb) {
|
var getStatus = function (ctx, chanId, cb) {
|
||||||
var channel = ctx.channels[chanId];
|
var channel = ctx.channels[chanId];
|
||||||
if (!channel) { return void cb('NO_SUCH_CHANNEL'); }
|
if (!channel) { return void cb('NO_SUCH_CHANNEL'); }
|
||||||
|
if (channel.onUserlistUpdate) {
|
||||||
|
channel.onUserlistUpdate();
|
||||||
|
}
|
||||||
var proxy = ctx.store.proxy;
|
var proxy = ctx.store.proxy;
|
||||||
var online = channel.wc.members.some(function (nId) {
|
var online = channel.wc.members.some(function (nId) {
|
||||||
if (nId === ctx.store.network.historyKeeper) { return; }
|
if (nId === ctx.store.network.historyKeeper) { return; }
|
||||||
@ -781,7 +804,7 @@ define([
|
|||||||
openChannel(ctx, chanData);
|
openChannel(ctx, chanData);
|
||||||
};
|
};
|
||||||
|
|
||||||
var openTeamChat = function (ctx, clientId, data, _cb) {
|
var openTeamChat = function (ctx, clientId, data, onUpdate, _cb) {
|
||||||
var chatData = data;
|
var chatData = data;
|
||||||
var chanId = chatData.channel;
|
var chanId = chatData.channel;
|
||||||
var secret = chatData.secret;
|
var secret = chatData.secret;
|
||||||
@ -820,6 +843,7 @@ define([
|
|||||||
return encryptor.decrypt(msg, vKey);
|
return encryptor.decrypt(msg, vKey);
|
||||||
},
|
},
|
||||||
clients: [clientId],
|
clients: [clientId],
|
||||||
|
onUserlistUpdate: onUpdate,
|
||||||
onReady: cb
|
onReady: cb
|
||||||
};
|
};
|
||||||
openChannel(ctx, chanData);
|
openChannel(ctx, chanData);
|
||||||
@ -927,6 +951,10 @@ define([
|
|||||||
onFriendRemoved(ctx, curvePublic, chanId);
|
onFriendRemoved(ctx, curvePublic, chanId);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
messenger.getOnlineList = function (chanId) {
|
||||||
|
return getOnlineList(ctx, chanId);
|
||||||
|
};
|
||||||
|
|
||||||
messenger.storeValidateKey = function (chan, key) {
|
messenger.storeValidateKey = function (chan, key) {
|
||||||
ctx.validateKeys[chan] = key;
|
ctx.validateKeys[chan] = key;
|
||||||
};
|
};
|
||||||
@ -945,8 +973,8 @@ define([
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
messenger.openTeamChat = function (data, cId, cb) {
|
messenger.openTeamChat = function (data, onUpdate, cId, cb) {
|
||||||
openTeamChat(ctx, cId, data, cb);
|
openTeamChat(ctx, cId, data, onUpdate, cb);
|
||||||
};
|
};
|
||||||
|
|
||||||
messenger.removeClient = function (clientId) {
|
messenger.removeClient = function (clientId) {
|
||||||
@ -964,9 +992,6 @@ 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);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -544,7 +544,18 @@ define([
|
|||||||
if (!team) { return void cb ({error: 'ENOENT'}); }
|
if (!team) { return void cb ({error: 'ENOENT'}); }
|
||||||
if (!team.roster) { return void cb({error: 'NO_ROSTER'}); }
|
if (!team.roster) { return void cb({error: 'NO_ROSTER'}); }
|
||||||
var state = team.roster.getState() || {};
|
var state = team.roster.getState() || {};
|
||||||
cb(state.members || {});
|
var members = state.members || {};
|
||||||
|
|
||||||
|
// Add online status (using messenger data)
|
||||||
|
var chatData = team.getChatData();
|
||||||
|
var online = ctx.store.messenger.getOnlineList(chatData.channel) || [];
|
||||||
|
online.forEach(function (curve) {
|
||||||
|
if (members[curve]) {
|
||||||
|
members[curve].online = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
cb(members);
|
||||||
};
|
};
|
||||||
|
|
||||||
var getTeamMetadata = function (ctx, data, cId, cb) {
|
var getTeamMetadata = function (ctx, data, cId, cb) {
|
||||||
@ -635,13 +646,12 @@ define([
|
|||||||
|
|
||||||
var state = team.roster.getState();
|
var state = team.roster.getState();
|
||||||
var userData = state.members[data.curvePublic];
|
var userData = state.members[data.curvePublic];
|
||||||
console.error(userData);
|
|
||||||
team.roster.remove([data.curvePublic], function (err) {
|
team.roster.remove([data.curvePublic], function (err) {
|
||||||
if (err) { return void cb({error: err}); }
|
if (err) { return void cb({error: err}); }
|
||||||
// The user has been removed, send them a notification
|
// The user has been removed, send them a notification
|
||||||
if (!userData || !userData.notifications) { return cb(); }
|
if (!userData || !userData.notifications) { return cb(); }
|
||||||
console.log('send notif');
|
|
||||||
ctx.store.mailbox.sendTo('KICKED_FROM_TEAM', {
|
ctx.store.mailbox.sendTo('KICKED_FROM_TEAM', {
|
||||||
|
pending: data.pending,
|
||||||
user: Messaging.createData(ctx.store.proxy, false),
|
user: Messaging.createData(ctx.store.proxy, false),
|
||||||
teamChannel: getInviteData(ctx, teamId).channel,
|
teamChannel: getInviteData(ctx, teamId).channel,
|
||||||
teamName: getInviteData(ctx, teamId).metadata.name
|
teamName: getInviteData(ctx, teamId).metadata.name
|
||||||
@ -711,7 +721,10 @@ define([
|
|||||||
var openTeamChat = function (ctx, data, cId, cb) {
|
var openTeamChat = function (ctx, data, cId, cb) {
|
||||||
var team = ctx.teams[data.teamId];
|
var team = ctx.teams[data.teamId];
|
||||||
if (!team) { return void cb({error: 'ENOENT'}); }
|
if (!team) { return void cb({error: 'ENOENT'}); }
|
||||||
ctx.store.messenger.openTeamChat(team.getChatData(), cId, cb);
|
var onUpdate = function () {
|
||||||
|
ctx.emit('ROSTER_CHANGE', data.teamId, team.clients);
|
||||||
|
};
|
||||||
|
ctx.store.messenger.openTeamChat(team.getChatData(), onUpdate, cId, cb);
|
||||||
};
|
};
|
||||||
|
|
||||||
Team.init = function (cfg, waitFor, emit) {
|
Team.init = function (cfg, waitFor, emit) {
|
||||||
@ -748,6 +761,7 @@ define([
|
|||||||
var t = {};
|
var t = {};
|
||||||
Object.keys(teams).forEach(function (id) {
|
Object.keys(teams).forEach(function (id) {
|
||||||
t[id] = {
|
t[id] = {
|
||||||
|
owner: teams[id].owner,
|
||||||
name: teams[id].metadata.name,
|
name: teams[id].metadata.name,
|
||||||
edPublic: Util.find(teams[id], ['keys', 'drive', 'edPublic']),
|
edPublic: Util.find(teams[id], ['keys', 'drive', 'edPublic']),
|
||||||
avatar: Util.find(teams[id], ['metadata', 'avatar'])
|
avatar: Util.find(teams[id], ['metadata', 'avatar'])
|
||||||
@ -775,6 +789,17 @@ define([
|
|||||||
});
|
});
|
||||||
|
|
||||||
};
|
};
|
||||||
|
team.updateMyData = function (data) {
|
||||||
|
Object.keys(ctx.teams).forEach(function (id) {
|
||||||
|
var team = ctx.teams[id];
|
||||||
|
if (!team.roster) { return; }
|
||||||
|
var obj = {};
|
||||||
|
obj[data.curvePublic] = data;
|
||||||
|
team.roster.describe(obj, function (err) {
|
||||||
|
if (err) { console.error(err); }
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
team.removeClient = function (clientId) {
|
team.removeClient = function (clientId) {
|
||||||
removeClient(ctx, clientId);
|
removeClient(ctx, clientId);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -821,7 +821,9 @@ define([
|
|||||||
UI.errorLoadingScreen(errorText);
|
UI.errorLoadingScreen(errorText);
|
||||||
throw new Error(errorText);
|
throw new Error(errorText);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
if (!proxy.metadata || typeof(proxy.metadata.title) === "undefined") {
|
||||||
|
console.error("UPDATE TITLE");
|
||||||
Title.updateTitle(Title.defaultTitle);
|
Title.updateTitle(Title.defaultTitle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -19,6 +19,16 @@
|
|||||||
@roster-bg-color: #efefef;
|
@roster-bg-color: #efefef;
|
||||||
|
|
||||||
#cp-sidebarlayout-container {
|
#cp-sidebarlayout-container {
|
||||||
|
@media screen and (max-width: 900px) {
|
||||||
|
.cp-app-drive-toolbar-leftside {
|
||||||
|
.cp-dropdown-button-title span:last-child {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.cp-toolbar-share-button span:last-child {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
div#cp-sidebarlayout-rightside.cp-rightside-drive {
|
div#cp-sidebarlayout-rightside.cp-rightside-drive {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
& > .cp-team-chat {
|
& > .cp-team-chat {
|
||||||
@ -39,8 +49,46 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.cp-team-list-avatar {
|
.cp-team-list {
|
||||||
.avatar_main(30px);
|
.cp-team-list-container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-evenly;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
.cp-team-list-team {
|
||||||
|
.tools_unselectable();
|
||||||
|
background-color: @roster-bg-color;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex-flow: column;
|
||||||
|
width: 300px;
|
||||||
|
max-width: 90%;
|
||||||
|
height: 400px;
|
||||||
|
padding: 20px;
|
||||||
|
margin: 5px;
|
||||||
|
.cp-team-list-avatar {
|
||||||
|
.avatar_main(200px);
|
||||||
|
}
|
||||||
|
.cp-team-list-name {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
max-width: 500px;
|
||||||
|
font-size: 25px;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
&.empty {
|
||||||
|
white-space: initial;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.cp-team-list-open {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.cp-team-avatar {
|
.cp-team-avatar {
|
||||||
.avatar_main(300px);
|
.avatar_main(300px);
|
||||||
@ -60,6 +108,16 @@
|
|||||||
.cp-avatar {
|
.cp-avatar {
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
|
.cp-team-member-status {
|
||||||
|
margin-left: 5px;
|
||||||
|
width: 5px;
|
||||||
|
height: 50px;
|
||||||
|
display: inline-block;
|
||||||
|
background-color: red;
|
||||||
|
&.online {
|
||||||
|
background-color: green;
|
||||||
|
}
|
||||||
|
}
|
||||||
.cp-team-member-name {
|
.cp-team-member-name {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|||||||
@ -6,6 +6,7 @@ define([
|
|||||||
'/common/common-interface.js',
|
'/common/common-interface.js',
|
||||||
'/common/common-ui-elements.js',
|
'/common/common-ui-elements.js',
|
||||||
'/common/common-feedback.js',
|
'/common/common-feedback.js',
|
||||||
|
'/common/common-constants.js',
|
||||||
'/bower_components/nthen/index.js',
|
'/bower_components/nthen/index.js',
|
||||||
'/common/sframe-common.js',
|
'/common/sframe-common.js',
|
||||||
'/common/proxy-manager.js',
|
'/common/proxy-manager.js',
|
||||||
@ -25,6 +26,7 @@ define([
|
|||||||
UI,
|
UI,
|
||||||
UIElements,
|
UIElements,
|
||||||
Feedback,
|
Feedback,
|
||||||
|
Constants,
|
||||||
nThen,
|
nThen,
|
||||||
SFCommon,
|
SFCommon,
|
||||||
ProxyManager,
|
ProxyManager,
|
||||||
@ -177,6 +179,8 @@ define([
|
|||||||
});
|
});
|
||||||
if (active === 'drive') {
|
if (active === 'drive') {
|
||||||
APP.$rightside.addClass('cp-rightside-drive');
|
APP.$rightside.addClass('cp-rightside-drive');
|
||||||
|
} else {
|
||||||
|
APP.$rightside.removeClass('cp-rightside-drive');
|
||||||
}
|
}
|
||||||
showCategories(categories[active]);
|
showCategories(categories[active]);
|
||||||
};
|
};
|
||||||
@ -264,25 +268,44 @@ define([
|
|||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var MAX_TEAMS_SLOTS = Constants.MAX_TEAMS_SLOTS;
|
||||||
var refreshList = function (common, cb) {
|
var refreshList = function (common, cb) {
|
||||||
var sframeChan = common.getSframeChannel();
|
var sframeChan = common.getSframeChannel();
|
||||||
var content = [];
|
var content = [];
|
||||||
content.push(h('h3', 'Your teams'));
|
|
||||||
APP.module.execCommand('LIST_TEAMS', null, function (obj) {
|
APP.module.execCommand('LIST_TEAMS', null, function (obj) {
|
||||||
if (!obj) { return; }
|
if (!obj) { return; }
|
||||||
if (obj.error) { return void console.error(obj.error); }
|
if (obj.error) { return void console.error(obj.error); }
|
||||||
var lis = [];
|
var list = [];
|
||||||
Object.keys(obj).forEach(function (id) {
|
var keys = Object.keys(obj).slice(0,3);
|
||||||
|
var slots = '('+Math.min(keys.length, MAX_TEAMS_SLOTS)+'/'+MAX_TEAMS_SLOTS+')';
|
||||||
|
for (var i = keys.length; i < MAX_TEAMS_SLOTS; i++) {
|
||||||
|
obj[i] = {
|
||||||
|
empty: true
|
||||||
|
};
|
||||||
|
keys.push(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
content.push(h('h3', Messages.team_listTitle + ' ' + slots));
|
||||||
|
|
||||||
|
keys.forEach(function (id) {
|
||||||
var team = obj[id];
|
var team = obj[id];
|
||||||
var a = h('a', Messages.team_listLoad);
|
if (team.empty) {
|
||||||
var avatar = h('span.cp-avatar.cp-team-list-avatar');
|
list.push(h('div.cp-team-list-team.empty', [
|
||||||
lis.push(h('li', h('ul', [ // XXX UI
|
h('span.cp-team-list-name.empty', Messages.team_listSlot)
|
||||||
h('li', avatar),
|
]));
|
||||||
h('li', team.metadata.name),
|
return;
|
||||||
h('li', a)
|
}
|
||||||
])));
|
var btn;
|
||||||
|
var avatar = h('span.cp-avatar');
|
||||||
|
list.push(h('div.cp-team-list-team', [
|
||||||
|
h('span.cp-team-list-avatar', avatar),
|
||||||
|
h('span.cp-team-list-name', {
|
||||||
|
title: team.metadata.name
|
||||||
|
}, team.metadata.name),
|
||||||
|
btn = h('button.cp-team-list-open.btn.btn-primary', Messages.team_listLoad)
|
||||||
|
]));
|
||||||
common.displayAvatar($(avatar), team.metadata.avatar, team.metadata.name);
|
common.displayAvatar($(avatar), team.metadata.avatar, team.metadata.name);
|
||||||
$(a).click(function () {
|
$(btn).click(function () {
|
||||||
APP.module.execCommand('SUBSCRIBE', id, function () {
|
APP.module.execCommand('SUBSCRIBE', id, function () {
|
||||||
sframeChan.query('Q_SET_TEAM', id, function (err) {
|
sframeChan.query('Q_SET_TEAM', id, function (err) {
|
||||||
if (err) { return void console.error(err); }
|
if (err) { return void console.error(err); }
|
||||||
@ -293,7 +316,7 @@ define([
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
content.push(h('ul', lis));
|
content.push(h('div.cp-team-list-container', list));
|
||||||
cb(content);
|
cb(content);
|
||||||
});
|
});
|
||||||
return content;
|
return content;
|
||||||
@ -303,7 +326,20 @@ define([
|
|||||||
});
|
});
|
||||||
|
|
||||||
makeBlock('create', function (common, cb) {
|
makeBlock('create', function (common, cb) {
|
||||||
|
var metadataMgr = common.getMetadataMgr();
|
||||||
|
var privateData = metadataMgr.getPrivateData();
|
||||||
var content = [];
|
var content = [];
|
||||||
|
|
||||||
|
var isOwner = Object.keys(privateData.teams || {}).some(function (id) {
|
||||||
|
return privateData.teams[id].owner;
|
||||||
|
});
|
||||||
|
if (Object.keys(privateData.teams || {}).length >= 3 || isOwner) {
|
||||||
|
content.push(h('div.alert.alert-warning', {
|
||||||
|
role:'alert'
|
||||||
|
}, isOwner ? Messages.team_maxOwner : Messages._getKey('team_maxTeams', [MAX_TEAMS_SLOTS])));
|
||||||
|
return void cb(content);
|
||||||
|
}
|
||||||
|
|
||||||
content.push(h('h3', Messages.team_createLabel));
|
content.push(h('h3', Messages.team_createLabel));
|
||||||
content.push(h('label', Messages.team_createName));
|
content.push(h('label', Messages.team_createName));
|
||||||
var input = h('input', {type:'text'});
|
var input = h('input', {type:'text'});
|
||||||
@ -393,6 +429,8 @@ define([
|
|||||||
common.displayAvatar($(avatar), data.avatar, data.displayName);
|
common.displayAvatar($(avatar), data.avatar, data.displayName);
|
||||||
// Name
|
// Name
|
||||||
var name = h('span.cp-team-member-name', data.displayName);
|
var name = h('span.cp-team-member-name', data.displayName);
|
||||||
|
// Status
|
||||||
|
var status = h('span.cp-team-member-status'+(data.online ? '.online' : ''));
|
||||||
// Actions
|
// Actions
|
||||||
var actions = h('span.cp-team-member-actions');
|
var actions = h('span.cp-team-member-actions');
|
||||||
var $actions = $(actions);
|
var $actions = $(actions);
|
||||||
@ -400,7 +438,7 @@ define([
|
|||||||
var myRole = me ? (ROLES.indexOf(me.role) || 0) : -1;
|
var myRole = me ? (ROLES.indexOf(me.role) || 0) : -1;
|
||||||
var theirRole = ROLES.indexOf(data.role) || 0;
|
var theirRole = ROLES.indexOf(data.role) || 0;
|
||||||
// If they're a member and I have a higher role than them, I can promote them to admin
|
// If they're a member and I have a higher role than them, I can promote them to admin
|
||||||
if (!isMe && myRole > theirRole && theirRole === 0) {
|
if (!isMe && myRole > theirRole && theirRole === 0 && !data.pending) {
|
||||||
var promote = h('span.fa.fa-angle-double-up', {
|
var promote = h('span.fa.fa-angle-double-up', {
|
||||||
title: Messages.team_rosterPromote
|
title: Messages.team_rosterPromote
|
||||||
});
|
});
|
||||||
@ -413,7 +451,7 @@ define([
|
|||||||
}
|
}
|
||||||
// If I'm not a member and I have an equal or higher role than them, I can demote them
|
// If I'm not a member and I have an equal or higher role than them, I can demote them
|
||||||
// (if they're not already a MEMBER)
|
// (if they're not already a MEMBER)
|
||||||
if (!isMe && myRole >= theirRole && theirRole > 0) {
|
if (!isMe && myRole >= theirRole && theirRole > 0 && !data.pending) {
|
||||||
var demote = h('span.fa.fa-angle-double-down', {
|
var demote = h('span.fa.fa-angle-double-down', {
|
||||||
title: Messages.team_rosterDemote
|
title: Messages.team_rosterDemote
|
||||||
});
|
});
|
||||||
@ -432,6 +470,7 @@ define([
|
|||||||
$(remove).click(function () {
|
$(remove).click(function () {
|
||||||
$(remove).hide();
|
$(remove).hide();
|
||||||
APP.module.execCommand('REMOVE_USER', {
|
APP.module.execCommand('REMOVE_USER', {
|
||||||
|
pending: data.pending,
|
||||||
teamId: APP.team,
|
teamId: APP.team,
|
||||||
curvePublic: data.curvePublic,
|
curvePublic: data.curvePublic,
|
||||||
}, function (obj) {
|
}, function (obj) {
|
||||||
@ -449,7 +488,8 @@ define([
|
|||||||
var content = [
|
var content = [
|
||||||
avatar,
|
avatar,
|
||||||
name,
|
name,
|
||||||
actions
|
actions,
|
||||||
|
status,
|
||||||
];
|
];
|
||||||
var div = h('div.cp-team-roster-member', {
|
var div = h('div.cp-team-roster-member', {
|
||||||
title: data.displayName
|
title: data.displayName
|
||||||
@ -486,6 +526,12 @@ define([
|
|||||||
}).map(function (k) {
|
}).map(function (k) {
|
||||||
return makeMember(common, roster[k], me);
|
return makeMember(common, roster[k], me);
|
||||||
});
|
});
|
||||||
|
var pending = Object.keys(roster).filter(function (k) {
|
||||||
|
if (!roster[k].pending) { return; }
|
||||||
|
return roster[k].role === "MEMBER" || !roster[k].role;
|
||||||
|
}).map(function (k) {
|
||||||
|
return makeMember(common, roster[k], me);
|
||||||
|
});
|
||||||
|
|
||||||
var header = h('div.cp-app-team-roster-header');
|
var header = h('div.cp-app-team-roster-header');
|
||||||
var $header = $(header);
|
var $header = $(header);
|
||||||
@ -538,7 +584,9 @@ define([
|
|||||||
h('h3', Messages.team_admins),
|
h('h3', Messages.team_admins),
|
||||||
h('div', admins),
|
h('div', admins),
|
||||||
h('h3', Messages.team_members),
|
h('h3', Messages.team_members),
|
||||||
h('div', members)
|
h('div', members),
|
||||||
|
h('h3', Messages.team_pending || 'PENDING'), // XXX
|
||||||
|
h('div', pending)
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
makeBlock('roster', function (common, cb) {
|
makeBlock('roster', function (common, cb) {
|
||||||
@ -576,6 +624,7 @@ define([
|
|||||||
|
|
||||||
var todo = function () {
|
var todo = function () {
|
||||||
var newName = $input.val();
|
var newName = $input.val();
|
||||||
|
if (!newName.trim()) { return; }
|
||||||
$spinner.show();
|
$spinner.show();
|
||||||
APP.module.execCommand('GET_TEAM_METADATA', {
|
APP.module.execCommand('GET_TEAM_METADATA', {
|
||||||
teamId: APP.team
|
teamId: APP.team
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user