Add avatars in the user list

pull/1/head
yflory 8 years ago
parent b6944e6638
commit b153dda6ff

@ -104,6 +104,43 @@ body .userlist-drawer {
background: rgba(0,0,0,0.1); background: rgba(0,0,0,0.1);
margin: 2px 0; margin: 2px 0;
font-size: 16px; font-size: 16px;
display: inline-flex;
align-items: center;
&.clickable {
cursor: pointer;
&:hover {
background-color: rgba(0,0,0,0.3);
}
}
.default, media-tag {
display: inline-flex;
width: 50px;
height: 50px;
justify-content: center;
align-items: center;
margin-right: 5px;
border-radius: 10px / 6px;
overflow: hidden;
border: 1px solid black;
box-sizing: content-box;
}
.default {
.unselectable();
background: white;
color: black;
font-size: 40px;
}
media-tag {
max-height: 50px;
max-width: 50px;
img {
min-width: 100%;
min-height: 100%;
max-width: none;
max-height: none !important; // To override 'media-tag img' in slide.less
flex-shrink: 0;
}
}
} }
} }
} }
@ -850,8 +887,10 @@ body .cryptpad-toolbar {
} }
} }
.cryptpad-toolbar-rightside { .cryptpad-toolbar-rightside {
height: 32px; min-height: 32px;
overflow: hidden;
&:empty { &:empty {
min-height: 0;
height: 0; height: 0;
} }
text-align: right; text-align: right;

@ -240,6 +240,16 @@ define(function () {
out.canvas_opacityLabel = "opacité: {0}"; out.canvas_opacityLabel = "opacité: {0}";
out.canvas_widthLabel = "taille: {0}"; out.canvas_widthLabel = "taille: {0}";
// Profile
out.profile_urlPlaceholder = 'URL';
out.profile_avatar = "Avatar";
out.profile_upload = " Importer un nouvel avatar";
out.profile_error = "Erreur lors de la création du profil : {0}";
out.profile_register = "Vous devez vous inscrire pour pouvoir créer un profil !";
out.profile_create = "Créer un profil";
out.profile_description = "Description";
out.profile_fieldSaved = 'Nouvelle valeur enregistrée: {0}';
// File manager // File manager
out.fm_rootName = "Documents"; out.fm_rootName = "Documents";

@ -242,6 +242,15 @@ define(function () {
out.canvas_opacityLabel = "opacity: {0}"; out.canvas_opacityLabel = "opacity: {0}";
out.canvas_widthLabel = "Width: {0}"; out.canvas_widthLabel = "Width: {0}";
// Profile
out.profile_urlPlaceholder = 'URL';
out.profile_avatar = "Avatar";
out.profile_upload = " Upload a new avatar";
out.profile_error = "Error while creating your profile: {0}";
out.profile_register = "You have to sign up to create a profile!";
out.profile_create = "Create a profile";
out.profile_description = "Description";
out.profile_fieldSaved = 'New value saved: {0}';
// File manager // File manager

@ -49,8 +49,10 @@ define(function () {
exp.myUserName = myUserNameTemp; exp.myUserName = myUserNameTemp;
myData = {}; myData = {};
myData[exp.myNetfluxId] = { myData[exp.myNetfluxId] = {
name: exp.myUserName, name: exp.myUserName,
uid: Cryptpad.getUid(), uid: Cryptpad.getUid(),
avatar: Cryptpad.getAvatarUrl(),
profile: Cryptpad.getProfileUrl()
}; };
addToUserData(myData); addToUserData(myData);
Cryptpad.setAttribute('username', exp.myUserName, function (err) { Cryptpad.setAttribute('username', exp.myUserName, function (err) {
@ -78,6 +80,8 @@ define(function () {
myData[exp.myNetfluxId] = { myData[exp.myNetfluxId] = {
name: "", name: "",
uid: Cryptpad.getUid(), uid: Cryptpad.getUid(),
avatar: Cryptpad.getAvatarUrl(),
profile: Cryptpad.getProfileUrl()
}; };
addToUserData(myData); addToUserData(myData);
onLocal(); onLocal();

@ -146,6 +146,16 @@ define([
} }
return; return;
}; };
common.getProfileUrl = function () {
if (store && store.getProfile()) {
return store.getProfile().view;
}
};
common.getAvatarUrl = function () {
if (store && store.getProfile()) {
return store.getProfile().avatar;
}
};
var feedback = common.feedback = function (action, force) { var feedback = common.feedback = function (action, force) {
if (force !== true) { if (force !== true) {
@ -1168,61 +1178,70 @@ define([
'image/jpg', 'image/jpg',
'image/gif', 'image/gif',
]; ];
common.displayAvatar = function ($container, href) { common.displayAvatar = function ($container, href, name, cb) {
var MutationObserver = window.MutationObserver; var MutationObserver = window.MutationObserver;
$container.html(''); var displayDefault = function () {
if (href) { var text = name.trim().length ? name.trim().slice(0,1) : '?';
var parsed = common.parsePadUrl(href); var $avatar = $('<span>', {'class': 'default'}).text(text);
var secret = common.getSecrets('file', parsed.hash); $container.append($avatar);
if (secret.keys && secret.channel) { if (cb) { cb(); }
var cryptKey = secret.keys && secret.keys.fileKeyStr; };
var hexFileName = common.base64ToHex(secret.channel);
var src = common.getBlobPathFromHex(hexFileName); if (!href) { return void displayDefault(); }
common.getFileSize(href, function (e, data) { var parsed = common.parsePadUrl(href);
if (e) { return void console.error(e); } var secret = common.getSecrets('file', parsed.hash);
if (typeof data !== "number") { return; } if (secret.keys && secret.channel) {
if (common.bytesToMegabytes(data) > 0.5) { return; } var cryptKey = secret.keys && secret.keys.fileKeyStr;
var $img = $('<media-tag>').appendTo($container); var hexFileName = common.base64ToHex(secret.channel);
$img.attr('src', src); var src = common.getBlobPathFromHex(hexFileName);
$img.attr('data-crypto-key', 'cryptpad:' + cryptKey); common.getFileSize(href, function (e, data) {
require(['/common/media-tag.js'], function (MediaTag) { if (e) {
MediaTag.CryptoFilter.setAllowedMediaTypes(common.avatarAllowedTypes); displayDefault();
MediaTag($img[0]); return void console.error(e);
var observer = new MutationObserver(function(mutations) { }
mutations.forEach(function(mutation) { if (typeof data !== "number") { return void displayDefault(); }
if (mutation.type === 'childList' && mutation.addedNodes.length) { if (common.bytesToMegabytes(data) > 0.5) { return void displayDefault(); }
console.log(mutation); var $img = $('<media-tag>').appendTo($container);
if (mutation.addedNodes.length > 1 || $img.attr('src', src);
mutation.addedNodes[0].nodeName !== 'IMG') { $img.attr('data-crypto-key', 'cryptpad:' + cryptKey);
$img.remove(); require(['/common/media-tag.js'], function (MediaTag) {
MediaTag.CryptoFilter.setAllowedMediaTypes(common.avatarAllowedTypes);
MediaTag($img[0]);
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.type === 'childList' && mutation.addedNodes.length) {
console.log(mutation);
if (mutation.addedNodes.length > 1 ||
mutation.addedNodes[0].nodeName !== 'IMG') {
$img.remove();
return void displayDefault();
}
var $image = $img.find('img');
var onLoad = function () {
var w = $image.width();
var h = $image.height();
if (w>h) {
$image.css('max-height', '100%');
$img.css('flex-direction', 'row');
if (cb) { cb($img); }
return; return;
//TODO display default avatar
} }
var $image = $img.find('img'); $image.css('max-width', '100%');
var onLoad = function () { $img.css('flex-direction', 'column');
var w = $image.width(); if (cb) { cb($img); }
var h = $image.height(); };
if (w>h) { if ($image[0].complete) { onLoad(); }
$image.css('max-height', '100%'); $image.on('load', onLoad);
$img.css('flex-direction', 'row'); }
return;
}
$image.css('max-width', '100%');
$img.css('flex-direction', 'column');
};
if ($image[0].complete) { onLoad(); }
$image.on('load', onLoad);
}
});
});
observer.observe($img[0], {
attributes: false,
childList: true,
characterData: false
}); });
}); });
observer.observe($img[0], {
attributes: false,
childList: true,
characterData: false
});
}); });
} });
} }
}; };

@ -211,6 +211,10 @@ define([
if (typeof(n) !== "string") { return; } if (typeof(n) !== "string") { return; }
Cryptpad.changeDisplayName(n); Cryptpad.changeDisplayName(n);
}); });
proxy.on('change', ['profile'], function () {
// Trigger userlist update when the avatar has changed
Cryptpad.changeDisplayName(proxy[Cryptpad.displayNameKey]);
});
proxy.on('change', [tokenKey], function () { proxy.on('change', [tokenKey], function () {
console.log('wut'); console.log('wut');
var localToken = tryParsing(localStorage.getItem(tokenKey)); var localToken = tryParsing(localStorage.getItem(tokenKey));

@ -149,6 +149,7 @@ define([
return $.inArray(i, b) > -1; return $.inArray(i, b) > -1;
}); });
}; };
var avatars = {};
var updateUserList = function (toolbar, config) { var updateUserList = function (toolbar, config) {
// Make sure the elements are displayed // Make sure the elements are displayed
var $userButtons = toolbar.userlist; var $userButtons = toolbar.userlist;
@ -189,7 +190,24 @@ define([
// Editors // Editors
editUsersNames.forEach(function (data) { editUsersNames.forEach(function (data) {
var name = data.name || Messages.anonymous; var name = data.name || Messages.anonymous;
var $span = $('<span>', {'title': name}).text(name); var $span = $('<span>', {'title': name});
if (data.profile) {
$span.addClass('clickable');
$span.click(function () {
window.open('/profile/#' + data.profile);
});
}
if (data.avatar && avatars[data.avatar]) {
$span.append(avatars[data.avatar]);
$span.append(name);
} else {
Cryptpad.displayAvatar($span, data.avatar, name, function ($img) {
if (data.avatar && $img) {
avatars[data.avatar] = $img[0].outerHTML;
}
$span.append(name);
});
}
$span.data('uid', data.uid); $span.data('uid', data.uid);
$editUsersList.append($span); $editUsersList.append($span);
}); });
@ -197,9 +215,9 @@ define([
// Viewers // Viewers
if (numberOfViewUsers > 0) { if (numberOfViewUsers > 0) {
var viewText = '<span class="viewer">'; var viewText = '<div class="viewer">';
var viewerText = numberOfViewUsers !== 1 ? Messages.viewers : Messages.viewer; var viewerText = numberOfViewUsers !== 1 ? Messages.viewers : Messages.viewer;
viewText += numberOfViewUsers + ' ' + viewerText + '</span>'; viewText += numberOfViewUsers + ' ' + viewerText + '</div>';
$editUsers.append(viewText); $editUsers.append(viewText);
} }

@ -105,7 +105,7 @@ define([
if (err) { return void console.error(err); } if (err) { return void console.error(err); }
Cryptpad.whenRealtimeSyncs(realtime, function () { Cryptpad.whenRealtimeSyncs(realtime, function () {
lastVal = newVal; lastVal = newVal;
Cryptpad.log('TODO: '+name+' saved'); Cryptpad.log(Messages._getKey('profile_fieldSaved', [newVal]));
editing = false; editing = false;
}); });
}); });
@ -196,7 +196,7 @@ define([
cb(); cb();
}; };
var rt = APP.lm.realtime; var rt = APP.lm.realtime;
var placeholder = "URL"; //XXX var placeholder = Messages.profile_urlPlaceholder;
createEditableInput($block, LINK_ID, placeholder, getValue, setValue, rt); createEditableInput($block, LINK_ID, placeholder, getValue, setValue, rt);
}; };
@ -209,7 +209,7 @@ define([
if (!APP.lm.proxy.avatar) { if (!APP.lm.proxy.avatar) {
$('<img>', { $('<img>', {
src: '/customize/images/avatar.png', src: '/customize/images/avatar.png',
title: 'Avatar', // XXX title: Messages.profile_avatar,
alt: 'Avatar' alt: 'Avatar'
}).appendTo($span); }).appendTo($span);
return; return;
@ -218,21 +218,20 @@ define([
if (APP.readOnly) { return; } if (APP.readOnly) { return; }
var $delButton = $('<button>', {'class': 'delete btn btn-danger fa fa-times'}); //XXX var $delButton = $('<button>', {
'class': 'delete btn btn-danger fa fa-times',
title: Messages.fc_delete
});
$span.append($delButton); $span.append($delButton);
$delButton.click(function () { $delButton.click(function () {
console.log('clicked');
var oldChanId = Cryptpad.hrefToHexChannelId(APP.lm.proxy.avatar); var oldChanId = Cryptpad.hrefToHexChannelId(APP.lm.proxy.avatar);
Cryptpad.unpinPads([oldChanId], function (e) { Cryptpad.unpinPads([oldChanId], function (e) {
if (e) { Cryptpad.log(e); } if (e) { Cryptpad.log(e); }
console.log('unpinned');
delete APP.lm.proxy.avatar; delete APP.lm.proxy.avatar;
delete Cryptpad.getProxy().profile.avatar; delete Cryptpad.getProxy().profile.avatar;
Cryptpad.whenRealtimeSyncs(APP.lm.realtime, function () { Cryptpad.whenRealtimeSyncs(APP.lm.realtime, function () {
console.log('synced1');
var driveRt = Cryptpad.getStore().getProxy().info.realtime; var driveRt = Cryptpad.getStore().getProxy().info.realtime;
Cryptpad.whenRealtimeSyncs(driveRt, function () { Cryptpad.whenRealtimeSyncs(driveRt, function () {
console.log('synced2');
displayAvatar(); displayAvatar();
}); });
}); });
@ -258,6 +257,7 @@ define([
Cryptpad.whenRealtimeSyncs(APP.lm.realtime, function () { Cryptpad.whenRealtimeSyncs(APP.lm.realtime, function () {
var driveRt = Cryptpad.getStore().getProxy().info.realtime; var driveRt = Cryptpad.getStore().getProxy().info.realtime;
Cryptpad.whenRealtimeSyncs(driveRt, function () { Cryptpad.whenRealtimeSyncs(driveRt, function () {
Cryptpad.changeDisplayName();
displayAvatar(); displayAvatar();
}); });
}); });
@ -285,7 +285,7 @@ define([
accept: ".gif,.jpg,.jpeg,.png" accept: ".gif,.jpg,.jpeg,.png"
}; };
var $upButton = Cryptpad.createButton('upload', false, data); var $upButton = Cryptpad.createButton('upload', false, data);
$upButton.text(" Upload a new avatar"); $upButton.text(Messages.profile_upload);
$upButton.prepend($('<span>', {'class': 'fa fa-upload'})); $upButton.prepend($('<span>', {'class': 'fa fa-upload'}));
$block.append($upButton); $block.append($upButton);
}; };
@ -300,6 +300,7 @@ define([
$div.html(val); $div.html(val);
return; return;
} }
$('<h3>').text(Messages.profile_description).insertBefore($block);
var $ok = $('<span>', {'class': 'ok fa fa-check', title: Messages.saved}).appendTo($block); var $ok = $('<span>', {'class': 'ok fa fa-check', title: Messages.saved}).appendTo($block);
var $spinner = $('<span>', {'class': 'spin fa fa-spinner fa-pulse'}).appendTo($block); var $spinner = $('<span>', {'class': 'spin fa fa-spinner fa-pulse'}).appendTo($block);
@ -388,17 +389,18 @@ define([
if (e === 'E_OVER_LIMIT') { if (e === 'E_OVER_LIMIT') {
Cryptpad.alert(Messages.pinLimitNotPinned, null, true); Cryptpad.alert(Messages.pinLimitNotPinned, null, true);
} }
return void Cryptpad.log('Error while creating your profile: ' + e); // XXX return void Cryptpad.log(Messages._getKey('profile_error', [e]));
} }
obj.profile.edit = Cryptpad.getEditHashFromKeys(channel, secret.keys); obj.profile.edit = Cryptpad.getEditHashFromKeys(channel, secret.keys);
obj.profile.view = Cryptpad.getViewHashFromKeys(channel, secret.keys); obj.profile.view = Cryptpad.getViewHashFromKeys(channel, secret.keys);
obj.profile.name = APP.rt.proxy[Cryptpad.displayNameKey] || ''; obj.profile.name = APP.rt.proxy[Cryptpad.displayNameKey] || '';
Cryptpad.changeDisplayName();
andThen(obj.profile.edit); andThen(obj.profile.edit);
}); });
}; };
if (!Cryptpad.isLoggedIn()) { // XXX if (!Cryptpad.isLoggedIn()) {
var $p = $('<p>').text('TODO: You have to register to create a profile'); var $p = $('<p>').text(Messages.error_register);
var $a = $('<a>', { var $a = $('<a>', {
href: '/register/' href: '/register/'
}); });
@ -411,7 +413,7 @@ define([
} }
var $create = $('<div>', {id: CREATE_ID}); var $create = $('<div>', {id: CREATE_ID});
var $button = $('<button>', {'class': 'btn btn-success'}); var $button = $('<button>', {'class': 'btn btn-success'});
$button.text('TODO: create a profile?').click(todo).appendTo($create); // XXX $button.text(Messages.profile_create).click(todo).appendTo($create);
APP.$container.append($create); APP.$container.append($create);
}; };

Loading…
Cancel
Save