mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-26 16:46:12 +01:00
perf: call getIconbackgrounds once
instead of 20x on topic/topic list load
This commit is contained in:
@@ -331,6 +331,12 @@ UserObjectFull:
|
|||||||
example:
|
example:
|
||||||
- administrators
|
- administrators
|
||||||
- Staff
|
- Staff
|
||||||
|
iconBackgrounds:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
description: A valid CSS colour code
|
||||||
|
example: '#fff'
|
||||||
muted:
|
muted:
|
||||||
type: boolean
|
type: boolean
|
||||||
description: Whether or not the user has been muted.
|
description: Whether or not the user has been muted.
|
||||||
|
|||||||
@@ -152,12 +152,6 @@ get:
|
|||||||
type: boolean
|
type: boolean
|
||||||
enableQuickReply:
|
enableQuickReply:
|
||||||
type: boolean
|
type: boolean
|
||||||
iconBackgrounds:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
description: A valid CSS colour code
|
|
||||||
example: '#fff'
|
|
||||||
emailPrompt:
|
emailPrompt:
|
||||||
type: number
|
type: number
|
||||||
useragent:
|
useragent:
|
||||||
|
|||||||
@@ -152,12 +152,6 @@ get:
|
|||||||
type: boolean
|
type: boolean
|
||||||
enableQuickReply:
|
enableQuickReply:
|
||||||
type: boolean
|
type: boolean
|
||||||
iconBackgrounds:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
description: A valid CSS colour code
|
|
||||||
example: '#fff'
|
|
||||||
emailPrompt:
|
emailPrompt:
|
||||||
type: number
|
type: number
|
||||||
useragent:
|
useragent:
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ define('accounts/picture', [
|
|||||||
icon: { text: ajaxify.data['icon:text'], bgColor: ajaxify.data['icon:bgColor'] },
|
icon: { text: ajaxify.data['icon:text'], bgColor: ajaxify.data['icon:bgColor'] },
|
||||||
defaultAvatar: ajaxify.data.defaultAvatar,
|
defaultAvatar: ajaxify.data.defaultAvatar,
|
||||||
allowProfileImageUploads: ajaxify.data.allowProfileImageUploads,
|
allowProfileImageUploads: ajaxify.data.allowProfileImageUploads,
|
||||||
iconBackgrounds: config.iconBackgrounds,
|
iconBackgrounds: ajaxify.data.iconBackgrounds,
|
||||||
user: {
|
user: {
|
||||||
uid: ajaxify.data.uid,
|
uid: ajaxify.data.uid,
|
||||||
username: ajaxify.data.username,
|
username: ajaxify.data.username,
|
||||||
|
|||||||
@@ -656,7 +656,7 @@ usersAPI.changePicture = async (caller, data) => {
|
|||||||
picture = returnData && returnData.picture;
|
picture = returnData && returnData.picture;
|
||||||
}
|
}
|
||||||
|
|
||||||
const validBackgrounds = await user.getIconBackgrounds(caller.uid);
|
const validBackgrounds = await user.getIconBackgrounds();
|
||||||
if (!validBackgrounds.includes(data.bgColor)) {
|
if (!validBackgrounds.includes(data.bgColor)) {
|
||||||
data.bgColor = validBackgrounds[0];
|
data.bgColor = validBackgrounds[0];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,11 +32,7 @@ helpers.getUserDataByUserSlug = async function (userslug, callerUID, query = {})
|
|||||||
await parseAboutMe(results.userData);
|
await parseAboutMe(results.userData);
|
||||||
|
|
||||||
let { userData } = results;
|
let { userData } = results;
|
||||||
const { userSettings } = results;
|
const { userSettings, isAdmin, isGlobalModerator, isModerator, canViewInfo } = results;
|
||||||
const { isAdmin } = results;
|
|
||||||
const { isGlobalModerator } = results;
|
|
||||||
const { isModerator } = results;
|
|
||||||
const { canViewInfo } = results;
|
|
||||||
const isSelf = parseInt(callerUID, 10) === parseInt(userData.uid, 10);
|
const isSelf = parseInt(callerUID, 10) === parseInt(userData.uid, 10);
|
||||||
|
|
||||||
if (meta.config['reputation:disabled']) {
|
if (meta.config['reputation:disabled']) {
|
||||||
@@ -84,6 +80,7 @@ helpers.getUserDataByUserSlug = async function (userslug, callerUID, query = {})
|
|||||||
userData.isFollowing = results.isFollowing;
|
userData.isFollowing = results.isFollowing;
|
||||||
userData.canChat = results.canChat;
|
userData.canChat = results.canChat;
|
||||||
userData.hasPrivateChat = results.hasPrivateChat;
|
userData.hasPrivateChat = results.hasPrivateChat;
|
||||||
|
userData.iconBackgrounds = results.iconBackgrounds;
|
||||||
userData.showHidden = results.canEdit; // remove in v1.19.0
|
userData.showHidden = results.canEdit; // remove in v1.19.0
|
||||||
userData.allowProfilePicture = !userData.isSelf || !!meta.config['reputation:disabled'] || userData.reputation >= meta.config['min:rep:profile-picture'];
|
userData.allowProfilePicture = !userData.isSelf || !!meta.config['reputation:disabled'] || userData.reputation >= meta.config['min:rep:profile-picture'];
|
||||||
userData.allowCoverPicture = !userData.isSelf || !!meta.config['reputation:disabled'] || userData.reputation >= meta.config['min:rep:cover-picture'];
|
userData.allowCoverPicture = !userData.isSelf || !!meta.config['reputation:disabled'] || userData.reputation >= meta.config['min:rep:cover-picture'];
|
||||||
@@ -160,6 +157,7 @@ async function getAllData(uid, callerUID) {
|
|||||||
canViewInfo: privileges.global.can('view:users:info', callerUID),
|
canViewInfo: privileges.global.can('view:users:info', callerUID),
|
||||||
canChat: canChat(callerUID, uid),
|
canChat: canChat(callerUID, uid),
|
||||||
hasPrivateChat: messaging.hasPrivateChat(callerUID, uid),
|
hasPrivateChat: messaging.hasPrivateChat(callerUID, uid),
|
||||||
|
iconBackgrounds: user.getIconBackgrounds(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -88,7 +88,6 @@ apiController.loadConfig = async function (req) {
|
|||||||
thumbs: {
|
thumbs: {
|
||||||
size: meta.config.topicThumbSize,
|
size: meta.config.topicThumbSize,
|
||||||
},
|
},
|
||||||
iconBackgrounds: await user.getIconBackgrounds(req.uid),
|
|
||||||
emailPrompt: meta.config.emailPrompt,
|
emailPrompt: meta.config.emailPrompt,
|
||||||
useragent: req.useragent,
|
useragent: req.useragent,
|
||||||
fontawesome: {
|
fontawesome: {
|
||||||
|
|||||||
@@ -44,6 +44,8 @@ module.exports = function (User) {
|
|||||||
'email:confirmed': 0,
|
'email:confirmed': 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let iconBackgrounds;
|
||||||
|
|
||||||
User.getUsersFields = async function (uids, fields) {
|
User.getUsersFields = async function (uids, fields) {
|
||||||
if (!Array.isArray(uids) || !uids.length) {
|
if (!Array.isArray(uids) || !uids.length) {
|
||||||
return [];
|
return [];
|
||||||
@@ -187,8 +189,11 @@ module.exports = function (User) {
|
|||||||
['showfullname']
|
['showfullname']
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
if (!iconBackgrounds) {
|
||||||
|
iconBackgrounds = await User.getIconBackgrounds();
|
||||||
|
}
|
||||||
|
|
||||||
await Promise.all(users.map(async (user) => {
|
users.forEach((user) => {
|
||||||
if (!user) {
|
if (!user) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -204,7 +209,7 @@ module.exports = function (User) {
|
|||||||
user.email = validator.escape(user.email ? user.email.toString() : '');
|
user.email = validator.escape(user.email ? user.email.toString() : '');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!parseInt(user.uid, 10)) {
|
if (!user.uid) {
|
||||||
for (const [key, value] of Object.entries(User.guestData)) {
|
for (const [key, value] of Object.entries(User.guestData)) {
|
||||||
user[key] = value;
|
user[key] = value;
|
||||||
}
|
}
|
||||||
@@ -234,15 +239,12 @@ module.exports = function (User) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// User Icons
|
// User Icons
|
||||||
if (requestedFields.includes('picture') && user.username && parseInt(user.uid, 10) && !meta.config.defaultAvatar) {
|
if (requestedFields.includes('picture') && user.username && user.uid && !meta.config.defaultAvatar) {
|
||||||
const iconBackgrounds = await User.getIconBackgrounds(user.uid);
|
if (!iconBackgrounds.includes(user['icon:bgColor'])) {
|
||||||
let bgColor = await User.getUserField(user.uid, 'icon:bgColor');
|
const nameAsIndex = Array.from(user.username).reduce((cur, next) => cur + next.charCodeAt(), 0);
|
||||||
if (!iconBackgrounds.includes(bgColor)) {
|
user['icon:bgColor'] = iconBackgrounds[nameAsIndex % iconBackgrounds.length];
|
||||||
bgColor = Array.prototype.reduce.call(user.username, (cur, next) => cur + next.charCodeAt(), 0);
|
|
||||||
bgColor = iconBackgrounds[bgColor % iconBackgrounds.length];
|
|
||||||
}
|
}
|
||||||
user['icon:text'] = (user.username[0] || '').toUpperCase();
|
user['icon:text'] = (user.username[0] || '').toUpperCase();
|
||||||
user['icon:bgColor'] = bgColor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user.hasOwnProperty('joindate')) {
|
if (user.hasOwnProperty('joindate')) {
|
||||||
@@ -253,6 +255,14 @@ module.exports = function (User) {
|
|||||||
user.lastonlineISO = utils.toISOString(user.lastonline) || user.joindateISO;
|
user.lastonlineISO = utils.toISOString(user.lastonline) || user.joindateISO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (user.hasOwnProperty('mutedUntil')) {
|
||||||
|
user.muted = user.mutedUntil > Date.now();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// TODO get rid of single calls
|
||||||
|
// dont do anything if user is not banned?
|
||||||
|
await Promise.all(users.map(async (user) => {
|
||||||
if (user.hasOwnProperty('banned') || user.hasOwnProperty('banned:expire')) {
|
if (user.hasOwnProperty('banned') || user.hasOwnProperty('banned:expire')) {
|
||||||
const result = await User.bans.calcExpiredFromUserData(user);
|
const result = await User.bans.calcExpiredFromUserData(user);
|
||||||
user.banned = result.banned;
|
user.banned = result.banned;
|
||||||
@@ -264,10 +274,6 @@ module.exports = function (User) {
|
|||||||
user.banned = false;
|
user.banned = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user.hasOwnProperty('mutedUntil')) {
|
|
||||||
user.muted = user.mutedUntil > Date.now();
|
|
||||||
}
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
return await plugins.hooks.fire('filter:users.get', users);
|
return await plugins.hooks.fire('filter:users.get', users);
|
||||||
@@ -313,14 +319,20 @@ module.exports = function (User) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
User.getIconBackgrounds = async (uid = 0) => {
|
|
||||||
let iconBackgrounds = [
|
User.getIconBackgrounds = async () => {
|
||||||
|
if (iconBackgrounds) {
|
||||||
|
return iconBackgrounds;
|
||||||
|
}
|
||||||
|
|
||||||
|
const _iconBackgrounds = [
|
||||||
'#f44336', '#e91e63', '#9c27b0', '#673ab7', '#3f51b5', '#2196f3',
|
'#f44336', '#e91e63', '#9c27b0', '#673ab7', '#3f51b5', '#2196f3',
|
||||||
'#009688', '#1b5e20', '#33691e', '#827717', '#e65100', '#ff5722',
|
'#009688', '#1b5e20', '#33691e', '#827717', '#e65100', '#ff5722',
|
||||||
'#795548', '#607d8b',
|
'#795548', '#607d8b',
|
||||||
];
|
];
|
||||||
|
|
||||||
({ iconBackgrounds } = await plugins.hooks.fire('filter:user.iconBackgrounds', { uid, iconBackgrounds }));
|
const data = await plugins.hooks.fire('filter:user.iconBackgrounds', { iconBackgrounds: _iconBackgrounds });
|
||||||
|
iconBackgrounds = data.iconBackgrounds;
|
||||||
return iconBackgrounds;
|
return iconBackgrounds;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -607,7 +607,7 @@ describe('User', () => {
|
|||||||
|
|
||||||
it('should return an icon text and valid background if username and picture is explicitly requested', async () => {
|
it('should return an icon text and valid background if username and picture is explicitly requested', async () => {
|
||||||
const payload = await User.getUserFields(testUid, ['username', 'picture']);
|
const payload = await User.getUserFields(testUid, ['username', 'picture']);
|
||||||
const validBackgrounds = await User.getIconBackgrounds(testUid);
|
const validBackgrounds = await User.getIconBackgrounds();
|
||||||
assert.strictEqual(payload['icon:text'], userData.username.slice(0, 1).toUpperCase());
|
assert.strictEqual(payload['icon:text'], userData.username.slice(0, 1).toUpperCase());
|
||||||
assert(payload['icon:bgColor']);
|
assert(payload['icon:bgColor']);
|
||||||
assert(validBackgrounds.includes(payload['icon:bgColor']));
|
assert(validBackgrounds.includes(payload['icon:bgColor']));
|
||||||
@@ -616,7 +616,7 @@ describe('User', () => {
|
|||||||
it('should return a valid background, even if an invalid background colour is set', async () => {
|
it('should return a valid background, even if an invalid background colour is set', async () => {
|
||||||
await User.setUserField(testUid, 'icon:bgColor', 'teal');
|
await User.setUserField(testUid, 'icon:bgColor', 'teal');
|
||||||
const payload = await User.getUserFields(testUid, ['username', 'picture']);
|
const payload = await User.getUserFields(testUid, ['username', 'picture']);
|
||||||
const validBackgrounds = await User.getIconBackgrounds(testUid);
|
const validBackgrounds = await User.getIconBackgrounds();
|
||||||
|
|
||||||
assert(payload['icon:bgColor']);
|
assert(payload['icon:bgColor']);
|
||||||
assert(validBackgrounds.includes(payload['icon:bgColor']));
|
assert(validBackgrounds.includes(payload['icon:bgColor']));
|
||||||
|
|||||||
Reference in New Issue
Block a user