Merge pull request #4503 from matrix-org/bwindels/customthemechanges

Support setting username and avatar colors in custom themes
pull/21833/head
Bruno Windels 2020-04-28 09:06:08 +00:00 committed by GitHub
commit 3d094ea542
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 74 additions and 6 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 169 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 171 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 170 B

View File

@ -17,6 +17,7 @@ limitations under the License.
//
// --accent-color
$accent-color: var(--accent-color);
$accent-bg-color: var(--accent-color-15pct);
$button-bg-color: var(--accent-color);
$button-link-fg-color: var(--accent-color);
$button-primary-bg-color: var(--accent-color);
@ -124,3 +125,12 @@ $notice-primary-color: var(--warning-color);
$pinned-unread-color: var(--warning-color);
$warning-color: var(--warning-color);
$button-danger-disabled-bg-color: var(--warning-color-50pct); // still needs alpha at 0.5
$username-variant1-color: var(--username-colors_1, $username-variant1-color);
$username-variant2-color: var(--username-colors_2, $username-variant2-color);
$username-variant3-color: var(--username-colors_3, $username-variant3-color);
$username-variant4-color: var(--username-colors_4, $username-variant4-color);
$username-variant5-color: var(--username-colors_5, $username-variant5-color);
$username-variant6-color: var(--username-colors_6, $username-variant6-color);
$username-variant7-color: var(--username-colors_7, $username-variant7-color);
$username-variant8-color: var(--username-colors_8, $username-variant8-color);

View File

@ -53,13 +53,56 @@ export function avatarUrlForUser(user, width, height, resizeMethod) {
return url;
}
function isValidHexColor(color) {
return typeof color === "string" &&
(color.length === 7 || color.lengh === 9) &&
color.charAt(0) === "#" &&
!color.substr(1).split("").some(c => isNaN(parseInt(c, 16)));
}
function urlForColor(color) {
const size = 40;
const canvas = document.createElement("canvas");
canvas.width = size;
canvas.height = size;
const ctx = canvas.getContext("2d");
// bail out when using jsdom in unit tests
if (!ctx) {
return "";
}
ctx.fillStyle = color;
ctx.fillRect(0, 0, size, size);
return canvas.toDataURL();
}
// XXX: Ideally we'd clear this cache when the theme changes
// but since this function is at global scope, it's a bit
// hard to install a listener here, even if there were a clear event to listen to
const colorToDataURLCache = new Map();
export function defaultAvatarUrlForString(s) {
const images = ['03b381', '368bd6', 'ac3ba8'];
const defaultColors = ['#03b381', '#368bd6', '#ac3ba8'];
let total = 0;
for (let i = 0; i < s.length; ++i) {
total += s.charCodeAt(i);
}
return require('../res/img/' + images[total % images.length] + '.png');
const colorIndex = total % defaultColors.length;
// overwritten color value in custom themes
const cssVariable = `--avatar-background-colors_${colorIndex}`;
const cssValue = document.body.style.getPropertyValue(cssVariable);
const color = cssValue || defaultColors[colorIndex];
let dataUrl = colorToDataURLCache.get(color);
if (!dataUrl) {
// validate color as this can come from account_data
// with custom theming
if (isValidHexColor(color)) {
dataUrl = urlForColor(color);
colorToDataURLCache.set(color, dataUrl);
} else {
dataUrl = "";
}
}
return dataUrl;
}
/**

View File

@ -141,16 +141,31 @@ export function enumerateThemes() {
return Object.assign({}, customThemeNames, BUILTIN_THEMES);
}
function setCustomThemeVars(customTheme) {
const {style} = document.body;
if (customTheme.colors) {
for (const [name, hexColor] of Object.entries(customTheme.colors)) {
style.setProperty(`--${name}`, hexColor);
// uses #rrggbbaa to define the color with alpha values at 0% and 50%
function setCSSVariable(name, hexColor, doPct = true) {
style.setProperty(`--${name}`, hexColor);
if (doPct) {
// uses #rrggbbaa to define the color with alpha values at 0%, 15% and 50%
style.setProperty(`--${name}-0pct`, hexColor + "00");
style.setProperty(`--${name}-15pct`, hexColor + "26");
style.setProperty(`--${name}-50pct`, hexColor + "7F");
}
}
if (customTheme.colors) {
for (const [name, value] of Object.entries(customTheme.colors)) {
if (Array.isArray(value)) {
for (let i = 0; i < value.length; i += 1) {
setCSSVariable(`${name}_${i}`, value[i], false);
}
} else {
setCSSVariable(name, value);
}
}
}
}
function getCustomTheme(themeName) {