diff options
author | Samuel Newman <mozzius@protonmail.com> | 2024-08-21 21:26:25 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-08-21 15:26:25 -0500 |
commit | 56ab5e177fa2b24d0e5d9d969aa37532b96128da (patch) | |
tree | 2fa3db0ef9e46474aac00d5a593c5e5d592da9e3 /src/view/com/post-thread/PostQuotes.tsx | |
parent | ddb0b80017c2b5bc158b8ff9da222abd5a8bf025 (diff) | |
download | voidsky-56ab5e177fa2b24d0e5d9d969aa37532b96128da.tar.zst |
Show quote posts (#4865)
* show quote posts * fix filter * fix keyExtractor * move likedby and repostedby to new file structure * use modern list component * remove relative imports * update quotes count after quoting * call `onPost` after updating quote count * Revert "update quotes count after quoting" This reverts commit 1f1887730a210c57c1e5a0eb0f47c42c42cf1b4b. * implement * update like count in quotes list * only add `onPostReply` where needed * Filter quotes with detached embeds * Bump SDK * Don't show error for no results --------- Co-authored-by: Samuel Newman <10959775+mozzius@users.noreply.github.com> Co-authored-by: Hailey <me@haileyok.com> Co-authored-by: Eric Bailey <git@esb.lol>
Diffstat (limited to 'src/view/com/post-thread/PostQuotes.tsx')
-rw-r--r-- | src/view/com/post-thread/PostQuotes.tsx | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/src/view/com/post-thread/PostQuotes.tsx b/src/view/com/post-thread/PostQuotes.tsx new file mode 100644 index 000000000..d573d27a1 --- /dev/null +++ b/src/view/com/post-thread/PostQuotes.tsx @@ -0,0 +1,141 @@ +import React, {useCallback, useState} from 'react' +import { + AppBskyFeedDefs, + AppBskyFeedPost, + ModerationDecision, +} from '@atproto/api' +import {msg} from '@lingui/macro' +import {useLingui} from '@lingui/react' + +import {moderatePost_wrapped as moderatePost} from '#/lib/moderatePost_wrapped' +import {cleanError} from '#/lib/strings/errors' +import {logger} from '#/logger' +import {isWeb} from '#/platform/detection' +import {useModerationOpts} from '#/state/preferences/moderation-opts' +import {usePostQuotesQuery} from '#/state/queries/post-quotes' +import {useResolveUriQuery} from '#/state/queries/resolve-uri' +import {useInitialNumToRender} from 'lib/hooks/useInitialNumToRender' +import {Post} from 'view/com/post/Post' +import { + ListFooter, + ListHeaderDesktop, + ListMaybePlaceholder, +} from '#/components/Lists' +import {List} from '../util/List' + +function renderItem({ + item, + index, +}: { + item: { + post: AppBskyFeedDefs.PostView + moderation: ModerationDecision + record: AppBskyFeedPost.Record + } + index: number +}) { + return <Post post={item.post} hideTopBorder={index === 0 && !isWeb} /> +} + +function keyExtractor(item: { + post: AppBskyFeedDefs.PostView + moderation: ModerationDecision + record: AppBskyFeedPost.Record +}) { + return item.post.uri +} + +export function PostQuotes({uri}: {uri: string}) { + const {_} = useLingui() + const initialNumToRender = useInitialNumToRender() + + const [isPTRing, setIsPTRing] = useState(false) + + const { + data: resolvedUri, + error: resolveError, + isLoading: isLoadingUri, + } = useResolveUriQuery(uri) + const { + data, + isLoading: isLoadingQuotes, + isFetchingNextPage, + hasNextPage, + fetchNextPage, + error, + refetch, + } = usePostQuotesQuery(resolvedUri?.uri) + + const moderationOpts = useModerationOpts() + + const isError = Boolean(resolveError || error) + + const quotes = + data?.pages + .flatMap(page => + page.posts.map(post => { + if (!AppBskyFeedPost.isRecord(post.record) || !moderationOpts) { + return null + } + const moderation = moderatePost(post, moderationOpts) + return {post, record: post.record, moderation} + }), + ) + .filter(item => item !== null) ?? [] + + const onRefresh = useCallback(async () => { + setIsPTRing(true) + try { + await refetch() + } catch (err) { + logger.error('Failed to refresh quotes', {message: err}) + } + setIsPTRing(false) + }, [refetch, setIsPTRing]) + + const onEndReached = useCallback(async () => { + if (isFetchingNextPage || !hasNextPage || isError) return + try { + await fetchNextPage() + } catch (err) { + logger.error('Failed to load more quotes', {message: err}) + } + }, [isFetchingNextPage, hasNextPage, isError, fetchNextPage]) + + if (isLoadingUri || isLoadingQuotes || isError) { + return ( + <ListMaybePlaceholder + isLoading={isLoadingUri || isLoadingQuotes} + isError={isError} + /> + ) + } + + // loaded + // = + return ( + <List + data={quotes} + renderItem={renderItem} + keyExtractor={keyExtractor} + refreshing={isPTRing} + onRefresh={onRefresh} + onEndReached={onEndReached} + onEndReachedThreshold={4} + ListHeaderComponent={<ListHeaderDesktop title={_(msg`Quotes`)} />} + ListFooterComponent={ + <ListFooter + isFetchingNextPage={isFetchingNextPage} + error={cleanError(error)} + onRetry={fetchNextPage} + showEndMessage + endMessageText={_(msg`That's all, folks!`)} + /> + } + // @ts-ignore our .web version only -prf + desktopFixedHeight + initialNumToRender={initialNumToRender} + windowSize={11} + /> + ) +} |