diff options
Diffstat (limited to 'src/view/com/post/Post.tsx')
-rw-r--r-- | src/view/com/post/Post.tsx | 217 |
1 files changed, 135 insertions, 82 deletions
diff --git a/src/view/com/post/Post.tsx b/src/view/com/post/Post.tsx index e8e741269..60d46f5cc 100644 --- a/src/view/com/post/Post.tsx +++ b/src/view/com/post/Post.tsx @@ -7,17 +7,22 @@ import { View, ViewStyle, } from 'react-native' +import {AppBskyFeedPost as FeedPost} from '@atproto/api' import {observer} from 'mobx-react-lite' import Clipboard from '@react-native-clipboard/clipboard' import {AtUri} from '@atproto/api' import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' -import {PostThreadModel} from 'state/models/content/post-thread' +import { + PostThreadModel, + PostThreadItemModel, +} from 'state/models/content/post-thread' import {Link} from '../util/Link' import {UserInfoText} from '../util/UserInfoText' import {PostMeta} from '../util/PostMeta' import {PostEmbeds} from '../util/post-embeds' import {PostCtrls} from '../util/PostCtrls' -import {PostMutedWrapper} from '../util/PostMuted' +import {PostHider} from '../util/moderation/PostHider' +import {ContentHider} from '../util/moderation/ContentHider' import {Text} from '../util/text/Text' import {RichText} from '../util/text/RichText' import * as Toast from '../util/Toast' @@ -61,7 +66,11 @@ export const Post = observer(function Post({ // loading // = - if (!view || view.isLoading || view.params.uri !== uri) { + if ( + !view || + (!view.hasContent && view.isLoading) || + view.params.uri !== uri + ) { return ( <View style={pal.view}> <ActivityIndicator /> @@ -84,85 +93,122 @@ export const Post = observer(function Post({ // loaded // = - const item = view.thread - const record = view.thread.postRecord - const itemUri = item.post.uri - const itemCid = item.post.cid - const itemUrip = new AtUri(item.post.uri) - const itemHref = `/profile/${item.post.author.handle}/post/${itemUrip.rkey}` - const itemTitle = `Post by ${item.post.author.handle}` - const authorHref = `/profile/${item.post.author.handle}` - const authorTitle = item.post.author.handle - let replyAuthorDid = '' - if (record.reply) { - const urip = new AtUri(record.reply.parent?.uri || record.reply.root.uri) - replyAuthorDid = urip.hostname - } - const onPressReply = () => { - store.shell.openComposer({ - replyTo: { - uri: item.post.uri, - cid: item.post.cid, - text: record.text as string, - author: { - handle: item.post.author.handle, - displayName: item.post.author.displayName, - avatar: item.post.author.avatar, + return ( + <PostLoaded + item={view.thread} + record={view.thread.postRecord} + setDeleted={setDeleted} + showReplyLine={showReplyLine} + style={style} + /> + ) +}) + +const PostLoaded = observer( + ({ + item, + record, + setDeleted, + showReplyLine, + style, + }: { + item: PostThreadItemModel + record: FeedPost.Record + setDeleted: (v: boolean) => void + showReplyLine?: boolean + style?: StyleProp<ViewStyle> + }) => { + const pal = usePalette('default') + const store = useStores() + + const itemUri = item.post.uri + const itemCid = item.post.cid + const itemUrip = new AtUri(item.post.uri) + const itemHref = `/profile/${item.post.author.handle}/post/${itemUrip.rkey}` + const itemTitle = `Post by ${item.post.author.handle}` + const authorHref = `/profile/${item.post.author.handle}` + const authorTitle = item.post.author.handle + let replyAuthorDid = '' + if (record.reply) { + const urip = new AtUri(record.reply.parent?.uri || record.reply.root.uri) + replyAuthorDid = urip.hostname + } + const onPressReply = React.useCallback(() => { + store.shell.openComposer({ + replyTo: { + uri: item.post.uri, + cid: item.post.cid, + text: record.text as string, + author: { + handle: item.post.author.handle, + displayName: item.post.author.displayName, + avatar: item.post.author.avatar, + }, }, - }, - }) - } - const onPressToggleRepost = () => { - return item - .toggleRepost() - .catch(e => store.log.error('Failed to toggle repost', e)) - } - const onPressToggleLike = () => { - return item - .toggleLike() - .catch(e => store.log.error('Failed to toggle like', e)) - } - const onCopyPostText = () => { - Clipboard.setString(record.text) - Toast.show('Copied to clipboard') - } - const onOpenTranslate = () => { - Linking.openURL( - encodeURI(`https://translate.google.com/#auto|en|${record?.text || ''}`), - ) - } - const onDeletePost = () => { - item.delete().then( - () => { - setDeleted(true) - Toast.show('Post deleted') - }, - e => { - store.log.error('Failed to delete post', e) - Toast.show('Failed to delete post, please try again') - }, - ) - } + }) + }, [store, item, record]) - return ( - <PostMutedWrapper isMuted={item.post.author.viewer?.muted === true}> - <Link - style={[styles.outer, pal.view, pal.border, style]} + const onPressToggleRepost = React.useCallback(() => { + return item + .toggleRepost() + .catch(e => store.log.error('Failed to toggle repost', e)) + }, [item, store]) + + const onPressToggleLike = React.useCallback(() => { + return item + .toggleLike() + .catch(e => store.log.error('Failed to toggle like', e)) + }, [item, store]) + + const onCopyPostText = React.useCallback(() => { + Clipboard.setString(record.text) + Toast.show('Copied to clipboard') + }, [record]) + + const onOpenTranslate = React.useCallback(() => { + Linking.openURL( + encodeURI( + `https://translate.google.com/#auto|en|${record?.text || ''}`, + ), + ) + }, [record]) + + const onDeletePost = React.useCallback(() => { + item.delete().then( + () => { + setDeleted(true) + Toast.show('Post deleted') + }, + e => { + store.log.error('Failed to delete post', e) + Toast.show('Failed to delete post, please try again') + }, + ) + }, [item, setDeleted, store]) + + return ( + <PostHider href={itemHref} - title={itemTitle} - noFeedback> + style={[styles.outer, pal.view, pal.border, style]} + isMuted={item.post.author.viewer?.muted === true} + labels={item.post.labels}> {showReplyLine && <View style={styles.replyLine} />} <View style={styles.layout}> <View style={styles.layoutAvi}> <Link href={authorHref} title={authorTitle} asAnchor> - <UserAvatar size={52} avatar={item.post.author.avatar} /> + <UserAvatar + size={52} + avatar={item.post.author.avatar} + hasWarning={!!item.post.author.labels?.length} + /> </Link> </View> <View style={styles.layoutContent}> <PostMeta authorHandle={item.post.author.handle} authorDisplayName={item.post.author.displayName} + authorHasWarning={!!item.post.author.labels?.length} timestamp={item.post.indexedAt} postHref={itemHref} did={item.post.author.did} @@ -185,16 +231,20 @@ export const Post = observer(function Post({ /> </View> )} - {item.richText?.text ? ( - <View style={styles.postTextContainer}> - <RichText - type="post-text" - richText={item.richText} - lineHeight={1.3} - /> - </View> - ) : undefined} - <PostEmbeds embed={item.post.embed} style={s.mb10} /> + <ContentHider + labels={item.post.labels} + containerStyle={styles.contentHider}> + {item.richText?.text ? ( + <View style={styles.postTextContainer}> + <RichText + type="post-text" + richText={item.richText} + lineHeight={1.3} + /> + </View> + ) : undefined} + <PostEmbeds embed={item.post.embed} style={s.mb10} /> + </ContentHider> <PostCtrls itemUri={itemUri} itemCid={itemCid} @@ -222,10 +272,10 @@ export const Post = observer(function Post({ /> </View> </View> - </Link> - </PostMutedWrapper> - ) -}) + </PostHider> + ) + }, +) const styles = StyleSheet.create({ outer: { @@ -257,4 +307,7 @@ const styles = StyleSheet.create({ borderLeftWidth: 2, borderLeftColor: colors.gray2, }, + contentHider: { + marginTop: 4, + }, }) |