File tree Expand file tree Collapse file tree 3 files changed +34
-3
lines changed
apps/postgres-new/components Expand file tree Collapse file tree 3 files changed +34
-3
lines changed Original file line number Diff line number Diff line change @@ -8,10 +8,11 @@ import { User } from '@supabase/supabase-js'
8
8
import {
9
9
createContext ,
10
10
PropsWithChildren ,
11
+ RefObject ,
11
12
useCallback ,
12
13
useContext ,
13
14
useEffect ,
14
- useMemo ,
15
+ useRef ,
15
16
useState ,
16
17
} from 'react'
17
18
import { DbManager } from '~/lib/db'
@@ -27,8 +28,20 @@ export default function AppProvider({ children }: AppProps) {
27
28
const [ isLoadingUser , setIsLoadingUser ] = useState ( true )
28
29
const [ user , setUser ] = useState < User > ( )
29
30
31
+ const focusRef = useRef < FocusHandle > ( null )
32
+
30
33
const supabase = createClient ( )
31
34
35
+ useEffect ( ( ) => {
36
+ const {
37
+ data : { subscription } ,
38
+ } = supabase . auth . onAuthStateChange ( ( e ) => {
39
+ focusRef . current ?. focus ( )
40
+ } )
41
+
42
+ return ( ) => subscription . unsubscribe ( )
43
+ } , [ supabase ] )
44
+
32
45
const loadUser = useCallback ( async ( ) => {
33
46
setIsLoadingUser ( true )
34
47
try {
@@ -97,6 +110,7 @@ export default function AppProvider({ children }: AppProps) {
97
110
isLoadingUser,
98
111
signIn,
99
112
signOut,
113
+ focusRef,
100
114
isPreview,
101
115
dbManager,
102
116
pgliteVersion,
@@ -108,11 +122,16 @@ export default function AppProvider({ children }: AppProps) {
108
122
)
109
123
}
110
124
125
+ export type FocusHandle = {
126
+ focus ( ) : void
127
+ }
128
+
111
129
export type AppContextValues = {
112
130
user ?: User
113
131
isLoadingUser : boolean
114
132
signIn : ( ) => Promise < User | undefined >
115
133
signOut : ( ) => Promise < void >
134
+ focusRef : RefObject < FocusHandle >
116
135
isPreview : boolean
117
136
dbManager ?: DbManager
118
137
pgliteVersion ?: string
Original file line number Diff line number Diff line change 9
9
FormEventHandler ,
10
10
useCallback ,
11
11
useEffect ,
12
+ useImperativeHandle ,
12
13
useMemo ,
13
14
useRef ,
14
15
useState ,
@@ -47,7 +48,7 @@ export function getInitialMessages(tables: TablesData): Message[] {
47
48
}
48
49
49
50
export default function Chat ( ) {
50
- const { user, isLoadingUser } = useApp ( )
51
+ const { user, isLoadingUser, focusRef } = useApp ( )
51
52
const [ inputFocusState , setInputFocusState ] = useState ( false )
52
53
53
54
const {
@@ -175,6 +176,15 @@ export default function Chat() {
175
176
const isSubmitEnabled =
176
177
! isLoadingMessages && ! isLoadingSchema && Boolean ( input . trim ( ) ) && user !== undefined
177
178
179
+ // Create imperative handle that can be used to focus the input anywhere in the app
180
+ useImperativeHandle ( focusRef , ( ) => ( {
181
+ focus ( ) {
182
+ if ( inputRef . current ) {
183
+ inputRef . current . focus ( )
184
+ }
185
+ } ,
186
+ } ) )
187
+
178
188
return (
179
189
< div ref = { dropZoneRef } className = "h-full flex flex-col items-stretch relative" >
180
190
{ isDraggingOver && (
Original file line number Diff line number Diff line change @@ -40,7 +40,7 @@ import {
40
40
} from './ui/dropdown-menu'
41
41
42
42
export default function Sidebar ( ) {
43
- const { user, signOut } = useApp ( )
43
+ const { user, signOut, focusRef } = useApp ( )
44
44
let { id : currentDatabaseId } = useParams < { id : string } > ( )
45
45
const router = useRouter ( )
46
46
const { data : databases , isLoading : isLoadingDatabases } = useDatabasesQuery ( )
@@ -84,6 +84,7 @@ export default function Sidebar() {
84
84
< Button
85
85
onClick = { ( ) => {
86
86
router . push ( '/' )
87
+ focusRef . current ?. focus ( )
87
88
} }
88
89
className = "gap-2"
89
90
>
@@ -176,6 +177,7 @@ export default function Sidebar() {
176
177
size = { 'icon' }
177
178
onClick = { ( ) => {
178
179
router . push ( '/' )
180
+ focusRef . current ?. focus ( )
179
181
} }
180
182
>
181
183
< PackagePlus size = { 14 } />
You can’t perform that action at this time.
0 commit comments