Update feeds on post created (#2085)
parent
bdb2bfdd83
commit
48f5cebc80
|
@ -36,3 +36,11 @@ export function listenSessionDropped(fn: () => void): UnlistenFn {
|
||||||
emitter.on('session-dropped', fn)
|
emitter.on('session-dropped', fn)
|
||||||
return () => emitter.off('session-dropped', fn)
|
return () => emitter.off('session-dropped', fn)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function emitPostCreated() {
|
||||||
|
emitter.emit('post-created')
|
||||||
|
}
|
||||||
|
export function listenPostCreated(fn: () => void): UnlistenFn {
|
||||||
|
emitter.on('post-created', fn)
|
||||||
|
return () => emitter.off('post-created', fn)
|
||||||
|
}
|
||||||
|
|
|
@ -248,7 +248,7 @@ export function findPostInQueryData(
|
||||||
export function* findAllPostsInQueryData(
|
export function* findAllPostsInQueryData(
|
||||||
queryClient: QueryClient,
|
queryClient: QueryClient,
|
||||||
uri: string,
|
uri: string,
|
||||||
): Generator<AppBskyFeedDefs.PostView, void> {
|
): Generator<AppBskyFeedDefs.PostView, undefined> {
|
||||||
const queryDatas = queryClient.getQueriesData<
|
const queryDatas = queryClient.getQueriesData<
|
||||||
InfiniteData<FeedPageUnselected>
|
InfiniteData<FeedPageUnselected>
|
||||||
>({
|
>({
|
||||||
|
|
|
@ -14,7 +14,7 @@ import {
|
||||||
import {useSafeAreaInsets} from 'react-native-safe-area-context'
|
import {useSafeAreaInsets} from 'react-native-safe-area-context'
|
||||||
import LinearGradient from 'react-native-linear-gradient'
|
import LinearGradient from 'react-native-linear-gradient'
|
||||||
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
|
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
|
||||||
import {RichText} from '@atproto/api'
|
import {AppBskyFeedGetPosts, RichText} from '@atproto/api'
|
||||||
import {useAnalytics} from 'lib/analytics/analytics'
|
import {useAnalytics} from 'lib/analytics/analytics'
|
||||||
import {useIsKeyboardVisible} from 'lib/hooks/useIsKeyboardVisible'
|
import {useIsKeyboardVisible} from 'lib/hooks/useIsKeyboardVisible'
|
||||||
import {ExternalEmbed} from './ExternalEmbed'
|
import {ExternalEmbed} from './ExternalEmbed'
|
||||||
|
@ -59,6 +59,8 @@ import {
|
||||||
import {useSession, getAgent} from '#/state/session'
|
import {useSession, getAgent} from '#/state/session'
|
||||||
import {useProfileQuery} from '#/state/queries/profile'
|
import {useProfileQuery} from '#/state/queries/profile'
|
||||||
import {useComposerControls} from '#/state/shell/composer'
|
import {useComposerControls} from '#/state/shell/composer'
|
||||||
|
import {until} from '#/lib/async/until'
|
||||||
|
import {emitPostCreated} from '#/state/events'
|
||||||
|
|
||||||
type Props = ComposerOpts
|
type Props = ComposerOpts
|
||||||
export const ComposePost = observer(function ComposePost({
|
export const ComposePost = observer(function ComposePost({
|
||||||
|
@ -208,17 +210,20 @@ export const ComposePost = observer(function ComposePost({
|
||||||
|
|
||||||
setIsProcessing(true)
|
setIsProcessing(true)
|
||||||
|
|
||||||
|
let postUri
|
||||||
try {
|
try {
|
||||||
await apilib.post(getAgent(), {
|
postUri = (
|
||||||
rawText: richtext.text,
|
await apilib.post(getAgent(), {
|
||||||
replyTo: replyTo?.uri,
|
rawText: richtext.text,
|
||||||
images: gallery.images,
|
replyTo: replyTo?.uri,
|
||||||
quote,
|
images: gallery.images,
|
||||||
extLink,
|
quote,
|
||||||
labels,
|
extLink,
|
||||||
onStateChange: setProcessingState,
|
labels,
|
||||||
langs: toPostLanguages(langPrefs.postLanguage),
|
onStateChange: setProcessingState,
|
||||||
})
|
langs: toPostLanguages(langPrefs.postLanguage),
|
||||||
|
})
|
||||||
|
).uri
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
if (extLink) {
|
if (extLink) {
|
||||||
setExtLink({
|
setExtLink({
|
||||||
|
@ -236,8 +241,10 @@ export const ComposePost = observer(function ComposePost({
|
||||||
})
|
})
|
||||||
if (replyTo && replyTo.uri) track('Post:Reply')
|
if (replyTo && replyTo.uri) track('Post:Reply')
|
||||||
}
|
}
|
||||||
if (!replyTo) {
|
if (postUri && !replyTo) {
|
||||||
// TODO onPostCreated
|
whenAppViewReady(postUri).then(() => {
|
||||||
|
emitPostCreated()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
setLangPrefs.savePostLanguageToHistory()
|
setLangPrefs.savePostLanguageToHistory()
|
||||||
onPost?.()
|
onPost?.()
|
||||||
|
@ -533,3 +540,15 @@ const styles = StyleSheet.create({
|
||||||
borderTopWidth: 1,
|
borderTopWidth: 1,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
async function whenAppViewReady(uri: string) {
|
||||||
|
await until(
|
||||||
|
5, // 5 tries
|
||||||
|
1e3, // 1s delay between tries
|
||||||
|
(res: AppBskyFeedGetPosts.Response) => !!res.data.posts[0],
|
||||||
|
() =>
|
||||||
|
getAgent().getPosts({
|
||||||
|
uris: [uri],
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import {
|
||||||
View,
|
View,
|
||||||
ViewStyle,
|
ViewStyle,
|
||||||
} from 'react-native'
|
} from 'react-native'
|
||||||
|
import {useQueryClient} from '@tanstack/react-query'
|
||||||
import {FlatList} from '../util/Views'
|
import {FlatList} from '../util/Views'
|
||||||
import {PostFeedLoadingPlaceholder} from '../util/LoadingPlaceholder'
|
import {PostFeedLoadingPlaceholder} from '../util/LoadingPlaceholder'
|
||||||
import {FeedErrorMessage} from './FeedErrorMessage'
|
import {FeedErrorMessage} from './FeedErrorMessage'
|
||||||
|
@ -20,6 +21,7 @@ import {useAnimatedScrollHandler} from '#/lib/hooks/useAnimatedScrollHandler_FIX
|
||||||
import {useTheme} from 'lib/ThemeContext'
|
import {useTheme} from 'lib/ThemeContext'
|
||||||
import {logger} from '#/logger'
|
import {logger} from '#/logger'
|
||||||
import {
|
import {
|
||||||
|
RQKEY,
|
||||||
FeedDescriptor,
|
FeedDescriptor,
|
||||||
FeedParams,
|
FeedParams,
|
||||||
usePostFeedQuery,
|
usePostFeedQuery,
|
||||||
|
@ -27,6 +29,8 @@ import {
|
||||||
} from '#/state/queries/post-feed'
|
} from '#/state/queries/post-feed'
|
||||||
import {useModerationOpts} from '#/state/queries/preferences'
|
import {useModerationOpts} from '#/state/queries/preferences'
|
||||||
import {isWeb} from '#/platform/detection'
|
import {isWeb} from '#/platform/detection'
|
||||||
|
import {listenPostCreated} from '#/state/events'
|
||||||
|
import {useSession} from '#/state/session'
|
||||||
|
|
||||||
const LOADING_ITEM = {_reactKey: '__loading__'}
|
const LOADING_ITEM = {_reactKey: '__loading__'}
|
||||||
const EMPTY_FEED_ITEM = {_reactKey: '__empty__'}
|
const EMPTY_FEED_ITEM = {_reactKey: '__empty__'}
|
||||||
|
@ -73,6 +77,8 @@ let Feed = ({
|
||||||
const pal = usePalette('default')
|
const pal = usePalette('default')
|
||||||
const theme = useTheme()
|
const theme = useTheme()
|
||||||
const {track} = useAnalytics()
|
const {track} = useAnalytics()
|
||||||
|
const queryClient = useQueryClient()
|
||||||
|
const {currentAccount} = useSession()
|
||||||
const [isPTRing, setIsPTRing] = React.useState(false)
|
const [isPTRing, setIsPTRing] = React.useState(false)
|
||||||
const checkForNewRef = React.useRef<(() => void) | null>(null)
|
const checkForNewRef = React.useRef<(() => void) | null>(null)
|
||||||
|
|
||||||
|
@ -104,6 +110,25 @@ let Feed = ({
|
||||||
}
|
}
|
||||||
}, [feed, data, isFetching, onHasNew, enabled])
|
}, [feed, data, isFetching, onHasNew, enabled])
|
||||||
|
|
||||||
|
const myDid = currentAccount?.did || ''
|
||||||
|
const onPostCreated = React.useCallback(() => {
|
||||||
|
// NOTE
|
||||||
|
// only invalidate if there's 1 page
|
||||||
|
// more than 1 page can trigger some UI freakouts on iOS and android
|
||||||
|
// -prf
|
||||||
|
if (
|
||||||
|
data?.pages.length === 1 &&
|
||||||
|
(feed === 'following' ||
|
||||||
|
feed === 'home' ||
|
||||||
|
feed === `author|${myDid}|posts_no_replies`)
|
||||||
|
) {
|
||||||
|
queryClient.invalidateQueries({queryKey: RQKEY(feed)})
|
||||||
|
}
|
||||||
|
}, [queryClient, feed, data, myDid])
|
||||||
|
React.useEffect(() => {
|
||||||
|
return listenPostCreated(onPostCreated)
|
||||||
|
}, [onPostCreated])
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
// we store the interval handler in a ref to avoid needless
|
// we store the interval handler in a ref to avoid needless
|
||||||
// reassignments of the interval
|
// reassignments of the interval
|
||||||
|
|
Loading…
Reference in New Issue