@@ -38,6 +38,7 @@ struct MainContentView: View {
3838 @State private var currentQueryTask : Task < Void , Never > ?
3939 @State private var queryGeneration : Int = 0
4040 @State private var changeManagerUpdateTask : Task < Void , Never > ?
41+ @State private var isRestoringTabs = false // Prevent circular sync during restoration
4142
4243 // Error alert state
4344 @State private var showErrorAlert = false
@@ -196,6 +197,29 @@ struct MainContentView: View {
196197 . onChange ( of: tabManager. selectedTabId) { oldTabId, newTabId in
197198 // Must be synchronous - save state BEFORE SwiftUI updates the view
198199 handleTabChange ( oldTabId: oldTabId, newTabId: newTabId)
200+
201+ // Sync selected tab ID to session for persistence
202+ if let sessionId = DatabaseManager . shared. currentSessionId {
203+ DatabaseManager . shared. updateSession ( sessionId) { session in
204+ session. selectedTabId = newTabId
205+ }
206+ }
207+ }
208+ . onChange ( of: tabManager. tabs) { _, newTabs in
209+ // Skip sync if we're currently restoring tabs from session (prevents circular updates)
210+ guard !isRestoringTabs else { return }
211+
212+ // Sync tabs array to session for persistence
213+ if let sessionId = DatabaseManager . shared. currentSessionId {
214+ DatabaseManager . shared. updateSession ( sessionId) { session in
215+ session. tabs = newTabs
216+ }
217+
218+ // Clear saved state immediately when all tabs are closed
219+ if newTabs. isEmpty {
220+ TabStateStorage . shared. clearTabState ( connectionId: connection. id)
221+ }
222+ }
199223 }
200224 . onChange ( of: currentTab? . resultColumns) { _, newColumns in
201225 Task { @MainActor in
@@ -283,6 +307,18 @@ struct MainContentView: View {
283307 viewWithToolbar
284308 . task {
285309 await initializeView ( )
310+
311+ // Restore tabs from session if available (after DatabaseManager has loaded them)
312+ if let sessionId = DatabaseManager . shared. currentSessionId,
313+ let session = DatabaseManager . shared. activeSessions [ sessionId] ,
314+ !session. tabs. isEmpty {
315+ // Set flag to prevent onChange(tabManager.tabs) from syncing back
316+ // Use defer to ensure flag is always reset even if an error occurs
317+ isRestoringTabs = true
318+ defer { isRestoringTabs = false }
319+ tabManager. tabs = session. tabs
320+ tabManager. selectedTabId = session. selectedTabId
321+ }
286322 }
287323 . onChange ( of: selectedTables) { oldTables, newTables in
288324 // Find newly added table to open
@@ -305,9 +341,10 @@ struct MainContentView: View {
305341 }
306342 }
307343 . onReceive ( NotificationCenter . default. publisher ( for: . newTab) ) { _ in
308- // Cmd+T to create new query tab
344+ // Cmd+T - create new query tab - load last query if available
309345 Task { @MainActor in
310- tabManager. addTab ( )
346+ let lastQuery = TabStateStorage . shared. loadLastQuery ( for: connection. id)
347+ tabManager. addTab ( initialQuery: lastQuery)
311348 }
312349 }
313350 . onReceive ( NotificationCenter . default. publisher ( for: NSNotification . Name ( " loadQueryIntoEditor " ) ) ) { notification in
@@ -421,6 +458,9 @@ struct MainContentView: View {
421458 set: { newValue in
422459 if let index = tabManager. selectedTabIndex {
423460 tabManager. tabs [ index] . query = newValue
461+
462+ // Save as last query for this connection (TablePlus-style)
463+ TabStateStorage . shared. saveLastQuery ( newValue, for: connection. id)
424464 }
425465 }
426466 ) ,
0 commit comments