From 56590c8ac39e924b919543da23ea6741554c393a Mon Sep 17 00:00:00 2001 From: jack Date: Sat, 13 Sep 2025 00:46:50 +0200 Subject: [PATCH] Location notes: prevent duplicate loading/subscriptions (StateObject manager, geohash captured at open, guard subscribe) --- bitchat/Services/LocationNotesManager.swift | 2 ++ bitchat/Views/ContentView.swift | 17 +++++++++++++---- bitchat/Views/LocationNotesView.swift | 7 ++++--- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/bitchat/Services/LocationNotesManager.swift b/bitchat/Services/LocationNotesManager.swift index 7208ed11..db0d36e5 100644 --- a/bitchat/Services/LocationNotesManager.swift +++ b/bitchat/Services/LocationNotesManager.swift @@ -45,6 +45,8 @@ final class LocationNotesManager: ObservableObject { } private func subscribe() { + // Avoid double subscription for the same geohash while active + if subscriptionID != nil { return } // Begin loading: always display Matrix for a randomized 1–3 seconds isLoading = true loadingStartedAt = Date() diff --git a/bitchat/Views/ContentView.swift b/bitchat/Views/ContentView.swift index 030df4d9..e170668a 100644 --- a/bitchat/Views/ContentView.swift +++ b/bitchat/Views/ContentView.swift @@ -50,6 +50,8 @@ struct ContentView: View { @State private var showVerifySheet = false @State private var expandedMessageIDs: Set = [] @State private var showLocationNotes = false + @State private var notesGeohash: String? = nil + @State private var showLocationNotes = false // Window sizes for rendering (infinite scroll up) @State private var windowCountPublic: Int = 300 @State private var windowCountPrivate: [String: Int] = [:] @@ -1147,7 +1149,15 @@ struct ContentView: View { } // Notes icon (mesh only), left of channel badge if case .mesh = locationManager.selectedChannel { - Button(action: { showLocationNotes = true }) { + Button(action: { + if let block = LocationChannelManager.shared.availableChannels.first(where: { $0.level == .block })?.geohash { + notesGeohash = block + showLocationNotes = true + } else { + notesGeohash = nil + showLocationNotes = true + } + }) { Image(systemName: "note.text") .font(.system(size: 12)) .foregroundColor(Color(hue: 0.60, saturation: 0.85, brightness: 0.82)) @@ -1213,9 +1223,8 @@ struct ContentView: View { .onDisappear { viewModel.isLocationChannelsSheetPresented = false } } .sheet(isPresented: $showLocationNotes) { - // Determine current block-level geohash for this place - if let block = LocationChannelManager.shared.availableChannels.first(where: { $0.level == .block })?.geohash { - LocationNotesView(geohash: block) + if let gh = notesGeohash { + LocationNotesView(geohash: gh) .environmentObject(viewModel) } else { VStack(spacing: 12) { diff --git a/bitchat/Views/LocationNotesView.swift b/bitchat/Views/LocationNotesView.swift index 55359eb6..d32dffd3 100644 --- a/bitchat/Views/LocationNotesView.swift +++ b/bitchat/Views/LocationNotesView.swift @@ -2,15 +2,16 @@ import SwiftUI struct LocationNotesView: View { @EnvironmentObject var viewModel: ChatViewModel - @ObservedObject var manager: LocationNotesManager + @StateObject private var manager: LocationNotesManager let geohash: String @Environment(\.colorScheme) var colorScheme @State private var draft: String = "" init(geohash: String) { - self.geohash = geohash.lowercased() - self.manager = LocationNotesManager(geohash: self.geohash) + let gh = geohash.lowercased() + self.geohash = gh + _manager = StateObject(wrappedValue: LocationNotesManager(geohash: gh)) } private var backgroundColor: Color {