2023-01-16 22:23:24 +00:00
|
|
|
import "@webscopeio/react-textarea-autocomplete/style.css";
|
2023-01-16 17:48:25 +00:00
|
|
|
import "./Textarea.css";
|
2023-01-14 10:07:49 +00:00
|
|
|
|
2023-02-07 19:47:57 +00:00
|
|
|
import { useIntl } from "react-intl";
|
2023-01-14 10:07:49 +00:00
|
|
|
import ReactTextareaAutocomplete from "@webscopeio/react-textarea-autocomplete";
|
2023-01-18 22:16:43 +00:00
|
|
|
import emoji from "@jukben/emoji-search";
|
2023-01-15 23:44:50 +00:00
|
|
|
import TextareaAutosize from "react-textarea-autosize";
|
2023-03-25 22:55:34 +00:00
|
|
|
import { NostrPrefix } from "@snort/nostr";
|
2023-01-14 10:07:49 +00:00
|
|
|
|
2023-01-20 11:11:50 +00:00
|
|
|
import Avatar from "Element/Avatar";
|
|
|
|
import Nip05 from "Element/Nip05";
|
|
|
|
import { hexToBech32 } from "Util";
|
2023-03-29 12:10:22 +00:00
|
|
|
import { MetadataCache } from "Cache";
|
|
|
|
import { UserCache } from "Cache/UserCache";
|
2023-01-14 10:07:49 +00:00
|
|
|
|
2023-02-08 21:10:26 +00:00
|
|
|
import messages from "./messages";
|
|
|
|
|
2023-01-18 22:16:43 +00:00
|
|
|
interface EmojiItemProps {
|
2023-02-07 20:04:50 +00:00
|
|
|
name: string;
|
|
|
|
char: string;
|
2023-01-18 22:16:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const EmojiItem = ({ entity: { name, char } }: { entity: EmojiItemProps }) => {
|
|
|
|
return (
|
|
|
|
<div className="emoji-item">
|
|
|
|
<div className="emoji">{char}</div>
|
|
|
|
<div className="emoji-name">{name}</div>
|
|
|
|
</div>
|
2023-02-07 20:04:50 +00:00
|
|
|
);
|
|
|
|
};
|
2023-01-18 22:16:43 +00:00
|
|
|
|
2023-01-16 23:19:50 +00:00
|
|
|
const UserItem = (metadata: MetadataCache) => {
|
2023-02-07 19:47:57 +00:00
|
|
|
const { pubkey, display_name, nip05, ...rest } = metadata;
|
2023-01-14 10:07:49 +00:00
|
|
|
return (
|
2023-01-14 10:18:01 +00:00
|
|
|
<div key={pubkey} className="user-item">
|
2023-01-14 10:07:49 +00:00
|
|
|
<div className="user-picture">
|
2023-01-16 23:19:50 +00:00
|
|
|
<Avatar user={metadata} />
|
2023-01-14 10:07:49 +00:00
|
|
|
</div>
|
|
|
|
<div className="user-details">
|
2023-01-14 10:18:01 +00:00
|
|
|
<strong>{display_name || rest.name}</strong>
|
2023-01-15 12:02:45 +00:00
|
|
|
<Nip05 nip05={nip05} pubkey={pubkey} />
|
2023-01-14 10:07:49 +00:00
|
|
|
</div>
|
|
|
|
</div>
|
2023-02-07 20:04:50 +00:00
|
|
|
);
|
|
|
|
};
|
2023-01-14 10:07:49 +00:00
|
|
|
|
2023-02-07 19:47:57 +00:00
|
|
|
interface TextareaProps {
|
|
|
|
autoFocus: boolean;
|
|
|
|
className: string;
|
|
|
|
onChange(ev: React.ChangeEvent<HTMLTextAreaElement>): void;
|
|
|
|
value: string;
|
|
|
|
onFocus(): void;
|
2023-04-10 09:59:38 +00:00
|
|
|
onKeyDown(ev: React.KeyboardEvent<HTMLTextAreaElement>): void;
|
2023-02-07 19:47:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const Textarea = (props: TextareaProps) => {
|
2023-02-08 21:10:26 +00:00
|
|
|
const { formatMessage } = useIntl();
|
2023-01-16 23:19:50 +00:00
|
|
|
|
2023-03-03 14:30:31 +00:00
|
|
|
const userDataProvider = async (token: string) => {
|
|
|
|
return await UserCache.search(token);
|
2023-02-07 20:04:50 +00:00
|
|
|
};
|
2023-01-16 23:19:50 +00:00
|
|
|
|
2023-01-18 22:16:43 +00:00
|
|
|
const emojiDataProvider = (token: string) => {
|
|
|
|
return emoji(token)
|
2023-01-20 11:19:38 +00:00
|
|
|
.slice(0, 5)
|
2023-01-18 22:16:43 +00:00
|
|
|
.map(({ name, char }) => ({ name, char }));
|
2023-02-07 20:04:50 +00:00
|
|
|
};
|
2023-01-18 22:16:43 +00:00
|
|
|
|
2023-01-16 13:17:29 +00:00
|
|
|
return (
|
2023-02-07 19:47:57 +00:00
|
|
|
// @ts-expect-error If anybody can figure out how to type this, please do
|
2023-01-16 13:17:29 +00:00
|
|
|
<ReactTextareaAutocomplete
|
2023-02-13 10:47:52 +00:00
|
|
|
dir="auto"
|
2023-02-07 19:47:57 +00:00
|
|
|
{...props}
|
|
|
|
loadingComponent={() => <span>Loading...</span>}
|
2023-02-08 21:10:26 +00:00
|
|
|
placeholder={formatMessage(messages.NotePlaceholder)}
|
2023-01-16 13:17:29 +00:00
|
|
|
textAreaComponent={TextareaAutosize}
|
|
|
|
trigger={{
|
2023-01-18 22:16:43 +00:00
|
|
|
":": {
|
|
|
|
dataProvider: emojiDataProvider,
|
|
|
|
component: EmojiItem,
|
2023-02-07 19:47:57 +00:00
|
|
|
output: (item: EmojiItemProps) => item.char,
|
2023-01-18 22:16:43 +00:00
|
|
|
},
|
2023-01-16 13:17:29 +00:00
|
|
|
"@": {
|
|
|
|
afterWhitespace: true,
|
2023-01-16 23:19:50 +00:00
|
|
|
dataProvider: userDataProvider,
|
2023-02-09 12:26:54 +00:00
|
|
|
component: (props: { entity: MetadataCache }) => <UserItem {...props.entity} />,
|
2023-03-25 22:55:34 +00:00
|
|
|
output: (item: { pubkey: string }) => `@${hexToBech32(NostrPrefix.PublicKey, item.pubkey)}`,
|
2023-02-07 20:04:50 +00:00
|
|
|
},
|
2023-01-16 13:17:29 +00:00
|
|
|
}}
|
|
|
|
/>
|
2023-02-07 20:04:50 +00:00
|
|
|
);
|
|
|
|
};
|
2023-01-15 01:46:13 +00:00
|
|
|
|
2023-02-07 20:04:50 +00:00
|
|
|
export default Textarea;
|