atagen

malice

public
Star0
Watch0
06339d2de37a2adbd7c9697702da5360fad61c36
2
ssh://brewery@pls.lobotomise.me:33/atagen/malice.git

Blame: web/src/lib/composer-marks.ts

05a48e9e7942atagen2026-10-24 09:32 UTC1
import type { Mention } from './mentions';
05a48e9e7942atagen2026-10-24 09:32 UTC2
05a48e9e7942atagen2026-10-24 09:32 UTC3
export interface MarkPart {
05a48e9e7942atagen2026-10-24 09:32 UTC4
  text: string;
05a48e9e7942atagen2026-10-24 09:32 UTC5
  mark: boolean;
05a48e9e7942atagen2026-10-24 09:32 UTC6
}
05a48e9e7942atagen2026-10-24 09:32 UTC7
05a48e9e7942atagen2026-10-24 09:32 UTC8
/** The composer text split so picked mention names and emote shortcodes can be highlighted behind the textarea. */
05a48e9e7942atagen2026-10-24 09:32 UTC9
export function markMentions(text: string, mentions: Mention[], extra: string[] = []): MarkPart[] {
05a48e9e7942atagen2026-10-24 09:32 UTC10
  const names = [...new Set([...mentions.map((m) => m.text), ...extra].filter(Boolean))].sort((a, b) => b.length - a.length);
05a48e9e7942atagen2026-10-24 09:32 UTC11
  if (!names.length || !text) return [{ text, mark: false }];
05a48e9e7942atagen2026-10-24 09:32 UTC12
  const parts: MarkPart[] = [];
05a48e9e7942atagen2026-10-24 09:32 UTC13
  let rest = text;
05a48e9e7942atagen2026-10-24 09:32 UTC14
  while (rest) {
05a48e9e7942atagen2026-10-24 09:32 UTC15
    let at = -1;
05a48e9e7942atagen2026-10-24 09:32 UTC16
    let hit = '';
05a48e9e7942atagen2026-10-24 09:32 UTC17
    for (const name of names) {
05a48e9e7942atagen2026-10-24 09:32 UTC18
      const i = rest.indexOf(name);
05a48e9e7942atagen2026-10-24 09:32 UTC19
      if (i >= 0 && (at < 0 || i < at)) {
05a48e9e7942atagen2026-10-24 09:32 UTC20
        at = i;
05a48e9e7942atagen2026-10-24 09:32 UTC21
        hit = name;
05a48e9e7942atagen2026-10-24 09:32 UTC22
      }
05a48e9e7942atagen2026-10-24 09:32 UTC23
    }
05a48e9e7942atagen2026-10-24 09:32 UTC24
    if (at < 0) {
05a48e9e7942atagen2026-10-24 09:32 UTC25
      parts.push({ text: rest, mark: false });
05a48e9e7942atagen2026-10-24 09:32 UTC26
      break;
05a48e9e7942atagen2026-10-24 09:32 UTC27
    }
05a48e9e7942atagen2026-10-24 09:32 UTC28
    if (at > 0) parts.push({ text: rest.slice(0, at), mark: false });
05a48e9e7942atagen2026-10-24 09:32 UTC29
    parts.push({ text: hit, mark: true });
05a48e9e7942atagen2026-10-24 09:32 UTC30
    rest = rest.slice(at + hit.length);
05a48e9e7942atagen2026-10-24 09:32 UTC31
  }
05a48e9e7942atagen2026-10-24 09:32 UTC32
  return parts;
05a48e9e7942atagen2026-10-24 09:32 UTC33
}