-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathmatrix-room-utils.ts
75 lines (63 loc) · 1.79 KB
/
matrix-room-utils.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import { registerFont, createCanvas } from "canvas"
import { Readable } from "stream"
registerFont("web/src/fonts/Inter-Regular.otf", {
family: "Inter",
})
type AvatarInfo = {
filename: string
pngStream: Readable
}
const AVATAR_DIMENSIONS = {
width: 234,
height: 234,
}
/**
* Returns the room alias for the given room name. If the prefix parent space
* name is given, it is converted to an alias and used as a prefix to the given
* room's name.
*
* For example, calling this with `general` and `Tally Ho` will result in
* `tally-ho-general`.
*/
export function roomNameToAlias(
roomName: string,
prefixParentSpaceName?: string,
): string {
const baseAlias = roomName.toLowerCase().replace(/[^a-z0-9]/g, "-")
if (prefixParentSpaceName !== undefined) {
return `${roomNameToAlias(prefixParentSpaceName)}-${baseAlias}`
}
return baseAlias
}
export function generateAvatar(
roomName: string,
baseColorHex: string,
prefixParentSpaceName: string | undefined,
): AvatarInfo {
const { width, height } = AVATAR_DIMENSIONS
const canvas = createCanvas(width, height)
const ctx = canvas.getContext("2d")
ctx.fillStyle = baseColorHex
ctx.ellipse(width / 2, height / 2, width / 2, height / 2, 0, 0, 2 * Math.PI)
ctx.fill()
ctx.font = "98pt 'Inter'"
ctx.fillStyle = "#ffffff"
const text = roomName.substring(0, 1).toUpperCase()
const {
width: textWidth,
actualBoundingBoxAscent,
actualBoundingBoxDescent,
} = ctx.measureText(text)
const textHeight = actualBoundingBoxAscent + actualBoundingBoxDescent
ctx.fillText(
text,
width / 2 - textWidth / 2,
width / 2 + textHeight / 2,
width,
)
const stream = canvas.createPNGStream()
return {
filename: `${roomNameToAlias(roomName, prefixParentSpaceName)}.png`,
pngStream: stream,
}
}