Update feeds on post created (#2085)

zio/stable
Paul Frazee 2023-12-04 17:58:45 -08:00 committed by GitHub
parent bdb2bfdd83
commit 48f5cebc80
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 66 additions and 14 deletions

View File

@ -36,3 +36,11 @@ export function listenSessionDropped(fn: () => void): UnlistenFn {
emitter.on('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)
}

View File

@ -248,7 +248,7 @@ export function findPostInQueryData(
export function* findAllPostsInQueryData(
queryClient: QueryClient,
uri: string,
): Generator<AppBskyFeedDefs.PostView, void> {
): Generator<AppBskyFeedDefs.PostView, undefined> {
const queryDatas = queryClient.getQueriesData<
InfiniteData<FeedPageUnselected>
>({

View File

@ -14,7 +14,7 @@ import {
import {useSafeAreaInsets} from 'react-native-safe-area-context'
import LinearGradient from 'react-native-linear-gradient'
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 {useIsKeyboardVisible} from 'lib/hooks/useIsKeyboardVisible'
import {ExternalEmbed} from './ExternalEmbed'
@ -59,6 +59,8 @@ import {
import {useSession, getAgent} from '#/state/session'
import {useProfileQuery} from '#/state/queries/profile'
import {useComposerControls} from '#/state/shell/composer'
import {until} from '#/lib/async/until'
import {emitPostCreated} from '#/state/events'
type Props = ComposerOpts
export const ComposePost = observer(function ComposePost({
@ -208,17 +210,20 @@ export const ComposePost = observer(function ComposePost({
setIsProcessing(true)
let postUri
try {
await apilib.post(getAgent(), {
rawText: richtext.text,
replyTo: replyTo?.uri,
images: gallery.images,
quote,
extLink,
labels,
onStateChange: setProcessingState,
langs: toPostLanguages(langPrefs.postLanguage),
})
postUri = (
await apilib.post(getAgent(), {
rawText: richtext.text,
replyTo: replyTo?.uri,
images: gallery.images,
quote,
extLink,
labels,
onStateChange: setProcessingState,
langs: toPostLanguages(langPrefs.postLanguage),
})
).uri
} catch (e: any) {
if (extLink) {
setExtLink({
@ -236,8 +241,10 @@ export const ComposePost = observer(function ComposePost({
})
if (replyTo && replyTo.uri) track('Post:Reply')
}
if (!replyTo) {
// TODO onPostCreated
if (postUri && !replyTo) {
whenAppViewReady(postUri).then(() => {
emitPostCreated()
})
}
setLangPrefs.savePostLanguageToHistory()
onPost?.()
@ -533,3 +540,15 @@ const styles = StyleSheet.create({
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],
}),
)
}

View File

@ -8,6 +8,7 @@ import {
View,
ViewStyle,
} from 'react-native'
import {useQueryClient} from '@tanstack/react-query'
import {FlatList} from '../util/Views'
import {PostFeedLoadingPlaceholder} from '../util/LoadingPlaceholder'
import {FeedErrorMessage} from './FeedErrorMessage'
@ -20,6 +21,7 @@ import {useAnimatedScrollHandler} from '#/lib/hooks/useAnimatedScrollHandler_FIX
import {useTheme} from 'lib/ThemeContext'
import {logger} from '#/logger'
import {
RQKEY,
FeedDescriptor,
FeedParams,
usePostFeedQuery,
@ -27,6 +29,8 @@ import {
} from '#/state/queries/post-feed'
import {useModerationOpts} from '#/state/queries/preferences'
import {isWeb} from '#/platform/detection'
import {listenPostCreated} from '#/state/events'
import {useSession} from '#/state/session'
const LOADING_ITEM = {_reactKey: '__loading__'}
const EMPTY_FEED_ITEM = {_reactKey: '__empty__'}
@ -73,6 +77,8 @@ let Feed = ({
const pal = usePalette('default')
const theme = useTheme()
const {track} = useAnalytics()
const queryClient = useQueryClient()
const {currentAccount} = useSession()
const [isPTRing, setIsPTRing] = React.useState(false)
const checkForNewRef = React.useRef<(() => void) | null>(null)
@ -104,6 +110,25 @@ let Feed = ({
}
}, [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(() => {
// we store the interval handler in a ref to avoid needless
// reassignments of the interval