diff options
Diffstat (limited to 'src/view/com/modals')
-rw-r--r-- | src/view/com/modals/Modal.tsx | 4 | ||||
-rw-r--r-- | src/view/com/modals/Modal.web.tsx | 3 | ||||
-rw-r--r-- | src/view/com/modals/ModerationDetails.tsx | 8 | ||||
-rw-r--r-- | src/view/com/modals/SelfLabel.tsx | 167 |
4 files changed, 178 insertions, 4 deletions
diff --git a/src/view/com/modals/Modal.tsx b/src/view/com/modals/Modal.tsx index 469492971..ce5dc40e0 100644 --- a/src/view/com/modals/Modal.tsx +++ b/src/view/com/modals/Modal.tsx @@ -15,6 +15,7 @@ import * as ProfilePreviewModal from './ProfilePreview' import * as ServerInputModal from './ServerInput' import * as ReportPostModal from './report/ReportPost' import * as RepostModal from './Repost' +import * as SelfLabelModal from './SelfLabel' import * as CreateOrEditMuteListModal from './CreateOrEditMuteList' import * as ListAddRemoveUserModal from './ListAddRemoveUser' import * as AltImageModal from './AltImage' @@ -104,6 +105,9 @@ export const ModalsContainer = observer(function ModalsContainer() { } else if (activeModal?.name === 'repost') { snapPoints = RepostModal.snapPoints element = <RepostModal.Component {...activeModal} /> + } else if (activeModal?.name === 'self-label') { + snapPoints = SelfLabelModal.snapPoints + element = <SelfLabelModal.Component {...activeModal} /> } else if (activeModal?.name === 'alt-text-image') { snapPoints = AltImageModal.snapPoints element = <AltImageModal.Component {...activeModal} /> diff --git a/src/view/com/modals/Modal.web.tsx b/src/view/com/modals/Modal.web.tsx index df13dfed2..0f6247822 100644 --- a/src/view/com/modals/Modal.web.tsx +++ b/src/view/com/modals/Modal.web.tsx @@ -16,6 +16,7 @@ import * as CreateOrEditMuteListModal from './CreateOrEditMuteList' import * as ListAddRemoveUserModal from './ListAddRemoveUser' import * as DeleteAccountModal from './DeleteAccount' import * as RepostModal from './Repost' +import * as SelfLabelModal from './SelfLabel' import * as CropImageModal from './crop-image/CropImage.web' import * as AltTextImageModal from './AltImage' import * as EditImageModal from './EditImage' @@ -89,6 +90,8 @@ function Modal({modal}: {modal: ModalIface}) { element = <DeleteAccountModal.Component /> } else if (modal.name === 'repost') { element = <RepostModal.Component {...modal} /> + } else if (modal.name === 'self-label') { + element = <SelfLabelModal.Component {...modal} /> } else if (modal.name === 'change-handle') { element = <ChangeHandleModal.Component {...modal} /> } else if (modal.name === 'waitlist') { diff --git a/src/view/com/modals/ModerationDetails.tsx b/src/view/com/modals/ModerationDetails.tsx index abeb2fdf4..598d26924 100644 --- a/src/view/com/modals/ModerationDetails.tsx +++ b/src/view/com/modals/ModerationDetails.tsx @@ -35,10 +35,7 @@ export function Component({ name = 'Account Blocks You' description = 'This user has blocked you. You cannot view their content.' } else if (moderation.cause.type === 'muted') { - if (moderation.cause.source.type === 'user') { - name = 'Account Muted' - description = 'You have muted this user.' - } else { + if (moderation.cause.source.type === 'list') { const list = moderation.cause.source.list name = <>Account Muted by List</> description = ( @@ -53,6 +50,9 @@ export function Component({ list which you have muted. </> ) + } else { + name = 'Account Muted' + description = 'You have muted this user.' } } else { name = moderation.cause.labelDef.strings[context].en.name diff --git a/src/view/com/modals/SelfLabel.tsx b/src/view/com/modals/SelfLabel.tsx new file mode 100644 index 000000000..cb78f3f15 --- /dev/null +++ b/src/view/com/modals/SelfLabel.tsx @@ -0,0 +1,167 @@ +import React, {useState} from 'react' +import {StyleSheet, TouchableOpacity, View} from 'react-native' +import {observer} from 'mobx-react-lite' +import {Text} from '../util/text/Text' +import {useStores} from 'state/index' +import {s, colors} from 'lib/styles' +import {usePalette} from 'lib/hooks/usePalette' +import {isDesktopWeb} from 'platform/detection' +import {SelectableBtn} from '../util/forms/SelectableBtn' +import {ScrollView} from 'view/com/modals/util' + +const ADULT_CONTENT_LABELS = ['sexual', 'nudity', 'porn'] + +export const snapPoints = ['50%'] + +export const Component = observer(function Component({ + labels, + onChange, +}: { + labels: string[] + onChange: (labels: string[]) => void +}) { + const pal = usePalette('default') + const store = useStores() + const [selected, setSelected] = useState(labels) + + const toggleAdultContent = (label: string) => { + const hadLabel = selected.includes(label) + const stripped = selected.filter(l => !ADULT_CONTENT_LABELS.includes(l)) + const final = !hadLabel ? stripped.concat([label]) : stripped + setSelected(final) + onChange(final) + } + + return ( + <View testID="selfLabelModal" style={[pal.view, styles.container]}> + <View style={styles.titleSection}> + <Text type="title-lg" style={[pal.text, styles.title]}> + Add a content warning + </Text> + </View> + + <ScrollView> + <View style={[styles.section, pal.border, {borderBottomWidth: 1}]}> + <View + style={{ + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-between', + paddingBottom: 8, + }}> + <Text type="title" style={pal.text}> + Adult Content + </Text> + + <Text type="lg" style={pal.text}> + {selected.includes('sexual') ? ( + <>😏</> + ) : selected.includes('nudity') ? ( + <>🫣</> + ) : selected.includes('porn') ? ( + <>🥵</> + ) : ( + <></> + )} + </Text> + </View> + <View style={s.flexRow}> + <SelectableBtn + testID="sexualLabelBtn" + selected={selected.includes('sexual')} + left + label="Suggestive" + onSelect={() => toggleAdultContent('sexual')} + accessibilityHint="" + style={s.flex1} + /> + <SelectableBtn + testID="nudityLabelBtn" + selected={selected.includes('nudity')} + label="Nudity" + onSelect={() => toggleAdultContent('nudity')} + accessibilityHint="" + style={s.flex1} + /> + <SelectableBtn + testID="pornLabelBtn" + selected={selected.includes('porn')} + label="Porn" + right + onSelect={() => toggleAdultContent('porn')} + accessibilityHint="" + style={s.flex1} + /> + </View> + + <Text style={[pal.text, styles.adultExplainer]}> + {selected.includes('sexual') ? ( + <>Pictures meant for adults.</> + ) : selected.includes('nudity') ? ( + <>Artistic or non-erotic nudity.</> + ) : selected.includes('porn') ? ( + <>Sexual activity or erotic nudity.</> + ) : ( + <>If none are selected, suitable for all ages.</> + )} + </Text> + </View> + </ScrollView> + + <View style={[styles.btnContainer, pal.borderDark]}> + <TouchableOpacity + testID="confirmBtn" + onPress={() => { + store.shell.closeModal() + }} + style={styles.btn} + accessibilityRole="button" + accessibilityLabel="Confirm" + accessibilityHint=""> + <Text style={[s.white, s.bold, s.f18]}>Done</Text> + </TouchableOpacity> + </View> + </View> + ) +}) + +const styles = StyleSheet.create({ + container: { + flex: 1, + paddingBottom: isDesktopWeb ? 0 : 40, + }, + titleSection: { + paddingTop: isDesktopWeb ? 0 : 4, + paddingBottom: isDesktopWeb ? 14 : 10, + }, + title: { + textAlign: 'center', + fontWeight: '600', + marginBottom: 5, + }, + description: { + textAlign: 'center', + paddingHorizontal: 32, + }, + section: { + borderTopWidth: 1, + paddingVertical: 20, + paddingHorizontal: isDesktopWeb ? 0 : 20, + }, + adultExplainer: { + paddingLeft: 5, + paddingTop: 10, + }, + btn: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'center', + borderRadius: 32, + padding: 14, + backgroundColor: colors.blue3, + }, + btnContainer: { + paddingTop: 20, + paddingHorizontal: 20, + }, +}) |