Skip to content

Commit 8188323

Browse files
authored
Merge pull request #6657 from nextcloud-libraries/refactor/username-to-color
refactor: drop `md5` dependency for `usernameToColor` and migrate to TS
2 parents 219a455 + 7dac7b5 commit 8188323

File tree

10 files changed

+90
-140
lines changed

10 files changed

+90
-140
lines changed

REUSE.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ SPDX-License-Identifier = "AGPL-3.0-or-later"
1414
[[annotations]]
1515
path = [
1616
"styleguide/assets/apps.css", "styleguide/assets/dark.css", "styleguide/assets/icons.css", "styleguide/assets/server.css",
17-
"tests/unit/functions/usernameToColor/__snapshots__/usernameToColor.spec.js.snap",
17+
"tests/unit/functions/usernameToColor/__snapshots__/usernameToColor.spec.ts.snap",
1818
"tests/component/snapshots/**"
1919
]
2020
precedence = "aggregate"

package-lock.json

Lines changed: 2 additions & 28 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,6 @@
9494
"floating-vue": "^5.2.2",
9595
"focus-trap": "^7.6.4",
9696
"linkify-string": "^4.2.0",
97-
"md5": "^2.3.0",
9897
"p-queue": "^8.0.1",
9998
"rehype-external-links": "^3.0.0",
10099
"rehype-highlight": "^7.0.2",

src/functions/usernameToColor/index.js renamed to src/functions/usernameToColor/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@
33
* SPDX-License-Identifier: AGPL-3.0-or-later
44
*/
55

6-
export { default } from './usernameToColor.js'
6+
export { usernameToColor as default } from './usernameToColor.js'

src/functions/usernameToColor/usernameToColor.js

Lines changed: 0 additions & 59 deletions
This file was deleted.
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/**
2+
* SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
3+
* SPDX-License-Identifier: AGPL-3.0-or-later
4+
*/
5+
6+
import { type Color, GenColors } from '../../utils/GenColors.js'
7+
8+
/**
9+
* Create a simple hash from a string
10+
* @param str - The string to hash
11+
*/
12+
function hashCode(str: string): number {
13+
let hash = 0
14+
15+
if (str.length === 0) {
16+
return hash
17+
}
18+
19+
for (let i = 0; i < str.length; i++) {
20+
const chr = str.charCodeAt(i)
21+
hash = ((hash << 5) - hash) + chr
22+
}
23+
24+
return Math.abs(hash)
25+
}
26+
27+
/**
28+
* Generate a color from a username
29+
*
30+
* @param username - Display name or user id to generate from
31+
* @return The RGB color
32+
*/
33+
export function usernameToColor(username: string): Color {
34+
const steps = 6
35+
const finalPalette = GenColors(steps)
36+
const hash = hashCode(username.toLocaleLowerCase())
37+
38+
return finalPalette[hash % finalPalette.length]
39+
}

src/utils/GenColors.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ export const defaultPalette = [
123123
* 3 colors * 6 will result in 18 generated colors
124124
*
125125
* @param {number} [steps] Number of steps to go from a color to another
126-
* @return {object[]}
126+
* @return {Color[]}
127127
*/
128128
export function GenColors(steps) {
129129
if (!steps) {
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,73 @@
11
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
22

3-
exports[`usernameToColor > has the proper color 1`] = `"#0082c9"`;
3+
exports[`usernameToColor > has the proper color 1`] = `"#b6469d"`;
44

5-
exports[`usernameToColor > , has the proper color 1`] = `"#1e78c1"`;
5+
exports[`usernameToColor > , has the proper color 1`] = `"#93b27b"`;
66

7-
exports[`usernameToColor > . has the proper color 1`] = `"#c98879"`;
7+
exports[`usernameToColor > . has the proper color 1`] = `"#499aa2"`;
88

9-
exports[`usernameToColor > 123e4567-e89b-12d3-a456-426614174000 has the proper color 1`] = `"#bc5c91"`;
9+
exports[`usernameToColor > 123e4567-e89b-12d3-a456-426614174000 has the proper color 1`] = `"#795aab"`;
1010

11-
exports[`usernameToColor > Akeel Robertson has the proper color 1`] = `"#9750a4"`;
11+
exports[`usernameToColor > Akeel Robertson has the proper color 1`] = `"#499aa2"`;
1212

13-
exports[`usernameToColor > Alishia Ann Lowry has the proper color 1`] = `"#d09e6d"`;
13+
exports[`usernameToColor > Alishia Ann Lowry has the proper color 1`] = `"#bc5c91"`;
1414

15-
exports[`usernameToColor > Arham Johnson has the proper color 1`] = `"#0082c9"`;
15+
exports[`usernameToColor > Arham Johnson has the proper color 1`] = `"#795aab"`;
1616

17-
exports[`usernameToColor > Brayden Truong has the proper color 1`] = `"#d09e6d"`;
17+
exports[`usernameToColor > Brayden Truong has the proper color 1`] = `"#c37285"`;
1818

19-
exports[`usernameToColor > Daphne Roy has the proper color 1`] = `"#9750a4"`;
19+
exports[`usernameToColor > Daphne Roy has the proper color 1`] = `"#795aab"`;
2020

21-
exports[`usernameToColor > Ellena Wright Frederic Conway has the proper color 1`] = `"#c37285"`;
21+
exports[`usernameToColor > Ellena Wright Frederic Conway has the proper color 1`] = `"#6ea68f"`;
2222

23-
exports[`usernameToColor > Gianluca Hills has the proper color 1`] = `"#d6b461"`;
23+
exports[`usernameToColor > Gianluca Hills has the proper color 1`] = `"#3c6eba"`;
2424

25-
exports[`usernameToColor > Haseeb Stephens has the proper color 1`] = `"#d6b461"`;
25+
exports[`usernameToColor > Haseeb Stephens has the proper color 1`] = `"#795aab"`;
2626

27-
exports[`usernameToColor > Idris Mac has the proper color 1`] = `"#9750a4"`;
27+
exports[`usernameToColor > Idris Mac has the proper color 1`] = `"#ddcb55"`;
2828

29-
exports[`usernameToColor > Kristi Fisher has the proper color 1`] = `"#0082c9"`;
29+
exports[`usernameToColor > Kristi Fisher has the proper color 1`] = `"#9750a4"`;
3030

31-
exports[`usernameToColor > Lillian Wall has the proper color 1`] = `"#bc5c91"`;
31+
exports[`usernameToColor > Lillian Wall has the proper color 1`] = `"#b8be68"`;
3232

33-
exports[`usernameToColor > Lorelai Taylor has the proper color 1`] = `"#ddcb55"`;
33+
exports[`usernameToColor > Lorelai Taylor has the proper color 1`] = `"#248eb5"`;
3434

35-
exports[`usernameToColor > Madina Knight has the proper color 1`] = `"#9750a4"`;
35+
exports[`usernameToColor > Madina Knight has the proper color 1`] = `"#bc5c91"`;
3636

37-
exports[`usernameToColor > Meeting has the proper color 1`] = `"#c98879"`;
37+
exports[`usernameToColor > Meeting has the proper color 1`] = `"#248eb5"`;
3838

39-
exports[`usernameToColor > Private Circle has the proper color 1`] = `"#c37285"`;
39+
exports[`usernameToColor > Private Circle has the proper color 1`] = `"#c98879"`;
4040

41-
exports[`usernameToColor > Rae Hope has the proper color 1`] = `"#795aab"`;
41+
exports[`usernameToColor > Rae Hope has the proper color 1`] = `"#ddcb55"`;
4242

4343
exports[`usernameToColor > Santiago Singleton has the proper color 1`] = `"#bc5c91"`;
4444

45-
exports[`usernameToColor > Sid Combs has the proper color 1`] = `"#d09e6d"`;
45+
exports[`usernameToColor > Sid Combs has the proper color 1`] = `"#c37285"`;
4646

47-
exports[`usernameToColor > TestCircle has the proper color 1`] = `"#499aa2"`;
47+
exports[`usernameToColor > TestCircle has the proper color 1`] = `"#c37285"`;
4848

49-
exports[`usernameToColor > Tom Mörtel has the proper color 1`] = `"#248eb5"`;
49+
exports[`usernameToColor > Tom Mörtel has the proper color 1`] = `"#3c6eba"`;
5050

51-
exports[`usernameToColor > Vivienne Jacobs has the proper color 1`] = `"#1e78c1"`;
51+
exports[`usernameToColor > Vivienne Jacobs has the proper color 1`] = `"#93b27b"`;
5252

53-
exports[`usernameToColor > Zaki Cortes has the proper color 1`] = `"#6ea68f"`;
53+
exports[`usernameToColor > Zaki Cortes has the proper color 1`] = `"#5b64b3"`;
5454

55-
exports[`usernameToColor > a user has the proper color 1`] = `"#5b64b3"`;
55+
exports[`usernameToColor > a user has the proper color 1`] = `"#795aab"`;
5656

57-
exports[`usernameToColor > admin has the proper color 1`] = `"#d09e6d"`;
57+
exports[`usernameToColor > admin has the proper color 1`] = `"#9750a4"`;
5858

59-
exports[`usernameToColor > admin@cloud.example.com has the proper color 1`] = `"#9750a4"`;
59+
exports[`usernameToColor > admin@cloud.example.com has the proper color 1`] = `"#c98879"`;
6060

61-
exports[`usernameToColor > another user has the proper color 1`] = `"#ddcb55"`;
61+
exports[`usernameToColor > another user has the proper color 1`] = `"#499aa2"`;
6262

63-
exports[`usernameToColor > asd has the proper color 1`] = `"#248eb5"`;
63+
exports[`usernameToColor > asd has the proper color 1`] = `"#ddcb55"`;
6464

65-
exports[`usernameToColor > bar has the proper color 1`] = `"#0082c9"`;
65+
exports[`usernameToColor > bar has the proper color 1`] = `"#6ea68f"`;
6666

67-
exports[`usernameToColor > foo has the proper color 1`] = `"#d09e6d"`;
67+
exports[`usernameToColor > foo has the proper color 1`] = `"#b6469d"`;
6868

69-
exports[`usernameToColor > wasd has the proper color 1`] = `"#b6469d"`;
69+
exports[`usernameToColor > wasd has the proper color 1`] = `"#9750a4"`;
7070

71-
exports[`usernameToColor > مرحبا بالعالم has the proper color 1`] = `"#c98879"`;
71+
exports[`usernameToColor > مرحبا بالعالم has the proper color 1`] = `"#d09e6d"`;
7272

73-
exports[`usernameToColor > 🙈 has the proper color 1`] = `"#b6469d"`;
73+
exports[`usernameToColor > 🙈 has the proper color 1`] = `"#b8be68"`;

tests/unit/functions/usernameToColor/usernameToColor.spec.js renamed to tests/unit/functions/usernameToColor/usernameToColor.spec.ts

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,15 @@
33
* SPDX-License-Identifier: AGPL-3.0-or-later
44
*/
55
import { describe, expect, it } from 'vitest'
6-
import usernameToColor from '../../../../src/functions/usernameToColor/index'
6+
import usernameToColor from '../../../../src/functions/usernameToColor/index.ts'
77

88
const rgbToHex = (color) => {
99
return '#' + ((1 << 24) + (color.r << 16) + (color.g << 8) + color.b).toString(16).slice(1)
1010
}
1111

1212
describe('usernameToColor', () => {
13-
'use strict'
1413

15-
const usernames = [
14+
it.for([
1615
'', ',', '.', 'admin', 'foo', 'bar', 'asd', 'wasd', 'a user', 'another user', 'admin@cloud.example.com',
1716
'Lorelai Taylor',
1817
'Lillian Wall',
@@ -36,13 +35,12 @@ describe('usernameToColor', () => {
3635
'🙈',
3736
'مرحبا بالعالم',
3837
'123e4567-e89b-12d3-a456-426614174000',
39-
'Meeting', 'TestCircle', 'Private Circle',
40-
]
41-
42-
usernames.forEach((key) => {
43-
it(key + ' has the proper color', () => {
44-
expect(rgbToHex(usernameToColor(key))).toMatchSnapshot()
45-
})
38+
'Meeting',
39+
'TestCircle',
40+
'Private Circle',
41+
])('%s has the proper color', (name: string) => {
42+
const color = usernameToColor(name)
43+
console.error(color)
44+
expect(rgbToHex(color)).toMatchSnapshot()
4645
})
47-
4846
})

vite.config.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,11 @@ import { globSync } from 'glob'
99
import { join, resolve } from 'node:path'
1010
import { defineConfig } from 'vite'
1111

12-
import md5 from 'md5'
13-
12+
import crypto from 'node:crypto'
1413
import l10nPlugin from './build/l10n-plugin.mjs'
1514

1615
const appVersion = JSON.stringify(process.env.npm_package_version || 'nextcloud-vue')
17-
const versionHash = md5(appVersion).slice(0, 7) as string
16+
const versionHash = crypto.createHash('md5').update(appVersion).digest('hex').slice(0, 7)
1817
const SCOPE_VERSION = JSON.stringify(versionHash)
1918

2019
// Entry points which we build using vite

0 commit comments

Comments
 (0)