diff --git a/www/common/common-ui-elements.js b/www/common/common-ui-elements.js
index d427de526..4b26de585 100644
--- a/www/common/common-ui-elements.js
+++ b/www/common/common-ui-elements.js
@@ -14,7 +14,9 @@ define([
'/customize/application_config.js',
'/customize/pages.js',
'/bower_components/nthen/index.js',
- 'css!/customize/fonts/cptools/style.css'
+ 'css!/customize/fonts/cptools/style.css',
+ '/bower_components/croppie/croppie.min.js',
+ 'css!/bower_components/croppie/croppie.css',
], function ($, Config, Util, Hash, Language, UI, Constants, Feedback, h, MediaTag, Clipboard,
Messages, AppConfig, Pages, NThen) {
var UIElements = {};
@@ -1937,6 +1939,84 @@ define([
});
}
};
+ var transformAvatar = function (file, cb) {
+ if (file.type === 'image/gif') { return void cb(file); }
+ var $croppie = $('
', {
+ 'class': 'cp-app-profile-resizer'
+ });
+
+ if (typeof ($croppie.croppie) !== "function") {
+ console.warn('fuck');
+ return void cb(file);
+ }
+
+ var todo = function () {
+ UI.confirm($croppie[0], function (yes) {
+ if (!yes) { return; }
+ $croppie.croppie('result', {
+ type: 'blob',
+ size: {width: 300, height: 300}
+ }).then(function(blob) {
+ blob.lastModifiedDate = new Date();
+ blob.name = 'avatar';
+ cb(blob);
+ });
+ });
+ };
+
+ var reader = new FileReader();
+ reader.onload = function(e) {
+ $croppie.croppie({
+ url: e.target.result,
+ viewport: { width: 100, height: 100 },
+ boundary: { width: 400, height: 300 },
+ });
+ todo();
+ };
+ reader.readAsDataURL(file);
+ };
+ UIElements.addAvatar = function (common, cb) {
+ var AVATAR_SIZE_LIMIT = 0.5;
+ var allowedMediaTypes = [
+ 'image/png',
+ 'image/jpeg',
+ 'image/jpg',
+ 'image/gif',
+ ];
+ var fmConfig = {
+ noHandlers: true,
+ noStore: true,
+ body: $('body'),
+ onUploaded: cb
+ };
+ var FM = common.createFileManager(fmConfig);
+ var accepted = ".gif,.jpg,.jpeg,.png";
+ var data = {
+ FM: FM,
+ filter: function (file) {
+ var sizeMB = Util.bytesToMegabytes(file.size);
+ var type = file.type;
+ // We can't resize .gif so we have to display an error if it is too big
+ if (sizeMB > AVATAR_SIZE_LIMIT && type === 'image/gif') {
+ UI.log(Messages._getKey('profile_uploadSizeError', [
+ Messages._getKey('formattedMB', [AVATAR_SIZE_LIMIT])
+ ]));
+ return false;
+ }
+ // Display an error if the image type is not allowed
+ if (allowedMediaTypes.indexOf(type) === -1) {
+ UI.log(Messages._getKey('profile_uploadTypeError', [
+ accepted.split(',').join(', ')
+ ]));
+ return false;
+ }
+ return true;
+ },
+ transformer: transformAvatar,
+ accept: accepted
+ };
+ return data;
+ };
/* Create a usage bar which keeps track of how much storage space is used
by your CryptDrive. The getPinnedUsage RPC is one of the heavier calls,
diff --git a/www/common/outer/team.js b/www/common/outer/team.js
index a49b27016..893f5a930 100644
--- a/www/common/outer/team.js
+++ b/www/common/outer/team.js
@@ -132,6 +132,7 @@ define([
realtime: lm.realtime,
handleSharedFolder: function (sfId, rt) { handleSharedFolder(ctx, id, sfId, rt); },
sharedFolders: {}, // equivalent of store.sharedFolders in async-store
+ roster: roster
};
if (cId) { team.clients.push(cId); }
@@ -447,6 +448,32 @@ define([
});
};
+ var getTeamMetadata = function (ctx, data, cId, cb) {
+ var teamId = data.teamId;
+ if (!teamId) { return void cb({error: 'EINVAL'}); }
+ var team = ctx.teams[teamId];
+ if (!team) { return void cb ({error: 'ENOENT'}); }
+ if (!team.roster) { return void cb({error: 'NO_ROSTER'}); }
+ var state = team.roster.getState() || {};
+ cb(state.metadata || {});
+ };
+
+ var setTeamMetadata = function (ctx, data, cId, cb) {
+ var teamId = data.teamId;
+ if (!teamId) { return void cb({error: 'EINVAL'}); }
+ var team = ctx.teams[teamId];
+ if (!team) { return void cb ({error: 'ENOENT'}); }
+ if (!team.roster) { return void cb({error: 'NO_ROSTER'}); }
+ team.roster.metadata(data.metadata, function (err) {
+ if (err) { return void cb({error: err}); }
+ var localTeam = ctx.store.proxy.teams[teamId];
+ if (localTeam) {
+ localTeam.metadata = data.metadata
+ }
+ cb();
+ });
+ };
+
// Remove a client from all the team they're subscribed to
var removeClient = function (ctx, cId) {
Object.keys(ctx.onReadyHandlers).forEach(function (teamId) {
@@ -565,6 +592,12 @@ define([
if (cmd === 'OPEN_TEAM_CHAT') {
return void openTeamChat(ctx, data, clientId, cb);
}
+ if (cmd === 'GET_TEAM_METADATA') {
+ return void getTeamMetadata(ctx, data, clientId, cb);
+ }
+ if (cmd === 'SET_TEAM_METADATA') {
+ return void setTeamMetadata(ctx, data, clientId, cb);
+ }
if (cmd === 'CREATE_TEAM') {
return void createTeam(ctx, data, clientId, cb);
}
diff --git a/www/profile/inner.js b/www/profile/inner.js
index 324e918a8..4635743f6 100644
--- a/www/profile/inner.js
+++ b/www/profile/inner.js
@@ -24,8 +24,6 @@ define([
'css!/bower_components/bootstrap/dist/css/bootstrap.min.css',
'css!/bower_components/components-font-awesome/css/font-awesome.min.css',
'less!/profile/app-profile.less',
- '/bower_components/croppie/croppie.min.js',
- 'css!/bower_components/croppie/croppie.css',
], function (
$,
Crypto,
@@ -233,48 +231,6 @@ define([
});
};
- var AVATAR_SIZE_LIMIT = 0.5;
- var allowedMediaTypes = [
- 'image/png',
- 'image/jpeg',
- 'image/jpg',
- 'image/gif',
- ];
- var transformAvatar = function (file, cb) {
- if (file.type === 'image/gif') { return void cb(file); }
- var $croppie = $('
', {
- 'class': 'cp-app-profile-resizer'
- });
-
- if (typeof ($croppie.croppie) !== "function") {
- return void cb(file);
- }
-
- var todo = function () {
- UI.confirm($croppie[0], function (yes) {
- if (!yes) { return; }
- $croppie.croppie('result', {
- type: 'blob',
- size: {width: 300, height: 300}
- }).then(function(blob) {
- blob.lastModifiedDate = new Date();
- blob.name = 'avatar';
- cb(blob);
- });
- });
- };
-
- var reader = new FileReader();
- reader.onload = function(e) {
- $croppie.croppie({
- url: e.target.result,
- viewport: { width: 100, height: 100 },
- boundary: { width: 400, height: 300 },
- });
- todo();
- };
- reader.readAsDataURL(file);
- };
var displayAvatar = function (val) {
var sframeChan = common.getSframeChannel();
var $span = APP.$avatar;
@@ -316,59 +272,28 @@ define([
displayAvatar();
if (APP.readOnly) { return; }
- var fmConfig = {
- noHandlers: true,
- noStore: true,
- body: $('body'),
- onUploaded: function (ev, data) {
- var old = common.getMetadataMgr().getUserData().avatar;
- var todo = function () {
- APP.module.execCommand("SET", {
- key: 'avatar',
- value: data.url
- }, function () {
- sframeChan.query("Q_PROFILE_AVATAR_ADD", data.url, function (err, err2) {
- if (err || err2) { return void UI.log(err || err2); }
- displayAvatar(data.url);
- });
- });
- };
- if (old) {
- sframeChan.query("Q_PROFILE_AVATAR_REMOVE", old, function (err, err2) {
+ var data = UIElements.addAvatar(common, function (ev, data) {
+ var old = common.getMetadataMgr().getUserData().avatar;
+ var todo = function () {
+ APP.module.execCommand("SET", {
+ key: 'avatar',
+ value: data.url
+ }, function () {
+ sframeChan.query("Q_PROFILE_AVATAR_ADD", data.url, function (err, err2) {
if (err || err2) { return void UI.log(err || err2); }
- todo();
+ displayAvatar(data.url);
});
- return;
- }
- todo();
+ });
+ };
+ if (old) {
+ sframeChan.query("Q_PROFILE_AVATAR_REMOVE", old, function (err, err2) {
+ if (err || err2) { return void UI.log(err || err2); }
+ todo();
+ });
+ return;
}
- };
- APP.FM = common.createFileManager(fmConfig);
- var accepted = ".gif,.jpg,.jpeg,.png";
- var data = {
- FM: APP.FM,
- filter: function (file) {
- var sizeMB = Util.bytesToMegabytes(file.size);
- var type = file.type;
- // We can't resize .gif so we have to display an error if it is too big
- if (sizeMB > AVATAR_SIZE_LIMIT && type === 'image/gif') {
- UI.log(Messages._getKey('profile_uploadSizeError', [
- Messages._getKey('formattedMB', [AVATAR_SIZE_LIMIT])
- ]));
- return false;
- }
- // Display an error if the image type is not allowed
- if (allowedMediaTypes.indexOf(type) === -1) {
- UI.log(Messages._getKey('profile_uploadTypeError', [
- accepted.split(',').join(', ')
- ]));
- return false;
- }
- return true;
- },
- transformer: transformAvatar,
- accept: accepted
- };
+ todo();
+ });
var $upButton = common.createButton('upload', false, data);
$upButton.text(Messages.profile_upload);
$upButton.prepend($('
', {'class': 'fa fa-upload'}));
diff --git a/www/team/app-team.less b/www/team/app-team.less
index c1412b4dc..8b009a1bc 100644
--- a/www/team/app-team.less
+++ b/www/team/app-team.less
@@ -34,6 +34,13 @@
}
}
}
+
+ .cp-team-list-avatar {
+ .avatar_main(30px);
+ }
+ .cp-team-avatar {
+ .avatar_main(300px);
+ }
}
}
diff --git a/www/team/inner.js b/www/team/inner.js
index b8ea4a083..9b9080fd1 100644
--- a/www/team/inner.js
+++ b/www/team/inner.js
@@ -4,6 +4,7 @@ define([
'/common/drive-ui.js',
'/common/common-util.js',
'/common/common-interface.js',
+ '/common/common-ui-elements.js',
'/common/common-feedback.js',
'/bower_components/nthen/index.js',
'/common/sframe-common.js',
@@ -22,6 +23,7 @@ define([
DriveUI,
Util,
UI,
+ UIElements,
Feedback,
nThen,
SFCommon,
@@ -109,6 +111,10 @@ define([
'chat': [
'cp-team-chat'
],
+ 'admin': [
+ 'cp-team-name',
+ 'cp-team-avatar'
+ ],
};
var create = {};
@@ -124,7 +130,7 @@ define([
APP.$rightside.find('.'+c).show();
});
};
- var createLeftSide = APP.createLeftSide = function (common, team) {
+ var createLeftSide = APP.createLeftSide = function (common, team, teamAdmin) {
APP.$leftside.empty();
var $categories = $('', {'class': 'cp-sidebarlayout-categories'})
.appendTo(APP.$leftside);
@@ -133,6 +139,8 @@ define([
var active = team ? 'drive' : 'list';
Object.keys(categories).forEach(function (key) {
+ if (key === 'admin' && !teamAdmin) { return; }
+
var $category = $('
', {'class': 'cp-sidebarlayout-category cp-team-cat-'+key}).appendTo($categories);
if (key === 'general') { $category.append($('
', {'class': 'fa fa-info-circle'})); }
if (key === 'list') { $category.append($('', {'class': 'fa fa-list cp-team-cat-list'})); }
@@ -141,6 +149,7 @@ define([
if (key === 'members') { $category.append($('', {'class': 'fa fa-users'})); }
if (key === 'chat') { $category.append($('', {'class': 'fa fa-comments'})); }
if (key === 'drive') { $category.append($('', {'class': 'fa fa-hdd-o'})); }
+ if (key === 'admin') { $category.append($('', {'class': 'fa fa-cogs'})); }
if (key === active) {
$category.addClass('cp-leftside-active');
@@ -172,7 +181,7 @@ define([
showCategories(categories[active]);
};
- var buildUI = APP.buildUI = function (common, team) {
+ var buildUI = APP.buildUI = function (common, team, teamAdmin) {
var $rightside = APP.$rightside;
$rightside.empty();
var addItem = function (cssClass) {
@@ -187,7 +196,7 @@ define([
categories[cat].forEach(addItem);
}
- createLeftSide(common, team);
+ createLeftSide(common, team, teamAdmin);
};
// Team APP
@@ -226,9 +235,16 @@ define([
// Rightside elements
- var makeBlock = function (key, getter) {
+ var makeBlock = function (key, getter, full) {
+ var safeKey = key.replace(/-([a-z])/g, function (g) { return g[1].toUpperCase(); });
+
create[key] = function (common) {
var $div = $('', {'class': 'cp-team-' + key + ' cp-sidebarlayout-element'});
+ if (full) {
+ $('