New Edit Profile dialog on web, use new Edit Image dialog everywhere (#8220)

This commit is contained in:
Samuel Newman
2025-05-06 22:50:28 +03:00
committed by GitHub
parent 3f7dc9a8e5
commit 4c8fd006f6
21 changed files with 532 additions and 441 deletions
+14 -7
View File
@@ -1,4 +1,11 @@
import React from 'react'
import {
createContext,
useContext,
useEffect,
useId,
useMemo,
useRef,
} from 'react'
import {useDialogStateContext} from '#/state/dialogs'
import {
@@ -8,7 +15,7 @@ import {
} from '#/components/Dialog/types'
import {BottomSheetSnapPoint} from '../../../modules/bottom-sheet/src/BottomSheet.types'
export const Context = React.createContext<DialogContextProps>({
export const Context = createContext<DialogContextProps>({
close: () => {},
isNativeDialog: false,
nativeSnapPoint: BottomSheetSnapPoint.Hidden,
@@ -18,18 +25,18 @@ export const Context = React.createContext<DialogContextProps>({
})
export function useDialogContext() {
return React.useContext(Context)
return useContext(Context)
}
export function useDialogControl(): DialogOuterProps['control'] {
const id = React.useId()
const control = React.useRef<DialogControlRefProps>({
const id = useId()
const control = useRef<DialogControlRefProps>({
open: () => {},
close: () => {},
})
const {activeDialogs} = useDialogStateContext()
React.useEffect(() => {
useEffect(() => {
activeDialogs.current.set(id, control)
return () => {
// eslint-disable-next-line react-hooks/exhaustive-deps
@@ -37,7 +44,7 @@ export function useDialogControl(): DialogOuterProps['control'] {
}
}, [id, activeDialogs])
return React.useMemo<DialogOuterProps['control']>(
return useMemo<DialogOuterProps['control']>(
() => ({
id,
ref: control,
+24 -14
View File
@@ -1,4 +1,14 @@
import React from 'react'
import {
createContext,
Fragment,
useCallback,
useContext,
useEffect,
useId,
useMemo,
useRef,
useState,
} from 'react'
type Component = React.ReactElement
@@ -9,32 +19,32 @@ type ContextType = {
}
type ComponentMap = {
[id: string]: Component
[id: string]: Component | null
}
export function createPortalGroup() {
const Context = React.createContext<ContextType>({
const Context = createContext<ContextType>({
outlet: null,
append: () => {},
remove: () => {},
})
function Provider(props: React.PropsWithChildren<{}>) {
const map = React.useRef<ComponentMap>({})
const [outlet, setOutlet] = React.useState<ContextType['outlet']>(null)
const map = useRef<ComponentMap>({})
const [outlet, setOutlet] = useState<ContextType['outlet']>(null)
const append = React.useCallback<ContextType['append']>((id, component) => {
const append = useCallback<ContextType['append']>((id, component) => {
if (map.current[id]) return
map.current[id] = <React.Fragment key={id}>{component}</React.Fragment>
map.current[id] = <Fragment key={id}>{component}</Fragment>
setOutlet(<>{Object.values(map.current)}</>)
}, [])
const remove = React.useCallback<ContextType['remove']>(id => {
delete map.current[id]
const remove = useCallback<ContextType['remove']>(id => {
map.current[id] = null
setOutlet(<>{Object.values(map.current)}</>)
}, [])
const contextValue = React.useMemo(
const contextValue = useMemo(
() => ({
outlet,
append,
@@ -49,14 +59,14 @@ export function createPortalGroup() {
}
function Outlet() {
const ctx = React.useContext(Context)
const ctx = useContext(Context)
return ctx.outlet
}
function Portal({children}: React.PropsWithChildren<{}>) {
const {append, remove} = React.useContext(Context)
const id = React.useId()
React.useEffect(() => {
const {append, remove} = useContext(Context)
const id = useId()
useEffect(() => {
append(id, children as Component)
return () => remove(id)
}, [id, children, append, remove])