atagen

malice

public
Star0
Watch0
61382e376b154e5b03d5e65195237ccd3ddfcd14
2
ssh://brewery@pls.lobotomise.me:33/atagen/malice.git
web/src/lib/quick-reactions-model.tsTypescript70 lines2.2 KB
1
import type { QuickEntry, QuickReaction, QuickSeparator } from './types';
2
3
export function isSeparator(entry: QuickEntry): entry is QuickSeparator {
4
  return 'separator' in entry;
5
}
6
7
export function normaliseQuick(entries: readonly QuickEntry[]): QuickEntry[] {
8
  const seen = new Set<string>();
9
  const out: QuickEntry[] = [];
10
  for (const entry of entries) {
11
    if (isSeparator(entry)) {
12
      const last = out[out.length - 1];
13
      if (last && !isSeparator(last)) out.push(entry);
14
      continue;
15
    }
16
    if (seen.has(entry.key)) continue;
17
    seen.add(entry.key);
18
    out.push(entry);
19
  }
20
  const last = out[out.length - 1];
21
  if (last && isSeparator(last)) out.pop();
22
  return out;
23
}
24
25
export function parseQuickReactions(raw: unknown): QuickEntry[] | null {
26
  if (typeof raw !== 'object' || raw === null) return null;
27
  const list = (raw as Record<string, unknown>)['reactions'];
28
  if (!Array.isArray(list)) return null;
29
  const entries: QuickEntry[] = [];
30
  for (const item of list) {
31
    if (typeof item !== 'object' || item === null) continue;
32
    const { key, shortcode, separator } = item as Record<string, unknown>;
33
    if (separator === true) {
34
      entries.push({ separator: true });
35
      continue;
36
    }
37
    if (typeof key !== 'string' || !key) continue;
38
    entries.push({ key, shortcode: typeof shortcode === 'string' ? shortcode : null });
39
  }
40
  return normaliseQuick(entries);
41
}
42
43
export function quickGroups(entries: readonly QuickEntry[]): QuickReaction[][] {
44
  const groups: QuickReaction[][] = [];
45
  let group: QuickReaction[] = [];
46
  for (const entry of entries) {
47
    if (!isSeparator(entry)) {
48
      group.push(entry);
49
      continue;
50
    }
51
    if (group.length > 0) groups.push(group);
52
    group = [];
53
  }
54
  if (group.length > 0) groups.push(group);
55
  return groups;
56
}
57
58
export function quickColumns(groups: readonly QuickReaction[][], perRow: number): number {
59
  return groups.reduce((cols, group) => Math.max(cols, Math.min(group.length, perRow)), 0);
60
}
61
62
export function sameQuick(a: readonly QuickEntry[], b: readonly QuickEntry[]): boolean {
63
  return (
64
    a.length === b.length &&
65
    a.every((entry, i) => {
66
      const other = b[i];
67
      return isSeparator(entry) ? isSeparator(other) : !isSeparator(other) && entry.key === other.key;
68
    })
69
  );
70
}