diff --git a/src/components/Note/SelectionHighlightTrigger.tsx b/src/components/Note/SelectionHighlightTrigger.tsx index cc8554cb..5f614cc1 100644 --- a/src/components/Note/SelectionHighlightTrigger.tsx +++ b/src/components/Note/SelectionHighlightTrigger.tsx @@ -1,5 +1,6 @@ import { buildHighlightDataFromEvent } from '@/lib/build-highlight-data' import { useCreateHighlight } from './CreateHighlightContext' +import { Drawer, DrawerContent, DrawerHeader, DrawerTitle } from '@/components/ui/drawer' import { useScreenSize } from '@/providers/ScreenSizeProvider' import { Event } from 'nostr-tools' import { Highlighter } from 'lucide-react' @@ -7,7 +8,9 @@ import { useCallback, useEffect, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' import { Button } from '@/components/ui/button' +/** After finger lift, wait before treating the gesture as finished (handle drag may still run). */ const MOBILE_TOUCH_END_SETTLE_MS = 600 +/** After selection stops changing, wait before opening the drawer so handles can extend the range. */ const MOBILE_SELECTION_STABLE_MS = 1600 const DESKTOP_SELECTION_DELAY_MS = 50 @@ -79,6 +82,7 @@ export default function SelectionHighlightTrigger({ const [selectedText, setSelectedText] = useState('') const [paragraphContext, setParagraphContext] = useState('') const [toolbarPos, setToolbarPos] = useState<{ top: number; left: number } | null>(null) + const [showMobileDrawer, setShowMobileDrawer] = useState(false) const debounceRef = useRef | null>(null) const touchEndTimeoutRef = useRef | null>(null) @@ -90,6 +94,7 @@ export default function SelectionHighlightTrigger({ setSelectedText('') setParagraphContext('') setToolbarPos(null) + setShowMobileDrawer(false) }, []) const applySelection = useCallback( @@ -101,19 +106,25 @@ export default function SelectionHighlightTrigger({ return } - if (isSmallScreen && isSelectingRef.current && !forceShow) return - setSelectedText(hit.selectedText) setParagraphContext(hit.paragraphContext) - const toolbarHeight = isSmallScreen ? 48 : 44 - const toolbarWidth = isSmallScreen ? 200 : 176 + if (isSmallScreen) { + if (forceShow || !isSelectingRef.current) { + setShowMobileDrawer(true) + setToolbarPos(null) + } + return + } + + const toolbarHeight = 44 const margin = 8 const top = hit.rect.top - toolbarHeight < margin ? hit.rect.bottom + margin : hit.rect.top - toolbarHeight - const rawLeft = hit.rect.left + hit.rect.width / 2 - toolbarWidth / 2 - const left = Math.max(margin, Math.min(rawLeft, window.innerWidth - toolbarWidth - margin)) + const rawLeft = hit.rect.left + hit.rect.width / 2 - 80 + const left = Math.max(margin, Math.min(rawLeft, window.innerWidth - 176 - margin)) setToolbarPos({ top, left }) + setShowMobileDrawer(false) }, [clearUi, isSmallScreen, openHighlight] ) @@ -149,14 +160,14 @@ export default function SelectionHighlightTrigger({ if (!isSmallScreen) return isSelectingRef.current = true if (selectionStableTimeoutRef.current) clearTimeout(selectionStableTimeoutRef.current) - setToolbarPos(null) + setShowMobileDrawer(false) } const onTouchMove = () => { if (!isSmallScreen) return isSelectingRef.current = true if (selectionStableTimeoutRef.current) clearTimeout(selectionStableTimeoutRef.current) - setToolbarPos(null) + setShowMobileDrawer(false) } const onTouchEnd = () => { @@ -186,7 +197,6 @@ export default function SelectionHighlightTrigger({ return } - setToolbarPos(null) scheduleMobileStableSelection() return } @@ -243,12 +253,12 @@ export default function SelectionHighlightTrigger({ if (!openHighlight) return <>{children} - const showToolbar = selectedText && toolbarPos + const showDesktopToolbar = !isSmallScreen && selectedText && toolbarPos return (
{children} - {showToolbar ? ( + {showDesktopToolbar ? ( <>
{ e.stopPropagation() handleCreateHighlight() @@ -271,8 +281,8 @@ export default function SelectionHighlightTrigger({
- {!isSmallScreen ? ( -
- ) : null} +
) : null} + + {isSmallScreen ? ( + 0} + onOpenChange={(open) => { + setShowMobileDrawer(open) + if (!open) handleDismiss() + }} + > + + + {t('Create Highlight')} + +
+
{t('Selected text')}:
+
“{selectedText}”
+ +
+
+
+ ) : null}
) }