1import {matchEmoji, matchMention} from '../../utils/match.js';
2import {emojiString} from '../emoji.js';
3
4export function initTextExpander(expander) {
5 expander?.addEventListener('text-expander-change', ({detail: {key, provide, text}}) => {
6 if (key === ':') {
7 const matches = matchEmoji(text);
8 if (!matches.length) return provide({matched: false});
9
10 const ul = document.createElement('ul');
11 ul.classList.add('suggestions');
12 for (const name of matches) {
13 const emoji = emojiString(name);
14 const li = document.createElement('li');
15 li.setAttribute('role', 'option');
16 li.setAttribute('data-value', emoji);
17 li.textContent = `${emoji} ${name}`;
18 ul.append(li);
19 }
20
21 provide({matched: true, fragment: ul});
22 } else if (key === '@') {
23 const matches = matchMention(text);
24 if (!matches.length) return provide({matched: false});
25
26 const ul = document.createElement('ul');
27 ul.classList.add('suggestions');
28 for (const {value, name, fullname, avatar} of matches) {
29 const li = document.createElement('li');
30 li.setAttribute('role', 'option');
31 li.setAttribute('data-value', `${key}${value}`);
32
33 const img = document.createElement('img');
34 img.src = avatar;
35 li.append(img);
36
37 const nameSpan = document.createElement('span');
38 nameSpan.textContent = name;
39 li.append(nameSpan);
40
41 if (fullname && fullname.toLowerCase() !== name) {
42 const fullnameSpan = document.createElement('span');
43 fullnameSpan.classList.add('fullname');
44 fullnameSpan.textContent = fullname;
45 li.append(fullnameSpan);
46 }
47
48 ul.append(li);
49 }
50
51 provide({matched: true, fragment: ul});
52 }
53 });
54 expander?.addEventListener('text-expander-value', ({detail}) => {
55 if (detail?.item) {
56 // add a space after @mentions as it's likely the user wants one
57 const suffix = detail.key === '@' ? ' ' : '';
58 detail.value = `${detail.item.getAttribute('data-value')}${suffix}`;
59 }
60 });
61}