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
76
/**
* modified version of https://unpkg.com/twemoji@13.1.0/dist/twemoji.esm.js.
*/
/* ! Copyright Twitter Inc. and other contributors. Licensed under MIT */
// this file added in: https://github.com/open-sauced/opengraph/issues/50
const U200D = String.fromCharCode(8205);
const UFE0Fg = /\uFE0F/g;
export function getIconCode (char: string) {
return toCodePoint(!char.includes(U200D) ? char.replace(UFE0Fg, "") : char);
}
function toCodePoint (unicodeSurrogates: string) {
const r = [];
let c = 0;
let i = 0;
let p = 0;
// eslint-disable-next-line no-loops/no-loops
while (i < unicodeSurrogates.length) {
c = unicodeSurrogates.charCodeAt(i++);
if (p) {
r.push((65536 + ((p - 55296) << 10) + (c - 56320)).toString(16));
p = 0;
} else if (55296 <= c && c <= 56319) {
p = c;
} else {
r.push(c.toString(16));
}
}
return r.join("-");
}
export const apis = {
twemoji: (code: string) =>
`https://cdnjs.cloudflare.com/ajax/libs/twemoji/14.0.2/svg/${
code.toLowerCase()
}.svg`,
openmoji: "https://cdn.jsdelivr.net/npm/@svgmoji/openmoji@2.0.0/svg/",
blobmoji: "https://cdn.jsdelivr.net/npm/@svgmoji/blob@2.0.0/svg/",
noto: "https://cdn.jsdelivr.net/gh/svgmoji/svgmoji/packages/svgmoji__noto/svg/",
fluent: (code: string) =>
`https://cdn.jsdelivr.net/gh/shuding/fluentui-emoji-unicode/assets/${
code.toLowerCase()
}_color.svg`,
fluentFlat: (code: string) =>
`https://cdn.jsdelivr.net/gh/shuding/fluentui-emoji-unicode/assets/${
code.toLowerCase()
}_flat.svg`,
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const emojiCache: Record<string, Promise<string>> = {};
export async function loadEmoji (type: keyof typeof apis, code: string) {
const key = `${type}:${code}`;
if (key in emojiCache) {
return emojiCache[key];
}
if (!type || !apis[type]) {
type = "twemoji";
}
const api = apis[type];
if (typeof api === "function") {
return (emojiCache[key] = fetch(api(code)).then(async r => r.text()));
}
return (emojiCache[key] = fetch(`${api}${code.toUpperCase()}.svg`).then(async r =>
r.text()));
}
👆 This is a val. Vals are TypeScript snippets of code, written in the browser and run on our servers. Create scheduled functions, email yourself, and persist small pieces of data — all from the browser.