cetirizine

An experimental matrix client written in reactjs utilizing tailwind and storybook
git clone git://archive.git.mtrnord.blog/MTRNord/cetirizine.git
Log | Files | Refs | README | LICENSE

MentionNode.ts (3583B)


      1 import type { Spread } from "lexical";
      2 
      3 import {
      4     DOMConversionMap,
      5     DOMConversionOutput,
      6     DOMExportOutput,
      7     EditorConfig,
      8     LexicalNode,
      9     NodeKey,
     10     SerializedTextNode,
     11     TextNode
     12 } from "lexical";
     13 import { IRoomMemberEvent } from "../../../../../app/sdk/api/events";
     14 
     15 export type SerializedMentionNode = Spread<
     16     {
     17         mentionEvent: IRoomMemberEvent;
     18         type: "mention";
     19         version: 1;
     20     },
     21     SerializedTextNode
     22 >;
     23 
     24 function convertMentionElement(
     25     domNode: HTMLElement
     26 ): DOMConversionOutput | null {
     27     const textContent = domNode.textContent;
     28     const mxid = domNode.getAttribute("data-lexical-mention-mxid");
     29 
     30     if (textContent && mxid) {
     31         const node = $createMentionNode({
     32             state_key: mxid,
     33             content: {
     34                 displayname: textContent,
     35             }
     36         } as IRoomMemberEvent);
     37         return {
     38             node
     39         };
     40     }
     41 
     42     return null;
     43 }
     44 
     45 export class MentionNode extends TextNode {
     46     __mention: IRoomMemberEvent;
     47 
     48     static getType(): string {
     49         return "mention";
     50     }
     51 
     52     static clone(node: MentionNode): MentionNode {
     53         return new MentionNode(node.__mention, node.__text, node.__key);
     54     }
     55     static importJSON(serializedNode: SerializedMentionNode): MentionNode {
     56         const node = $createMentionNode(serializedNode.mentionEvent);
     57         node.setTextContent(serializedNode.text);
     58         node.setFormat(serializedNode.format);
     59         node.setDetail(serializedNode.detail);
     60         node.setMode(serializedNode.mode);
     61         node.setStyle(serializedNode.style);
     62         return node;
     63     }
     64 
     65     constructor(memberEvent: IRoomMemberEvent, text?: string, key?: NodeKey) {
     66         super(text ?? (memberEvent.content.displayname || memberEvent.state_key), key);
     67         this.__mention = memberEvent;
     68     }
     69 
     70     exportJSON(): SerializedMentionNode {
     71         return {
     72             ...super.exportJSON(),
     73             mentionEvent: this.__mention,
     74             type: "mention",
     75             version: 1
     76         };
     77     }
     78 
     79     createDOM(config: EditorConfig): HTMLElement {
     80         const dom = super.createDOM(config);
     81         dom.className = "mention";
     82         return dom;
     83     }
     84 
     85     exportDOM(): DOMExportOutput {
     86         const element = document.createElement("a");
     87         element.setAttribute("href", `matrix:u/${this.__mention.state_key.replace("@", "")}`);
     88         element.setAttribute("data-lexical-mention", "true");
     89         element.setAttribute("data-lexical-mention-mxid", this.__mention.state_key);
     90         element.textContent = this.__text;
     91         return { element };
     92     }
     93 
     94     isSegmented(): false {
     95         return false;
     96     }
     97 
     98     static importDOM(): DOMConversionMap | null {
     99         return {
    100             a: (domNode: HTMLElement) => {
    101                 if (!domNode.hasAttribute("data-lexical-mention") && !domNode.hasAttribute("data-lexical-mention-mxid")) {
    102                     return null;
    103                 }
    104                 return {
    105                     conversion: convertMentionElement,
    106                     priority: 1
    107                 };
    108             }
    109         };
    110     }
    111 
    112     isTextEntity(): true {
    113         return true;
    114     }
    115 
    116     isToken(): true {
    117         return true;
    118     }
    119 }
    120 
    121 export function $createMentionNode(memberEvent: IRoomMemberEvent,): MentionNode {
    122     const mentionNode = new MentionNode(memberEvent);
    123     mentionNode.setMode("segmented").toggleDirectionless();
    124     return mentionNode;
    125 }
    126 
    127 export function $isMentionNode(
    128     node: LexicalNode | null | undefined
    129 ): node is MentionNode {
    130     return node instanceof MentionNode;
    131 }