Composer update (react-query refactor) (#1899)
* Move composer state to a context * Rework composer to use RQ --------- Co-authored-by: Eric Bailey <git@esb.lol>
This commit is contained in:
parent
c687172de9
commit
0a26e78dcb
32 changed files with 269 additions and 239 deletions
|
@ -16,7 +16,6 @@ import LinearGradient from 'react-native-linear-gradient'
|
|||
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
|
||||
import {RichText} from '@atproto/api'
|
||||
import {useAnalytics} from 'lib/analytics/analytics'
|
||||
import {UserAutocompleteModel} from 'state/models/discovery/user-autocomplete'
|
||||
import {useIsKeyboardVisible} from 'lib/hooks/useIsKeyboardVisible'
|
||||
import {ExternalEmbed} from './ExternalEmbed'
|
||||
import {Text} from '../util/text/Text'
|
||||
|
@ -26,9 +25,8 @@ import * as Toast from '../util/Toast'
|
|||
import {TextInput, TextInputRef} from './text-input/TextInput'
|
||||
import {CharProgress} from './char-progress/CharProgress'
|
||||
import {UserAvatar} from '../util/UserAvatar'
|
||||
import {useStores} from 'state/index'
|
||||
import * as apilib from 'lib/api/index'
|
||||
import {ComposerOpts} from 'state/models/ui/shell'
|
||||
import {ComposerOpts} from 'state/shell/composer'
|
||||
import {s, colors, gradients} from 'lib/styles'
|
||||
import {sanitizeDisplayName} from 'lib/strings/display-names'
|
||||
import {sanitizeHandle} from 'lib/strings/handles'
|
||||
|
@ -58,6 +56,9 @@ import {
|
|||
useLanguagePrefsApi,
|
||||
toPostLanguages,
|
||||
} from '#/state/preferences/languages'
|
||||
import {useSession} from '#/state/session'
|
||||
import {useProfileQuery} from '#/state/queries/profile'
|
||||
import {useComposerControls} from '#/state/shell/composer'
|
||||
|
||||
type Props = ComposerOpts
|
||||
export const ComposePost = observer(function ComposePost({
|
||||
|
@ -66,12 +67,14 @@ export const ComposePost = observer(function ComposePost({
|
|||
quote: initQuote,
|
||||
mention: initMention,
|
||||
}: Props) {
|
||||
const {agent, currentAccount} = useSession()
|
||||
const {data: currentProfile} = useProfileQuery({did: currentAccount!.did})
|
||||
const {activeModals} = useModals()
|
||||
const {openModal, closeModal} = useModalControls()
|
||||
const {closeComposer} = useComposerControls()
|
||||
const {track} = useAnalytics()
|
||||
const pal = usePalette('default')
|
||||
const {isDesktop, isMobile} = useWebMediaQueries()
|
||||
const store = useStores()
|
||||
const {_} = useLingui()
|
||||
const requireAltTextEnabled = useRequireAltTextEnabled()
|
||||
const langPrefs = useLanguagePrefs()
|
||||
|
@ -101,15 +104,10 @@ export const ComposePost = observer(function ComposePost({
|
|||
const {extLink, setExtLink} = useExternalLinkFetch({setQuote})
|
||||
const [labels, setLabels] = useState<string[]>([])
|
||||
const [suggestedLinks, setSuggestedLinks] = useState<Set<string>>(new Set())
|
||||
const gallery = useMemo(() => new GalleryModel(store), [store])
|
||||
const gallery = useMemo(() => new GalleryModel(), [])
|
||||
const onClose = useCallback(() => {
|
||||
store.shell.closeComposer()
|
||||
}, [store])
|
||||
|
||||
const autocompleteView = useMemo<UserAutocompleteModel>(
|
||||
() => new UserAutocompleteModel(store),
|
||||
[store],
|
||||
)
|
||||
closeComposer()
|
||||
}, [closeComposer])
|
||||
|
||||
const insets = useSafeAreaInsets()
|
||||
const viewStyles = useMemo(
|
||||
|
@ -162,11 +160,6 @@ export const ComposePost = observer(function ComposePost({
|
|||
}
|
||||
}, [onPressCancel])
|
||||
|
||||
// initial setup
|
||||
useEffect(() => {
|
||||
autocompleteView.setup()
|
||||
}, [autocompleteView])
|
||||
|
||||
// listen to escape key on desktop web
|
||||
const onEscape = useCallback(
|
||||
(e: KeyboardEvent) => {
|
||||
|
@ -216,7 +209,7 @@ export const ComposePost = observer(function ComposePost({
|
|||
setIsProcessing(true)
|
||||
|
||||
try {
|
||||
await apilib.post(store, {
|
||||
await apilib.post(agent, {
|
||||
rawText: richtext.text,
|
||||
replyTo: replyTo?.uri,
|
||||
images: gallery.images,
|
||||
|
@ -224,7 +217,6 @@ export const ComposePost = observer(function ComposePost({
|
|||
extLink,
|
||||
labels,
|
||||
onStateChange: setProcessingState,
|
||||
knownHandles: autocompleteView.knownHandles,
|
||||
langs: toPostLanguages(langPrefs.postLanguage),
|
||||
})
|
||||
} catch (e: any) {
|
||||
|
@ -381,13 +373,12 @@ export const ComposePost = observer(function ComposePost({
|
|||
styles.textInputLayout,
|
||||
isNative && styles.textInputLayoutMobile,
|
||||
]}>
|
||||
<UserAvatar avatar={store.me.avatar} size={50} />
|
||||
<UserAvatar avatar={currentProfile?.avatar} size={50} />
|
||||
<TextInput
|
||||
ref={textInput}
|
||||
richtext={richtext}
|
||||
placeholder={selectTextInputPlaceholder}
|
||||
suggestedLinks={suggestedLinks}
|
||||
autocompleteView={autocompleteView}
|
||||
autoFocus={true}
|
||||
setRichText={setRichText}
|
||||
onPhotoPasted={onPhotoPasted}
|
||||
|
|
|
@ -3,6 +3,7 @@ import React, {
|
|||
useCallback,
|
||||
useRef,
|
||||
useMemo,
|
||||
useState,
|
||||
ComponentProps,
|
||||
} from 'react'
|
||||
import {
|
||||
|
@ -18,7 +19,6 @@ import PasteInput, {
|
|||
} from '@mattermost/react-native-paste-input'
|
||||
import {AppBskyRichtextFacet, RichText} from '@atproto/api'
|
||||
import isEqual from 'lodash.isequal'
|
||||
import {UserAutocompleteModel} from 'state/models/discovery/user-autocomplete'
|
||||
import {Autocomplete} from './mobile/Autocomplete'
|
||||
import {Text} from 'view/com/util/text/Text'
|
||||
import {cleanError} from 'lib/strings/errors'
|
||||
|
@ -38,7 +38,6 @@ interface TextInputProps extends ComponentProps<typeof RNTextInput> {
|
|||
richtext: RichText
|
||||
placeholder: string
|
||||
suggestedLinks: Set<string>
|
||||
autocompleteView: UserAutocompleteModel
|
||||
setRichText: (v: RichText | ((v: RichText) => RichText)) => void
|
||||
onPhotoPasted: (uri: string) => void
|
||||
onPressPublish: (richtext: RichText) => Promise<void>
|
||||
|
@ -56,7 +55,6 @@ export const TextInput = forwardRef(function TextInputImpl(
|
|||
richtext,
|
||||
placeholder,
|
||||
suggestedLinks,
|
||||
autocompleteView,
|
||||
setRichText,
|
||||
onPhotoPasted,
|
||||
onSuggestedLinksChanged,
|
||||
|
@ -69,6 +67,7 @@ export const TextInput = forwardRef(function TextInputImpl(
|
|||
const textInput = useRef<PasteInputRef>(null)
|
||||
const textInputSelection = useRef<Selection>({start: 0, end: 0})
|
||||
const theme = useTheme()
|
||||
const [autocompletePrefix, setAutocompletePrefix] = useState('')
|
||||
|
||||
React.useImperativeHandle(ref, () => ({
|
||||
focus: () => textInput.current?.focus(),
|
||||
|
@ -99,10 +98,9 @@ export const TextInput = forwardRef(function TextInputImpl(
|
|||
textInputSelection.current?.start || 0,
|
||||
)
|
||||
if (prefix) {
|
||||
autocompleteView.setActive(true)
|
||||
autocompleteView.setPrefix(prefix.value)
|
||||
} else {
|
||||
autocompleteView.setActive(false)
|
||||
setAutocompletePrefix(prefix.value)
|
||||
} else if (autocompletePrefix) {
|
||||
setAutocompletePrefix('')
|
||||
}
|
||||
|
||||
const set: Set<string> = new Set()
|
||||
|
@ -139,7 +137,8 @@ export const TextInput = forwardRef(function TextInputImpl(
|
|||
},
|
||||
[
|
||||
setRichText,
|
||||
autocompleteView,
|
||||
autocompletePrefix,
|
||||
setAutocompletePrefix,
|
||||
suggestedLinks,
|
||||
onSuggestedLinksChanged,
|
||||
onPhotoPasted,
|
||||
|
@ -179,9 +178,9 @@ export const TextInput = forwardRef(function TextInputImpl(
|
|||
item,
|
||||
),
|
||||
)
|
||||
autocompleteView.setActive(false)
|
||||
setAutocompletePrefix('')
|
||||
},
|
||||
[onChangeText, richtext, autocompleteView],
|
||||
[onChangeText, richtext, setAutocompletePrefix],
|
||||
)
|
||||
|
||||
const textDecorated = useMemo(() => {
|
||||
|
@ -221,7 +220,7 @@ export const TextInput = forwardRef(function TextInputImpl(
|
|||
{textDecorated}
|
||||
</PasteInput>
|
||||
<Autocomplete
|
||||
view={autocompleteView}
|
||||
prefix={autocompletePrefix}
|
||||
onSelect={onSelectAutocompleteItem}
|
||||
/>
|
||||
</View>
|
||||
|
|
|
@ -11,13 +11,15 @@ import {Paragraph} from '@tiptap/extension-paragraph'
|
|||
import {Placeholder} from '@tiptap/extension-placeholder'
|
||||
import {Text} from '@tiptap/extension-text'
|
||||
import isEqual from 'lodash.isequal'
|
||||
import {UserAutocompleteModel} from 'state/models/discovery/user-autocomplete'
|
||||
import {createSuggestion} from './web/Autocomplete'
|
||||
import {useColorSchemeStyle} from 'lib/hooks/useColorSchemeStyle'
|
||||
import {isUriImage, blobToDataUri} from 'lib/media/util'
|
||||
import {Emoji} from './web/EmojiPicker.web'
|
||||
import {LinkDecorator} from './web/LinkDecorator'
|
||||
import {generateJSON} from '@tiptap/html'
|
||||
import {ActorAutocomplete} from '#/state/queries/actor-autocomplete'
|
||||
import {useSession} from '#/state/session'
|
||||
import {useMyFollowsQuery} from '#/state/queries/my-follows'
|
||||
|
||||
export interface TextInputRef {
|
||||
focus: () => void
|
||||
|
@ -28,7 +30,6 @@ interface TextInputProps {
|
|||
richtext: RichText
|
||||
placeholder: string
|
||||
suggestedLinks: Set<string>
|
||||
autocompleteView: UserAutocompleteModel
|
||||
setRichText: (v: RichText | ((v: RichText) => RichText)) => void
|
||||
onPhotoPasted: (uri: string) => void
|
||||
onPressPublish: (richtext: RichText) => Promise<void>
|
||||
|
@ -43,7 +44,6 @@ export const TextInput = React.forwardRef(function TextInputImpl(
|
|||
richtext,
|
||||
placeholder,
|
||||
suggestedLinks,
|
||||
autocompleteView,
|
||||
setRichText,
|
||||
onPhotoPasted,
|
||||
onPressPublish,
|
||||
|
@ -52,6 +52,16 @@ export const TextInput = React.forwardRef(function TextInputImpl(
|
|||
TextInputProps,
|
||||
ref,
|
||||
) {
|
||||
const {agent} = useSession()
|
||||
const autocomplete = React.useMemo(
|
||||
() => new ActorAutocomplete(agent),
|
||||
[agent],
|
||||
)
|
||||
const {data: follows} = useMyFollowsQuery()
|
||||
if (follows) {
|
||||
autocomplete.setFollows(follows)
|
||||
}
|
||||
|
||||
const modeClass = useColorSchemeStyle('ProseMirror-light', 'ProseMirror-dark')
|
||||
const extensions = React.useMemo(
|
||||
() => [
|
||||
|
@ -61,7 +71,7 @@ export const TextInput = React.forwardRef(function TextInputImpl(
|
|||
HTMLAttributes: {
|
||||
class: 'mention',
|
||||
},
|
||||
suggestion: createSuggestion({autocompleteView}),
|
||||
suggestion: createSuggestion({autocomplete}),
|
||||
}),
|
||||
Paragraph,
|
||||
Placeholder.configure({
|
||||
|
@ -71,7 +81,7 @@ export const TextInput = React.forwardRef(function TextInputImpl(
|
|||
History,
|
||||
Hardbreak,
|
||||
],
|
||||
[autocompleteView, placeholder],
|
||||
[autocomplete, placeholder],
|
||||
)
|
||||
|
||||
React.useEffect(() => {
|
||||
|
|
|
@ -1,31 +1,33 @@
|
|||
import React, {useEffect} from 'react'
|
||||
import {Animated, TouchableOpacity, StyleSheet, View} from 'react-native'
|
||||
import {observer} from 'mobx-react-lite'
|
||||
import {UserAutocompleteModel} from 'state/models/discovery/user-autocomplete'
|
||||
import {useAnimatedValue} from 'lib/hooks/useAnimatedValue'
|
||||
import {usePalette} from 'lib/hooks/usePalette'
|
||||
import {Text} from 'view/com/util/text/Text'
|
||||
import {UserAvatar} from 'view/com/util/UserAvatar'
|
||||
import {useGrapheme} from '../hooks/useGrapheme'
|
||||
import {useActorAutocompleteQuery} from '#/state/queries/actor-autocomplete'
|
||||
|
||||
export const Autocomplete = observer(function AutocompleteImpl({
|
||||
view,
|
||||
prefix,
|
||||
onSelect,
|
||||
}: {
|
||||
view: UserAutocompleteModel
|
||||
prefix: string
|
||||
onSelect: (item: string) => void
|
||||
}) {
|
||||
const pal = usePalette('default')
|
||||
const positionInterp = useAnimatedValue(0)
|
||||
const {getGraphemeString} = useGrapheme()
|
||||
const isActive = !!prefix
|
||||
const {data: suggestions} = useActorAutocompleteQuery(prefix)
|
||||
|
||||
useEffect(() => {
|
||||
Animated.timing(positionInterp, {
|
||||
toValue: view.isActive ? 1 : 0,
|
||||
toValue: isActive ? 1 : 0,
|
||||
duration: 200,
|
||||
useNativeDriver: true,
|
||||
}).start()
|
||||
}, [positionInterp, view.isActive])
|
||||
}, [positionInterp, isActive])
|
||||
|
||||
const topAnimStyle = {
|
||||
transform: [
|
||||
|
@ -40,10 +42,10 @@ export const Autocomplete = observer(function AutocompleteImpl({
|
|||
|
||||
return (
|
||||
<Animated.View style={topAnimStyle}>
|
||||
{view.isActive ? (
|
||||
{isActive ? (
|
||||
<View style={[pal.view, styles.container, pal.border]}>
|
||||
{view.suggestions.length > 0 ? (
|
||||
view.suggestions.slice(0, 5).map(item => {
|
||||
{suggestions?.length ? (
|
||||
suggestions.slice(0, 5).map(item => {
|
||||
// Eventually use an average length
|
||||
const MAX_CHARS = 40
|
||||
const MAX_HANDLE_CHARS = 20
|
||||
|
|
|
@ -12,7 +12,7 @@ import {
|
|||
SuggestionProps,
|
||||
SuggestionKeyDownProps,
|
||||
} from '@tiptap/suggestion'
|
||||
import {UserAutocompleteModel} from 'state/models/discovery/user-autocomplete'
|
||||
import {ActorAutocomplete} from '#/state/queries/actor-autocomplete'
|
||||
import {usePalette} from 'lib/hooks/usePalette'
|
||||
import {Text} from 'view/com/util/text/Text'
|
||||
import {UserAvatar} from 'view/com/util/UserAvatar'
|
||||
|
@ -23,15 +23,14 @@ interface MentionListRef {
|
|||
}
|
||||
|
||||
export function createSuggestion({
|
||||
autocompleteView,
|
||||
autocomplete,
|
||||
}: {
|
||||
autocompleteView: UserAutocompleteModel
|
||||
autocomplete: ActorAutocomplete
|
||||
}): Omit<SuggestionOptions, 'editor'> {
|
||||
return {
|
||||
async items({query}) {
|
||||
autocompleteView.setActive(true)
|
||||
await autocompleteView.setPrefix(query)
|
||||
return autocompleteView.suggestions.slice(0, 8)
|
||||
await autocomplete.query(query)
|
||||
return autocomplete.suggestions.slice(0, 8)
|
||||
},
|
||||
|
||||
render: () => {
|
||||
|
|
|
@ -14,7 +14,7 @@ import {
|
|||
isBskyCustomFeedUrl,
|
||||
isBskyListUrl,
|
||||
} from 'lib/strings/url-helpers'
|
||||
import {ComposerOpts} from 'state/models/ui/shell'
|
||||
import {ComposerOpts} from 'state/shell/composer'
|
||||
import {POST_IMG_MAX} from 'lib/constants'
|
||||
import {logger} from '#/logger'
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ import {LoadLatestBtn} from '../util/load-latest/LoadLatestBtn'
|
|||
import {msg} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {useSession} from '#/state/session'
|
||||
import {useComposerControls} from '#/state/shell/composer'
|
||||
|
||||
const POLL_FREQ = 30e3 // 30sec
|
||||
|
||||
|
@ -46,6 +47,7 @@ export function FeedPage({
|
|||
const {_} = useLingui()
|
||||
const {isDesktop} = useWebMediaQueries()
|
||||
const queryClient = useQueryClient()
|
||||
const {openComposer} = useComposerControls()
|
||||
const [onMainScroll, isScrolledDown, resetMainScroll] = useOnMainScroll()
|
||||
const {screen, track} = useAnalytics()
|
||||
const headerOffset = useHeaderOffset()
|
||||
|
@ -80,8 +82,8 @@ export function FeedPage({
|
|||
|
||||
const onPressCompose = React.useCallback(() => {
|
||||
track('HomeScreen:PressCompose')
|
||||
store.shell.openComposer({})
|
||||
}, [store, track])
|
||||
openComposer({})
|
||||
}, [openComposer, track])
|
||||
|
||||
const onPressLoadLatest = React.useCallback(() => {
|
||||
scrollToTop()
|
||||
|
|
|
@ -20,7 +20,6 @@ import {sanitizeHandle} from 'lib/strings/handles'
|
|||
import {countLines, pluralize} from 'lib/strings/helpers'
|
||||
import {isEmbedByEmbedder} from 'lib/embeds'
|
||||
import {getTranslatorLink, isPostInLanguage} from '../../../locale/helpers'
|
||||
import {useStores} from 'state/index'
|
||||
import {PostMeta} from '../util/PostMeta'
|
||||
import {PostEmbeds} from '../util/post-embeds'
|
||||
import {PostCtrls} from '../util/post-ctrls/PostCtrls'
|
||||
|
@ -39,6 +38,8 @@ import {MAX_POST_LINES} from 'lib/constants'
|
|||
import {Trans} from '@lingui/macro'
|
||||
import {useLanguagePrefs} from '#/state/preferences'
|
||||
import {usePostShadow, POST_TOMBSTONE} from '#/state/cache/post-shadow'
|
||||
import {useComposerControls} from '#/state/shell/composer'
|
||||
import {useModerationOpts} from '#/state/queries/preferences'
|
||||
|
||||
export function PostThreadItem({
|
||||
post,
|
||||
|
@ -65,7 +66,7 @@ export function PostThreadItem({
|
|||
hasPrecedingItem: boolean
|
||||
onPostReply: () => void
|
||||
}) {
|
||||
const store = useStores()
|
||||
const moderationOpts = useModerationOpts()
|
||||
const postShadowed = usePostShadow(post, dataUpdatedAt)
|
||||
const richText = useMemo(
|
||||
() =>
|
||||
|
@ -77,8 +78,8 @@ export function PostThreadItem({
|
|||
)
|
||||
const moderation = useMemo(
|
||||
() =>
|
||||
post ? moderatePost(post, store.preferences.moderationOpts) : undefined,
|
||||
[post, store],
|
||||
post && moderationOpts ? moderatePost(post, moderationOpts) : undefined,
|
||||
[post, moderationOpts],
|
||||
)
|
||||
if (postShadowed === POST_TOMBSTONE) {
|
||||
return <PostThreadItemDeleted />
|
||||
|
@ -145,8 +146,8 @@ function PostThreadItemLoaded({
|
|||
onPostReply: () => void
|
||||
}) {
|
||||
const pal = usePalette('default')
|
||||
const store = useStores()
|
||||
const langPrefs = useLanguagePrefs()
|
||||
const {openComposer} = useComposerControls()
|
||||
const [limitLines, setLimitLines] = React.useState(
|
||||
countLines(richText?.text) >= MAX_POST_LINES,
|
||||
)
|
||||
|
@ -187,7 +188,7 @@ function PostThreadItemLoaded({
|
|||
)
|
||||
|
||||
const onPressReply = React.useCallback(() => {
|
||||
store.shell.openComposer({
|
||||
openComposer({
|
||||
replyTo: {
|
||||
uri: post.uri,
|
||||
cid: post.cid,
|
||||
|
@ -200,7 +201,7 @@ function PostThreadItemLoaded({
|
|||
},
|
||||
onPost: onPostReply,
|
||||
})
|
||||
}, [store, post, record, onPostReply])
|
||||
}, [openComposer, post, record, onPostReply])
|
||||
|
||||
const onPressShowMore = React.useCallback(() => {
|
||||
setLimitLines(false)
|
||||
|
|
|
@ -19,7 +19,6 @@ import {PostAlerts} from '../util/moderation/PostAlerts'
|
|||
import {Text} from '../util/text/Text'
|
||||
import {RichText} from '../util/text/RichText'
|
||||
import {PreviewableUserAvatar} from '../util/UserAvatar'
|
||||
import {useStores} from 'state/index'
|
||||
import {s, colors} from 'lib/styles'
|
||||
import {usePalette} from 'lib/hooks/usePalette'
|
||||
import {makeProfileLink} from 'lib/routes/links'
|
||||
|
@ -27,6 +26,7 @@ import {MAX_POST_LINES} from 'lib/constants'
|
|||
import {countLines} from 'lib/strings/helpers'
|
||||
import {useModerationOpts} from '#/state/queries/preferences'
|
||||
import {usePostShadow, POST_TOMBSTONE} from '#/state/cache/post-shadow'
|
||||
import {useComposerControls} from '#/state/shell/composer'
|
||||
|
||||
export function Post({
|
||||
post,
|
||||
|
@ -97,7 +97,7 @@ function PostInner({
|
|||
style?: StyleProp<ViewStyle>
|
||||
}) {
|
||||
const pal = usePalette('default')
|
||||
const store = useStores()
|
||||
const {openComposer} = useComposerControls()
|
||||
const [limitLines, setLimitLines] = useState(
|
||||
countLines(richText?.text) >= MAX_POST_LINES,
|
||||
)
|
||||
|
@ -110,7 +110,7 @@ function PostInner({
|
|||
}
|
||||
|
||||
const onPressReply = React.useCallback(() => {
|
||||
store.shell.openComposer({
|
||||
openComposer({
|
||||
replyTo: {
|
||||
uri: post.uri,
|
||||
cid: post.cid,
|
||||
|
@ -122,7 +122,7 @@ function PostInner({
|
|||
},
|
||||
},
|
||||
})
|
||||
}, [store, post, record])
|
||||
}, [openComposer, post, record])
|
||||
|
||||
const onPressShowMore = React.useCallback(() => {
|
||||
setLimitLines(false)
|
||||
|
|
|
@ -24,7 +24,6 @@ import {RichText} from '../util/text/RichText'
|
|||
import {PostSandboxWarning} from '../util/PostSandboxWarning'
|
||||
import {PreviewableUserAvatar} from '../util/UserAvatar'
|
||||
import {s} from 'lib/styles'
|
||||
import {useStores} from 'state/index'
|
||||
import {usePalette} from 'lib/hooks/usePalette'
|
||||
import {useAnalytics} from 'lib/analytics/analytics'
|
||||
import {sanitizeDisplayName} from 'lib/strings/display-names'
|
||||
|
@ -34,6 +33,7 @@ import {isEmbedByEmbedder} from 'lib/embeds'
|
|||
import {MAX_POST_LINES} from 'lib/constants'
|
||||
import {countLines} from 'lib/strings/helpers'
|
||||
import {usePostShadow, POST_TOMBSTONE} from '#/state/cache/post-shadow'
|
||||
import {useComposerControls} from '#/state/shell/composer'
|
||||
|
||||
export function FeedItem({
|
||||
post,
|
||||
|
@ -102,7 +102,7 @@ function FeedItemInner({
|
|||
isThreadLastChild?: boolean
|
||||
isThreadParent?: boolean
|
||||
}) {
|
||||
const store = useStores()
|
||||
const {openComposer} = useComposerControls()
|
||||
const pal = usePalette('default')
|
||||
const {track} = useAnalytics()
|
||||
const [limitLines, setLimitLines] = useState(
|
||||
|
@ -124,7 +124,7 @@ function FeedItemInner({
|
|||
|
||||
const onPressReply = React.useCallback(() => {
|
||||
track('FeedItem:PostReply')
|
||||
store.shell.openComposer({
|
||||
openComposer({
|
||||
replyTo: {
|
||||
uri: post.uri,
|
||||
cid: post.cid,
|
||||
|
@ -136,7 +136,7 @@ function FeedItemInner({
|
|||
},
|
||||
},
|
||||
})
|
||||
}, [post, record, track, store])
|
||||
}, [post, record, track, openComposer])
|
||||
|
||||
const onPressShowMore = React.useCallback(() => {
|
||||
setLimitLines(false)
|
||||
|
|
|
@ -13,7 +13,6 @@ import {HeartIcon, HeartIconSolid, CommentBottomArrow} from 'lib/icons'
|
|||
import {s, colors} from 'lib/styles'
|
||||
import {pluralize} from 'lib/strings/helpers'
|
||||
import {useTheme} from 'lib/ThemeContext'
|
||||
import {useStores} from 'state/index'
|
||||
import {RepostButton} from './RepostButton'
|
||||
import {Haptics} from 'lib/haptics'
|
||||
import {HITSLOP_10, HITSLOP_20} from 'lib/constants'
|
||||
|
@ -24,6 +23,7 @@ import {
|
|||
usePostRepostMutation,
|
||||
usePostUnrepostMutation,
|
||||
} from '#/state/queries/post'
|
||||
import {useComposerControls} from '#/state/shell/composer'
|
||||
|
||||
export function PostCtrls({
|
||||
big,
|
||||
|
@ -38,8 +38,8 @@ export function PostCtrls({
|
|||
style?: StyleProp<ViewStyle>
|
||||
onPressReply: () => void
|
||||
}) {
|
||||
const store = useStores()
|
||||
const theme = useTheme()
|
||||
const {openComposer} = useComposerControls()
|
||||
const {closeModal} = useModalControls()
|
||||
const postLikeMutation = usePostLikeMutation()
|
||||
const postUnlikeMutation = usePostUnlikeMutation()
|
||||
|
@ -90,7 +90,7 @@ export function PostCtrls({
|
|||
|
||||
const onQuote = useCallback(() => {
|
||||
closeModal()
|
||||
store.shell.openComposer({
|
||||
openComposer({
|
||||
quote: {
|
||||
uri: post.uri,
|
||||
cid: post.cid,
|
||||
|
@ -100,7 +100,7 @@ export function PostCtrls({
|
|||
},
|
||||
})
|
||||
Haptics.default()
|
||||
}, [post, record, store.shell, closeModal])
|
||||
}, [post, record, openComposer, closeModal])
|
||||
return (
|
||||
<View style={[styles.ctrls, style]}>
|
||||
<TouchableOpacity
|
||||
|
|
|
@ -12,7 +12,7 @@ import {PostMeta} from '../PostMeta'
|
|||
import {Link} from '../Link'
|
||||
import {Text} from '../text/Text'
|
||||
import {usePalette} from 'lib/hooks/usePalette'
|
||||
import {ComposerOptsQuote} from 'state/models/ui/shell'
|
||||
import {ComposerOptsQuote} from 'state/shell/composer'
|
||||
import {PostEmbeds} from '.'
|
||||
import {PostAlerts} from '../moderation/PostAlerts'
|
||||
import {makeProfileLink} from 'lib/routes/links'
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue