mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-07-25 00:05:18 +00:00
Cut public message path over to ConversationStore; delete PublicTimelineStore
Mesh and geohash timelines are now store conversations. All public mutation sites flow through store intents; PublicMessagePipeline keeps its 80ms UI batching but commits batches via store appends with each buffered entry carrying its destination conversation (a mid-batch channel switch now flushes instead of dropping the buffer). ChatViewModel.messages becomes a cached get-only view of the active conversation, invalidated through the change subject. The mesh late-insert threshold is consciously removed: it only ever ordered the non-rendered messages copy, so strict timestamp insertion makes the working set agree with rendered order. PublicTimelineStore and the per-message full-array legacy sync are deleted; the coalescing bridge mirrors public conversations for the remaining legacy readers. pipeline.publicIngest: 6.6k -> 9.5k msg/s (+45%); private steady; store.append 237k/s. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -52,23 +52,17 @@ private final class MockChatMediaTransferContext: ChatMediaTransferContext {
|
||||
return true
|
||||
}
|
||||
|
||||
var meshTimeline: [BitchatMessage] = []
|
||||
private(set) var refreshedChannels: [ChannelID?] = []
|
||||
private(set) var trimCount = 0
|
||||
private(set) var appendedPublicMessages: [(message: BitchatMessage, conversationID: ConversationID)] = []
|
||||
private(set) var removedMessages: [(messageID: String, cleanupFile: Bool)] = []
|
||||
private(set) var systemMessages: [String] = []
|
||||
private(set) var notifyUIChangedCount = 0
|
||||
|
||||
func appendTimelineMessage(_ message: BitchatMessage, to channel: ChannelID) {
|
||||
meshTimeline.append(message)
|
||||
@discardableResult
|
||||
func appendPublicMessage(_ message: BitchatMessage, to conversationID: ConversationID) -> Bool {
|
||||
appendedPublicMessages.append((message, conversationID))
|
||||
return true
|
||||
}
|
||||
|
||||
func refreshVisibleMessages(from channel: ChannelID?) {
|
||||
refreshedChannels.append(channel)
|
||||
}
|
||||
|
||||
func trimMessagesIfNeeded() { trimCount += 1 }
|
||||
|
||||
func removeMessage(withID messageID: String, cleanupFile: Bool) {
|
||||
removedMessages.append((messageID, cleanupFile))
|
||||
}
|
||||
@@ -129,22 +123,21 @@ struct ChatMediaTransferCoordinatorContextTests {
|
||||
#expect(message.senderPeerID == context.myPeerID)
|
||||
#expect(message.deliveryStatus == .sending)
|
||||
#expect(context.recordedContentKeys == ["[voice] note.m4a"])
|
||||
#expect(context.trimCount == 1)
|
||||
#expect(context.notifyUIChangedCount == 1)
|
||||
#expect(context.meshTimeline.isEmpty)
|
||||
#expect(context.appendedPublicMessages.isEmpty)
|
||||
}
|
||||
|
||||
@Test @MainActor
|
||||
func enqueueMediaMessage_publicAppendsToTimelineAndRefreshes() async {
|
||||
func enqueueMediaMessage_publicAppendsToActiveConversation() async {
|
||||
let context = MockChatMediaTransferContext()
|
||||
let coordinator = ChatMediaTransferCoordinator(context: context)
|
||||
|
||||
let message = coordinator.enqueueMediaMessage(content: "[image] pic.jpg", targetPeer: nil)
|
||||
|
||||
#expect(context.meshTimeline.map(\.id) == [message.id])
|
||||
#expect(context.appendedPublicMessages.map(\.message.id) == [message.id])
|
||||
#expect(context.appendedPublicMessages.first?.conversationID == .mesh)
|
||||
#expect(!message.isPrivate)
|
||||
#expect(message.sender == "me")
|
||||
#expect(context.refreshedChannels.count == 1)
|
||||
#expect(context.privateChats.isEmpty)
|
||||
#expect(context.notifyUIChangedCount == 1)
|
||||
}
|
||||
@@ -210,7 +203,7 @@ struct ChatMediaTransferCoordinatorContextTests {
|
||||
#expect(!FileManager.default.fileExists(atPath: url.path))
|
||||
#expect(context.systemMessages == ["Voice notes are only available in mesh chats."])
|
||||
#expect(context.privateChats.isEmpty)
|
||||
#expect(context.meshTimeline.isEmpty)
|
||||
#expect(context.appendedPublicMessages.isEmpty)
|
||||
#expect(coordinator.transferIdToMessageIDs.isEmpty)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user