fix: position session action menu at touch/click point

- Updated useLongPress.ts to pass click coordinates to onLongPress callback
- Modified SessionList.tsx to use menuAnchorPoint state instead of menuAnchorRef
- Updated SessionActionMenu.tsx to position menu based on anchorPoint coordinates
- Enhanced SessionHeader.tsx to calculate anchorPoint from button position and added stopPropagation to fix toggle issue

The menu now appears at the exact touch/click position instead of being centered or aligned to the button edge.
This commit is contained in:
weishu
2026-01-12 19:08:01 +08:00
parent 83664a7fc9
commit 8ed94193d8
4 changed files with 38 additions and 44 deletions
+5 -6
View File
@@ -1,4 +1,4 @@
import { useEffect, useMemo, useRef, useState } from 'react'
import { useEffect, useMemo, useState } from 'react'
import type { SessionSummary } from '@/types/api'
import type { ApiClient } from '@/api/client'
import { useLongPress } from '@/hooks/useLongPress'
@@ -171,7 +171,7 @@ function SessionItem(props: {
const { session: s, onSelect, showPath = true, api } = props
const { haptic } = usePlatform()
const [menuOpen, setMenuOpen] = useState(false)
const menuAnchorRef = useRef<HTMLButtonElement | null>(null)
const [menuAnchorPoint, setMenuAnchorPoint] = useState<{ x: number; y: number }>({ x: 0, y: 0 })
const [renameOpen, setRenameOpen] = useState(false)
const [archiveOpen, setArchiveOpen] = useState(false)
const [deleteOpen, setDeleteOpen] = useState(false)
@@ -183,8 +183,9 @@ function SessionItem(props: {
)
const longPressHandlers = useLongPress({
onLongPress: () => {
onLongPress: (point) => {
haptic.impact('medium')
setMenuAnchorPoint(point)
setMenuOpen(true)
},
onClick: () => {
@@ -204,7 +205,6 @@ function SessionItem(props: {
<button
type="button"
{...longPressHandlers}
ref={menuAnchorRef}
className="session-list-item flex w-full flex-col gap-1.5 px-3 py-3 text-left transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--app-link)] select-none"
style={{ WebkitTouchCallout: 'none' }}
>
@@ -271,8 +271,7 @@ function SessionItem(props: {
onRename={() => setRenameOpen(true)}
onArchive={() => setArchiveOpen(true)}
onDelete={() => setDeleteOpen(true)}
anchorRef={menuAnchorRef}
align="end"
anchorPoint={menuAnchorPoint}
/>
<RenameSessionDialog