Create a standard postcontainer and improve show/hide UI on posts

This commit is contained in:
Paul Frazee
2023-04-12 10:57:23 -07:00
parent b730b7c81f
commit 03ada6ed73
4 changed files with 241 additions and 223 deletions
+8 -10
View File
@@ -22,7 +22,7 @@ import {useStores} from 'state/index'
import {PostMeta} from '../util/PostMeta' import {PostMeta} from '../util/PostMeta'
import {PostEmbeds} from '../util/post-embeds' import {PostEmbeds} from '../util/post-embeds'
import {PostCtrls} from '../util/PostCtrls' import {PostCtrls} from '../util/PostCtrls'
import {PostHider} from '../util/PostHider' import {PostContainer} from '../util/PostContainer'
import {ErrorMessage} from '../util/error/ErrorMessage' import {ErrorMessage} from '../util/error/ErrorMessage'
import {usePalette} from 'lib/hooks/usePalette' import {usePalette} from 'lib/hooks/usePalette'
@@ -270,15 +270,13 @@ export const PostThreadItem = observer(function PostThreadItem({
) )
} else { } else {
return ( return (
<PostHider <>
isMuted={item.post.author.viewer?.muted === true} <PostContainer
labels={item.post.labels}>
<Link
testID={`postThreadItem-by-${item.post.author.handle}`} testID={`postThreadItem-by-${item.post.author.handle}`}
style={[styles.outer, {borderTopColor: pal.colors.border}, pal.view]}
href={itemHref} href={itemHref}
title={itemTitle} style={[styles.outer, {borderTopColor: pal.colors.border}, pal.view]}
noFeedback> isMuted={item.post.author.viewer?.muted === true}
labels={item.post.labels}>
{item._showParentReplyLine && ( {item._showParentReplyLine && (
<View <View
style={[ style={[
@@ -347,7 +345,7 @@ export const PostThreadItem = observer(function PostThreadItem({
/> />
</View> </View>
</View> </View>
</Link> </PostContainer>
{item._hasMore ? ( {item._hasMore ? (
<Link <Link
style={[ style={[
@@ -366,7 +364,7 @@ export const PostThreadItem = observer(function PostThreadItem({
/> />
</Link> </Link>
) : undefined} ) : undefined}
</PostHider> </>
) )
} }
}) })
+74 -78
View File
@@ -17,7 +17,7 @@ import {UserInfoText} from '../util/UserInfoText'
import {PostMeta} from '../util/PostMeta' import {PostMeta} from '../util/PostMeta'
import {PostEmbeds} from '../util/post-embeds' import {PostEmbeds} from '../util/post-embeds'
import {PostCtrls} from '../util/PostCtrls' import {PostCtrls} from '../util/PostCtrls'
import {PostHider} from '../util/PostHider' import {PostContainer} from '../util/PostContainer'
import {Text} from '../util/text/Text' import {Text} from '../util/text/Text'
import {RichText} from '../util/text/RichText' import {RichText} from '../util/text/RichText'
import * as Toast from '../util/Toast' import * as Toast from '../util/Toast'
@@ -150,86 +150,82 @@ export const Post = observer(function Post({
} }
return ( return (
<PostHider <PostContainer
href={itemHref}
style={[styles.outer, pal.view, pal.border, style]}
isMuted={item.post.author.viewer?.muted === true} isMuted={item.post.author.viewer?.muted === true}
labels={item.post.labels}> labels={item.post.labels}>
<Link {showReplyLine && <View style={styles.replyLine} />}
style={[styles.outer, pal.view, pal.border, style]} <View style={styles.layout}>
href={itemHref} <View style={styles.layoutAvi}>
title={itemTitle} <Link href={authorHref} title={authorTitle} asAnchor>
noFeedback> <UserAvatar size={52} avatar={item.post.author.avatar} />
{showReplyLine && <View style={styles.replyLine} />} </Link>
<View style={styles.layout}>
<View style={styles.layoutAvi}>
<Link href={authorHref} title={authorTitle} asAnchor>
<UserAvatar size={52} avatar={item.post.author.avatar} />
</Link>
</View>
<View style={styles.layoutContent}>
<PostMeta
authorHandle={item.post.author.handle}
authorDisplayName={item.post.author.displayName}
timestamp={item.post.indexedAt}
postHref={itemHref}
did={item.post.author.did}
/>
{replyAuthorDid !== '' && (
<View style={[s.flexRow, s.mb2, s.alignCenter]}>
<FontAwesomeIcon
icon="reply"
size={9}
style={[pal.textLight, s.mr5]}
/>
<Text type="sm" style={[pal.textLight, s.mr2]} lineHeight={1.2}>
Reply to
</Text>
<UserInfoText
type="sm"
did={replyAuthorDid}
attr="displayName"
style={[pal.textLight]}
/>
</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} />
<PostCtrls
itemUri={itemUri}
itemCid={itemCid}
itemHref={itemHref}
itemTitle={itemTitle}
author={{
avatar: item.post.author.avatar!,
handle: item.post.author.handle,
displayName: item.post.author.displayName!,
}}
indexedAt={item.post.indexedAt}
text={item.richText?.text || record.text}
isAuthor={item.post.author.did === store.me.did}
replyCount={item.post.replyCount}
repostCount={item.post.repostCount}
likeCount={item.post.likeCount}
isReposted={!!item.post.viewer?.repost}
isLiked={!!item.post.viewer?.like}
onPressReply={onPressReply}
onPressToggleRepost={onPressToggleRepost}
onPressToggleLike={onPressToggleLike}
onCopyPostText={onCopyPostText}
onOpenTranslate={onOpenTranslate}
onDeletePost={onDeletePost}
/>
</View>
</View> </View>
</Link> <View style={styles.layoutContent}>
</PostHider> <PostMeta
authorHandle={item.post.author.handle}
authorDisplayName={item.post.author.displayName}
timestamp={item.post.indexedAt}
postHref={itemHref}
did={item.post.author.did}
/>
{replyAuthorDid !== '' && (
<View style={[s.flexRow, s.mb2, s.alignCenter]}>
<FontAwesomeIcon
icon="reply"
size={9}
style={[pal.textLight, s.mr5]}
/>
<Text type="sm" style={[pal.textLight, s.mr2]} lineHeight={1.2}>
Reply to
</Text>
<UserInfoText
type="sm"
did={replyAuthorDid}
attr="displayName"
style={[pal.textLight]}
/>
</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} />
<PostCtrls
itemUri={itemUri}
itemCid={itemCid}
itemHref={itemHref}
itemTitle={itemTitle}
author={{
avatar: item.post.author.avatar!,
handle: item.post.author.handle,
displayName: item.post.author.displayName!,
}}
indexedAt={item.post.indexedAt}
text={item.richText?.text || record.text}
isAuthor={item.post.author.did === store.me.did}
replyCount={item.post.replyCount}
repostCount={item.post.repostCount}
likeCount={item.post.likeCount}
isReposted={!!item.post.viewer?.repost}
isLiked={!!item.post.viewer?.like}
onPressReply={onPressReply}
onPressToggleRepost={onPressToggleRepost}
onPressToggleLike={onPressToggleLike}
onCopyPostText={onCopyPostText}
onOpenTranslate={onOpenTranslate}
onDeletePost={onDeletePost}
/>
</View>
</View>
</PostContainer>
) )
}) })
+121 -124
View File
@@ -14,7 +14,7 @@ import {UserInfoText} from '../util/UserInfoText'
import {PostMeta} from '../util/PostMeta' import {PostMeta} from '../util/PostMeta'
import {PostCtrls} from '../util/PostCtrls' import {PostCtrls} from '../util/PostCtrls'
import {PostEmbeds} from '../util/post-embeds' import {PostEmbeds} from '../util/post-embeds'
import {PostHider} from '../util/PostHider' import {PostContainer} from '../util/PostContainer'
import {RichText} from '../util/text/RichText' import {RichText} from '../util/text/RichText'
import * as Toast from '../util/Toast' import * as Toast from '../util/Toast'
import {UserAvatar} from '../util/UserAvatar' import {UserAvatar} from '../util/UserAvatar'
@@ -132,137 +132,134 @@ export const FeedItem = observer(function ({
] ]
return ( return (
<PostHider isMuted={isMuted} labels={item.post.labels}> <PostContainer
<Link testID={`feedItem-by-${item.post.author.handle}`}
testID={`feedItem-by-${item.post.author.handle}`} style={outerStyles}
style={outerStyles} href={itemHref}
href={itemHref} isMuted={isMuted}
title={itemTitle} labels={item.post.labels}>
noFeedback> {isThreadChild && (
{isThreadChild && ( <View
<View style={[styles.topReplyLine, {borderColor: pal.colors.replyLine}]}
style={[styles.topReplyLine, {borderColor: pal.colors.replyLine}]} />
/> )}
)} {isThreadParent && (
{isThreadParent && ( <View
<View style={[
styles.bottomReplyLine,
{borderColor: pal.colors.replyLine},
isNoTop ? styles.bottomReplyLineNoTop : undefined,
]}
/>
)}
{item.reasonRepost && (
<Link
style={styles.includeReason}
href={`/profile/${item.reasonRepost.by.handle}`}
title={sanitizeDisplayName(
item.reasonRepost.by.displayName || item.reasonRepost.by.handle,
)}>
<FontAwesomeIcon
icon="retweet"
style={[ style={[
styles.bottomReplyLine, styles.includeReasonIcon,
{borderColor: pal.colors.replyLine}, {color: pal.colors.textLight} as FontAwesomeIconStyle,
isNoTop ? styles.bottomReplyLineNoTop : undefined,
]} ]}
/> />
)} <Text
{item.reasonRepost && ( type="sm-bold"
<Link style={pal.textLight}
style={styles.includeReason} lineHeight={1.2}
href={`/profile/${item.reasonRepost.by.handle}`} numberOfLines={1}>
title={sanitizeDisplayName( Reposted by{' '}
item.reasonRepost.by.displayName || item.reasonRepost.by.handle, <DesktopWebTextLink
)}>
<FontAwesomeIcon
icon="retweet"
style={[
styles.includeReasonIcon,
{color: pal.colors.textLight} as FontAwesomeIconStyle,
]}
/>
<Text
type="sm-bold" type="sm-bold"
style={pal.textLight} style={pal.textLight}
lineHeight={1.2} lineHeight={1.2}
numberOfLines={1}> numberOfLines={1}
Reposted by{' '} text={sanitizeDisplayName(
<DesktopWebTextLink item.reasonRepost.by.displayName || item.reasonRepost.by.handle,
type="sm-bold" )}
style={pal.textLight} href={`/profile/${item.reasonRepost.by.handle}`}
lineHeight={1.2} />
numberOfLines={1} </Text>
text={sanitizeDisplayName( </Link>
item.reasonRepost.by.displayName || )}
item.reasonRepost.by.handle, <View style={styles.layout}>
)} <View style={styles.layoutAvi}>
href={`/profile/${item.reasonRepost.by.handle}`} <Link href={authorHref} title={item.post.author.handle} asAnchor>
/> <UserAvatar size={52} avatar={item.post.author.avatar} />
</Text>
</Link> </Link>
)}
<View style={styles.layout}>
<View style={styles.layoutAvi}>
<Link href={authorHref} title={item.post.author.handle} asAnchor>
<UserAvatar size={52} avatar={item.post.author.avatar} />
</Link>
</View>
<View style={styles.layoutContent}>
<PostMeta
authorHandle={item.post.author.handle}
authorDisplayName={item.post.author.displayName}
timestamp={item.post.indexedAt}
postHref={itemHref}
did={item.post.author.did}
showFollowBtn={showFollowBtn}
/>
{!isThreadChild && replyAuthorDid !== '' && (
<View style={[s.flexRow, s.mb2, s.alignCenter]}>
<FontAwesomeIcon
icon="reply"
size={9}
style={[
{color: pal.colors.textLight} as FontAwesomeIconStyle,
s.mr5,
]}
/>
<Text type="md" style={[pal.textLight, s.mr2]} lineHeight={1.2}>
Reply to
</Text>
<UserInfoText
type="md"
did={replyAuthorDid}
attr="displayName"
style={[pal.textLight, s.ml2]}
/>
</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={styles.embed} />
<PostCtrls
style={styles.ctrls}
itemUri={itemUri}
itemCid={itemCid}
itemHref={itemHref}
itemTitle={itemTitle}
author={{
avatar: item.post.author.avatar!,
handle: item.post.author.handle,
displayName: item.post.author.displayName!,
}}
text={item.richText?.text || record.text}
indexedAt={item.post.indexedAt}
isAuthor={item.post.author.did === store.me.did}
replyCount={item.post.replyCount}
repostCount={item.post.repostCount}
likeCount={item.post.likeCount}
isReposted={!!item.post.viewer?.repost}
isLiked={!!item.post.viewer?.like}
onPressReply={onPressReply}
onPressToggleRepost={onPressToggleRepost}
onPressToggleLike={onPressToggleLike}
onCopyPostText={onCopyPostText}
onOpenTranslate={onOpenTranslate}
onDeletePost={onDeletePost}
/>
</View>
</View> </View>
</Link> <View style={styles.layoutContent}>
</PostHider> <PostMeta
authorHandle={item.post.author.handle}
authorDisplayName={item.post.author.displayName}
timestamp={item.post.indexedAt}
postHref={itemHref}
did={item.post.author.did}
showFollowBtn={showFollowBtn}
/>
{!isThreadChild && replyAuthorDid !== '' && (
<View style={[s.flexRow, s.mb2, s.alignCenter]}>
<FontAwesomeIcon
icon="reply"
size={9}
style={[
{color: pal.colors.textLight} as FontAwesomeIconStyle,
s.mr5,
]}
/>
<Text type="md" style={[pal.textLight, s.mr2]} lineHeight={1.2}>
Reply to
</Text>
<UserInfoText
type="md"
did={replyAuthorDid}
attr="displayName"
style={[pal.textLight, s.ml2]}
/>
</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={styles.embed} />
<PostCtrls
style={styles.ctrls}
itemUri={itemUri}
itemCid={itemCid}
itemHref={itemHref}
itemTitle={itemTitle}
author={{
avatar: item.post.author.avatar!,
handle: item.post.author.handle,
displayName: item.post.author.displayName!,
}}
text={item.richText?.text || record.text}
indexedAt={item.post.indexedAt}
isAuthor={item.post.author.did === store.me.did}
replyCount={item.post.replyCount}
repostCount={item.post.repostCount}
likeCount={item.post.likeCount}
isReposted={!!item.post.viewer?.repost}
isLiked={!!item.post.viewer?.like}
onPressReply={onPressReply}
onPressToggleRepost={onPressToggleRepost}
onPressToggleLike={onPressToggleLike}
onCopyPostText={onCopyPostText}
onOpenTranslate={onOpenTranslate}
onDeletePost={onDeletePost}
/>
</View>
</View>
</PostContainer>
) )
}) })
@@ -1,25 +1,43 @@
import React from 'react' import React from 'react'
import {StyleSheet, TouchableOpacity, View} from 'react-native' import {
StyleProp,
StyleSheet,
TouchableOpacity,
View,
ViewStyle,
} from 'react-native'
import {ComAtprotoLabelDefs} from '@atproto/api' import {ComAtprotoLabelDefs} from '@atproto/api'
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
import {usePalette} from 'lib/hooks/usePalette' import {usePalette} from 'lib/hooks/usePalette'
import {Link} from './Link'
import {Text} from './text/Text' import {Text} from './text/Text'
import {getLabelValueGroup} from 'lib/labeling/helpers' import {getLabelValueGroup} from 'lib/labeling/helpers'
import {addStyle} from 'lib/styles'
export function PostHider({ export function PostContainer({
testID,
href,
isMuted, isMuted,
labels, labels,
style,
children, children,
}: React.PropsWithChildren<{ }: React.PropsWithChildren<{
testID?: string
href: string
isMuted?: boolean isMuted?: boolean
style: StyleProp<ViewStyle>
labels: ComAtprotoLabelDefs.Label[] | undefined labels: ComAtprotoLabelDefs.Label[] | undefined
}>) { }>) {
const pal = usePalette('default') const pal = usePalette('default')
const palError = usePalette('error')
const [override, setOverride] = React.useState(false) const [override, setOverride] = React.useState(false)
const bg = override ? pal.viewLight : pal.view
if (!isMuted && !labels?.length) { if (!isMuted && !labels?.length) {
return <>{children}</> return (
<Link testID={testID} style={style} href={href} noFeedback>
{children}
</Link>
)
} }
const label = labels?.[0] // TODO use config to settle on most relevant item const label = labels?.[0] // TODO use config to settle on most relevant item
@@ -29,8 +47,8 @@ export function PostHider({
} }
return ( return (
<View style={[styles.container, pal.view]}> <>
<View style={[styles.description, pal.view, pal.border]}> <View style={[styles.description, bg, pal.border]}>
<FontAwesomeIcon <FontAwesomeIcon
icon={['far', 'eye-slash']} icon={['far', 'eye-slash']}
style={[styles.icon, pal.text]} style={[styles.icon, pal.text]}
@@ -53,12 +71,17 @@ export function PostHider({
</TouchableOpacity> </TouchableOpacity>
</View> </View>
{override && ( {override && (
<View <View style={[styles.childrenContainer, pal.border, bg]}>
style={[styles.childrenContainer, pal.border, palError.viewLight]}> <Link
{children} testID={testID}
style={addStyle(style, styles.child)}
href={href}
noFeedback>
{children}
</Link>
</View> </View>
)} )}
</View> </>
) )
} }
@@ -78,6 +101,10 @@ const styles = StyleSheet.create({
}, },
childrenContainer: { childrenContainer: {
paddingHorizontal: 6, paddingHorizontal: 6,
paddingVertical: 6, paddingBottom: 6,
},
child: {
borderWidth: 1,
borderRadius: 12,
}, },
}) })