Skip to content

Commit de12c77

Browse files
authored
Merge pull request #283 from datlechin/refactor/direct-sidebar-reload
refactor: replace data refresh broadcasts with direct coordinator-to-sidebar calls
2 parents 8ba85ce + d8383d4 commit de12c77

File tree

9 files changed

+263
-26
lines changed

9 files changed

+263
-26
lines changed

TablePro/ContentView.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,8 @@ struct ContentView: View {
227227
tableOperationOptions: sessionTableOperationOptionsBinding,
228228
databaseType: currentSession.connection.type,
229229
connectionId: currentSession.connection.id,
230-
schemaProvider: SchemaProviderRegistry.shared.provider(for: currentSession.connection.id)
230+
schemaProvider: SchemaProviderRegistry.shared.provider(for: currentSession.connection.id),
231+
coordinator: sessionState.coordinator
231232
)
232233
}
233234
.searchable(

TablePro/ViewModels/SidebarViewModel.swift

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -152,18 +152,6 @@ final class SidebarViewModel {
152152
guard !hasSetupNotifications else { return }
153153
hasSetupNotifications = true
154154

155-
Publishers.Merge(
156-
NotificationCenter.default.publisher(for: .databaseDidConnect),
157-
NotificationCenter.default.publisher(for: .refreshData)
158-
)
159-
.receive(on: DispatchQueue.main)
160-
.sink { [weak self] _ in
161-
Task { @MainActor in
162-
self?.forceLoadTables()
163-
}
164-
}
165-
.store(in: &cancellables)
166-
167155
NotificationCenter.default.publisher(for: .copyTableNames)
168156
.receive(on: DispatchQueue.main)
169157
.sink { [weak self] _ in

TablePro/Views/Main/Extensions/MainContentCoordinator+Discard.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,6 @@ extension MainContentCoordinator {
7979
tabManager.tabs[index].pendingChanges = TabPendingChanges()
8080
}
8181

82-
NotificationCenter.default.post(name: .databaseDidConnect, object: nil)
82+
reloadSidebar()
8383
}
8484
}

TablePro/Views/Main/Extensions/MainContentCoordinator+Navigation.swift

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,7 @@ extension MainContentCoordinator {
438438

439439
await loadSchema()
440440

441-
NotificationCenter.default.post(name: .refreshData, object: nil)
441+
reloadSidebar()
442442
} else if connection.type == .postgresql {
443443
DatabaseManager.shared.updateSession(connectionId) { session in
444444
session.connection.database = database
@@ -450,7 +450,7 @@ extension MainContentCoordinator {
450450

451451
await loadSchema()
452452

453-
NotificationCenter.default.post(name: .refreshData, object: nil)
453+
reloadSidebar()
454454
} else if connection.type == .redshift {
455455
guard let schemaDriver = driver as? SchemaSwitchable else { return }
456456
try await schemaDriver.switchSchema(to: database)
@@ -461,7 +461,7 @@ extension MainContentCoordinator {
461461

462462
await loadSchema()
463463

464-
NotificationCenter.default.post(name: .refreshData, object: nil)
464+
reloadSidebar()
465465
} else if connection.type == .oracle {
466466
guard let schemaDriver = driver as? SchemaSwitchable else { return }
467467
try await schemaDriver.switchSchema(to: database)
@@ -472,7 +472,7 @@ extension MainContentCoordinator {
472472

473473
await loadSchema()
474474

475-
NotificationCenter.default.post(name: .refreshData, object: nil)
475+
reloadSidebar()
476476
} else if connection.type == .mssql {
477477
if let adapter = driver as? PluginDriverAdapter {
478478
try await adapter.switchDatabase(to: database)
@@ -486,7 +486,7 @@ extension MainContentCoordinator {
486486

487487
await loadSchema()
488488

489-
NotificationCenter.default.post(name: .refreshData, object: nil)
489+
reloadSidebar()
490490
} else if connection.type == .mongodb {
491491
if let adapter = driver as? PluginDriverAdapter {
492492
try await adapter.switchDatabase(to: database)
@@ -498,7 +498,7 @@ extension MainContentCoordinator {
498498

499499
await loadSchema()
500500

501-
NotificationCenter.default.post(name: .refreshData, object: nil)
501+
reloadSidebar()
502502
} else if connection.type == .redis {
503503
guard let dbIndex = Int(database) else { return }
504504

@@ -512,13 +512,13 @@ extension MainContentCoordinator {
512512

513513
await loadSchema()
514514

515-
NotificationCenter.default.post(name: .refreshData, object: nil)
515+
reloadSidebar()
516516
}
517517
} catch {
518518
// Restore toolbar to previous database on failure
519519
toolbarState.databaseName = previousDatabase
520520
// Reload previous tables so sidebar isn't left empty
521-
NotificationCenter.default.post(name: .refreshData, object: nil)
521+
reloadSidebar()
522522

523523
navigationLogger.error("Failed to switch database: \(error.localizedDescription, privacy: .public)")
524524
AlertHelper.showErrorSheet(
@@ -560,11 +560,11 @@ extension MainContentCoordinator {
560560

561561
await loadSchema()
562562

563-
NotificationCenter.default.post(name: .refreshData, object: nil)
563+
reloadSidebar()
564564
} catch {
565565
// Restore toolbar to previous schema on failure
566566
toolbarState.databaseName = previousSchema
567-
NotificationCenter.default.post(name: .refreshData, object: nil)
567+
reloadSidebar()
568568

569569
navigationLogger.error("Failed to switch schema: \(error.localizedDescription, privacy: .public)")
570570
AlertHelper.showErrorSheet(

TablePro/Views/Main/Extensions/MainContentCoordinator+SaveChanges.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ extension MainContentCoordinator {
233233
}
234234
}
235235

236-
NotificationCenter.default.post(name: .databaseDidConnect, object: nil)
236+
reloadSidebar()
237237
}
238238

239239
if tabManager.selectedTabIndex != nil && !tabManager.tabs.isEmpty {

TablePro/Views/Main/MainContentCommandActions.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,7 @@ final class MainContentCommandActions {
565565
self?.pendingDeletes.wrappedValue.removeAll()
566566
}
567567
)
568+
coordinator?.reloadSidebar()
568569
}
569570

570571
// MARK: Tab Broadcasts
@@ -694,6 +695,7 @@ final class MainContentCommandActions {
694695
if let driver = DatabaseManager.shared.driver(for: self.connection.id) {
695696
coordinator?.toolbarState.databaseVersion = driver.serverVersion
696697
}
698+
coordinator?.reloadSidebar()
697699
}
698700
}
699701

TablePro/Views/Main/MainContentCoordinator.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ final class MainContentCoordinator {
6161
/// Stable identifier for this coordinator's window (set by MainContentView on appear)
6262
var windowId: UUID?
6363

64+
/// Direct reference to sidebar viewmodel — eliminates global notification broadcasts
65+
weak var sidebarViewModel: SidebarViewModel?
66+
6467
// MARK: - Published State
6568

6669
var schemaProvider: SQLSchemaProvider
@@ -283,6 +286,10 @@ final class MainContentCoordinator {
283286
_teardownScheduled.withLock { $0 = false }
284287
}
285288

289+
func reloadSidebar() {
290+
sidebarViewModel?.forceLoadTables()
291+
}
292+
286293
/// Explicit cleanup called from `onDisappear`. Releases schema provider
287294
/// synchronously on MainActor so we don't depend on deinit + Task scheduling.
288295
func teardown() {

TablePro/Views/Sidebar/SidebarView.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ struct SidebarView: View {
2424
var onShowAllTables: (() -> Void)?
2525
var onDoubleClick: ((TableInfo) -> Void)?
2626
var connectionId: UUID
27+
private weak var coordinator: MainContentCoordinator?
2728

2829
/// Computed on the view (not ViewModel) so SwiftUI tracks both
2930
/// `@Binding var tables` and `@Published var searchText` as dependencies.
@@ -50,7 +51,8 @@ struct SidebarView: View {
5051
tableOperationOptions: Binding<[String: TableOperationOptions]>,
5152
databaseType: DatabaseType,
5253
connectionId: UUID,
53-
schemaProvider: SQLSchemaProvider? = nil
54+
schemaProvider: SQLSchemaProvider? = nil,
55+
coordinator: MainContentCoordinator? = nil
5456
) {
5557
_tables = tables
5658
self.sidebarState = sidebarState
@@ -76,6 +78,7 @@ struct SidebarView: View {
7678
self.activeTableName = activeTableName
7779
self.onShowAllTables = onShowAllTables
7880
self.connectionId = connectionId
81+
self.coordinator = coordinator
7982
}
8083

8184
// MARK: - Body
@@ -97,6 +100,7 @@ struct SidebarView: View {
97100
.onAppear {
98101
viewModel.setupNotifications()
99102
viewModel.onAppear()
103+
coordinator?.sidebarViewModel = viewModel
100104
}
101105
.sheet(isPresented: $viewModel.showOperationDialog) {
102106
if let operationType = viewModel.pendingOperationType {

0 commit comments

Comments
 (0)