MCPcopy Create free account
hub / github.com/mailvelope/mailvelope / RecipientInput

Function RecipientInput

src/components/editor/components/RecipientInput.js:56–149  ·  view source on GitHub ↗
({extraKey, hideErrorMsg, keys, recipients, onChangeRecipients})

Source from the content-addressed store, hash-verified

54}
55
56export function RecipientInput({extraKey, hideErrorMsg, keys, recipients, onChangeRecipients}) {
57 const idRef = useRef(getUUID());
58
59 const tags = useMemo(
60 () => recipients.map(r => recipientToTag(r, keys, extraKey)),
61 [recipients, keys, extraKey]
62 );
63
64 const updateParentRecipients = nextTags => onChangeRecipients(nextTags.map(t => tagToRecipient(t, keys)));
65
66 const onDelete = tagIndex => updateParentRecipients(tags.filter((_, i) => i !== tagIndex));
67
68 const onAddition = newTag => {
69 if (!isValidAddress(newTag.id)) {
70 return;
71 }
72 updateParentRecipients([...tags, newTag]);
73 // <ReactTags> exposes neither its input element nor a focus API, so we
74 // re-focus by querying for it after the parent state update lands.
75 setTimeout(() => {
76 const inputElem = document.querySelector(`[id="${idRef.current}"] .tag-input-field`);
77 inputElem?.focus();
78 }, 0);
79 };
80
81 const onFilterSuggestions = (textInputValue, possibleSuggestionsArray) => {
82 const lowerCaseQuery = textInputValue.toLowerCase();
83 return possibleSuggestionsArray
84 .filter(suggestion => suggestion.text.toLowerCase().includes(lowerCaseQuery))
85 .slice(0, 10);
86 };
87
88 const suggestions = keys
89 .filter(key => !tags.find(tag => tag.id === key.email))
90 .map(key => ({
91 id: key.email,
92 text: `${key.userId} - ${key.keyId}`,
93 }));
94
95 const renderSuggestion = ({text}, query) => {
96 query = query.trim();
97 let html = text.replaceAll(query, `<mark>${query}</mark>`);
98 html = encodeHTML(html);
99 html = html.replaceAll('&lt;mark&gt;', '<mark>').replaceAll('&lt;&#x2F;mark&gt;', '</mark>'); // decode mark tag
100 return <span dangerouslySetInnerHTML={{__html: html}} />;
101 };
102
103 const showNotFoundAlert = !hideErrorMsg && !extraKey && hasAnyUnresolvedRecipient(recipients, keys);
104 const showExtraKeyAlert = extraKey && !recipients.some(r => r.lookupPending);
105
106 return (
107 <div id={idRef.current} className="mb-0">
108 <ReactTags
109 tags={tags}
110 suggestions={suggestions}
111 renderSuggestion = {renderSuggestion}
112 handleDelete={onDelete}
113 handleAddition={onAddition}

Callers

nothing calls this directly

Calls 3

getUUIDFunction · 0.90
recipientToTagFunction · 0.85

Tested by

no test coverage detected