[APP-639] Improve nsfw handling & force hidden on iOS (#605)

* Identify adult content labels and handle them more specifically

* Change adult content defaults to more conservative settings

* Add an adultcontentenabled override that prohibits access on iOS

* Improve usability of the content hider

* Fix lint
This commit is contained in:
Paul Frazee 2023-05-09 00:43:20 -05:00 committed by GitHub
parent 7a176b3fdf
commit b756a27958
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 223 additions and 62 deletions

View file

@ -1,11 +1,5 @@
import React from 'react'
import {
StyleProp,
StyleSheet,
TouchableOpacity,
View,
ViewStyle,
} from 'react-native'
import {Pressable, StyleProp, StyleSheet, View, ViewStyle} from 'react-native'
import {usePalette} from 'lib/hooks/usePalette'
import {Text} from '../text/Text'
import {addStyle} from 'lib/styles'
@ -25,6 +19,12 @@ export function ContentHider({
}>) {
const pal = usePalette('default')
const [override, setOverride] = React.useState(false)
const onPressShow = React.useCallback(() => {
setOverride(true)
}, [setOverride])
const onPressHide = React.useCallback(() => {
setOverride(false)
}, [setOverride])
if (
moderation.behavior === ModerationBehaviorCode.Show ||
@ -44,7 +44,15 @@ export function ContentHider({
return (
<View style={[styles.container, pal.view, pal.border, containerStyle]}>
<View
<Pressable
onPress={override ? onPressHide : onPressShow}
accessibilityLabel={override ? 'Hide post' : 'Show post'}
// TODO: The text labelling should be split up so controls have unique roles
accessibilityHint={
override
? 'Re-hide post'
: 'Shows post hidden based on your moderation settings'
}
style={[
styles.description,
pal.viewLight,
@ -53,21 +61,12 @@ export function ContentHider({
<Text type="md" style={pal.textLight}>
{moderation.reason || 'Content warning'}
</Text>
<TouchableOpacity
style={styles.showBtn}
onPress={() => setOverride(v => !v)}
accessibilityLabel={override ? 'Hide post' : 'Show post'}
// TODO: The text labelling should be split up so controls have unique roles
accessibilityHint={
override
? 'Re-hide post'
: 'Shows post hidden based on your moderation settings'
}>
<Text type="md" style={pal.link}>
<View style={styles.showBtn}>
<Text type="md-medium" style={pal.link}>
{override ? 'Hide' : 'Show'}
</Text>
</TouchableOpacity>
</View>
</View>
</Pressable>
{override && (
<View style={[styles.childrenContainer, pal.border]}>
<View testID={testID} style={addStyle(style, styles.child)}>

View file

@ -0,0 +1,128 @@
import React from 'react'
import {Pressable, StyleProp, StyleSheet, View, ViewStyle} from 'react-native'
import {usePalette} from 'lib/hooks/usePalette'
import {Text} from '../text/Text'
import {BlurView} from '../BlurView'
import {ModerationBehavior, ModerationBehaviorCode} from 'lib/labeling/types'
import {isAndroid} from 'platform/detection'
export function ImageHider({
testID,
moderation,
style,
containerStyle,
children,
}: React.PropsWithChildren<{
testID?: string
moderation: ModerationBehavior
style?: StyleProp<ViewStyle>
containerStyle?: StyleProp<ViewStyle>
}>) {
const pal = usePalette('default')
const [override, setOverride] = React.useState(false)
const onPressShow = React.useCallback(() => {
setOverride(true)
}, [setOverride])
const onPressHide = React.useCallback(() => {
setOverride(false)
}, [setOverride])
if (moderation.behavior !== ModerationBehaviorCode.WarnImages) {
return (
<View testID={testID} style={style}>
{children}
</View>
)
}
if (moderation.behavior === ModerationBehaviorCode.Hide) {
return null
}
return (
<View style={[styles.container, containerStyle]}>
<View testID={testID} style={style}>
{children}
</View>
{override ? (
<Pressable
onPress={onPressHide}
style={[styles.hideBtn, pal.view]}
accessibilityLabel="Hide image"
accessibilityHint="Rehides the image">
<Text type="xl-bold" style={pal.link}>
Hide
</Text>
</Pressable>
) : (
<>
{isAndroid ? (
/* android has an issue that breaks the blurview */
/* see https://github.com/Kureev/react-native-blur/issues/486 */
<View style={[pal.viewLight, styles.overlay, styles.coverView]} />
) : (
<BlurView
style={[styles.overlay, styles.blurView]}
blurType="light"
blurAmount={100}
reducedTransparencyFallbackColor="white"
/>
)}
<View style={[styles.overlay, styles.info]}>
<Pressable
onPress={onPressShow}
style={[styles.showBtn, pal.view]}
accessibilityLabel="Show image"
accessibilityHint="Shows image hidden based on your moderation settings">
<Text type="xl" style={pal.text}>
{moderation.reason || 'Content warning'}
</Text>
<Text type="xl-bold" style={pal.link}>
Show
</Text>
</Pressable>
</View>
</>
)}
</View>
)
}
const styles = StyleSheet.create({
container: {
position: 'relative',
marginBottom: 10,
},
overlay: {
position: 'absolute',
left: 0,
top: 0,
right: 0,
bottom: 0,
},
blurView: {
borderRadius: 8,
},
coverView: {
borderRadius: 8,
},
info: {
justifyContent: 'center',
alignItems: 'center',
},
showBtn: {
flexDirection: 'row',
gap: 8,
paddingHorizontal: 18,
paddingVertical: 14,
borderRadius: 24,
},
hideBtn: {
position: 'absolute',
left: 8,
bottom: 20,
paddingHorizontal: 8,
paddingVertical: 6,
borderRadius: 8,
},
})