diff --git a/src/components/LabelsOnMe.tsx b/src/components/LabelsOnMe.tsx
new file mode 100644
index 0000000000..3af3d8fe34
--- /dev/null
+++ b/src/components/LabelsOnMe.tsx
@@ -0,0 +1,94 @@
+import React from 'react'
+import {View} from 'react-native'
+import {msg, Trans} from '@lingui/macro'
+import {useLingui} from '@lingui/react'
+import {ComAtprotoLabelDefs} from '@atproto/api'
+
+import {atoms as a, useBreakpoints} from '#/alf'
+import {Text} from '#/components/Typography'
+import * as Dialog from '#/components/Dialog'
+import {Button} from '#/components/Button'
+
+export {useDialogControl as useLabelsOnMeDialogControl} from '#/components/Dialog'
+
+type Subject =
+ | {
+ uri: string
+ cid: string
+ }
+ | {
+ did: string
+ }
+
+export interface LabelsOnMeDialogProps {
+ control: Dialog.DialogOuterProps['control']
+ subject: Subject
+ labels: ComAtprotoLabelDefs.Label[]
+}
+
+export function LabelsOnMeDialogInner(props: LabelsOnMeDialogProps) {
+ const {_} = useLingui()
+ const control = Dialog.useDialogControl()
+ const {gtMobile} = useBreakpoints()
+ const {subject, labels} = props
+ const isAccount = 'did' in subject
+
+ // TODO
+ // const submit = async () => {
+ // try {
+ // const $type = !isAccountReport
+ // ? 'com.atproto.repo.strongRef'
+ // : 'com.atproto.admin.defs#repoRef'
+ // await getAgent().createModerationReport({
+ // reasonType: ComAtprotoModerationDefs.REASONAPPEAL,
+ // subject: {
+ // $type,
+ // ...props,
+ // },
+ // reason: details,
+ // })
+ // Toast.show(_(msg`We'll look into your appeal promptly.`))
+ // } finally {
+ // closeModal()
+ // }
+ // }
+
+ return (
+
+
+ Labels on my {isAccount ? 'account' : 'content'}
+
+
+
+ You may appeal these labels if you feel they were placed in error.
+
+
+ {labels.map(label => (
+ {label.val} TODO
+ ))}
+
+
+
+
+ )
+}
+
+export function LabelsOnMeDialog(props: LabelsOnMeDialogProps) {
+ return (
+
+
+
+
+
+ )
+}
diff --git a/src/components/dialogs/LabelsOnMe/index.tsx b/src/components/dialogs/LabelsOnMe/index.tsx
deleted file mode 100644
index efc8019bda..0000000000
--- a/src/components/dialogs/LabelsOnMe/index.tsx
+++ /dev/null
@@ -1,92 +0,0 @@
-import React from 'react'
-import {View} from 'react-native'
-import {msg, Trans} from '@lingui/macro'
-import {useLingui} from '@lingui/react'
-import {ComAtprotoLabelDefs} from '@atproto/api'
-
-import {atoms as a, useBreakpoints} from '#/alf'
-import {Text} from '#/components/Typography'
-import * as Dialog from '#/components/Dialog'
-import {GlobalDialogProps} from '#/components/dialogs'
-import {Button} from '#/components/Button'
-
-type Subject =
- | {
- uri: string
- cid: string
- }
- | {
- did: string
- }
-
-export interface LabelsOnMeDialogProps {
- subject: Subject
- labels: ComAtprotoLabelDefs.Label[]
-}
-
-export function LabelsOnMeDialog({
- params,
- cleanup,
-}: GlobalDialogProps) {
- const {_} = useLingui()
- const control = Dialog.useDialogControl()
- const {gtMobile} = useBreakpoints()
- const {subject, labels} = params
- const isAccount = 'did' in subject
-
- // REQUIRED CLEANUP
- const onClose = React.useCallback(() => cleanup(), [cleanup])
-
- // TODO
- // const submit = async () => {
- // try {
- // const $type = !isAccountReport
- // ? 'com.atproto.repo.strongRef'
- // : 'com.atproto.admin.defs#repoRef'
- // await getAgent().createModerationReport({
- // reasonType: ComAtprotoModerationDefs.REASONAPPEAL,
- // subject: {
- // $type,
- // ...props,
- // },
- // reason: details,
- // })
- // Toast.show(_(msg`We'll look into your appeal promptly.`))
- // } finally {
- // closeModal()
- // }
- // }
-
- return (
-
-
-
-
-
- Labels on my {isAccount ? 'account' : 'content'}
-
-
-
- You may appeal these labels if you feel they were placed in error.
-
-
- {labels.map(label => (
- {label.val} TODO
- ))}
-
-
-
-
-
- )
-}
diff --git a/src/components/dialogs/README.md b/src/components/dialogs/README.md
deleted file mode 100644
index cda1242bc6..0000000000
--- a/src/components/dialogs/README.md
+++ /dev/null
@@ -1,16 +0,0 @@
-# Global Dialogs
-
-The dialogs and utils contained in this directory are intended to be "global" in
-the sense that they are very common.
-
-A good example: the report dialog. We need to be able to open one from every
-post, but if every post had its own `Dialog`, performance would suffer.
-Previously the solution was to use the same modal/sheet via `Modal`, and just
-swap out the content.
-
-The solution here is to only render the dialog when it's opened, and to enable
-programmatic opening of said dialog e.g. from a context menu.
-
-**For other dialogs that can be rendered _in situ_, use `Dialog` directly.**
-Only use this abstraction for instances that either aren't possible or would be
-performance intensive when defining a `Dialog` in situ.
diff --git a/src/components/dialogs/index.tsx b/src/components/dialogs/index.tsx
deleted file mode 100644
index 8118f5f5a1..0000000000
--- a/src/components/dialogs/index.tsx
+++ /dev/null
@@ -1,101 +0,0 @@
-import React from 'react'
-
-import * as Dialog from '#/components/Dialog'
-
-/**
- * Type util for global dialog components. Wrap individual dialog component
- * types with this to get types for the additional properties applied by the
- * the global dialon controller.
- */
-export type GlobalDialogProps = {
- params: T
- cleanup(): void
- options?: Dialog.DialogControlOpenOptions
-}
-
-type ActiveDialog> = {
- component: T
- props: React.ComponentProps
- options?: Dialog.DialogControlOpenOptions
-}
-
-type ContextProps = {
- activeDialogs: ActiveDialog[]
- open>(
- component: T,
- props: React.ComponentProps['params'],
- options?: Dialog.DialogControlOpenOptions,
- ): void
- popTopDialog(): void
-}
-
-export const Context = React.createContext({
- activeDialogs: [],
- open() {},
- popTopDialog() {},
-})
-
-/**
- * Hook to open a "global" dialog.
- *
- * @example
- * ```tsx
- * const openGlobalDialog = useOpenGlobalDialog()
- * openGlobalDialog(
- * MyDialog,
- * // component props
- * {foo: 'bar'},
- * // base Dialog options
- * { index: 1 }
- * )
- * ```
- */
-export function useOpenGlobalDialog() {
- return React.useContext(Context).open
-}
-
-/**
- * Provider for "global" dialogs _only_. ALL dialogs are still registered by
- * `#/state/dialogs` as well.
- */
-export function Provider({children}: React.PropsWithChildren<{}>) {
- const [activeDialogs, setActiveDialogs] = React.useState[]>(
- [],
- )
- const ctx = React.useMemo(
- () => ({
- activeDialogs,
- open(component, props, options) {
- setActiveDialogs(s => [...s, {component, props, options}])
- },
- popTopDialog() {
- setActiveDialogs(s => s.slice(0, -1))
- },
- }),
- [activeDialogs, setActiveDialogs],
- )
-
- return {children}
-}
-
-/**
- * Outlet for any active "global" dialogs. Since these are rendered into a
- * portal in the root, this is technically not their final resting place.
- */
-export function GlobalDialog() {
- const {activeDialogs, popTopDialog} = React.useContext(Context)
-
- const cleanup = React.useCallback(() => {
- popTopDialog()
- }, [popTopDialog])
-
- return React.useMemo(
- () =>
- activeDialogs.map(({component: Comp, props, options}, i) => {
- return (
-
- )
- }),
- [activeDialogs, cleanup],
- )
-}
diff --git a/src/state/dialogs/index.tsx b/src/state/dialogs/index.tsx
index 1808ef5152..ae762bd97e 100644
--- a/src/state/dialogs/index.tsx
+++ b/src/state/dialogs/index.tsx
@@ -1,7 +1,6 @@
import React from 'react'
import {DialogControlProps} from '#/components/Dialog'
-import {Provider as GlobalDialogsProvider} from '#/components/dialogs'
-import {Provider as GlobalDialogsProviderV2} from '#/components/dialogs/Context'
+import {Provider as GlobalDialogsProvider} from '#/components/dialogs/Context'
const DialogContext = React.createContext<{
activeDialogs: React.MutableRefObject<
@@ -39,9 +38,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
return (
-
- {children}
-
+ {children}
)
diff --git a/src/view/com/util/moderation/LabelsOnMe.tsx b/src/view/com/util/moderation/LabelsOnMe.tsx
index 900ceb26ac..4c8b8e0223 100644
--- a/src/view/com/util/moderation/LabelsOnMe.tsx
+++ b/src/view/com/util/moderation/LabelsOnMe.tsx
@@ -8,8 +8,10 @@ import {useSession} from '#/state/session'
import {atoms as a} from '#/alf'
import {Button, ButtonText, ButtonIcon, ButtonSize} from '#/components/Button'
import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo'
-import {useOpenGlobalDialog} from '#/components/dialogs'
-import {LabelsOnMeDialog} from '#/components/dialogs/LabelsOnMe'
+import {
+ LabelsOnMeDialog,
+ useLabelsOnMeDialogControl,
+} from '#/components/LabelsOnMe'
export function LabelsOnMe({
details,
@@ -25,7 +27,7 @@ export function LabelsOnMe({
const {_} = useLingui()
const {currentAccount} = useSession()
const isAccount = 'did' in details
- const openDialog = useOpenGlobalDialog()
+ const control = useLabelsOnMeDialogControl()
if (!labels || !currentAccount) {
return null
@@ -39,16 +41,15 @@ export function LabelsOnMe({
return (
+
+