mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-08-28 05:24:44 +00:00
ios: fix chat list subscription status indicator stuck at empty "%"
The toolbar-hosted indicator held its subscription totals in @State and refreshed them via a 1s poll; the toolbar rebuilds frequently, recreating the view and resetting the @State totals to the empty "share unknown" state. Move the totals into a dedicated SubsStatusModel observable (a shared singleton, like ChannelRelaysModel/ConnectProgressManager) so they survive view recreation, instead of binding poll state into the widely-observed ChatModel. The poll publishes only on change (SMPServerSubs is now Equatable), so the indicator does not re-render every idle second.
This commit is contained in:
@@ -2382,7 +2382,7 @@ struct ServerSessions: Codable {
|
||||
var hasSess: Bool { ssConnected > 0 }
|
||||
}
|
||||
|
||||
struct SMPServerSubs: Codable {
|
||||
struct SMPServerSubs: Codable, Equatable {
|
||||
var ssActive: Int
|
||||
var ssPending: Int
|
||||
|
||||
|
||||
@@ -359,6 +359,24 @@ class ChannelRelaysModel: ObservableObject {
|
||||
}
|
||||
}
|
||||
|
||||
// Subscription totals for the chat list status indicator. Kept in a dedicated
|
||||
// observable (not on ChatModel) so they survive the toolbar-hosted indicator
|
||||
// being recreated on frequent toolbar rebuilds, without waking ChatModel's many
|
||||
// observers on every poll tick.
|
||||
class SubsStatusModel: ObservableObject {
|
||||
static let shared = SubsStatusModel()
|
||||
@Published var totalSubs: SMPServerSubs = SMPServerSubs.newSMPServerSubs
|
||||
@Published var hasSession: Bool = false
|
||||
|
||||
func update(_ totalSubs: SMPServerSubs, _ hasSession: Bool) {
|
||||
// only publish on change - avoid re-rendering the indicator on every idle poll tick
|
||||
if self.totalSubs != totalSubs || self.hasSession != hasSession {
|
||||
self.totalSubs = totalSubs
|
||||
self.hasSession = hasSession
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Spec: spec/state.md#ChatModel
|
||||
final class ChatModel: ObservableObject {
|
||||
@Published var onboardingStage: OnboardingStage?
|
||||
|
||||
@@ -559,8 +559,8 @@ struct ChatListView: View {
|
||||
}
|
||||
|
||||
struct SubsStatusIndicator: View {
|
||||
@State private var subs: SMPServerSubs = SMPServerSubs.newSMPServerSubs
|
||||
@State private var hasSess: Bool = false
|
||||
// Totals live on a dedicated observable so they survive this view being recreated on frequent toolbar rebuilds
|
||||
@ObservedObject private var subsModel = SubsStatusModel.shared
|
||||
@State private var task: Task<Void, Never>?
|
||||
@State private var showServersSummary = false
|
||||
|
||||
@@ -572,9 +572,9 @@ struct SubsStatusIndicator: View {
|
||||
} label: {
|
||||
HStack(spacing: 4) {
|
||||
Text("Chats").foregroundStyle(Color.primary).fixedSize().font(.headline)
|
||||
SubscriptionStatusIndicatorView(subs: subs, hasSess: hasSess)
|
||||
SubscriptionStatusIndicatorView(subs: subsModel.totalSubs, hasSess: subsModel.hasSession)
|
||||
if showSubscriptionPercentage {
|
||||
SubscriptionStatusPercentageView(subs: subs, hasSess: hasSess)
|
||||
SubscriptionStatusPercentageView(subs: subsModel.totalSubs, hasSess: subsModel.hasSession)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -598,8 +598,7 @@ struct SubsStatusIndicator: View {
|
||||
do {
|
||||
let (subs, hasSess) = try await getAgentSubsTotal()
|
||||
await MainActor.run {
|
||||
self.subs = subs
|
||||
self.hasSess = hasSess
|
||||
SubsStatusModel.shared.update(subs, hasSess)
|
||||
}
|
||||
} catch let error {
|
||||
logger.error("getSubsTotal error: \(responseError(error))")
|
||||
|
||||
Reference in New Issue
Block a user