about summary refs log tree commit diff
path: root/src/view/com/composer/labels/LabelsBtn.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/view/com/composer/labels/LabelsBtn.tsx')
-rw-r--r--src/view/com/composer/labels/LabelsBtn.tsx225
1 files changed, 178 insertions, 47 deletions
diff --git a/src/view/com/composer/labels/LabelsBtn.tsx b/src/view/com/composer/labels/LabelsBtn.tsx
index 27e3813dc..d72366aea 100644
--- a/src/view/com/composer/labels/LabelsBtn.tsx
+++ b/src/view/com/composer/labels/LabelsBtn.tsx
@@ -1,15 +1,17 @@
 import React from 'react'
-import {Keyboard, StyleSheet} from 'react-native'
-import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
-import {FontAwesomeIconStyle} from '@fortawesome/react-native-fontawesome'
-import {msg} from '@lingui/macro'
+import {Keyboard, LayoutAnimation, View} from 'react-native'
+import {msg, Trans} from '@lingui/macro'
 import {useLingui} from '@lingui/react'
 
-import {useModalControls} from '#/state/modals'
-import {usePalette} from 'lib/hooks/usePalette'
-import {ShieldExclamation} from 'lib/icons'
-import {isNative} from 'platform/detection'
-import {Button} from 'view/com/util/forms/Button'
+import {ShieldExclamation} from '#/lib/icons'
+import {atoms as a, useTheme} from '#/alf'
+import {Button, ButtonText} from '#/components/Button'
+import * as Dialog from '#/components/Dialog'
+import * as ToggleButton from '#/components/forms/ToggleButton'
+import {Check_Stroke2_Corner0_Rounded as Check} from '#/components/icons/Check'
+import {Text} from '#/components/Typography'
+
+const ADULT_CONTENT_LABELS = ['sexual', 'nudity', 'porn']
 
 export function LabelsBtn({
   labels,
@@ -20,48 +22,177 @@ export function LabelsBtn({
   hasMedia: boolean
   onChange: (v: string[]) => void
 }) {
-  const pal = usePalette('default')
+  const control = Dialog.useDialogControl()
+  const t = useTheme()
   const {_} = useLingui()
-  const {openModal} = useModalControls()
+
+  const removeAdultLabel = () => {
+    const final = labels.filter(l => !ADULT_CONTENT_LABELS.includes(l))
+    onChange(final)
+    LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut)
+  }
+
+  const hasAdultSelection =
+    labels.includes('sexual') ||
+    labels.includes('nudity') ||
+    labels.includes('porn')
+
+  if (!hasMedia && hasAdultSelection) {
+    removeAdultLabel()
+  }
 
   return (
-    <Button
-      type="default-light"
-      testID="labelsBtn"
-      style={[styles.button, !hasMedia && styles.dimmed]}
-      accessibilityLabel={_(msg`Content warnings`)}
-      accessibilityHint=""
-      onPress={() => {
-        if (isNative) {
-          if (Keyboard.isVisible()) {
-            Keyboard.dismiss()
-          }
-        }
-        openModal({name: 'self-label', labels, hasMedia, onChange})
-      }}>
-      <ShieldExclamation style={pal.link} size={24} />
-      {labels.length > 0 ? (
-        <FontAwesomeIcon
-          icon="check"
-          size={16}
-          style={pal.link as FontAwesomeIconStyle}
+    <>
+      <Button
+        testID="labelsBtn"
+        style={!hasMedia && {opacity: 0.4}}
+        label={_(msg`Content warnings`)}
+        accessibilityHint={_(
+          msg`Opens a dialog to add a content warning to your post`,
+        )}
+        onPress={() => {
+          Keyboard.dismiss()
+          control.open()
+        }}>
+        <ShieldExclamation style={{color: t.palette.primary_500}} size={24} />
+        {labels.length > 0 ? (
+          <Check size="sm" fill={t.palette.primary_500} />
+        ) : null}
+      </Button>
+
+      <Dialog.Outer control={control} nativeOptions={{preventExpansion: true}}>
+        <Dialog.Handle />
+        <DialogInner
+          labels={labels}
+          onChange={onChange}
+          hasAdultSelection={hasAdultSelection}
+          hasMedia={hasMedia}
+          removeAdultLabel={removeAdultLabel}
         />
-      ) : null}
-    </Button>
+      </Dialog.Outer>
+    </>
   )
 }
 
-const styles = StyleSheet.create({
-  button: {
-    flexDirection: 'row',
-    alignItems: 'center',
-    paddingVertical: 2,
-    paddingHorizontal: 6,
-  },
-  dimmed: {
-    opacity: 0.4,
-  },
-  label: {
-    maxWidth: 100,
-  },
-})
+function DialogInner({
+  labels,
+  onChange,
+  hasAdultSelection,
+  hasMedia,
+  removeAdultLabel,
+}: {
+  labels: string[]
+  onChange: (v: string[]) => void
+  hasAdultSelection: boolean
+  hasMedia: boolean
+  removeAdultLabel: () => void
+}) {
+  const {_} = useLingui()
+  const control = Dialog.useDialogContext()
+  const t = useTheme()
+
+  return (
+    <Dialog.ScrollableInner
+      label={_(msg`Add a content warning`)}
+      style={[{maxWidth: 500}, a.w_full]}>
+      <View style={[a.flex_1, a.gap_md]}>
+        <Text style={[a.text_2xl, a.font_bold]}>
+          <Trans>Add a content warning</Trans>
+        </Text>
+
+        <View
+          style={[
+            a.border,
+            a.p_md,
+            t.atoms.border_contrast_high,
+            a.rounded_md,
+          ]}>
+          <View
+            style={[a.flex_row, a.align_center, a.justify_between, a.pb_sm]}>
+            <Text style={[a.font_bold, a.text_lg]}>
+              <Trans>Adult Content</Trans>
+            </Text>
+
+            <Button
+              label={_(msg`Remove`)}
+              variant="ghost"
+              color="primary"
+              size="tiny"
+              onPress={removeAdultLabel}
+              disabled={!hasAdultSelection}
+              style={{opacity: hasAdultSelection ? 1 : 0}}
+              aria-hidden={!hasAdultSelection}>
+              <ButtonText>
+                <Trans>Remove</Trans>
+              </ButtonText>
+            </Button>
+          </View>
+          {hasMedia ? (
+            <>
+              <ToggleButton.Group
+                label={_(msg`Adult Content labels`)}
+                values={labels}
+                onChange={values => {
+                  onChange(values)
+                  LayoutAnimation.configureNext(
+                    LayoutAnimation.Presets.easeInEaseOut,
+                  )
+                }}>
+                <ToggleButton.Button name="sexual" label={_(msg`Suggestive`)}>
+                  <ToggleButton.ButtonText>
+                    <Trans>Suggestive</Trans>
+                  </ToggleButton.ButtonText>
+                </ToggleButton.Button>
+                <ToggleButton.Button name="nudity" label={_(msg`Nudity`)}>
+                  <ToggleButton.ButtonText>
+                    <Trans>Nudity</Trans>
+                  </ToggleButton.ButtonText>
+                </ToggleButton.Button>
+                <ToggleButton.Button name="porn" label={_(msg`Porn`)}>
+                  <ToggleButton.ButtonText>
+                    <Trans>Porn</Trans>
+                  </ToggleButton.ButtonText>
+                </ToggleButton.Button>
+              </ToggleButton.Group>
+
+              <Text style={[a.mt_sm, t.atoms.text_contrast_medium]}>
+                {labels.includes('sexual') ? (
+                  <Trans>Pictures meant for adults.</Trans>
+                ) : labels.includes('nudity') ? (
+                  <Trans>Artistic or non-erotic nudity.</Trans>
+                ) : labels.includes('porn') ? (
+                  <Trans>Sexual activity or erotic nudity.</Trans>
+                ) : (
+                  <Trans>If none are selected, suitable for all ages.</Trans>
+                )}
+              </Text>
+            </>
+          ) : (
+            <View>
+              <Text style={t.atoms.text_contrast_medium}>
+                <Trans>
+                  <Text style={[a.font_bold, t.atoms.text_contrast_medium]}>
+                    Not Applicable.
+                  </Text>{' '}
+                  This warning is only available for posts with media attached.
+                </Trans>
+              </Text>
+            </View>
+          )}
+        </View>
+      </View>
+
+      <Button
+        label={_(msg`Done`)}
+        onPress={() => control.close()}
+        color="primary"
+        size="large"
+        variant="solid"
+        style={a.mt_xl}>
+        <ButtonText>
+          <Trans>Done</Trans>
+        </ButtonText>
+      </Button>
+    </Dialog.ScrollableInner>
+  )
+}