MM-52280: Generate higher contrast for some usernames (#25073)
* MM-52280: Generate higher contrast for some usernames Keep 3 tries but return the best value instead of the last one Signed-off-by: Nicolas Le Cam <niko.lecam@gmail.com> * Try ten times to find the best contrast before giving up --------- Signed-off-by: Nicolas Le Cam <niko.lecam@gmail.com>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
375404c12e
Коммит
573e45691f
30
webapp/channels/src/components/user_profile/user.test.ts
Обычный файл
30
webapp/channels/src/components/user_profile/user.test.ts
Обычный файл
@@ -0,0 +1,30 @@
|
|||||||
|
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||||
|
// See LICENSE.txt for license information.
|
||||||
|
|
||||||
|
import ColorContrastChecker from 'color-contrast-checker';
|
||||||
|
|
||||||
|
import {cachedUserNameColors, generateColor} from './utils';
|
||||||
|
|
||||||
|
const CONSTRAST_CHECKER = new ColorContrastChecker();
|
||||||
|
const BACKGROUND_COLOR = '#ACC8E5';
|
||||||
|
|
||||||
|
describe('components/user_profile/utils', () => {
|
||||||
|
test.each([
|
||||||
|
['Ross_Bednar', '#432dd2', 4.5],
|
||||||
|
['Geovany95', '#2d3086', 4.5],
|
||||||
|
['Madisen25', '#52783a', 2.9],
|
||||||
|
['Gerard17', '#783a54', 4.5],
|
||||||
|
['Alia30', '#392d86', 4.5],
|
||||||
|
['Darien.Prosacco97', '#862d6d', 4.5],
|
||||||
|
['Alf48', '#4053bf', 3.7],
|
||||||
|
['Darron_Orn-Walsh49', '#742d86', 4.5],
|
||||||
|
])('should generate best color contrast', (userName, expected, ratio) => {
|
||||||
|
cachedUserNameColors.clear();
|
||||||
|
|
||||||
|
const actual = generateColor(userName, BACKGROUND_COLOR);
|
||||||
|
expect(actual).toBe(expected);
|
||||||
|
expect(
|
||||||
|
CONSTRAST_CHECKER.isLevelCustom(actual, BACKGROUND_COLOR, ratio),
|
||||||
|
).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -4,27 +4,44 @@
|
|||||||
import ColorContrastChecker from 'color-contrast-checker';
|
import ColorContrastChecker from 'color-contrast-checker';
|
||||||
import ColorHash from 'color-hash';
|
import ColorHash from 'color-hash';
|
||||||
|
|
||||||
const cachedColors = new Map<string, string>();
|
const REQUIRED_COLOR_RATIO = 4.5;
|
||||||
|
|
||||||
|
export const cachedUserNameColors = new Map<string, string>();
|
||||||
|
|
||||||
export function generateColor(username: string, background: string): string {
|
export function generateColor(username: string, background: string): string {
|
||||||
const cacheKey = `${username}-${background}`;
|
const cacheKey = `${username}-${background}`;
|
||||||
const cachedColor = cachedColors.get(cacheKey);
|
const cachedColor = cachedUserNameColors.get(cacheKey);
|
||||||
if (cachedColor) {
|
if (cachedColor) {
|
||||||
return cachedColor;
|
return cachedColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
let userColor = background;
|
let userColor = background;
|
||||||
|
let contrastRatio = 1;
|
||||||
let userAndSalt = username;
|
let userAndSalt = username;
|
||||||
const checker = new ColorContrastChecker();
|
const checker = new ColorContrastChecker();
|
||||||
const colorHash = new ColorHash();
|
const colorHash = new ColorHash();
|
||||||
|
|
||||||
let tries = 3;
|
const backgroundLuminance = checker.hexToLuminance(background);
|
||||||
while (!checker.isLevelCustom(userColor, background, 4.5) && tries > 0) {
|
for (let tries = 10; tries > 0; tries--) {
|
||||||
userColor = colorHash.hex(userAndSalt);
|
const textColor = colorHash.hex(userAndSalt);
|
||||||
|
|
||||||
|
const cr = checker.getContrastRatio(
|
||||||
|
checker.hexToLuminance(textColor),
|
||||||
|
backgroundLuminance,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (cr > contrastRatio) {
|
||||||
|
userColor = textColor;
|
||||||
|
contrastRatio = cr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cr >= REQUIRED_COLOR_RATIO) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
userAndSalt += 'salt';
|
userAndSalt += 'salt';
|
||||||
tries--;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cachedColors.set(cacheKey, userColor);
|
cachedUserNameColors.set(cacheKey, userColor);
|
||||||
return userColor;
|
return userColor;
|
||||||
}
|
}
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user