git.iko.soy/parseable-macos
on master help sign in
Fix 4 bugs: double reconnect on active connection edit, stale sidebar streams/filters, stale users list, validation state persistence
d417819iko
ParseableViewer/App/AppState.swift+15−12
@@ -287,23 +287,26 @@ final class AppState {
287 // If the active connection was edited, its URL or credentials may now point
287 // If the active connection was edited, its URL or credentials may now point
288 // at a different server, so swapping the client alone isn't enough — the
288 // at a different server, so swapping the client alone isn't enough — the
289 // displayed streams/selection/server-info would be stale and queries would
289 // displayed streams/selection/server-info would be stale and queries would
290+ // 404. The caller is responsible for the actual reconnect (re-validate
290− // 404. Reconnect end to end (re-validate health, reload streams/filters/
291+ // health, reload streams/filters/about); we only clear the now-possibly-
291− // about). Clear the stream selection first so a now-missing stream doesn't
292+ // stale UI state here, since `performConnect` skips its own cleanup when the
292− // keep driving detail-tab requests during the reconnect.
293+ // connection id is unchanged. We must NOT also spawn a connect here: the
294+ // sole caller (ConnectionSheet.saveAndConnect) already connects right after,
295+ // and a second connect would run two full reconnects and flash the UI twice.
293 if activeConnection?.id == connection.id {
296 if activeConnection?.id == connection.id {
294− // `performConnect` skips its stale-state cleanup because the id is
295− // unchanged, but the edited URL/credentials may point at a different
296− // server. Clear the stream-specific UI state here so a leftover sidebar
297+ // Clear the stream-specific UI state so a leftover sidebar search filter
297− // search filter doesn't hide the new server's streams and a
298+ // doesn't hide the new server's streams and a stream-specific tab
298− // stream-specific tab doesn't linger with no valid selection.
299+ // doesn't linger with no valid selection.
299 selectedStream = nil
300 selectedStream = nil
300 streamSearchText = ""
301 streamSearchText = ""
301 currentTab = .query
302 currentTab = .query
302− // Drop the previous server's cached `about` too — performConnect skips
303+ // Drop the previous server's cached `about`, stream list, and filters —
303− // its own clear (id unchanged), so without this ServerInfoView keeps
304+ // performConnect skips its own clear (id unchanged), so without this the
305+ // sidebar keeps rendering server A's streams/filters and ServerInfoView
304− // painting the old server's version/storage until the new /about lands.
306+ // paints the old version/storage until the new server's responses land.
305 serverAbout = nil
307 serverAbout = nil
306− Task { await connect(to: connection) }
308+ streams = []
309+ filters = []
307 }
310 }
308 }
311 }
309
312
ParseableViewer/Views/ConnectionSheet.swift+1
@@ -43,6 +43,7 @@ struct ConnectionSheet: View {
43 TextField("Name:", text: $name)
43 TextField("Name:", text: $name)
44 .textFieldStyle(.roundedBorder)
44 .textFieldStyle(.roundedBorder)
45 .accessibilityLabel("Connection name")
45 .accessibilityLabel("Connection name")
46+ .onChange(of: name) { _, _ in testResult = nil }
46
47
47 TextField("Server URL:", text: $url)
48 TextField("Server URL:", text: $url)
48 .textFieldStyle(.roundedBorder)
49 .textFieldStyle(.roundedBorder)
ParseableViewer/Views/UsersView.swift+4
@@ -84,6 +84,10 @@ struct UsersView: View {
84 let connID = appState.activeConnection?.id
84 let connID = appState.activeConnection?.id
85 isLoading = true
85 isLoading = true
86 errorMessage = nil
86 errorMessage = nil
87+ // Clear the previous server's list up front so it can't briefly show through
88+ // after a switch (e.g. on the stale-guard early-return below). Matches the
89+ // sibling views (AlertsView clears alertConfig, ServerInfoView clears about).
90+ users = []
87
91
88 let loaded: [UserInfo]?
92 let loaded: [UserInfo]?
89 let loadError: String?
93 let loadError: String?