From 9edd61db789b67f258d78910e1f25a26c1865f52 Mon Sep 17 00:00:00 2001 From: codytseng Date: Tue, 27 May 2025 22:39:57 +0800 Subject: [PATCH] feat: add emoji picker to post editor --- src/PageManager.tsx | 8 +++ src/components/EmojiPickerDialog/index.tsx | 51 +++++++++++++++++++ src/components/PostEditor/PostContent.tsx | 22 ++++---- .../PostEditor/PostTextarea/index.tsx | 6 +++ 4 files changed, 78 insertions(+), 9 deletions(-) create mode 100644 src/components/EmojiPickerDialog/index.tsx diff --git a/src/PageManager.tsx b/src/PageManager.tsx index 3389260..5cd6672 100644 --- a/src/PageManager.tsx +++ b/src/PageManager.tsx @@ -12,6 +12,7 @@ import { RefObject, useContext, useEffect, + useRef, useState } from 'react' import ExplorePage from './pages/primary/ExplorePage' @@ -90,6 +91,7 @@ export function PageManager({ maxStackSize = 5 }: { maxStackSize?: number }) { const [secondaryStack, setSecondaryStack] = useState([]) const [isShared, setIsShared] = useState(false) const { isSmallScreen } = useScreenSize() + const ignorePopStateRef = useRef(false) useEffect(() => { window.history.pushState(null, '', window.location.href) @@ -118,8 +120,14 @@ export function PageManager({ maxStackSize = 5 }: { maxStackSize?: number }) { } const onPopState = (e: PopStateEvent) => { + if (ignorePopStateRef.current) { + ignorePopStateRef.current = false + return + } + const closeModal = modalManager.pop() if (closeModal) { + ignorePopStateRef.current = true window.history.forward() return } diff --git a/src/components/EmojiPickerDialog/index.tsx b/src/components/EmojiPickerDialog/index.tsx new file mode 100644 index 0000000..f89ab47 --- /dev/null +++ b/src/components/EmojiPickerDialog/index.tsx @@ -0,0 +1,51 @@ +import { Drawer, DrawerContent, DrawerTrigger } from '@/components/ui/drawer' +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuTrigger +} from '@/components/ui/dropdown-menu' +import { useScreenSize } from '@/providers/ScreenSizeProvider' +import { useState } from 'react' +import EmojiPicker from '../EmojiPicker' + +export default function EmojiPickerDialog({ + children, + onEmojiClick +}: { + children: React.ReactNode + onEmojiClick?: (emoji: string) => void +}) { + const { isSmallScreen } = useScreenSize() + const [open, setOpen] = useState(false) + + if (isSmallScreen) { + return ( + + {children} + + { + setOpen(false) + onEmojiClick?.(data.emoji) + }} + /> + + + ) + } + + return ( + + {children} + + { + e.stopPropagation() + setOpen(false) + onEmojiClick?.(data.emoji) + }} + /> + + + ) +} diff --git a/src/components/PostEditor/PostContent.tsx b/src/components/PostEditor/PostContent.tsx index 4db424b..558aef3 100644 --- a/src/components/PostEditor/PostContent.tsx +++ b/src/components/PostEditor/PostContent.tsx @@ -5,10 +5,11 @@ import { useToast } from '@/hooks/use-toast' import { createCommentDraftEvent, createShortTextNoteDraftEvent } from '@/lib/draft-event' import { useNostr } from '@/providers/NostrProvider' import postContentCache from '@/services/post-content-cache.service' -import { ChevronDown, ImageUp, LoaderCircle } from 'lucide-react' +import { ImageUp, LoaderCircle, Settings, Smile } from 'lucide-react' import { Event, kinds } from 'nostr-tools' import { useRef, useState } from 'react' import { useTranslation } from 'react-i18next' +import EmojiPickerDialog from '../EmojiPickerDialog' import Mentions from './Mentions' import { usePostEditor } from './PostEditorProvider' import PostOptions from './PostOptions' @@ -88,7 +89,7 @@ export default function PostContent({ } return ( -
+
{parentEvent && (
@@ -120,19 +121,22 @@ export default function PostContent({ } accept="image/*,video/*,audio/*" > - + textareaRef.current?.insertText(emoji)}> + +
diff --git a/src/components/PostEditor/PostTextarea/index.tsx b/src/components/PostEditor/PostTextarea/index.tsx index f9e9b10..33319e7 100644 --- a/src/components/PostEditor/PostTextarea/index.tsx +++ b/src/components/PostEditor/PostTextarea/index.tsx @@ -19,6 +19,7 @@ import suggestion from './suggestion' export type TPostTextareaHandle = { appendText: (text: string) => void + insertText: (text: string) => void } const PostTextarea = forwardRef< @@ -94,6 +95,11 @@ const PostTextarea = forwardRef< .insertContent(text) .run() } + }, + insertText: (text: string) => { + if (editor) { + editor.chain().focus().insertContent(text).run() + } } }))