support portals, minor refactor
This commit is contained in:
@@ -37,7 +37,7 @@ export function GifSelectDialog({
|
||||
onSelectGif: onSelectGifProp,
|
||||
}: {
|
||||
controlRef: React.RefObject<{open: () => void}>
|
||||
onClose: () => void
|
||||
onClose?: () => void
|
||||
onSelectGif: (gif: Gif) => void
|
||||
}) {
|
||||
const control = Dialog.useDialogControl()
|
||||
|
||||
@@ -497,10 +497,6 @@ export const ComposePost = ({
|
||||
openEmojiPicker?.(textInput.current?.getCursorPosition())
|
||||
}, [openEmojiPicker])
|
||||
|
||||
const focusTextInput = useCallback(() => {
|
||||
textInput.current?.focus()
|
||||
}, [])
|
||||
|
||||
const onSelectGif = useCallback((gif: Gif) => {
|
||||
dispatch({type: 'embed_add_gif', gif})
|
||||
}, [])
|
||||
@@ -569,6 +565,7 @@ export const ComposePost = ({
|
||||
dispatch({type: 'update_labels', labels: nextLabels})
|
||||
}}
|
||||
hasMedia={hasMedia || Boolean(extLink)}
|
||||
Portal={Portal.Portal}
|
||||
/>
|
||||
{canPost ? (
|
||||
<Button
|
||||
@@ -807,7 +804,6 @@ export const ComposePost = ({
|
||||
onAdd={onImageAdd}
|
||||
/>
|
||||
<SelectGifBtn
|
||||
onClose={focusTextInput}
|
||||
onSelectGif={onSelectGif}
|
||||
disabled={hasMedia}
|
||||
/>
|
||||
|
||||
@@ -4,12 +4,12 @@ import {msg, Trans} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
import {ShieldExclamation} from '#/lib/icons'
|
||||
import {isNative} from '#/platform/detection'
|
||||
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 {PortalComponent} from '#/components/Portal'
|
||||
import {Text} from '#/components/Typography'
|
||||
|
||||
const ADULT_CONTENT_LABELS = ['sexual', 'nudity', 'porn']
|
||||
@@ -18,10 +18,12 @@ export function LabelsBtn({
|
||||
labels,
|
||||
hasMedia,
|
||||
onChange,
|
||||
Portal,
|
||||
}: {
|
||||
labels: string[]
|
||||
hasMedia: boolean
|
||||
onChange: (v: string[]) => void
|
||||
Portal: PortalComponent
|
||||
}) {
|
||||
const control = Dialog.useDialogControl()
|
||||
const t = useTheme()
|
||||
@@ -52,9 +54,7 @@ export function LabelsBtn({
|
||||
msg`Opens a dialog to add a content warning to your post`,
|
||||
)}
|
||||
onPress={() => {
|
||||
if (isNative && Keyboard.isVisible()) {
|
||||
Keyboard.dismiss()
|
||||
}
|
||||
Keyboard.dismiss()
|
||||
control.open()
|
||||
}}>
|
||||
<ShieldExclamation style={{color: t.palette.primary_500}} size={24} />
|
||||
@@ -63,122 +63,143 @@ export function LabelsBtn({
|
||||
) : null}
|
||||
</Button>
|
||||
|
||||
<Dialog.Outer control={control}>
|
||||
<Dialog.Outer
|
||||
control={control}
|
||||
Portal={Portal}
|
||||
nativeOptions={{preventExpansion: true}}>
|
||||
<Dialog.Handle />
|
||||
<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="xsmall"
|
||||
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()}
|
||||
onAccessibilityEscape={control.close}
|
||||
color="primary"
|
||||
size="medium"
|
||||
variant="solid"
|
||||
style={a.mt_xl}>
|
||||
<ButtonText>
|
||||
<Trans>Done</Trans>
|
||||
</ButtonText>
|
||||
</Button>
|
||||
</Dialog.ScrollableInner>
|
||||
<DialogInner
|
||||
labels={labels}
|
||||
onChange={onChange}
|
||||
hasAdultSelection={hasAdultSelection}
|
||||
hasMedia={hasMedia}
|
||||
removeAdultLabel={removeAdultLabel}
|
||||
/>
|
||||
</Dialog.Outer>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
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()}
|
||||
onAccessibilityEscape={() => control.close()}
|
||||
color="primary"
|
||||
size="large"
|
||||
variant="solid"
|
||||
style={a.mt_xl}>
|
||||
<ButtonText>
|
||||
<Trans>Done</Trans>
|
||||
</ButtonText>
|
||||
</Button>
|
||||
</Dialog.ScrollableInner>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import {GifSelectDialog} from '#/components/dialogs/GifSelect'
|
||||
import {GifSquare_Stroke2_Corner0_Rounded as GifIcon} from '#/components/icons/Gif'
|
||||
|
||||
type Props = {
|
||||
onClose: () => void
|
||||
onClose?: () => void
|
||||
onSelectGif: (gif: Gif) => void
|
||||
disabled?: boolean
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user