{
+ handlePointerDown(event, Direction.south | Direction.west);
+ }}
+ />
+
{
+ handlePointerDown(event, Direction.west);
+ }}
+ />
+
{
+ handlePointerDown(event, Direction.north | Direction.west);
+ }}
+ />
+
+ );
+}
diff --git a/src/pages/Note/Hlexical/plugins/Input/Placeholder/index.jsx b/src/pages/Note/Hlexical/plugins/Input/Placeholder/index.jsx
new file mode 100644
index 0000000..7c9e12e
--- /dev/null
+++ b/src/pages/Note/Hlexical/plugins/Input/Placeholder/index.jsx
@@ -0,0 +1,11 @@
+
+import './index.less';
+
+import * as React from 'react';
+
+export default function Placeholder({
+ children,
+ className,
+ }) {
+ return
{children}
;
+}
diff --git a/src/pages/Note/Hlexical/plugins/Input/Placeholder/index.less b/src/pages/Note/Hlexical/plugins/Input/Placeholder/index.less
new file mode 100644
index 0000000..38dbd3c
--- /dev/null
+++ b/src/pages/Note/Hlexical/plugins/Input/Placeholder/index.less
@@ -0,0 +1,19 @@
+.Placeholder__root {
+ font-size: 15px;
+ color: #999;
+ overflow: hidden;
+ position: absolute;
+ text-overflow: ellipsis;
+ top: 8px;
+ left: 28px;
+ right: 28px;
+ user-select: none;
+ white-space: nowrap;
+ display: inline-block;
+ pointer-events: none;
+}
+@media (max-width: 1025px) {
+ .Placeholder__root {
+ left: 8px;
+ }
+}
diff --git a/src/pages/Note/Hlexical/plugins/KeywordsPlugin/index.jsx b/src/pages/Note/Hlexical/plugins/KeywordsPlugin/index.jsx
new file mode 100644
index 0000000..d941c04
--- /dev/null
+++ b/src/pages/Note/Hlexical/plugins/KeywordsPlugin/index.jsx
@@ -0,0 +1,45 @@
+import {useLexicalComposerContext} from '@lexical/react/LexicalComposerContext';
+import {useLexicalTextEntity} from '@lexical/react/useLexicalTextEntity';
+import {useCallback, useEffect} from 'react';
+
+import {$createKeywordNode, KeywordNode} from '../../nodes/KeywordNode';
+
+const KEYWORDS_REGEX =
+ /(^|$|[^A-Za-zªµºÀ-ÖØ-öø-ˁˆ-ˑˠ-ˤˬˮͰ-ʹͶͷͺ-ͽΆΈ-ΊΌΎ-ΡΣ-ϵϷ-ҁҊ-ԧԱ-Ֆՙա-ևא-תװ-ײؠ-يٮٯٱ-ۓەۥۦۮۯۺ-ۼۿܐܒ-ܯݍ-ޥޱߊ-ߪߴߵߺࠀ-ࠕࠚࠤࠨࡀ-ࡘࢠࢢ-ࢬऄ-हऽॐक़-ॡॱ-ॷॹ-ॿঅ-ঌএঐও-নপ-রলশ-হঽৎড়ঢ়য়-ৡৰৱਅ-ਊਏਐਓ-ਨਪ-ਰਲਲ਼ਵਸ਼ਸਹਖ਼-ੜਫ਼ੲ-ੴઅ-ઍએ-ઑઓ-નપ-રલળવ-હઽૐૠૡଅ-ଌଏଐଓ-ନପ-ରଲଳଵ-ହଽଡ଼ଢ଼ୟ-ୡୱஃஅ-ஊஎ-ஐஒ-கஙசஜஞடணதந-பம-ஹௐఅ-ఌఎ-ఐఒ-నప-ళవ-హఽౘౙౠౡಅ-ಌಎ-ಐಒ-ನಪ-ಳವ-ಹಽೞೠೡೱೲഅ-ഌഎ-ഐഒ-ഺഽൎൠൡൺ-ൿඅ-ඖක-නඳ-රලව-ෆก-ะาำเ-ๆກຂຄງຈຊຍດ-ທນ-ຟມ-ຣລວສຫອ-ະາຳຽເ-ໄໆໜ-ໟༀཀ-ཇཉ-ཬྈ-ྌက-ဪဿၐ-ၕၚ-ၝၡၥၦၮ-ၰၵ-ႁႎႠ-ჅჇჍა-ჺჼ-ቈቊ-ቍቐ-ቖቘቚ-ቝበ-ኈኊ-ኍነ-ኰኲ-ኵኸ-ኾዀዂ-ዅወ-ዖዘ-ጐጒ-ጕጘ-ፚᎀ-ᎏᎠ-Ᏼᐁ-ᙬᙯ-ᙿᚁ-ᚚᚠ-ᛪᜀ-ᜌᜎ-ᜑᜠ-ᜱᝀ-ᝑᝠ-ᝬᝮ-ᝰក-ឳៗៜᠠ-ᡷᢀ-ᢨᢪᢰ-ᣵᤀ-ᤜᥐ-ᥭᥰ-ᥴᦀ-ᦫᧁ-ᧇᨀ-ᨖᨠ-ᩔᪧᬅ-ᬳᭅ-ᭋᮃ-ᮠᮮᮯᮺ-ᯥᰀ-ᰣᱍ-ᱏᱚ-ᱽᳩ-ᳬᳮ-ᳱᳵᳶᴀ-ᶿḀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼιῂ-ῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲ-ῴῶ-ῼⁱⁿₐ-ₜℂℇℊ-ℓℕℙ-ℝℤΩℨK-ℭℯ-ℹℼ-ℿⅅ-ⅉⅎↃↄⰀ-Ⱞⰰ-ⱞⱠ-ⳤⳫ-ⳮⳲⳳⴀ-ⴥⴧⴭⴰ-ⵧⵯⶀ-ⶖⶠ-ⶦⶨ-ⶮⶰ-ⶶⶸ-ⶾⷀ-ⷆⷈ-ⷎⷐ-ⷖⷘ-ⷞⸯ々〆〱-〵〻〼ぁ-ゖゝ-ゟァ-ヺー-ヿㄅ-ㄭㄱ-ㆎㆠ-ㆺㇰ-ㇿ㐀-䶵一-鿌ꀀ-ꒌꓐ-ꓽꔀ-ꘌꘐ-ꘟꘪꘫꙀ-ꙮꙿ-ꚗꚠ-ꛥꜗ-ꜟꜢ-ꞈꞋ-ꞎꞐ-ꞓꞠ-Ɦꟸ-ꠁꠃ-ꠅꠇ-ꠊꠌ-ꠢꡀ-ꡳꢂ-ꢳꣲ-ꣷꣻꤊ-ꤥꤰ-ꥆꥠ-ꥼꦄ-ꦲꧏꨀ-ꨨꩀ-ꩂꩄ-ꩋꩠ-ꩶꩺꪀ-ꪯꪱꪵꪶꪹ-ꪽꫀꫂꫛ-ꫝꫠ-ꫪꫲ-ꫴꬁ-ꬆꬉ-ꬎꬑ-ꬖꬠ-ꬦꬨ-ꬮꯀ-ꯢ가-힣ힰ-ퟆퟋ-ퟻ豈-舘並-龎ff-stﬓ-ﬗיִײַ-ﬨשׁ-זּטּ-לּמּנּסּףּפּצּ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻﹰ-ﹴﹶ-ﻼA-Za-zヲ-하-ᅦᅧ-ᅬᅭ-ᅲᅳ-ᅵ])(congrats|congratulations|gratuluju|gratuluji|gratulujeme|blahopřeju|blahopřeji|blahopřejeme|Til lykke|Tillykke|Glückwunsch|Gratuliere|felicitaciones|enhorabuena|paljon onnea|onnittelut|Félicitations|gratula|gratulálok|gratulálunk|congratulazioni|complimenti|おめでとう|おめでとうございます|축하해|축하해요|gratulerer|Gefeliciteerd|gratulacje|Parabéns|parabéns|felicitações|felicitări|мои поздравления|поздравляем|поздравляю|gratulujem|blahoželám|ยินดีด้วย|ขอแสดงความยินดี|tebrikler|tebrik ederim|恭喜|祝贺你|恭喜你|恭喜|恭喜|baie geluk|veels geluk|অভিনন্দন|Čestitam|Čestitke|Čestitamo|Συγχαρητήρια|Μπράβο|અભિનંદન|badhai|बधाई|अभिनंदन|Честитам|Свака част|hongera|வாழ்த்துகள்|வாழ்த்துக்கள்|అభినందనలు|അഭിനന്ദനങ്ങൾ|Chúc mừng|מזל טוב|mazel tov|mazal tov)(^|$|[^A-Za-zªµºÀ-ÖØ-öø-ˁˆ-ˑˠ-ˤˬˮͰ-ʹͶͷͺ-ͽΆΈ-ΊΌΎ-ΡΣ-ϵϷ-ҁҊ-ԧԱ-Ֆՙա-ևא-תװ-ײؠ-يٮٯٱ-ۓەۥۦۮۯۺ-ۼۿܐܒ-ܯݍ-ޥޱߊ-ߪߴߵߺࠀ-ࠕࠚࠤࠨࡀ-ࡘࢠࢢ-ࢬऄ-हऽॐक़-ॡॱ-ॷॹ-ॿঅ-ঌএঐও-নপ-রলশ-হঽৎড়ঢ়য়-ৡৰৱਅ-ਊਏਐਓ-ਨਪ-ਰਲਲ਼ਵਸ਼ਸਹਖ਼-ੜਫ਼ੲ-ੴઅ-ઍએ-ઑઓ-નપ-રલળવ-હઽૐૠૡଅ-ଌଏଐଓ-ନପ-ରଲଳଵ-ହଽଡ଼ଢ଼ୟ-ୡୱஃஅ-ஊஎ-ஐஒ-கஙசஜஞடணதந-பம-ஹௐఅ-ఌఎ-ఐఒ-నప-ళవ-హఽౘౙౠౡಅ-ಌಎ-ಐಒ-ನಪ-ಳವ-ಹಽೞೠೡೱೲഅ-ഌഎ-ഐഒ-ഺഽൎൠൡൺ-ൿඅ-ඖක-නඳ-රලව-ෆก-ะาำเ-ๆກຂຄງຈຊຍດ-ທນ-ຟມ-ຣລວສຫອ-ະາຳຽເ-ໄໆໜ-ໟༀཀ-ཇཉ-ཬྈ-ྌက-ဪဿၐ-ၕၚ-ၝၡၥၦၮ-ၰၵ-ႁႎႠ-ჅჇჍა-ჺჼ-ቈቊ-ቍቐ-ቖቘቚ-ቝበ-ኈኊ-ኍነ-ኰኲ-ኵኸ-ኾዀዂ-ዅወ-ዖዘ-ጐጒ-ጕጘ-ፚᎀ-ᎏᎠ-Ᏼᐁ-ᙬᙯ-ᙿᚁ-ᚚᚠ-ᛪᜀ-ᜌᜎ-ᜑᜠ-ᜱᝀ-ᝑᝠ-ᝬᝮ-ᝰក-ឳៗៜᠠ-ᡷᢀ-ᢨᢪᢰ-ᣵᤀ-ᤜᥐ-ᥭᥰ-ᥴᦀ-ᦫᧁ-ᧇᨀ-ᨖᨠ-ᩔᪧᬅ-ᬳᭅ-ᭋᮃ-ᮠᮮᮯᮺ-ᯥᰀ-ᰣᱍ-ᱏᱚ-ᱽᳩ-ᳬᳮ-ᳱᳵᳶᴀ-ᶿḀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼιῂ-ῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲ-ῴῶ-ῼⁱⁿₐ-ₜℂℇℊ-ℓℕℙ-ℝℤΩℨK-ℭℯ-ℹℼ-ℿⅅ-ⅉⅎↃↄⰀ-Ⱞⰰ-ⱞⱠ-ⳤⳫ-ⳮⳲⳳⴀ-ⴥⴧⴭⴰ-ⵧⵯⶀ-ⶖⶠ-ⶦⶨ-ⶮⶰ-ⶶⶸ-ⶾⷀ-ⷆⷈ-ⷎⷐ-ⷖⷘ-ⷞⸯ々〆〱-〵〻〼ぁ-ゖゝ-ゟァ-ヺー-ヿㄅ-ㄭㄱ-ㆎㆠ-ㆺㇰ-ㇿ㐀-䶵一-鿌ꀀ-ꒌꓐ-ꓽꔀ-ꘌꘐ-ꘟꘪꘫꙀ-ꙮꙿ-ꚗꚠ-ꛥꜗ-ꜟꜢ-ꞈꞋ-ꞎꞐ-ꞓꞠ-Ɦꟸ-ꠁꠃ-ꠅꠇ-ꠊꠌ-ꠢꡀ-ꡳꢂ-ꢳꣲ-ꣷꣻꤊ-ꤥꤰ-ꥆꥠ-ꥼꦄ-ꦲꧏꨀ-ꨨꩀ-ꩂꩄ-ꩋꩠ-ꩶꩺꪀ-ꪯꪱꪵꪶꪹ-ꪽꫀꫂꫛ-ꫝꫠ-ꫪꫲ-ꫴꬁ-ꬆꬉ-ꬎꬑ-ꬖꬠ-ꬦꬨ-ꬮꯀ-ꯢ가-힣ힰ-ퟆퟋ-ퟻ豈-舘並-龎ff-stﬓ-ﬗיִײַ-ﬨשׁ-זּטּ-לּמּנּסּףּפּצּ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻﹰ-ﹴﹶ-ﻼA-Za-zヲ-하-ᅦᅧ-ᅬᅭ-ᅲᅳ-ᅵ])/i;
+
+export default function KeywordsPlugin(){
+ const [editor] = useLexicalComposerContext();
+
+ useEffect(() => {
+ if (!editor.hasNodes([KeywordNode])) {
+ throw new Error('KeywordsPlugin: KeywordNode not registered on editor');
+ }
+ }, [editor]);
+
+ const createKeywordNode = useCallback((textNode) => {
+ return $createKeywordNode(textNode.getTextContent());
+ }, []);
+
+ const getKeywordMatch = useCallback((text) => {
+ const matchArr = KEYWORDS_REGEX.exec(text);
+
+ if (matchArr === null) {
+ return null;
+ }
+
+ const hashtagLength = matchArr[2].length;
+ const startOffset = matchArr.index + matchArr[1].length;
+ const endOffset = startOffset + hashtagLength;
+ return {
+ end: endOffset,
+ start: startOffset,
+ };
+ }, []);
+
+ useLexicalTextEntity(
+ getKeywordMatch,
+ KeywordNode,
+ createKeywordNode,
+ );
+ return null;
+}
diff --git a/src/pages/Note/Hlexical/plugins/LinkPlugin/index.jsx b/src/pages/Note/Hlexical/plugins/LinkPlugin/index.jsx
new file mode 100644
index 0000000..e2d1023
--- /dev/null
+++ b/src/pages/Note/Hlexical/plugins/LinkPlugin/index.jsx
@@ -0,0 +1,8 @@
+import {LinkPlugin as LexicalLinkPlugin} from '@lexical/react/LexicalLinkPlugin';
+import * as React from 'react';
+
+import {validateUrl} from '../../utils/url';
+
+export default function LinkPlugin() {
+ return
;
+}
diff --git a/src/pages/Note/Hlexical/plugins/MentionsPlugin/index.jsx b/src/pages/Note/Hlexical/plugins/MentionsPlugin/index.jsx
new file mode 100644
index 0000000..759b494
--- /dev/null
+++ b/src/pages/Note/Hlexical/plugins/MentionsPlugin/index.jsx
@@ -0,0 +1,682 @@
+import {useLexicalComposerContext} from '@lexical/react/LexicalComposerContext';
+import {
+ LexicalTypeaheadMenuPlugin,
+ MenuOption,
+ MenuTextMatch,
+ useBasicTypeaheadTriggerMatch,
+} from '@lexical/react/LexicalTypeaheadMenuPlugin';
+import {TextNode} from 'lexical';
+import {useCallback, useEffect, useMemo, useState} from 'react';
+import * as React from 'react';
+import * as ReactDOM from 'react-dom';
+
+import {$createMentionNode} from '../../nodes/MentionNode';
+
+const PUNCTUATION =
+ '\\.,\\+\\*\\?\\$\\@\\|#{}\\(\\)\\^\\-\\[\\]\\\\/!%\'"~=<>_:;';
+const NAME = '\\b[A-Z][^\\s' + PUNCTUATION + ']';
+
+const DocumentMentionsRegex = {
+ NAME,
+ PUNCTUATION,
+};
+
+const PUNC = DocumentMentionsRegex.PUNCTUATION;
+
+const TRIGGERS = ['@'].join('');
+
+// Chars we expect to see in a mention (non-space, non-punctuation).
+const VALID_CHARS = '[^' + TRIGGERS + PUNC + '\\s]';
+
+// Non-standard series of chars. Each series must be preceded and followed by
+// a valid char.
+const VALID_JOINS =
+ '(?:' +
+ '\\.[ |$]|' + // E.g. "r. " in "Mr. Smith"
+ ' |' + // E.g. " " in "Josh Duck"
+ '[' +
+ PUNC +
+ ']|' + // E.g. "-' in "Salier-Hellendag"
+ ')';
+
+const LENGTH_LIMIT = 75;
+
+const AtSignMentionsRegex = new RegExp(
+ '(^|\\s|\\()(' +
+ '[' +
+ TRIGGERS +
+ ']' +
+ '((?:' +
+ VALID_CHARS +
+ VALID_JOINS +
+ '){0,' +
+ LENGTH_LIMIT +
+ '})' +
+ ')$',
+);
+
+// 50 is the longest alias length limit.
+const ALIAS_LENGTH_LIMIT = 50;
+
+// Regex used to match alias.
+const AtSignMentionsRegexAliasRegex = new RegExp(
+ '(^|\\s|\\()(' +
+ '[' +
+ TRIGGERS +
+ ']' +
+ '((?:' +
+ VALID_CHARS +
+ '){0,' +
+ ALIAS_LENGTH_LIMIT +
+ '})' +
+ ')$',
+);
+
+// At most, 5 suggestions are shown in the popup.
+const SUGGESTION_LIST_LENGTH_LIMIT = 5;
+
+const mentionsCache = new Map();
+
+const dummyMentionsData = [
+ 'Aayla Secura',
+ 'Adi Gallia',
+ 'Admiral Dodd Rancit',
+ 'Admiral Firmus Piett',
+ 'Admiral Gial Ackbar',
+ 'Admiral Ozzel',
+ 'Admiral Raddus',
+ 'Admiral Terrinald Screed',
+ 'Admiral Trench',
+ 'Admiral U.O. Statura',
+ 'Agen Kolar',
+ 'Agent Kallus',
+ 'Aiolin and Morit Astarte',
+ 'Aks Moe',
+ 'Almec',
+ 'Alton Kastle',
+ 'Amee',
+ 'AP-5',
+ 'Armitage Hux',
+ 'Artoo',
+ 'Arvel Crynyd',
+ 'Asajj Ventress',
+ 'Aurra Sing',
+ 'AZI-3',
+ 'Bala-Tik',
+ 'Barada',
+ 'Bargwill Tomder',
+ 'Baron Papanoida',
+ 'Barriss Offee',
+ 'Baze Malbus',
+ 'Bazine Netal',
+ 'BB-8',
+ 'BB-9E',
+ 'Ben Quadinaros',
+ 'Berch Teller',
+ 'Beru Lars',
+ 'Bib Fortuna',
+ 'Biggs Darklighter',
+ 'Black Krrsantan',
+ 'Bo-Katan Kryze',
+ 'Boba Fett',
+ 'Bobbajo',
+ 'Bodhi Rook',
+ 'Borvo the Hutt',
+ 'Boss Nass',
+ 'Bossk',
+ 'Breha Antilles-Organa',
+ 'Bren Derlin',
+ 'Brendol Hux',
+ 'BT-1',
+ 'C-3PO',
+ 'C1-10P',
+ 'Cad Bane',
+ 'Caluan Ematt',
+ 'Captain Gregor',
+ 'Captain Phasma',
+ 'Captain Quarsh Panaka',
+ 'Captain Rex',
+ 'Carlist Rieekan',
+ 'Casca Panzoro',
+ 'Cassian Andor',
+ 'Cassio Tagge',
+ 'Cham Syndulla',
+ 'Che Amanwe Papanoida',
+ 'Chewbacca',
+ 'Chi Eekway Papanoida',
+ 'Chief Chirpa',
+ 'Chirrut Îmwe',
+ 'Ciena Ree',
+ 'Cin Drallig',
+ 'Clegg Holdfast',
+ 'Cliegg Lars',
+ 'Coleman Kcaj',
+ 'Coleman Trebor',
+ 'Colonel Kaplan',
+ 'Commander Bly',
+ 'Commander Cody (CC-2224)',
+ 'Commander Fil (CC-3714)',
+ 'Commander Fox',
+ 'Commander Gree',
+ 'Commander Jet',
+ 'Commander Wolffe',
+ 'Conan Antonio Motti',
+ 'Conder Kyl',
+ 'Constable Zuvio',
+ 'Cordé',
+ 'Cpatain Typho',
+ 'Crix Madine',
+ 'Cut Lawquane',
+ 'Dak Ralter',
+ 'Dapp',
+ 'Darth Bane',
+ 'Darth Maul',
+ 'Darth Tyranus',
+ 'Daultay Dofine',
+ 'Del Meeko',
+ 'Delian Mors',
+ 'Dengar',
+ 'Depa Billaba',
+ 'Derek Klivian',
+ 'Dexter Jettster',
+ 'Dineé Ellberger',
+ 'DJ',
+ 'Doctor Aphra',
+ 'Doctor Evazan',
+ 'Dogma',
+ 'Dormé',
+ 'Dr. Cylo',
+ 'Droidbait',
+ 'Droopy McCool',
+ 'Dryden Vos',
+ 'Dud Bolt',
+ 'Ebe E. Endocott',
+ 'Echuu Shen-Jon',
+ 'Eeth Koth',
+ 'Eighth Brother',
+ 'Eirtaé',
+ 'Eli Vanto',
+ 'Ellé',
+ 'Ello Asty',
+ 'Embo',
+ 'Eneb Ray',
+ 'Enfys Nest',
+ 'EV-9D9',
+ 'Evaan Verlaine',
+ 'Even Piell',
+ 'Ezra Bridger',
+ 'Faro Argyus',
+ 'Feral',
+ 'Fifth Brother',
+ 'Finis Valorum',
+ 'Finn',
+ 'Fives',
+ 'FN-1824',
+ 'FN-2003',
+ 'Fodesinbeed Annodue',
+ 'Fulcrum',
+ 'FX-7',
+ 'GA-97',
+ 'Galen Erso',
+ 'Gallius Rax',
+ 'Garazeb "Zeb" Orrelios',
+ 'Gardulla the Hutt',
+ 'Garrick Versio',
+ 'Garven Dreis',
+ 'Gavyn Sykes',
+ 'Gideon Hask',
+ 'Gizor Dellso',
+ 'Gonk droid',
+ 'Grand Inquisitor',
+ 'Greeata Jendowanian',
+ 'Greedo',
+ 'Greer Sonnel',
+ 'Grievous',
+ 'Grummgar',
+ 'Gungi',
+ 'Hammerhead',
+ 'Han Solo',
+ 'Harter Kalonia',
+ 'Has Obbit',
+ 'Hera Syndulla',
+ 'Hevy',
+ 'Hondo Ohnaka',
+ 'Huyang',
+ 'Iden Versio',
+ 'IG-88',
+ 'Ima-Gun Di',
+ 'Inquisitors',
+ 'Inspector Thanoth',
+ 'Jabba',
+ 'Jacen Syndulla',
+ 'Jan Dodonna',
+ 'Jango Fett',
+ 'Janus Greejatus',
+ 'Jar Jar Binks',
+ 'Jas Emari',
+ 'Jaxxon',
+ 'Jek Tono Porkins',
+ 'Jeremoch Colton',
+ 'Jira',
+ 'Jobal Naberrie',
+ 'Jocasta Nu',
+ 'Joclad Danva',
+ 'Joh Yowza',
+ 'Jom Barell',
+ 'Joph Seastriker',
+ 'Jova Tarkin',
+ 'Jubnuk',
+ 'Jyn Erso',
+ 'K-2SO',
+ 'Kanan Jarrus',
+ 'Karbin',
+ 'Karina the Great',
+ 'Kes Dameron',
+ 'Ketsu Onyo',
+ 'Ki-Adi-Mundi',
+ 'King Katuunko',
+ 'Kit Fisto',
+ 'Kitster Banai',
+ 'Klaatu',
+ 'Klik-Klak',
+ 'Korr Sella',
+ 'Kylo Ren',
+ 'L3-37',
+ 'Lama Su',
+ 'Lando Calrissian',
+ 'Lanever Villecham',
+ 'Leia Organa',
+ 'Letta Turmond',
+ 'Lieutenant Kaydel Ko Connix',
+ 'Lieutenant Thire',
+ 'Lobot',
+ 'Logray',
+ 'Lok Durd',
+ 'Longo Two-Guns',
+ 'Lor San Tekka',
+ 'Lorth Needa',
+ 'Lott Dod',
+ 'Luke Skywalker',
+ 'Lumat',
+ 'Luminara Unduli',
+ 'Lux Bonteri',
+ 'Lyn Me',
+ 'Lyra Erso',
+ 'Mace Windu',
+ 'Malakili',
+ 'Mama the Hutt',
+ 'Mars Guo',
+ 'Mas Amedda',
+ 'Mawhonic',
+ 'Max Rebo',
+ 'Maximilian Veers',
+ 'Maz Kanata',
+ 'ME-8D9',
+ 'Meena Tills',
+ 'Mercurial Swift',
+ 'Mina Bonteri',
+ 'Miraj Scintel',
+ 'Mister Bones',
+ 'Mod Terrik',
+ 'Moden Canady',
+ 'Mon Mothma',
+ 'Moradmin Bast',
+ 'Moralo Eval',
+ 'Morley',
+ 'Mother Talzin',
+ 'Nahdar Vebb',
+ 'Nahdonnis Praji',
+ 'Nien Nunb',
+ 'Niima the Hutt',
+ 'Nines',
+ 'Norra Wexley',
+ 'Nute Gunray',
+ 'Nuvo Vindi',
+ 'Obi-Wan Kenobi',
+ 'Odd Ball',
+ 'Ody Mandrell',
+ 'Omi',
+ 'Onaconda Farr',
+ 'Oola',
+ 'OOM-9',
+ 'Oppo Rancisis',
+ 'Orn Free Taa',
+ 'Oro Dassyne',
+ 'Orrimarko',
+ 'Osi Sobeck',
+ 'Owen Lars',
+ 'Pablo-Jill',
+ 'Padmé Amidala',
+ 'Pagetti Rook',
+ 'Paige Tico',
+ 'Paploo',
+ 'Petty Officer Thanisson',
+ 'Pharl McQuarrie',
+ 'Plo Koon',
+ 'Po Nudo',
+ 'Poe Dameron',
+ 'Poggle the Lesser',
+ 'Pong Krell',
+ 'Pooja Naberrie',
+ 'PZ-4CO',
+ 'Quarrie',
+ 'Quay Tolsite',
+ 'Queen Apailana',
+ 'Queen Jamillia',
+ 'Queen Neeyutnee',
+ 'Qui-Gon Jinn',
+ 'Quiggold',
+ 'Quinlan Vos',
+ 'R2-D2',
+ 'R2-KT',
+ 'R3-S6',
+ 'R4-P17',
+ 'R5-D4',
+ 'RA-7',
+ 'Rabé',
+ 'Rako Hardeen',
+ 'Ransolm Casterfo',
+ 'Rappertunie',
+ 'Ratts Tyerell',
+ 'Raymus Antilles',
+ 'Ree-Yees',
+ 'Reeve Panzoro',
+ 'Rey',
+ 'Ric Olié',
+ 'Riff Tamson',
+ 'Riley',
+ 'Rinnriyin Di',
+ 'Rio Durant',
+ 'Rogue Squadron',
+ 'Romba',
+ 'Roos Tarpals',
+ 'Rose Tico',
+ 'Rotta the Hutt',
+ 'Rukh',
+ 'Rune Haako',
+ 'Rush Clovis',
+ 'Ruwee Naberrie',
+ 'Ryoo Naberrie',
+ 'Sabé',
+ 'Sabine Wren',
+ 'Saché',
+ 'Saelt-Marae',
+ 'Saesee Tiin',
+ 'Salacious B. Crumb',
+ 'San Hill',
+ 'Sana Starros',
+ 'Sarco Plank',
+ 'Sarkli',
+ 'Satine Kryze',
+ 'Savage Opress',
+ 'Sebulba',
+ 'Senator Organa',
+ 'Sergeant Kreel',
+ 'Seventh Sister',
+ 'Shaak Ti',
+ 'Shara Bey',
+ 'Shmi Skywalker',
+ 'Shu Mai',
+ 'Sidon Ithano',
+ 'Sifo-Dyas',
+ 'Sim Aloo',
+ 'Siniir Rath Velus',
+ 'Sio Bibble',
+ 'Sixth Brother',
+ 'Slowen Lo',
+ 'Sly Moore',
+ 'Snaggletooth',
+ 'Snap Wexley',
+ 'Snoke',
+ 'Sola Naberrie',
+ 'Sora Bulq',
+ 'Strono Tuggs',
+ 'Sy Snootles',
+ 'Tallissan Lintra',
+ 'Tarfful',
+ 'Tasu Leech',
+ 'Taun We',
+ 'TC-14',
+ 'Tee Watt Kaa',
+ 'Teebo',
+ 'Teedo',
+ 'Teemto Pagalies',
+ 'Temiri Blagg',
+ 'Tessek',
+ 'Tey How',
+ 'Thane Kyrell',
+ 'The Bendu',
+ 'The Smuggler',
+ 'Thrawn',
+ 'Tiaan Jerjerrod',
+ 'Tion Medon',
+ 'Tobias Beckett',
+ 'Tulon Voidgazer',
+ 'Tup',
+ 'U9-C4',
+ 'Unkar Plutt',
+ 'Val Beckett',
+ 'Vanden Willard',
+ 'Vice Admiral Amilyn Holdo',
+ 'Vober Dand',
+ 'WAC-47',
+ 'Wag Too',
+ 'Wald',
+ 'Walrus Man',
+ 'Warok',
+ 'Wat Tambor',
+ 'Watto',
+ 'Wedge Antilles',
+ 'Wes Janson',
+ 'Wicket W. Warrick',
+ 'Wilhuff Tarkin',
+ 'Wollivan',
+ 'Wuher',
+ 'Wullf Yularen',
+ 'Xamuel Lennox',
+ 'Yaddle',
+ 'Yarael Poof',
+ 'Yoda',
+ 'Zam Wesell',
+ 'Zev Senesca',
+ 'Ziro the Hutt',
+ 'Zuckuss',
+];
+
+const dummyLookupService = {
+ search(string, callback) {
+ setTimeout(() => {
+ const results = dummyMentionsData.filter((mention) =>
+ mention.toLowerCase().includes(string.toLowerCase()),
+ );
+ callback(results);
+ }, 500);
+ },
+};
+
+function useMentionLookupService(mentionString) {
+ const [results, setResults] = useState([]);
+
+ useEffect(() => {
+ const cachedResults = mentionsCache.get(mentionString);
+
+ if (mentionString == null) {
+ setResults([]);
+ return;
+ }
+
+ if (cachedResults === null) {
+ return;
+ } else if (cachedResults !== undefined) {
+ setResults(cachedResults);
+ return;
+ }
+
+ mentionsCache.set(mentionString, null);
+ dummyLookupService.search(mentionString, (newResults) => {
+ mentionsCache.set(mentionString, newResults);
+ setResults(newResults);
+ });
+ }, [mentionString]);
+
+ return results;
+}
+
+function checkForAtSignMentions(
+ text,
+ minMatchLength,
+){
+ let match = AtSignMentionsRegex.exec(text);
+
+ if (match === null) {
+ match = AtSignMentionsRegexAliasRegex.exec(text);
+ }
+ if (match !== null) {
+ // The strategy ignores leading whitespace but we need to know it's
+ // length to add it to the leadOffset
+ const maybeLeadingWhitespace = match[1];
+
+ const matchingString = match[3];
+ if (matchingString.length >= minMatchLength) {
+ return {
+ leadOffset: match.index + maybeLeadingWhitespace.length,
+ matchingString,
+ replaceableString: match[2],
+ };
+ }
+ }
+ return null;
+}
+
+function getPossibleQueryMatch(text) {
+ return checkForAtSignMentions(text, 1);
+}
+
+class MentionTypeaheadOption extends MenuOption {
+ name;
+ picture;
+
+ constructor(name, picture) {
+ super(name);
+ this.name = name;
+ this.picture = picture;
+ }
+}
+
+function MentionsTypeaheadMenuItem({
+ index,
+ isSelected,
+ onClick,
+ onMouseEnter,
+ option,
+}) {
+ let className = 'item';
+ if (isSelected) {
+ className += ' selected';
+ }
+ return (
+
+ {option.picture}
+ {option.name}
+
+ );
+}
+
+// export default function NewMentionsPlugin() {
+// const [editor] = useLexicalComposerContext();
+//
+// const [queryString, setQueryString] = useState(null);
+//
+// const results = useMentionLookupService(queryString);
+//
+// const checkForSlashTriggerMatch = useBasicTypeaheadTriggerMatch('/', {
+// minLength: 0,
+// });
+//
+// const options = useMemo(
+// () =>
+// results
+// .map(
+// (result) =>
+// new MentionTypeaheadOption(result,
),
+// )
+// .slice(0, SUGGESTION_LIST_LENGTH_LIMIT),
+// [results],
+// );
+//
+// const onSelectOption = useCallback(
+// (
+// selectedOption,
+// nodeToReplace,
+// closeMenu,
+// ) => {
+// editor.update(() => {
+// const mentionNode = $createMentionNode(selectedOption.name);
+// if (nodeToReplace) {
+// nodeToReplace.replace(mentionNode);
+// }
+// mentionNode.select();
+// closeMenu();
+// });
+// },
+// [editor],
+// );
+//
+// const checkForMentionMatch = useCallback(
+// (text) => {
+// const slashMatch = checkForSlashTriggerMatch(text, editor);
+// if (slashMatch !== null) {
+// return null;
+// }
+// return getPossibleQueryMatch(text);
+// },
+// [checkForSlashTriggerMatch, editor],
+// );
+//
+// return (
+//
+// onQueryChange={setQueryString}
+// onSelectOption={onSelectOption}
+// triggerFn={checkForMentionMatch}
+// options={options}
+// menuRenderFn={(
+// anchorElementRef,
+// {selectedIndex, selectOptionAndCleanUp, setHighlightedIndex},
+// ) =>
+// anchorElementRef.current && results.length
+// ? ReactDOM.createPortal(
+//
+//
+// {options.map((option, i) => (
+// {
+// setHighlightedIndex(i);
+// selectOptionAndCleanUp(option);
+// }}
+// onMouseEnter={() => {
+// setHighlightedIndex(i);
+// }}
+// key={option.key}
+// option={option}
+// />
+// ))}
+//
+//
,
+// anchorElementRef.current,
+// )
+// : null
+// }
+// />
+// );
+// }
diff --git a/src/pages/Note/Hlexical/plugins/SaveFilePlugin.js b/src/pages/Note/Hlexical/plugins/SaveFilePlugin.js
index cd317cb..06209df 100644
--- a/src/pages/Note/Hlexical/plugins/SaveFilePlugin.js
+++ b/src/pages/Note/Hlexical/plugins/SaveFilePlugin.js
@@ -13,7 +13,7 @@ const {ipcRenderer} = window.require('electron')
const SaveFilePlugin=(props)=> {
let activeKey = useSelector(state => state.tableBarItem.activeKey);
const dispatch = useDispatch();
- const [messageApi,contextHolder] = message.useMessage();
+ // const [messageApi,contextHolder] = message.useMessage();
const [editor] = useLexicalComposerContext();
const [editorState,setEditorState]=useState();
@@ -86,7 +86,8 @@ const SaveFilePlugin=(props)=> {
if (save) {
overWriteFile(filePath, resultSave)
console.log("保存成功"+ filePath)
- messageApi.open({type:"success",content:"保存成功:" + filePath,duration:1})
+ // messageApi.open({type:"success",content:"保存成功:" + filePath,duration:1})
+ message.success("保存成功:" + filePath)
}
}).catch(error =>
console.error(error)
@@ -106,10 +107,10 @@ const SaveFilePlugin=(props)=> {
};
},[editor,onChange]
)
- return (
- <>
- {contextHolder}
- >
- )
+ // return (
+ //
+ // {contextHolder}
+ //
+ // )
}
export default SaveFilePlugin
diff --git a/src/pages/Note/Hlexical/plugins/ToolbarPlugin.js b/src/pages/Note/Hlexical/plugins/ToolbarPlugin.js
index deecc04..9404a98 100644
--- a/src/pages/Note/Hlexical/plugins/ToolbarPlugin.js
+++ b/src/pages/Note/Hlexical/plugins/ToolbarPlugin.js
@@ -728,7 +728,7 @@ export default function ToolbarPlugin() {
{/**/}
{
- showModal('Insert Image', (onClose) => (
+ showModal('插入图片', (onClose) => (
+ );
+}
diff --git a/src/pages/Note/Hlexical/utils/url/index.jsx b/src/pages/Note/Hlexical/utils/url/index.jsx
new file mode 100644
index 0000000..cfbb5b5
--- /dev/null
+++ b/src/pages/Note/Hlexical/utils/url/index.jsx
@@ -0,0 +1,27 @@
+const SUPPORTED_URL_PROTOCOLS = new Set([
+ 'http:',
+ 'https:',
+ 'mailto:',
+ 'sms:',
+ 'tel:',
+]);
+
+export function sanitizeUrl(url) {
+ try {
+ const parsedUrl = new URL(url);
+ // eslint-disable-next-line no-script-url
+ if (!SUPPORTED_URL_PROTOCOLS.has(parsedUrl.protocol)) {
+ return 'about:blank';
+ }
+ } catch {
+ return url;
+ }
+ return url;
+}
+
+const urlRegExp = new RegExp(
+ /((([A-Za-z]{3,9}:(?:\/\/)?)(?:[-;:&=+$,\w]+@)?[A-Za-z0-9.-]+|(?:www.|[-;:&=+$,\w]+@)[A-Za-z0-9.-]+)((?:\/[+~%/.\w-_]*)?\??(?:[-+=&;%@.\w_]*)#?(?:[\w]*))?)/,
+);
+export function validateUrl(url) {
+ return url === 'https://' || urlRegExp.test(url);
+}