Allow nested sheets without boilerplate (#5660)

Co-authored-by: Hailey <me@haileyok.com>
This commit is contained in:
Samuel Newman
2024-10-09 21:30:42 +03:00
committed by GitHub
parent b3ade19bbe
commit cca344a3d1
20 changed files with 596 additions and 555 deletions
+4 -16
View File
@@ -107,9 +107,9 @@ import {Button, ButtonIcon, ButtonText} from '#/components/Button'
import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo'
import {EmojiArc_Stroke2_Corner0_Rounded as EmojiSmile} from '#/components/icons/Emoji'
import {TimesLarge_Stroke2_Corner0_Rounded as X} from '#/components/icons/Times'
import {createPortalGroup} from '#/components/Portal'
import * as Prompt from '#/components/Prompt'
import {Text as NewText} from '#/components/Typography'
import {BottomSheetPortalProvider} from '../../../../modules/bottom-sheet'
import {
composerReducer,
createComposerState,
@@ -117,8 +117,6 @@ import {
} from './state/composer'
import {NO_VIDEO, NoVideoState, processVideo, VideoState} from './state/video'
const Portal = createPortalGroup()
type CancelRef = {
onPressCancel: () => void
}
@@ -522,7 +520,7 @@ export const ComposePost = ({
const keyboardVerticalOffset = useKeyboardVerticalOffset()
return (
<Portal.Provider>
<BottomSheetPortalProvider>
<KeyboardAvoidingView
testID="composePostView"
behavior={isIOS ? 'padding' : 'height'}
@@ -666,11 +664,7 @@ export const ComposePost = ({
/>
</View>
<Gallery
images={images}
dispatch={dispatch}
Portal={Portal.Portal}
/>
<Gallery images={images} dispatch={dispatch} />
{extGif && (
<View style={a.relative} key={extGif.url}>
@@ -684,7 +678,6 @@ export const ComposePost = ({
gif={extGif}
altText={extGifAlt ?? ''}
onSubmit={handleChangeGifAltText}
Portal={Portal.Portal}
/>
</View>
)}
@@ -744,7 +737,6 @@ export const ComposePost = ({
},
})
}}
Portal={Portal.Portal}
/>
</Animated.View>
)}
@@ -782,7 +774,6 @@ export const ComposePost = ({
})
}}
style={bottomBarAnimatedStyle}
Portal={Portal.Portal}
/>
)}
<View
@@ -819,7 +810,6 @@ export const ComposePost = ({
onClose={focusTextInput}
onSelectGif={onSelectGif}
disabled={hasMedia}
Portal={Portal.Portal}
/>
{!isMobile ? (
<Button
@@ -849,11 +839,9 @@ export const ComposePost = ({
onConfirm={onClose}
confirmButtonCta={_(msg`Discard`)}
confirmButtonColor="negative"
Portal={Portal.Portal}
/>
</KeyboardAvoidingView>
<Portal.Outlet />
</Portal.Provider>
</BottomSheetPortalProvider>
)
}
+1 -8
View File
@@ -21,7 +21,6 @@ import * as TextField from '#/components/forms/TextField'
import {Check_Stroke2_Corner0_Rounded as Check} from '#/components/icons/Check'
import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo'
import {PlusSmall_Stroke2_Corner0_Rounded as Plus} from '#/components/icons/Plus'
import {PortalComponent} from '#/components/Portal'
import {Text} from '#/components/Typography'
import {GifEmbed} from '../util/post-embeds/GifEmbed'
import {AltTextReminder} from './photos/Gallery'
@@ -30,12 +29,10 @@ export function GifAltTextDialog({
gif,
altText,
onSubmit,
Portal,
}: {
gif: Gif
altText: string
onSubmit: (alt: string) => void
Portal: PortalComponent
}) {
const {data} = useResolveGifQuery(gif)
const vendorAltText = parseAltFromGIFDescription(data?.description ?? '').alt
@@ -50,7 +47,6 @@ export function GifAltTextDialog({
thumb={data.thumb?.source.path}
params={params}
onSubmit={onSubmit}
Portal={Portal}
/>
)
}
@@ -61,14 +57,12 @@ export function GifAltTextDialogLoaded({
onSubmit,
params,
thumb,
Portal,
}: {
vendorAltText: string
altText: string
onSubmit: (alt: string) => void
params: EmbedPlayerParams
thumb: string | undefined
Portal: PortalComponent
}) {
const control = Dialog.useDialogControl()
const {_} = useLingui()
@@ -113,8 +107,7 @@ export function GifAltTextDialogLoaded({
control={control}
onClose={() => {
onSubmit(altTextDraft)
}}
Portal={Portal}>
}}>
<Dialog.Handle />
<AltTextInner
vendorAltText={vendorAltText}
+1 -12
View File
@@ -21,7 +21,6 @@ import {ComposerImage, cropImage} from '#/state/gallery'
import {Text} from '#/view/com/util/text/Text'
import {useTheme} from '#/alf'
import * as Dialog from '#/components/Dialog'
import {PortalComponent} from '#/components/Portal'
import {ComposerAction} from '../state/composer'
import {EditImageDialog} from './EditImageDialog'
import {ImageAltTextDialog} from './ImageAltTextDialog'
@@ -31,7 +30,6 @@ const IMAGE_GAP = 8
interface GalleryProps {
images: ComposerImage[]
dispatch: (action: ComposerAction) => void
Portal: PortalComponent
}
export let Gallery = (props: GalleryProps): React.ReactNode => {
@@ -59,12 +57,7 @@ interface GalleryInnerProps extends GalleryProps {
containerInfo: Dimensions
}
const GalleryInner = ({
images,
containerInfo,
dispatch,
Portal,
}: GalleryInnerProps) => {
const GalleryInner = ({images, containerInfo, dispatch}: GalleryInnerProps) => {
const {isMobile} = useWebMediaQueries()
const {altTextControlStyle, imageControlsStyle, imageStyle} =
@@ -118,7 +111,6 @@ const GalleryInner = ({
onRemove={() => {
dispatch({type: 'embed_remove_image', image})
}}
Portal={Portal}
/>
)
})}
@@ -135,7 +127,6 @@ type GalleryItemProps = {
imageStyle?: ViewStyle
onChange: (next: ComposerImage) => void
onRemove: () => void
Portal: PortalComponent
}
const GalleryItem = ({
@@ -145,7 +136,6 @@ const GalleryItem = ({
imageStyle,
onChange,
onRemove,
Portal,
}: GalleryItemProps): React.ReactNode => {
const {_} = useLingui()
const t = useTheme()
@@ -240,7 +230,6 @@ const GalleryItem = ({
control={altTextControl}
image={image}
onChange={onChange}
Portal={Portal}
/>
<EditImageDialog
@@ -15,21 +15,18 @@ import * as Dialog from '#/components/Dialog'
import {DialogControlProps} from '#/components/Dialog'
import * as TextField from '#/components/forms/TextField'
import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo'
import {PortalComponent} from '#/components/Portal'
import {Text} from '#/components/Typography'
type Props = {
control: Dialog.DialogOuterProps['control']
image: ComposerImage
onChange: (next: ComposerImage) => void
Portal: PortalComponent
}
export const ImageAltTextDialog = ({
control,
image,
onChange,
Portal,
}: Props): React.ReactNode => {
const [altText, setAltText] = React.useState(image.alt)
@@ -41,8 +38,7 @@ export const ImageAltTextDialog = ({
...image,
alt: enforceLen(altText, MAX_ALT_TEXT, true),
})
}}
Portal={Portal}>
}}>
<Dialog.Handle />
<ImageAltTextInner
control={control}
@@ -9,16 +9,14 @@ import {atoms as a, useTheme} from '#/alf'
import {Button} from '#/components/Button'
import {GifSelectDialog} from '#/components/dialogs/GifSelect'
import {GifSquare_Stroke2_Corner0_Rounded as GifIcon} from '#/components/icons/Gif'
import {PortalComponent} from '#/components/Portal'
type Props = {
onClose: () => void
onSelectGif: (gif: Gif) => void
disabled?: boolean
Portal?: PortalComponent
}
export function SelectGifBtn({onClose, onSelectGif, disabled, Portal}: Props) {
export function SelectGifBtn({onClose, onSelectGif, disabled}: Props) {
const {_} = useLingui()
const ref = useRef<{open: () => void}>(null)
const t = useTheme()
@@ -48,7 +46,6 @@ export function SelectGifBtn({onClose, onSelectGif, disabled, Portal}: Props) {
controlRef={ref}
onClose={onClose}
onSelectGif={onSelectGif}
Portal={Portal}
/>
</>
)
@@ -13,7 +13,6 @@ import * as Dialog from '#/components/Dialog'
import {PostInteractionSettingsControlledDialog} from '#/components/dialogs/PostInteractionSettingsDialog'
import {Earth_Stroke2_Corner0_Rounded as Earth} from '#/components/icons/Globe'
import {Group3_Stroke2_Corner0_Rounded as Group} from '#/components/icons/Group'
import {PortalComponent} from '#/components/Portal'
export function ThreadgateBtn({
postgate,
@@ -21,7 +20,6 @@ export function ThreadgateBtn({
threadgateAllowUISettings,
onChangeThreadgateAllowUISettings,
style,
Portal,
}: {
postgate: AppBskyFeedPostgate.Record
onChangePostgate: (v: AppBskyFeedPostgate.Record) => void
@@ -30,8 +28,6 @@ export function ThreadgateBtn({
onChangeThreadgateAllowUISettings: (v: ThreadgateAllowUISetting[]) => void
style?: StyleProp<AnimatedStyle<ViewStyle>>
Portal: PortalComponent
}) {
const {_} = useLingui()
const t = useTheme()
@@ -81,7 +77,6 @@ export function ThreadgateBtn({
onChangePostgate={onChangePostgate}
threadgateAllowUISettings={threadgateAllowUISettings}
onChangeThreadgateAllowUISettings={onChangeThreadgateAllowUISettings}
Portal={Portal}
/>
</>
)
@@ -17,7 +17,6 @@ import {CC_Stroke2_Corner0_Rounded as CCIcon} from '#/components/icons/CC'
import {PageText_Stroke2_Corner0_Rounded as PageTextIcon} from '#/components/icons/PageText'
import {TimesLarge_Stroke2_Corner0_Rounded as X} from '#/components/icons/Times'
import {Warning_Stroke2_Corner0_Rounded as WarningIcon} from '#/components/icons/Warning'
import {PortalComponent} from '#/components/Portal'
import {Text} from '#/components/Typography'
import {SubtitleFilePicker} from './SubtitleFilePicker'
@@ -30,7 +29,6 @@ interface Props {
captions: CaptionsTrack[]
saveAltText: (altText: string) => void
setCaptions: (updater: (prev: CaptionsTrack[]) => CaptionsTrack[]) => void
Portal: PortalComponent
}
export function SubtitleDialogBtn(props: Props) {
@@ -58,7 +56,7 @@ export function SubtitleDialogBtn(props: Props) {
{isWeb ? <Trans>Captions & alt text</Trans> : <Trans>Alt text</Trans>}
</ButtonText>
</Button>
<Dialog.Outer control={control} Portal={props.Portal}>
<Dialog.Outer control={control}>
<Dialog.Handle />
<SubtitleDialogInner {...props} />
</Dialog.Outer>