mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-11-08 06:55:46 +01:00
WIP user-icons
This commit is contained in:
@@ -17,9 +17,11 @@
|
|||||||
max-width: 125px;
|
max-width: 125px;
|
||||||
min-width: 125px;
|
min-width: 125px;
|
||||||
|
|
||||||
img {
|
img, .user-icon {
|
||||||
width:80px;
|
width:80px;
|
||||||
height:80px;
|
height:80px;
|
||||||
|
line-height: 80px;
|
||||||
|
font-size: 4rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
|
|||||||
@@ -29,10 +29,13 @@
|
|||||||
background: #eee;
|
background: #eee;
|
||||||
}
|
}
|
||||||
|
|
||||||
img {
|
img, .user-icon {
|
||||||
float: left;
|
float: left;
|
||||||
max-width: 36px;
|
height: 36px;
|
||||||
padding-right: 1rem;
|
width: 36px;
|
||||||
|
margin-right: 1rem;
|
||||||
|
line-height: 36px;
|
||||||
|
font-size: 1.8rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
span {
|
span {
|
||||||
@@ -41,3 +44,17 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.user-icon {
|
||||||
|
display: inline-block;
|
||||||
|
text-align: center;
|
||||||
|
color: @gray-lighter;
|
||||||
|
font-weight: normal;
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
content: '';
|
||||||
|
display: inline-block;
|
||||||
|
height: 100%;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -138,7 +138,9 @@ app.cacheBuster = null;
|
|||||||
username: app.user.username,
|
username: app.user.username,
|
||||||
userslug: app.user.userslug,
|
userslug: app.user.userslug,
|
||||||
picture: app.user.picture,
|
picture: app.user.picture,
|
||||||
status: app.user.status
|
status: app.user.status,
|
||||||
|
'icon:bgColor': app.user['icon:bgColor'],
|
||||||
|
'icon:text': app.user['icon:text']
|
||||||
}, function(err) {
|
}, function(err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
app.alertError(err.message);
|
app.alertError(err.message);
|
||||||
@@ -158,7 +160,7 @@ app.cacheBuster = null;
|
|||||||
}
|
}
|
||||||
|
|
||||||
app.createUserTooltips = function() {
|
app.createUserTooltips = function() {
|
||||||
$('img[title].teaser-pic,img[title].user-img').each(function() {
|
$('img[title].teaser-pic,img[title].user-img,div.user-icon').each(function() {
|
||||||
$(this).tooltip({
|
$(this).tooltip({
|
||||||
placement: 'top',
|
placement: 'top',
|
||||||
title: $(this).attr('title')
|
title: $(this).attr('title')
|
||||||
|
|||||||
@@ -71,8 +71,9 @@ define('forum/topic/browsing', function() {
|
|||||||
if (!user.userslug) {
|
if (!user.userslug) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
console.log(user);
|
||||||
var browsingList = $('[component="topic/browsing/list"]');
|
var browsingList = $('[component="topic/browsing/list"]');
|
||||||
var userEl = createUserIcon(user.uid, user.picture, user.userslug, user.username);
|
var userEl = createUserIcon(user.uid, user.picture, user.userslug, user.username, user['icon:bgColor'], user['icon:text']);
|
||||||
var isSelf = parseInt(user.uid, 10) === parseInt(app.user.uid, 10);
|
var isSelf = parseInt(user.uid, 10) === parseInt(app.user.uid, 10);
|
||||||
if (isSelf) {
|
if (isSelf) {
|
||||||
browsingList.prepend(userEl);
|
browsingList.prepend(userEl);
|
||||||
@@ -85,9 +86,14 @@ define('forum/topic/browsing', function() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function createUserIcon(uid, picture, userslug, username) {
|
function createUserIcon(uid, picture, userslug, username, iconBg, iconText) {
|
||||||
if (!$('[component="topic/browsing/list"]').find('[data-uid="' + uid + '"]').length) {
|
if (!$('[component="topic/browsing/list"]').find('[data-uid="' + uid + '"]').length) {
|
||||||
return $('<div class="inline-block"><a title="' + username + '" data-uid="' + uid + '" data-count="1" href="' + config.relative_path + '/user/' + userslug + '"><img src="'+ picture +'"/></a></div>');
|
console.log(iconBg, iconText);
|
||||||
|
var imgOrIcon = picture ?
|
||||||
|
'<img src="'+ picture +'" />' :
|
||||||
|
'<div class="user-icon" style="background-color: ' + iconBg + ';">' + iconText + '</div>';
|
||||||
|
|
||||||
|
return $('<div class="inline-block"><a title="' + username + '" data-uid="' + uid + '" data-count="1" href="' + config.relative_path + '/user/' + userslug + '">' + imgOrIcon + '</a></div>');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -161,6 +161,14 @@
|
|||||||
return locale.replace('_', '-');
|
return locale.replace('_', '-');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
helpers.renderTopicImage = function(topicObj) {
|
||||||
|
if (topicObj.thumb) {
|
||||||
|
return '<img src="' + topicObj.thumb + '" class="img-circle user-img" title="' + topicObj.user.username + '" />';
|
||||||
|
} else {
|
||||||
|
return '<img src="' + topicObj.user.picture + '" class="user-img" title="' + topicObj.user.username + '" />';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
exports.register = function() {
|
exports.register = function() {
|
||||||
var templates;
|
var templates;
|
||||||
|
|
||||||
|
|||||||
@@ -240,7 +240,7 @@ module.exports = function(Groups) {
|
|||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
user.getUsersFields(uids, ['uid', 'username', 'picture', 'userslug'], next);
|
user.getUsersFields(uids, ['uid', 'username', 'picture', 'userslug', 'icon:bgColor', 'icon:text'], next);
|
||||||
});
|
});
|
||||||
}, callback);
|
}, callback);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -244,7 +244,7 @@ middleware.renderHeader = function(req, res, data, callback) {
|
|||||||
},
|
},
|
||||||
user: function(next) {
|
user: function(next) {
|
||||||
if (req.uid) {
|
if (req.uid) {
|
||||||
user.getUserFields(req.uid, ['username', 'userslug', 'email', 'picture', 'status', 'email:confirmed', 'banned'], next);
|
user.getUserFields(req.uid, ['username', 'userslug', 'email', 'picture', 'status', 'email:confirmed', 'banned', 'icon:bgColor', 'icon:text'], next);
|
||||||
} else {
|
} else {
|
||||||
next(null, {
|
next(null, {
|
||||||
username: '[[global:guest]]',
|
username: '[[global:guest]]',
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ module.exports = function(Posts) {
|
|||||||
|
|
||||||
async.parallel({
|
async.parallel({
|
||||||
users: function(next) {
|
users: function(next) {
|
||||||
user.getUsersFields(uids, ['uid', 'username', 'userslug', 'picture'], next);
|
user.getUsersFields(uids, ['uid', 'username', 'userslug', 'picture', 'icon:bgColor', 'icon:text'], next);
|
||||||
},
|
},
|
||||||
topicsAndCategories: function(next) {
|
topicsAndCategories: function(next) {
|
||||||
getTopicAndCategories(topicKeys, next);
|
getTopicAndCategories(topicKeys, next);
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ module.exports = function(Posts) {
|
|||||||
user.getMultipleUserSettings(uids, next);
|
user.getMultipleUserSettings(uids, next);
|
||||||
},
|
},
|
||||||
userData: function(next) {
|
userData: function(next) {
|
||||||
user.getUsersFields(uids, ['uid', 'username', 'userslug', 'reputation', 'postcount', 'picture', 'signature', 'banned', 'status'], next);
|
user.getUsersFields(uids, ['uid', 'username', 'userslug', 'reputation', 'postcount', 'picture', 'signature', 'banned', 'status', 'icon:bgColor', 'icon:text'], next);
|
||||||
},
|
},
|
||||||
online: function(next) {
|
online: function(next) {
|
||||||
require('../socket.io').isUsersOnline(uids, next);
|
require('../socket.io').isUsersOnline(uids, next);
|
||||||
@@ -55,7 +55,7 @@ module.exports = function(Posts) {
|
|||||||
userData.reputation = userData.reputation || 0;
|
userData.reputation = userData.reputation || 0;
|
||||||
userData.postcount = userData.postcount || 0;
|
userData.postcount = userData.postcount || 0;
|
||||||
userData.banned = parseInt(userData.banned, 10) === 1;
|
userData.banned = parseInt(userData.banned, 10) === 1;
|
||||||
userData.picture = userData.picture || user.createGravatarURLFromEmail('');
|
userData.picture = userData.picture || '';
|
||||||
|
|
||||||
async.parallel({
|
async.parallel({
|
||||||
signature: function(next) {
|
signature: function(next) {
|
||||||
|
|||||||
@@ -281,7 +281,7 @@ Sockets.getUsersInRoom = function (uid, roomName, start, stop, callback) {
|
|||||||
if (!uids.length) {
|
if (!uids.length) {
|
||||||
return callback(null, {users: [], total: 0 , room: roomName});
|
return callback(null, {users: [], total: 0 , room: roomName});
|
||||||
}
|
}
|
||||||
user.getUsersFields(uids, ['uid', 'username', 'userslug', 'picture', 'status'], function(err, users) {
|
user.getUsersFields(uids, ['uid', 'username', 'userslug', 'picture', 'status', 'icon:bgColor', 'icon:text'], function(err, users) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var nconf = require('nconf'),
|
var nconf = require('nconf'),
|
||||||
gravatar = require('gravatar'),
|
|
||||||
winston = require('winston'),
|
winston = require('winston'),
|
||||||
validator = require('validator'),
|
validator = require('validator'),
|
||||||
|
|
||||||
|
|||||||
@@ -18,12 +18,12 @@ module.exports = function(SocketUser) {
|
|||||||
|
|
||||||
var type = data.type;
|
var type = data.type;
|
||||||
|
|
||||||
if (type === 'gravatar') {
|
if (type === 'default') {
|
||||||
type = 'gravatarpicture';
|
type = null;
|
||||||
} else if (type === 'uploaded') {
|
} else if (type === 'uploaded') {
|
||||||
type = 'uploadedpicture';
|
type = 'uploadedpicture';
|
||||||
} else {
|
} else {
|
||||||
return callback(new Error('[[error:invalid-image-type, ' + ['gravatar', 'uploadedpicture'].join(', ') + ']]'));
|
return callback(new Error('[[error:invalid-image-type, ' + ['default', 'uploadedpicture'].join(', ') + ']]'));
|
||||||
}
|
}
|
||||||
|
|
||||||
async.waterfall([
|
async.waterfall([
|
||||||
@@ -31,6 +31,9 @@ module.exports = function(SocketUser) {
|
|||||||
SocketUser.isAdminOrSelf(socket, data.uid, next);
|
SocketUser.isAdminOrSelf(socket, data.uid, next);
|
||||||
},
|
},
|
||||||
function (next) {
|
function (next) {
|
||||||
|
if (!type) {
|
||||||
|
next(null, '');
|
||||||
|
}
|
||||||
user.getUserField(data.uid, type, next);
|
user.getUserField(data.uid, type, next);
|
||||||
},
|
},
|
||||||
function (picture, next) {
|
function (picture, next) {
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ var async = require('async'),
|
|||||||
|
|
||||||
async.parallel({
|
async.parallel({
|
||||||
users: function(next) {
|
users: function(next) {
|
||||||
user.getUsersFields(uids, ['uid', 'username', 'userslug', 'picture'], next);
|
user.getUsersFields(uids, ['uid', 'username', 'userslug', 'picture', 'icon:bgColor', 'icon:text'], next);
|
||||||
},
|
},
|
||||||
categories: function(next) {
|
categories: function(next) {
|
||||||
categories.getCategoriesFields(cids, ['cid', 'name', 'slug', 'icon', 'bgColor', 'color', 'disabled'], next);
|
categories.getCategoriesFields(cids, ['cid', 'name', 'slug', 'icon', 'bgColor', 'color', 'disabled'], next);
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ var async = require('async'),
|
|||||||
require('./user/picture')(User);
|
require('./user/picture')(User);
|
||||||
require('./user/approval')(User);
|
require('./user/approval')(User);
|
||||||
require('./user/invite')(User);
|
require('./user/invite')(User);
|
||||||
|
require('./user/icon')(User);
|
||||||
|
|
||||||
User.updateLastOnlineTime = function(uid, callback) {
|
User.updateLastOnlineTime = function(uid, callback) {
|
||||||
callback = callback || function() {};
|
callback = callback || function() {};
|
||||||
@@ -93,7 +94,7 @@ var async = require('async'),
|
|||||||
};
|
};
|
||||||
|
|
||||||
User.getUsers = function(uids, uid, callback) {
|
User.getUsers = function(uids, uid, callback) {
|
||||||
var fields = ['uid', 'username', 'userslug', 'picture', 'status', 'banned', 'joindate', 'postcount', 'reputation', 'email:confirmed'];
|
var fields = ['uid', 'username', 'userslug', 'picture', 'icon:bgColor', 'icon:text', 'status', 'banned', 'joindate', 'postcount', 'reputation', 'email:confirmed'];
|
||||||
plugins.fireHook('filter:users.addFields', {fields: fields}, function(err, data) {
|
plugins.fireHook('filter:users.addFields', {fields: fields}, function(err, data) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return callback(err);
|
return callback(err);
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ module.exports = function(User) {
|
|||||||
if (err) {
|
if (err) {
|
||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
}
|
||||||
var gravatar = User.createGravatarURLFromEmail(data.email);
|
|
||||||
var timestamp = data.timestamp || Date.now();
|
var timestamp = data.timestamp || Date.now();
|
||||||
|
|
||||||
var userData = {
|
var userData = {
|
||||||
@@ -32,8 +31,7 @@ module.exports = function(User) {
|
|||||||
'userslug': data.userslug,
|
'userslug': data.userslug,
|
||||||
'email': data.email,
|
'email': data.email,
|
||||||
'joindate': timestamp,
|
'joindate': timestamp,
|
||||||
'picture': gravatar,
|
'picture': '',
|
||||||
'gravatarpicture': gravatar,
|
|
||||||
'fullname': '',
|
'fullname': '',
|
||||||
'location': '',
|
'location': '',
|
||||||
'birthday': '',
|
'birthday': '',
|
||||||
@@ -128,7 +126,8 @@ module.exports = function(User) {
|
|||||||
async.apply(User.reset.updateExpiry, userData.uid)
|
async.apply(User.reset.updateExpiry, userData.uid)
|
||||||
], next);
|
], next);
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
|
async.apply(User.icon.generate, userData.uid)
|
||||||
], next);
|
], next);
|
||||||
},
|
},
|
||||||
function(results, next) {
|
function(results, next) {
|
||||||
|
|||||||
@@ -44,7 +44,6 @@ module.exports = function(User) {
|
|||||||
|
|
||||||
if (fields.indexOf('picture') !== -1) {
|
if (fields.indexOf('picture') !== -1) {
|
||||||
addField('email');
|
addField('email');
|
||||||
addField('gravatarpicture');
|
|
||||||
addField('uploadedpicture');
|
addField('uploadedpicture');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,15 +101,11 @@ module.exports = function(User) {
|
|||||||
user.uid = 0;
|
user.uid = 0;
|
||||||
user.username = '[[global:guest]]';
|
user.username = '[[global:guest]]';
|
||||||
user.userslug = '';
|
user.userslug = '';
|
||||||
user.picture = User.createGravatarURLFromEmail('');
|
user.picture = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user.picture) {
|
if (user.picture && user.picture === user.uploadedpicture) {
|
||||||
if (user.picture === user.uploadedpicture) {
|
user.picture = user.uploadedpicture = user.picture.startsWith('http') ? user.picture : nconf.get('relative_path') + user.picture;
|
||||||
user.picture = user.uploadedpicture = user.picture.startsWith('http') ? user.picture : nconf.get('relative_path') + user.picture;
|
|
||||||
} else {
|
|
||||||
user.picture = User.createGravatarURLFromEmail(user.email);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for(var i=0; i<fieldsToRemove.length; ++i) {
|
for(var i=0; i<fieldsToRemove.length; ++i) {
|
||||||
|
|||||||
20
src/user/icon.js
Normal file
20
src/user/icon.js
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
var async = require('async');
|
||||||
|
|
||||||
|
module.exports = function(User) {
|
||||||
|
User.icon = {};
|
||||||
|
|
||||||
|
User.icon.generate = function(uid, callback) {
|
||||||
|
// For convenience, only backgrounds that work well with white as used
|
||||||
|
var backgrounds = ['#AB4642', '#DC9656', '#A1B56C', '#7CAFC2', '#BA8BAF', '#A16946'],
|
||||||
|
bgColor = backgrounds[Math.floor(Math.random() * backgrounds.length) + 1];
|
||||||
|
|
||||||
|
User.getUserField(uid, 'username', function(err, username) {
|
||||||
|
User.setUserFields(uid, {
|
||||||
|
'icon:text': username.slice(0, 1).toUpperCase(),
|
||||||
|
'icon:bgColor': bgColor
|
||||||
|
}, callback);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -110,7 +110,7 @@ module.exports = function(User) {
|
|||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
}
|
||||||
plugins.fireHook('action:user.updateProfile', {data: data, uid: uid});
|
plugins.fireHook('action:user.updateProfile', {data: data, uid: uid});
|
||||||
User.getUserFields(uid, ['email', 'username', 'userslug', 'picture', 'gravatarpicture'], callback);
|
User.getUserFields(uid, ['email', 'username', 'userslug', 'picture'], callback);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -155,11 +155,7 @@ module.exports = function(User) {
|
|||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
var gravatarpicture = User.createGravatarURLFromEmail(newEmail);
|
|
||||||
async.parallel([
|
async.parallel([
|
||||||
function(next) {
|
|
||||||
User.setUserField(uid, 'gravatarpicture', gravatarpicture, next);
|
|
||||||
},
|
|
||||||
function(next) {
|
function(next) {
|
||||||
db.sortedSetAdd('email:uid', uid, newEmail.toLowerCase(), next);
|
db.sortedSetAdd('email:uid', uid, newEmail.toLowerCase(), next);
|
||||||
},
|
},
|
||||||
@@ -174,14 +170,7 @@ module.exports = function(User) {
|
|||||||
User.email.sendValidationEmail(uid, newEmail);
|
User.email.sendValidationEmail(uid, newEmail);
|
||||||
}
|
}
|
||||||
User.setUserField(uid, 'email:confirmed', 0, next);
|
User.setUserField(uid, 'email:confirmed', 0, next);
|
||||||
},
|
}
|
||||||
function(next) {
|
|
||||||
if (userData.picture !== userData.uploadedpicture) {
|
|
||||||
User.setUserField(uid, 'picture', gravatarpicture, next);
|
|
||||||
} else {
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
], callback);
|
], callback);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -65,7 +65,11 @@
|
|||||||
<ul class="members current_members user-list">
|
<ul class="members current_members user-list">
|
||||||
<!-- BEGIN group.members -->
|
<!-- BEGIN group.members -->
|
||||||
<li data-uid="{group.members.uid}">
|
<li data-uid="{group.members.uid}">
|
||||||
|
<!-- IF group.members.picture -->
|
||||||
<img src="{group.members.picture}" />
|
<img src="{group.members.picture}" />
|
||||||
|
<!-- ELSE -->
|
||||||
|
<div class="user-icon" style="background-color: {group.members.icon:bgColor};">{group.members.icon:text}</div>
|
||||||
|
<!-- ENDIF group.members.picture -->
|
||||||
<span>{group.members.username}</span>
|
<span>{group.members.username}</span>
|
||||||
</li>
|
</li>
|
||||||
<!-- END group.members -->
|
<!-- END group.members -->
|
||||||
|
|||||||
@@ -51,7 +51,11 @@
|
|||||||
<!-- BEGIN users -->
|
<!-- BEGIN users -->
|
||||||
<div class="users-box" data-uid="{users.uid}" data-username="{users.username}">
|
<div class="users-box" data-uid="{users.uid}" data-username="{users.username}">
|
||||||
<div class="user-image">
|
<div class="user-image">
|
||||||
|
<!-- IF users.picture -->
|
||||||
<img src="{users.picture}" class="img-thumbnail user-selectable"/>
|
<img src="{users.picture}" class="img-thumbnail user-selectable"/>
|
||||||
|
<!-- ELSE -->
|
||||||
|
<div class="user-icon user-selectable" style="background-color: {users.icon:bgColor};">{users.icon:text}</div>
|
||||||
|
<!-- ENDIF users.picture -->
|
||||||
<div class="labels">
|
<div class="labels">
|
||||||
<!-- IF config.requireEmailConfirmation -->
|
<!-- IF config.requireEmailConfirmation -->
|
||||||
<!-- IF !users.email:confirmed -->
|
<!-- IF !users.email:confirmed -->
|
||||||
|
|||||||
@@ -282,6 +282,23 @@ describe('User', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('User.icon.generate()', function() {
|
||||||
|
it('should add icon text and bgColor fields to user hash', function(done) {
|
||||||
|
var backgrounds = ['#AB4642', '#DC9656', '#A1B56C', '#7CAFC2', '#BA8BAF', '#A16946'];
|
||||||
|
|
||||||
|
User.icon.generate(1, function(err) {
|
||||||
|
assert.ifError(err);
|
||||||
|
|
||||||
|
User.getUserFields(1, ['icon:text', 'icon:bgColor'], function(err, fields) {
|
||||||
|
assert.strictEquals('J', fields[0]);
|
||||||
|
assert(backgrounds.indexOf(fields[1]) !== -1);
|
||||||
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
after(function() {
|
after(function() {
|
||||||
db.flushdb();
|
db.flushdb();
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user