You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

71 lines
2.4 KiB

import postEditor from '@/services/post-editor.service'
import { useCallback, useEffect, useMemo, useState } from 'react'
import type { Editor } from '@tiptap/core'
import type { PickerSearchMode } from '@/services/mention-event-search.service'
import NeventNaddrPickerDialog from './NeventNaddrPickerDialog'
import { NeventPickerContext } from './nevent-picker-context'
import { OPEN_NEVENT_PICKER_EVENT, extendMentionRangeToEndOfWord } from './suggestion'
export function NeventPickerProvider({ children }: { children: React.ReactNode }) {
const [open, setOpen] = useState(false)
const [onSelectedRef, setOnSelectedRef] = useState<((link: string) => void) | null>(null)
const [initialMode, setInitialMode] = useState<PickerSearchMode>('nevent')
useEffect(() => {
const handler = (e: Event) => {
const { editor, range, initialMode: detailMode } = (
e as CustomEvent<{
editor: Editor
range: { from: number; to: number }
initialMode?: PickerSearchMode
}>
).detail
const to = extendMentionRangeToEndOfWord(editor, range)
setOnSelectedRef(() => (link: string) => {
editor.chain().focus().insertContentAt({ from: range.from, to }, link + ' ').run()
postEditor.closeSuggestionPopup()
})
setInitialMode(detailMode ?? 'nevent')
setOpen(true)
}
window.addEventListener(OPEN_NEVENT_PICKER_EVENT, handler)
return () => window.removeEventListener(OPEN_NEVENT_PICKER_EVENT, handler)
}, [])
const openNeventPicker = useCallback((onSelected: (nostrLink: string) => void, mode?: PickerSearchMode) => {
setOnSelectedRef(() => onSelected)
setInitialMode(mode ?? 'nevent')
setOpen(true)
}, [])
const handleSelect = useCallback(
(link: string) => {
onSelectedRef?.(link)
setOnSelectedRef(null)
postEditor.closeSuggestionPopup()
},
[onSelectedRef]
)
const handleOpenChange = useCallback((next: boolean) => {
if (!next) {
setOnSelectedRef(null)
setInitialMode('nevent')
}
setOpen(next)
}, [])
const value = useMemo(() => ({ openNeventPicker }), [openNeventPicker])
return (
<NeventPickerContext.Provider value={value}>
{children}
<NeventNaddrPickerDialog
open={open}
onOpenChange={handleOpenChange}
onSelect={handleSelect}
initialMode={initialMode}
/>
</NeventPickerContext.Provider>
)
}