diff --git a/client/package.json b/client/package.json index a70e888..1a7fce6 100644 --- a/client/package.json +++ b/client/package.json @@ -3,12 +3,16 @@ "version": "0.1.0", "private": false, "dependencies": { + "@emoji-mart/data": "^1.1.2", + "@emoji-mart/react": "^1.1.1", "@heroicons/react": "^2.0.18", "@types/jest": "^27.5.2", "@types/node": "^17.0.45", "@types/react": "^18.2.21", "@types/react-dom": "^18.2.7", "@types/react-swipeable-views": "^0.13.2", + "emoji-mart": "^5.5.2", + "emoji-picker-react": "^4.5.15", "link-preview-js": "^3.0.5", "nostr-tools": "latest", "react": "^18.2.0", diff --git a/client/src/components/Forms/Emojis/emoji-picker.tsx b/client/src/components/Forms/Emojis/emoji-picker.tsx new file mode 100644 index 0000000..ef96462 --- /dev/null +++ b/client/src/components/Forms/Emojis/emoji-picker.tsx @@ -0,0 +1,71 @@ +import data, { Emoji } from "@emoji-mart/data"; +import Picker from "@emoji-mart/react"; +import { RefObject } from "react"; +import customEmojis from '../custom_emojis.json'; + +interface EmojiPickerProps { + topOffset: number; + leftOffset: number; + onEmojiSelect: (e: Emoji) => void; + onClickOutside: () => void; + height?: number; + ref: RefObject; +} + +const customCategoryIcons = { + categoryIcons: { + "poast": { + src: 'https://poa.st/emoji/custom/poast_hat.png', + }, + }, +} + +export function EmojiPicker({ + topOffset, + leftOffset, + onEmojiSelect, + onClickOutside, + height = 300, + ref, +}: EmojiPickerProps) { + const customEmojiList = customEmojis.map(pack => { + return { + id: pack.id, + name: pack.name, + emojis: pack.emojis.map(e => { + return { + id: e.shortcode, + name: e.shortcode, + skins: [{ src: e.static_url }], + }; + }), + }; + }); + + return ( + <> +
+ + +
+ + ); +} \ No newline at end of file diff --git a/client/src/components/Forms/PostFormCard.tsx b/client/src/components/Forms/PostFormCard.tsx index ad5d749..0167718 100644 --- a/client/src/components/Forms/PostFormCard.tsx +++ b/client/src/components/Forms/PostFormCard.tsx @@ -2,12 +2,15 @@ import { ArrowUpTrayIcon, CpuChipIcon, ArrowPathIcon, + Square2StackIcon } from "@heroicons/react/24/outline"; import { XCircleIcon } from "@heroicons/react/24/solid"; -import { useState, useEffect, useMemo } from "react"; +import { useState, useEffect, useRef } from "react"; import { generatePrivateKey, getPublicKey, finishEvent, UnsignedEvent, Event as NostrEvent, nip19 } from "nostr-tools"; import { publish } from "../../utils/relays"; import { renderMedia, attachFile } from "../../utils/FileUpload"; +import { EmojiPicker } from "./Emojis/emoji-picker"; +import customEmojis from './custom_emojis.json'; const useWorkers = (numCores: number, unsigned: UnsignedEvent, difficulty: string, deps: any[]) => { const [messageFromWorker, setMessageFromWorker] = useState(null); @@ -54,6 +57,7 @@ const NewNoteCard = ({ refEvent, tagType }: FormProps) => { + const ref = useRef(null); const [comment, setComment] = useState(""); const [file, setFile] = useState(""); const [sk, setSk] = useState(generatePrivateKey()); @@ -77,7 +81,6 @@ const NewNoteCard = ({ const { startWork, messageFromWorker, doingWorkProgress } = useWorkers(numCores, unsigned, difficulty, [unsigned]); - useEffect(() => { if (refEvent && tagType && unsigned.tags.length === 0) { const tags = tagMapping[tagType]; @@ -134,6 +137,43 @@ const NewNoteCard = ({ } }, [messageFromWorker]); + //Emoji stuff + const emojiRef = useRef(null); + const [showEmojiPicker, setShowEmojiPicker] = useState(false); + + interface Emoji { + native?: string; + id?: string; + } + + const emojiNames = customEmojis.map(p => p.emojis).flat(); + function getEmojiById(id: string) { + return emojiNames.find(e => e.shortcode === id); + } + + async function onEmojiSelect(emoji: Emoji) { + setShowEmojiPicker(false); + try { + if (emoji.id) { + const e = getEmojiById(emoji.id); + if (e) { + setComment(comment + " :" + e.shortcode + ":"); + unsigned.tags.push(['emoji', e.shortcode, e.url]); + }; + } + } catch { + //ignore + } + } + + const topOffset = ref.current?.getBoundingClientRect().top; + const leftOffset = ref.current?.getBoundingClientRect().left; + + function pickEmoji(e: React.MouseEvent) { + e.stopPropagation(); + setShowEmojiPicker(!showEmojiPicker); + } + return (