e782db33dc
* Unify onPostReply handler * Show just-posted replies above OP replies * Only do this for the highlighted post or thread mode It's confusing to have your post displace OP thread or other people's leaf posts.
94 lines
2.2 KiB
TypeScript
94 lines
2.2 KiB
TypeScript
import React from 'react'
|
|
import {
|
|
AppBskyActorDefs,
|
|
AppBskyEmbedRecord,
|
|
AppBskyRichtextFacet,
|
|
ModerationDecision,
|
|
} from '@atproto/api'
|
|
|
|
import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback'
|
|
|
|
export interface ComposerOptsPostRef {
|
|
uri: string
|
|
cid: string
|
|
text: string
|
|
author: AppBskyActorDefs.ProfileViewBasic
|
|
embed?: AppBskyEmbedRecord.ViewRecord['embed']
|
|
moderation?: ModerationDecision
|
|
}
|
|
export interface ComposerOptsQuote {
|
|
uri: string
|
|
cid: string
|
|
text: string
|
|
facets?: AppBskyRichtextFacet.Main[]
|
|
indexedAt: string
|
|
author: {
|
|
did: string
|
|
handle: string
|
|
displayName?: string
|
|
avatar?: string
|
|
}
|
|
embeds?: AppBskyEmbedRecord.ViewRecord['embeds']
|
|
}
|
|
export interface ComposerOpts {
|
|
replyTo?: ComposerOptsPostRef
|
|
onPost?: (postUri: string | undefined) => void
|
|
quote?: ComposerOptsQuote
|
|
mention?: string // handle of user to mention
|
|
openPicker?: (pos: DOMRect | undefined) => void
|
|
text?: string
|
|
imageUris?: {uri: string; width: number; height: number}[]
|
|
}
|
|
|
|
type StateContext = ComposerOpts | undefined
|
|
type ControlsContext = {
|
|
openComposer: (opts: ComposerOpts) => void
|
|
closeComposer: () => boolean
|
|
}
|
|
|
|
const stateContext = React.createContext<StateContext>(undefined)
|
|
const controlsContext = React.createContext<ControlsContext>({
|
|
openComposer(_opts: ComposerOpts) {},
|
|
closeComposer() {
|
|
return false
|
|
},
|
|
})
|
|
|
|
export function Provider({children}: React.PropsWithChildren<{}>) {
|
|
const [state, setState] = React.useState<StateContext>()
|
|
|
|
const openComposer = useNonReactiveCallback((opts: ComposerOpts) => {
|
|
setState(opts)
|
|
})
|
|
|
|
const closeComposer = useNonReactiveCallback(() => {
|
|
let wasOpen = !!state
|
|
setState(undefined)
|
|
return wasOpen
|
|
})
|
|
|
|
const api = React.useMemo(
|
|
() => ({
|
|
openComposer,
|
|
closeComposer,
|
|
}),
|
|
[openComposer, closeComposer],
|
|
)
|
|
|
|
return (
|
|
<stateContext.Provider value={state}>
|
|
<controlsContext.Provider value={api}>
|
|
{children}
|
|
</controlsContext.Provider>
|
|
</stateContext.Provider>
|
|
)
|
|
}
|
|
|
|
export function useComposerState() {
|
|
return React.useContext(stateContext)
|
|
}
|
|
|
|
export function useComposerControls() {
|
|
return React.useContext(controlsContext)
|
|
}
|