@@ -18,10 +18,11 @@ struct ConnectedView: View {
1818 @State private var session : ConnectionSession ?
1919 @State private var tables : [ TableInfo ] = [ ]
2020 @State private var isConnecting = true
21+ @State private var isConnectInProgress = false
2122 @State private var appError : AppError ?
2223 @State private var failureAlertMessage : String ?
2324 @State private var showFailureAlert = false
24- @State private var selectedTab = ConnectedTab . tables
25+ @AppStorage ( " lastSelectedTab " ) private var selectedTabRaw : String = ConnectedTab . tables. rawValue
2526 @State private var queryHistory : [ QueryHistoryItem ] = [ ]
2627 @State private var historyStorage = QueryHistoryStorage ( )
2728 @State private var databases : [ String ] = [ ]
@@ -40,6 +41,18 @@ struct ConnectedView: View {
4041 case query = " Query "
4142 }
4243
44+ private var selectedTab : ConnectedTab {
45+ get { ConnectedTab ( rawValue: selectedTabRaw) ?? . tables }
46+ set { selectedTabRaw = newValue. rawValue }
47+ }
48+
49+ private var selectedTabBinding : Binding < ConnectedTab > {
50+ Binding (
51+ get: { ConnectedTab ( rawValue: selectedTabRaw) ?? . tables } ,
52+ set: { selectedTabRaw = $0. rawValue }
53+ )
54+ }
55+
4356 private var displayName : String {
4457 connection. name. isEmpty ? connection. host : connection. name
4558 }
@@ -119,7 +132,7 @@ struct ConnectedView: View {
119132 . navigationTitle ( supportsDatabaseSwitching && databases. count > 1 ? " " : displayName)
120133 . navigationBarTitleDisplayMode ( . inline)
121134 . safeAreaInset ( edge: . top) {
122- Picker ( " Tab " , selection: $selectedTab ) {
135+ Picker ( " Tab " , selection: selectedTabBinding ) {
123136 Text ( " Tables " ) . tag ( ConnectedTab . tables)
124137 Text ( " Query " ) . tag ( ConnectedTab . query)
125138 }
@@ -128,10 +141,10 @@ struct ConnectedView: View {
128141 . padding ( . vertical, 8 )
129142 }
130143 . background {
131- Button ( " " ) { selectedTab = . tables }
144+ Button ( " " ) { selectedTabRaw = ConnectedTab . tables. rawValue }
132145 . keyboardShortcut ( " 1 " , modifiers: . command)
133146 . hidden ( )
134- Button ( " " ) { selectedTab = . query }
147+ Button ( " " ) { selectedTabRaw = ConnectedTab . query. rawValue }
135148 . keyboardShortcut ( " 2 " , modifiers: . command)
136149 . hidden ( )
137150 }
@@ -203,12 +216,22 @@ struct ConnectedView: View {
203216 }
204217 }
205218 . onAppear {
219+ let key = connection. id. uuidString
220+ activeDatabase = UserDefaults . standard. string ( forKey: " lastDB. \( key) " ) ?? " "
221+ activeSchema = UserDefaults . standard. string ( forKey: " lastSchema. \( key) " ) ?? " public "
222+
206223 let hasDriver = appState. connectionManager. session ( for: connection. id) ? . driver != nil
207- if !hasDriver, !isConnecting {
208- appError = nil
224+ if !hasDriver, !isConnecting, appError == nil {
209225 Task { await connect ( ) }
210226 }
211227 }
228+ . onChange ( of: activeDatabase) { _, newValue in
229+ guard !newValue. isEmpty else { return }
230+ UserDefaults . standard. set ( newValue, forKey: " lastDB. \( connection. id. uuidString) " )
231+ }
232+ . onChange ( of: activeSchema) { _, newValue in
233+ UserDefaults . standard. set ( newValue, forKey: " lastSchema. \( connection. id. uuidString) " )
234+ }
212235 . onChange ( of: scenePhase) { _, phase in
213236 if phase == . active, session != nil {
214237 Task { await reconnectIfNeeded ( ) }
@@ -241,11 +264,15 @@ struct ConnectedView: View {
241264 }
242265
243266 private func connect( ) async {
267+ guard !isConnectInProgress else { return }
244268 guard session == nil else {
245269 isConnecting = false
246270 return
247271 }
248272
273+ isConnectInProgress = true
274+ defer { isConnectInProgress = false }
275+
249276 if let existing = appState. connectionManager. session ( for: connection. id) {
250277 self . session = existing
251278 do {
@@ -271,18 +298,13 @@ struct ConnectedView: View {
271298
272299 do {
273300 let session = try await appState. connectionManager. connect ( connection)
274- guard !Task. isCancelled else {
275- await appState. connectionManager. disconnect ( connection. id)
276- return
277- }
278301 self . session = session
279302 self . tables = try await session. driver. fetchTables ( schema: nil )
280303 isConnecting = false
281304 hapticSuccess. toggle ( )
282305 await loadDatabases ( )
283306 await loadSchemas ( )
284307 } catch {
285- guard !Task. isCancelled else { return }
286308 let context = ErrorContext (
287309 operation: " connect " ,
288310 databaseType: connection. type,
@@ -324,8 +346,14 @@ struct ConnectedView: View {
324346 guard let session, supportsDatabaseSwitching else { return }
325347 do {
326348 databases = try await session. driver. fetchDatabases ( )
327- // Use session's active database (may differ from connection.database after a switch)
328- if let stored = appState. connectionManager. session ( for: connection. id) {
349+ if !activeDatabase. isEmpty, databases. contains ( activeDatabase) {
350+ let sessionDB = appState. connectionManager. session ( for: connection. id) ? . activeDatabase ?? connection. database
351+ if activeDatabase != sessionDB {
352+ let target = activeDatabase
353+ activeDatabase = sessionDB
354+ await switchDatabase ( to: target)
355+ }
356+ } else if let stored = appState. connectionManager. session ( for: connection. id) {
329357 activeDatabase = stored. activeDatabase
330358 } else {
331359 activeDatabase = connection. database
@@ -339,7 +367,14 @@ struct ConnectedView: View {
339367 guard let session, supportsSchemas else { return }
340368 do {
341369 schemas = try await session. driver. fetchSchemas ( )
342- activeSchema = session. driver. currentSchema ?? " public "
370+ let currentSchema = session. driver. currentSchema ?? " public "
371+ if schemas. contains ( activeSchema) , activeSchema != currentSchema {
372+ let target = activeSchema
373+ activeSchema = currentSchema
374+ await switchSchema ( to: target)
375+ } else if !schemas. contains ( activeSchema) {
376+ activeSchema = currentSchema
377+ }
343378 } catch {
344379 // Silently fail — don't show picker
345380 }
0 commit comments