Improve label rendering to give more context to users when appropriate
This commit is contained in:
@@ -22,8 +22,8 @@ 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 {PostContainer} from '../util/PostContainer'
|
import {PostHider} from '../util/moderation/PostHider'
|
||||||
import {ContentContainer} from '../util/ContentContainer'
|
import {ContentHider} from '../util/moderation/ContentHider'
|
||||||
import {ErrorMessage} from '../util/error/ErrorMessage'
|
import {ErrorMessage} from '../util/error/ErrorMessage'
|
||||||
import {usePalette} from 'lib/hooks/usePalette'
|
import {usePalette} from 'lib/hooks/usePalette'
|
||||||
|
|
||||||
@@ -194,7 +194,7 @@ export const PostThreadItem = observer(function PostThreadItem({
|
|||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
<View style={[s.pl10, s.pr10, s.pb10]}>
|
<View style={[s.pl10, s.pr10, s.pb10]}>
|
||||||
<ContentContainer
|
<ContentHider
|
||||||
isMuted={item.post.author.viewer?.muted === true}
|
isMuted={item.post.author.viewer?.muted === true}
|
||||||
labels={item.post.labels}>
|
labels={item.post.labels}>
|
||||||
{item.richText?.text ? (
|
{item.richText?.text ? (
|
||||||
@@ -211,7 +211,7 @@ export const PostThreadItem = observer(function PostThreadItem({
|
|||||||
</View>
|
</View>
|
||||||
) : undefined}
|
) : undefined}
|
||||||
<PostEmbeds embed={item.post.embed} style={s.mb10} />
|
<PostEmbeds embed={item.post.embed} style={s.mb10} />
|
||||||
</ContentContainer>
|
</ContentHider>
|
||||||
{item._isHighlightedPost && hasEngagement ? (
|
{item._isHighlightedPost && hasEngagement ? (
|
||||||
<View style={[styles.expandedInfo, pal.border]}>
|
<View style={[styles.expandedInfo, pal.border]}>
|
||||||
{item.post.repostCount ? (
|
{item.post.repostCount ? (
|
||||||
@@ -279,7 +279,7 @@ export const PostThreadItem = observer(function PostThreadItem({
|
|||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<PostContainer
|
<PostHider
|
||||||
testID={`postThreadItem-by-${item.post.author.handle}`}
|
testID={`postThreadItem-by-${item.post.author.handle}`}
|
||||||
href={itemHref}
|
href={itemHref}
|
||||||
style={[styles.outer, {borderTopColor: pal.colors.border}, pal.view]}
|
style={[styles.outer, {borderTopColor: pal.colors.border}, pal.view]}
|
||||||
@@ -315,17 +315,22 @@ export const PostThreadItem = observer(function PostThreadItem({
|
|||||||
postHref={itemHref}
|
postHref={itemHref}
|
||||||
did={item.post.author.did}
|
did={item.post.author.did}
|
||||||
/>
|
/>
|
||||||
{item.richText?.text ? (
|
<ContentHider
|
||||||
<View style={styles.postTextContainer}>
|
isMuted={item.post.author.viewer?.muted === true}
|
||||||
<RichText
|
labels={item.post.labels}
|
||||||
type="post-text"
|
containerStyle={styles.contentHider}>
|
||||||
richText={item.richText}
|
{item.richText?.text ? (
|
||||||
style={pal.text}
|
<View style={styles.postTextContainer}>
|
||||||
lineHeight={1.3}
|
<RichText
|
||||||
/>
|
type="post-text"
|
||||||
</View>
|
richText={item.richText}
|
||||||
) : undefined}
|
style={pal.text}
|
||||||
<PostEmbeds embed={item.post.embed} style={s.mb10} />
|
lineHeight={1.3}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
) : undefined}
|
||||||
|
<PostEmbeds embed={item.post.embed} style={s.mb10} />
|
||||||
|
</ContentHider>
|
||||||
<PostCtrls
|
<PostCtrls
|
||||||
itemUri={itemUri}
|
itemUri={itemUri}
|
||||||
itemCid={itemCid}
|
itemCid={itemCid}
|
||||||
@@ -353,7 +358,7 @@ export const PostThreadItem = observer(function PostThreadItem({
|
|||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</PostContainer>
|
</PostHider>
|
||||||
{item._hasMore ? (
|
{item._hasMore ? (
|
||||||
<Link
|
<Link
|
||||||
style={[
|
style={[
|
||||||
@@ -441,6 +446,9 @@ const styles = StyleSheet.create({
|
|||||||
paddingHorizontal: 0,
|
paddingHorizontal: 0,
|
||||||
paddingBottom: 10,
|
paddingBottom: 10,
|
||||||
},
|
},
|
||||||
|
contentHider: {
|
||||||
|
marginTop: 4,
|
||||||
|
},
|
||||||
expandedInfo: {
|
expandedInfo: {
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
padding: 10,
|
padding: 10,
|
||||||
|
|||||||
+185
-138
@@ -7,17 +7,22 @@ import {
|
|||||||
View,
|
View,
|
||||||
ViewStyle,
|
ViewStyle,
|
||||||
} from 'react-native'
|
} from 'react-native'
|
||||||
|
import {AppBskyFeedPost as FeedPost} from '@atproto/api'
|
||||||
import {observer} from 'mobx-react-lite'
|
import {observer} from 'mobx-react-lite'
|
||||||
import Clipboard from '@react-native-clipboard/clipboard'
|
import Clipboard from '@react-native-clipboard/clipboard'
|
||||||
import {AtUri} from '@atproto/api'
|
import {AtUri} from '@atproto/api'
|
||||||
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
|
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 {Link} from '../util/Link'
|
||||||
import {UserInfoText} from '../util/UserInfoText'
|
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 {PostContainer} from '../util/PostContainer'
|
import {PostHider} from '../util/moderation/PostHider'
|
||||||
|
import {ContentHider} from '../util/moderation/ContentHider'
|
||||||
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'
|
||||||
@@ -88,147 +93,186 @@ export const Post = observer(function Post({
|
|||||||
|
|
||||||
// loaded
|
// 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,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
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')
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PostContainer
|
<PostLoaded
|
||||||
href={itemHref}
|
view={view}
|
||||||
style={[styles.outer, pal.view, pal.border, style]}
|
item={view.thread}
|
||||||
isMuted={item.post.author.viewer?.muted === true}
|
record={view.thread.postRecord}
|
||||||
labels={item.post.labels}>
|
setDeleted={setDeleted}
|
||||||
{showReplyLine && <View style={styles.replyLine} />}
|
showReplyLine={showReplyLine}
|
||||||
<View style={styles.layout}>
|
style={style}
|
||||||
<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>
|
|
||||||
</PostContainer>
|
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
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,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}, [store, item, record])
|
||||||
|
|
||||||
|
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}
|
||||||
|
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} />
|
||||||
|
</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>
|
||||||
|
)}
|
||||||
|
<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}
|
||||||
|
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>
|
||||||
|
</PostHider>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
outer: {
|
outer: {
|
||||||
padding: 10,
|
padding: 10,
|
||||||
@@ -259,4 +303,7 @@ const styles = StyleSheet.create({
|
|||||||
borderLeftWidth: 2,
|
borderLeftWidth: 2,
|
||||||
borderLeftColor: colors.gray2,
|
borderLeftColor: colors.gray2,
|
||||||
},
|
},
|
||||||
|
contentHider: {
|
||||||
|
marginTop: 4,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -14,7 +14,8 @@ 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 {PostContainer} from '../util/PostContainer'
|
import {PostHider} from '../util/moderation/PostHider'
|
||||||
|
import {ContentHider} from '../util/moderation/ContentHider'
|
||||||
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,7 +133,7 @@ export const FeedItem = observer(function ({
|
|||||||
]
|
]
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PostContainer
|
<PostHider
|
||||||
testID={`feedItem-by-${item.post.author.handle}`}
|
testID={`feedItem-by-${item.post.author.handle}`}
|
||||||
style={outerStyles}
|
style={outerStyles}
|
||||||
href={itemHref}
|
href={itemHref}
|
||||||
@@ -221,16 +222,20 @@ export const FeedItem = observer(function ({
|
|||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
{item.richText?.text ? (
|
<ContentHider
|
||||||
<View style={styles.postTextContainer}>
|
labels={item.post.labels}
|
||||||
<RichText
|
containerStyle={styles.contentHider}>
|
||||||
type="post-text"
|
{item.richText?.text ? (
|
||||||
richText={item.richText}
|
<View style={styles.postTextContainer}>
|
||||||
lineHeight={1.3}
|
<RichText
|
||||||
/>
|
type="post-text"
|
||||||
</View>
|
richText={item.richText}
|
||||||
) : undefined}
|
lineHeight={1.3}
|
||||||
<PostEmbeds embed={item.post.embed} style={styles.embed} />
|
/>
|
||||||
|
</View>
|
||||||
|
) : undefined}
|
||||||
|
<PostEmbeds embed={item.post.embed} style={styles.embed} />
|
||||||
|
</ContentHider>
|
||||||
<PostCtrls
|
<PostCtrls
|
||||||
style={styles.ctrls}
|
style={styles.ctrls}
|
||||||
itemUri={itemUri}
|
itemUri={itemUri}
|
||||||
@@ -259,7 +264,7 @@ export const FeedItem = observer(function ({
|
|||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</PostContainer>
|
</PostHider>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -322,6 +327,9 @@ const styles = StyleSheet.create({
|
|||||||
flexWrap: 'wrap',
|
flexWrap: 'wrap',
|
||||||
paddingBottom: 4,
|
paddingBottom: 4,
|
||||||
},
|
},
|
||||||
|
contentHider: {
|
||||||
|
marginTop: 4,
|
||||||
|
},
|
||||||
embed: {
|
embed: {
|
||||||
marginBottom: 6,
|
marginBottom: 6,
|
||||||
},
|
},
|
||||||
|
|||||||
+9
-10
@@ -9,21 +9,23 @@ import {
|
|||||||
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 {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'
|
import {addStyle} from 'lib/styles'
|
||||||
|
|
||||||
export function ContentContainer({
|
export function ContentHider({
|
||||||
testID,
|
testID,
|
||||||
isMuted,
|
isMuted,
|
||||||
labels,
|
labels,
|
||||||
style,
|
style,
|
||||||
|
containerStyle,
|
||||||
children,
|
children,
|
||||||
}: React.PropsWithChildren<{
|
}: React.PropsWithChildren<{
|
||||||
testID?: string
|
testID?: string
|
||||||
isMuted: boolean
|
isMuted?: boolean
|
||||||
labels: ComAtprotoLabelDefs.Label[] | undefined
|
labels: ComAtprotoLabelDefs.Label[] | undefined
|
||||||
style?: StyleProp<ViewStyle>
|
style?: StyleProp<ViewStyle>
|
||||||
|
containerStyle?: StyleProp<ViewStyle>
|
||||||
}>) {
|
}>) {
|
||||||
const pal = usePalette('default')
|
const pal = usePalette('default')
|
||||||
const [override, setOverride] = React.useState(false)
|
const [override, setOverride] = React.useState(false)
|
||||||
@@ -43,17 +45,13 @@ export function ContentContainer({
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={[styles.container, pal.view, pal.border]}>
|
<View style={[styles.container, pal.view, pal.border, containerStyle]}>
|
||||||
<View
|
<View
|
||||||
style={[
|
style={[
|
||||||
styles.description,
|
styles.description,
|
||||||
pal.viewLight,
|
pal.viewLight,
|
||||||
override && styles.descriptionOpen,
|
override && styles.descriptionOpen,
|
||||||
]}>
|
]}>
|
||||||
<FontAwesomeIcon
|
|
||||||
icon={['far', 'eye-slash']}
|
|
||||||
style={[styles.icon, pal.text]}
|
|
||||||
/>
|
|
||||||
<Text type="md" style={pal.textLight}>
|
<Text type="md" style={pal.textLight}>
|
||||||
{isMuted ? (
|
{isMuted ? (
|
||||||
<>Post from an account you muted.</>
|
<>Post from an account you muted.</>
|
||||||
@@ -92,7 +90,8 @@ const styles = StyleSheet.create({
|
|||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
paddingVertical: 14,
|
paddingVertical: 14,
|
||||||
paddingHorizontal: 18,
|
paddingLeft: 14,
|
||||||
|
paddingRight: 18,
|
||||||
borderRadius: 12,
|
borderRadius: 12,
|
||||||
},
|
},
|
||||||
descriptionOpen: {
|
descriptionOpen: {
|
||||||
@@ -106,7 +105,7 @@ const styles = StyleSheet.create({
|
|||||||
marginLeft: 'auto',
|
marginLeft: 'auto',
|
||||||
},
|
},
|
||||||
childrenContainer: {
|
childrenContainer: {
|
||||||
paddingHorizontal: 8,
|
paddingHorizontal: 12,
|
||||||
paddingTop: 8,
|
paddingTop: 8,
|
||||||
},
|
},
|
||||||
child: {},
|
child: {},
|
||||||
@@ -9,12 +9,12 @@ import {
|
|||||||
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 {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'
|
import {addStyle} from 'lib/styles'
|
||||||
|
|
||||||
export function PostContainer({
|
export function PostHider({
|
||||||
testID,
|
testID,
|
||||||
href,
|
href,
|
||||||
isMuted,
|
isMuted,
|
||||||
@@ -24,7 +24,7 @@ export function PostContainer({
|
|||||||
}: React.PropsWithChildren<{
|
}: React.PropsWithChildren<{
|
||||||
testID?: string
|
testID?: string
|
||||||
href: string
|
href: string
|
||||||
isMuted: boolean
|
isMuted: boolean | undefined
|
||||||
labels: ComAtprotoLabelDefs.Label[] | undefined
|
labels: ComAtprotoLabelDefs.Label[] | undefined
|
||||||
style: StyleProp<ViewStyle>
|
style: StyleProp<ViewStyle>
|
||||||
}>) {
|
}>) {
|
||||||
@@ -32,7 +32,14 @@ export function PostContainer({
|
|||||||
const [override, setOverride] = React.useState(false)
|
const [override, setOverride] = React.useState(false)
|
||||||
const bg = override ? pal.viewLight : pal.view
|
const bg = override ? pal.viewLight : pal.view
|
||||||
|
|
||||||
if (!isMuted && !labels?.length) {
|
const label = labels?.[0] // TODO use config to settle on most relevant item
|
||||||
|
const labelGroup = getLabelValueGroup(label?.val || '')
|
||||||
|
if (labelGroup.id === 'illegal') {
|
||||||
|
return <></>
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isMuted) {
|
||||||
|
// NOTE: any further label enforcement should occur in ContentContainer
|
||||||
return (
|
return (
|
||||||
<Link testID={testID} style={style} href={href} noFeedback>
|
<Link testID={testID} style={style} href={href} noFeedback>
|
||||||
{children}
|
{children}
|
||||||
@@ -40,12 +47,6 @@ export function PostContainer({
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const label = labels?.[0] // TODO use config to settle on most relevant item
|
|
||||||
const labelGroup = getLabelValueGroup(label?.val || '')
|
|
||||||
if (labelGroup.id === 'illegal') {
|
|
||||||
return <></>
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<View style={[styles.description, bg, pal.border]}>
|
<View style={[styles.description, bg, pal.border]}>
|
||||||
@@ -54,13 +55,7 @@ export function PostContainer({
|
|||||||
style={[styles.icon, pal.text]}
|
style={[styles.icon, pal.text]}
|
||||||
/>
|
/>
|
||||||
<Text type="md" style={pal.textLight}>
|
<Text type="md" style={pal.textLight}>
|
||||||
{isMuted ? (
|
Post from an account you muted.
|
||||||
<>Post from an account you muted.</>
|
|
||||||
) : label ? (
|
|
||||||
<>Warning: {labelGroup.title}</>
|
|
||||||
) : (
|
|
||||||
''
|
|
||||||
)}
|
|
||||||
</Text>
|
</Text>
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
style={styles.showBtn}
|
style={styles.showBtn}
|
||||||
Reference in New Issue
Block a user