Skip to content

Commit 09afe78

Browse files
fix(settings): replace portal workaround with direct VersionSelectDialog render
Remove the createPortal + useRef guarded-close pattern for the version dialog (introduced to work around Radix nesting issues). Instead render VersionSelectDialog directly inside the Dialog and prevent outside interactions via onInteractOutside/onFocusOutside/onPointerDownOutside preventDefault. Delete the obsolete VersionSelectContent component.
1 parent fc3a5b0 commit 09afe78

2 files changed

Lines changed: 10 additions & 197 deletions

File tree

frontend/src/components/settings/SettingsDialog.tsx

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import { useState, useEffect, useCallback, useRef } from 'react'
2-
import { createPortal } from 'react-dom'
1+
import { useState, useEffect, useCallback } from 'react'
32
import { GeneralSettings } from '@/components/settings/GeneralSettings'
43
import { GitSettings } from '@/components/settings/GitSettings'
54
import { KeyboardShortcuts } from '@/components/settings/KeyboardShortcuts'
@@ -12,7 +11,7 @@ import { ProviderSettings } from '@/components/settings/ProviderSettings'
1211
import { AccountSettings } from '@/components/settings/AccountSettings'
1312
import { VoiceSettings } from '@/components/settings/VoiceSettings'
1413
import { NotificationSettings } from '@/components/settings/NotificationSettings'
15-
import { VersionSelectContent } from '@/components/settings/VersionSelectContent'
14+
import { VersionSelectDialog } from '@/components/settings/VersionSelectDialog'
1615
import { Dialog, DialogContent } from '@/components/ui/dialog'
1716
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
1817
import { Settings2, Keyboard, Code, ChevronLeft, Key, GitBranch, User, Volume2, Bell, X } from 'lucide-react'
@@ -22,18 +21,12 @@ import { useSettingsDialog } from '@/hooks/useSettingsDialog'
2221
type SettingsView = 'menu' | 'general' | 'git' | 'shortcuts' | 'opencode' | 'providers' | 'account' | 'voice' | 'notifications'
2322

2423
export function SettingsDialog() {
25-
const { isOpen, close: originalClose, activeTab, setActiveTab } = useSettingsDialog()
24+
const { isOpen, close, activeTab, setActiveTab } = useSettingsDialog()
2625
const [mobileView, setMobileView] = useState<SettingsView>('menu')
2726
const [isVersionDialogOpen, setIsVersionDialogOpen] = useState(false)
2827
const [sectionHistory, setSectionHistory] = useState<SettingsView[]>([])
2928
const [authSectionsOpen, setAuthSectionsOpen] = useState(true)
3029
const toggleAuthSections = useCallback(() => setAuthSectionsOpen((open) => !open), [])
31-
const versionDialogOpenRef = useRef(false)
32-
versionDialogOpenRef.current = isVersionDialogOpen
33-
const close = useCallback(() => {
34-
if (versionDialogOpenRef.current) return
35-
originalClose()
36-
}, [originalClose])
3730

3831
const pushSectionHistory = useCallback((view: SettingsView) => {
3932
if (view === 'menu') return
@@ -106,13 +99,15 @@ export function SettingsDialog() {
10699
}
107100

108101
return (
109-
<>
110102
<Dialog open={isOpen} modal={false} onOpenChange={(open) => !open && close()}>
111103
<DialogContent
112104
className="inset-0 w-full h-full max-w-none max-h-none p-0 rounded-none bg-gradient-to-br from-background via-background to-background border-border overflow-hidden !flex !flex-col !gap-0"
113105
fullscreen
114106
canSwipeBack={() => mobileView !== 'menu'}
115107
onSwipeBack={handleSettingsBack}
108+
onInteractOutside={(e) => e.preventDefault()}
109+
onFocusOutside={(e) => e.preventDefault()}
110+
onPointerDownOutside={(e) => e.preventDefault()}
116111
>
117112
<div className="hidden sm:flex sm:flex-col sm:h-full sm:min-h-0">
118113
<div className="sticky top-0 z-10 bg-gradient-to-b from-background via-background to-transparent border-b border-border backdrop-blur-sm px-6 py-4 flex-shrink-0 flex items-center justify-between">
@@ -253,11 +248,10 @@ export function SettingsDialog() {
253248
</div>
254249

255250
</DialogContent>
251+
<VersionSelectDialog
252+
open={isVersionDialogOpen}
253+
onOpenChange={setIsVersionDialogOpen}
254+
/>
256255
</Dialog>
257-
{typeof document !== 'undefined' && createPortal(
258-
<VersionSelectContent onClose={() => setIsVersionDialogOpen(false)} />,
259-
document.body,
260-
)}
261-
</>
262256
)
263257
}

frontend/src/components/settings/VersionSelectContent.tsx

Lines changed: 0 additions & 181 deletions
This file was deleted.

0 commit comments

Comments
 (0)