Add start of post-hiding by labels

This commit is contained in:
Paul Frazee
2023-04-11 22:44:53 -07:00
parent 866a5da0f0
commit b730b7c81f
8 changed files with 240 additions and 69 deletions
+5 -3
View File
@@ -22,7 +22,7 @@ import {useStores} from 'state/index'
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/PostHider'
import {ErrorMessage} from '../util/error/ErrorMessage'
import {usePalette} from 'lib/hooks/usePalette'
@@ -270,7 +270,9 @@ export const PostThreadItem = observer(function PostThreadItem({
)
} else {
return (
<PostMutedWrapper isMuted={item.post.author.viewer?.muted === true}>
<PostHider
isMuted={item.post.author.viewer?.muted === true}
labels={item.post.labels}>
<Link
testID={`postThreadItem-by-${item.post.author.handle}`}
style={[styles.outer, {borderTopColor: pal.colors.border}, pal.view]}
@@ -364,7 +366,7 @@ export const PostThreadItem = observer(function PostThreadItem({
/>
</Link>
) : undefined}
</PostMutedWrapper>
</PostHider>
)
}
})
+5 -3
View File
@@ -17,7 +17,7 @@ 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/PostHider'
import {Text} from '../util/text/Text'
import {RichText} from '../util/text/RichText'
import * as Toast from '../util/Toast'
@@ -150,7 +150,9 @@ export const Post = observer(function Post({
}
return (
<PostMutedWrapper isMuted={item.post.author.viewer?.muted === true}>
<PostHider
isMuted={item.post.author.viewer?.muted === true}
labels={item.post.labels}>
<Link
style={[styles.outer, pal.view, pal.border, style]}
href={itemHref}
@@ -227,7 +229,7 @@ export const Post = observer(function Post({
</View>
</View>
</Link>
</PostMutedWrapper>
</PostHider>
)
})
+18 -13
View File
@@ -14,7 +14,7 @@ import {UserInfoText} from '../util/UserInfoText'
import {PostMeta} from '../util/PostMeta'
import {PostCtrls} from '../util/PostCtrls'
import {PostEmbeds} from '../util/post-embeds'
import {PostMutedWrapper} from '../util/PostMuted'
import {PostHider} from '../util/PostHider'
import {RichText} from '../util/text/RichText'
import * as Toast from '../util/Toast'
import {UserAvatar} from '../util/UserAvatar'
@@ -59,7 +59,7 @@ export const FeedItem = observer(function ({
return urip.hostname
}, [record?.reply])
const onPressReply = () => {
const onPressReply = React.useCallback(() => {
track('FeedItem:PostReply')
store.shell.openComposer({
replyTo: {
@@ -73,29 +73,34 @@ export const FeedItem = observer(function ({
},
},
})
}
const onPressToggleRepost = () => {
}, [item, track, record, store])
const onPressToggleRepost = React.useCallback(() => {
track('FeedItem:PostRepost')
return item
.toggleRepost()
.catch(e => store.log.error('Failed to toggle repost', e))
}
const onPressToggleLike = () => {
}, [track, item, store])
const onPressToggleLike = React.useCallback(() => {
track('FeedItem:PostLike')
return item
.toggleLike()
.catch(e => store.log.error('Failed to toggle like', e))
}
const onCopyPostText = () => {
}, [track, 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 = () => {
const onDeletePost = React.useCallback(() => {
track('FeedItem:PostDelete')
item.delete().then(
() => {
@@ -107,7 +112,7 @@ export const FeedItem = observer(function ({
Toast.show('Failed to delete post, please try again')
},
)
}
}, [track, item, setDeleted, store])
if (!record || deleted) {
return <View />
@@ -127,7 +132,7 @@ export const FeedItem = observer(function ({
]
return (
<PostMutedWrapper isMuted={isMuted}>
<PostHider isMuted={isMuted} labels={item.post.labels}>
<Link
testID={`feedItem-by-${item.post.author.handle}`}
style={outerStyles}
@@ -257,7 +262,7 @@ export const FeedItem = observer(function ({
</View>
</View>
</Link>
</PostMutedWrapper>
</PostHider>
)
})
+83
View File
@@ -0,0 +1,83 @@
import React from 'react'
import {StyleSheet, TouchableOpacity, View} from 'react-native'
import {ComAtprotoLabelDefs} from '@atproto/api'
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
import {usePalette} from 'lib/hooks/usePalette'
import {Text} from './text/Text'
import {getLabelValueGroup} from 'lib/labeling/helpers'
export function PostHider({
isMuted,
labels,
children,
}: React.PropsWithChildren<{
isMuted?: boolean
labels: ComAtprotoLabelDefs.Label[] | undefined
}>) {
const pal = usePalette('default')
const palError = usePalette('error')
const [override, setOverride] = React.useState(false)
if (!isMuted && !labels?.length) {
return <>{children}</>
}
const label = labels?.[0] // TODO use config to settle on most relevant item
const labelGroup = getLabelValueGroup(label?.val || '')
if (labelGroup.id === 'illegal') {
return <></>
}
return (
<View style={[styles.container, pal.view]}>
<View style={[styles.description, pal.view, pal.border]}>
<FontAwesomeIcon
icon={['far', 'eye-slash']}
style={[styles.icon, pal.text]}
/>
<Text type="md" style={pal.textLight}>
{isMuted ? (
<>Post from an account you muted.</>
) : label ? (
<>Warning: {labelGroup.title}</>
) : (
''
)}
</Text>
<TouchableOpacity
style={styles.showBtn}
onPress={() => setOverride(v => !v)}>
<Text type="md" style={pal.link}>
{override ? 'Hide' : 'Show'} post
</Text>
</TouchableOpacity>
</View>
{override && (
<View
style={[styles.childrenContainer, pal.border, palError.viewLight]}>
{children}
</View>
)}
</View>
)
}
const styles = StyleSheet.create({
description: {
flexDirection: 'row',
alignItems: 'center',
paddingVertical: 14,
paddingHorizontal: 18,
borderTopWidth: 1,
},
icon: {
marginRight: 10,
},
showBtn: {
marginLeft: 'auto',
},
childrenContainer: {
paddingHorizontal: 6,
paddingVertical: 6,
},
})
-50
View File
@@ -1,50 +0,0 @@
import React from 'react'
import {StyleSheet, TouchableOpacity, View} from 'react-native'
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
import {usePalette} from 'lib/hooks/usePalette'
import {Text} from './text/Text'
export function PostMutedWrapper({
isMuted,
children,
}: React.PropsWithChildren<{isMuted?: boolean}>) {
const pal = usePalette('default')
const [override, setOverride] = React.useState(false)
if (!isMuted || override) {
return <>{children}</>
}
return (
<View style={[styles.container, pal.view, pal.border]}>
<FontAwesomeIcon
icon={['far', 'eye-slash']}
style={[styles.icon, pal.text]}
/>
<Text type="md" style={pal.textLight}>
Post from an account you muted.
</Text>
<TouchableOpacity
style={styles.showBtn}
onPress={() => setOverride(true)}>
<Text type="md" style={pal.link}>
Show post
</Text>
</TouchableOpacity>
</View>
)
}
const styles = StyleSheet.create({
container: {
flexDirection: 'row',
alignItems: 'center',
paddingVertical: 14,
paddingHorizontal: 18,
borderTopWidth: 1,
},
icon: {
marginRight: 10,
},
showBtn: {
marginLeft: 'auto',
},
})