mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-07-25 03:05:19 +00:00
Extract BLE packet handlers and migrate coordinators to narrow contexts
BLEService's per-packet-type orchestration moves into owned, tested components (BLEAnnounceHandler, BLEPublicMessageHandler, BLENoisePacketHandler, BLEFileTransferHandler, BLEFragmentHandler), each taking an environment struct of closures so every queue hop stays in BLEService and the handlers are synchronously testable. Behavior is preserved verbatim, including Noise session recovery on decrypt failure and single-block UI event ordering. handleLeave/handleRequestSync stay in place as already-thin delegations. BLEService drops to 3393 lines. Four coordinators (delivery, private conversation, Nostr, public conversation) drop their unowned/weak ChatViewModel back-references for narrow @MainActor context protocols, with ChatViewModel conformances as single shared witnesses for overlapping members. Their true coupling is now an explicit, reviewable surface, and each gains a mock-context test suite covering flows previously testable only through the full view model. Delivery/read acks now also clear the router's retained-send outbox via the delivery context. New LargeTopologyTests exercise production-shaped meshes with the in-memory harness: an 8-peer relay chain with per-hop TTL decay, a 14-peer cyclic mesh with exactly-once delivery, partition/heal, and topology churn. App-layer runtime/model files updated alongside. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -152,11 +152,11 @@ final class ChatViewModel: ObservableObject, BitchatDelegate, TransportEventDele
|
||||
private lazy var peerListCoordinator = ChatPeerListCoordinator(viewModel: self)
|
||||
private lazy var messageFormatter = ChatMessageFormatter(viewModel: self)
|
||||
lazy var peerIdentityCoordinator = ChatPeerIdentityCoordinator(viewModel: self)
|
||||
lazy var deliveryCoordinator = ChatDeliveryCoordinator(viewModel: self)
|
||||
lazy var deliveryCoordinator = ChatDeliveryCoordinator(context: self)
|
||||
lazy var composerCoordinator = ChatComposerCoordinator(viewModel: self)
|
||||
lazy var publicConversationCoordinator = ChatPublicConversationCoordinator(viewModel: self)
|
||||
lazy var privateConversationCoordinator = ChatPrivateConversationCoordinator(viewModel: self)
|
||||
lazy var nostrCoordinator = ChatNostrCoordinator(viewModel: self)
|
||||
lazy var publicConversationCoordinator = ChatPublicConversationCoordinator(context: self)
|
||||
lazy var privateConversationCoordinator = ChatPrivateConversationCoordinator(context: self)
|
||||
lazy var nostrCoordinator = ChatNostrCoordinator(context: self)
|
||||
lazy var mediaTransferCoordinator = ChatMediaTransferCoordinator(viewModel: self)
|
||||
lazy var verificationCoordinator = ChatVerificationCoordinator(viewModel: self)
|
||||
|
||||
@@ -168,7 +168,7 @@ final class ChatViewModel: ObservableObject, BitchatDelegate, TransportEventDele
|
||||
get { privateChatManager.privateChats }
|
||||
set {
|
||||
privateChatManager.privateChats = newValue
|
||||
synchronizePrivateConversationStore()
|
||||
schedulePrivateConversationStoreSynchronization()
|
||||
}
|
||||
}
|
||||
var selectedPrivateChatPeer: PeerID? {
|
||||
@@ -187,7 +187,7 @@ final class ChatViewModel: ObservableObject, BitchatDelegate, TransportEventDele
|
||||
get { privateChatManager.unreadMessages }
|
||||
set {
|
||||
privateChatManager.unreadMessages = newValue
|
||||
synchronizePrivateConversationStore()
|
||||
schedulePrivateConversationStoreSynchronization()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -372,6 +372,7 @@ final class ChatViewModel: ObservableObject, BitchatDelegate, TransportEventDele
|
||||
// MARK: - Message Delivery Tracking
|
||||
|
||||
var cancellables = Set<AnyCancellable>()
|
||||
private var pendingPrivateConversationStoreSyncTask: Task<Void, Never>?
|
||||
|
||||
var transferIdToMessageIDs: [String: [String]] {
|
||||
mediaTransferCoordinator.transferIdToMessageIDs
|
||||
@@ -967,6 +968,17 @@ final class ChatViewModel: ObservableObject, BitchatDelegate, TransportEventDele
|
||||
publicConversationCoordinator.synchronizeAllPublicConversationStores()
|
||||
}
|
||||
|
||||
@MainActor
|
||||
func schedulePrivateConversationStoreSynchronization() {
|
||||
guard pendingPrivateConversationStoreSyncTask == nil else { return }
|
||||
pendingPrivateConversationStoreSyncTask = Task { @MainActor [weak self] in
|
||||
await Task.yield()
|
||||
guard let self else { return }
|
||||
self.pendingPrivateConversationStoreSyncTask = nil
|
||||
self.synchronizePrivateConversationStore()
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
func synchronizePrivateConversationStore() {
|
||||
conversationStore.synchronizePrivateChats(
|
||||
|
||||
Reference in New Issue
Block a user