Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,9 @@ extension ChatItem {
_ messages: [ConversationMessage],
selfUserID: UserID,
// How long a pause has to be before it heads the next message with its own separator and
// ends the run above it. Android's `SeparatorConfig.Continuous` gap, so a pause of minutes
// keeps one exchange together on both platforms instead of cutting it into single bubbles.
gap: TimeInterval = 3 * 60 * 60,
// ends the run above it. Android's `SeparatorConfig.Continuous` gap (one hour), so a pause of
// minutes keeps one exchange together on both platforms instead of cutting it into single bubbles.
gap: TimeInterval = 60 * 60,
counterpartRead: (pointer: MessageID, date: Date?)? = nil,
suppressReceiptFor: String? = nil,
cashBranding: (ExchangedFiat) -> (token: String, iconURL: URL?) = { _ in ("Cash", nil) },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,5 +156,5 @@ extension ChatItem {

/// Matches the in-app chat: a separator opens the transcript and breaks any run whose gap from
/// the previous message exceeds this.
private static let separatorGap: TimeInterval = 15 * 60
private static let separatorGap: TimeInterval = 60 * 60
}
14 changes: 14 additions & 0 deletions FlipcashTests/Chat/ChatMessageMappingTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,20 @@ struct ChatMessageMappingTests {
#expect(!broken[1].isContinuationFromPrevious)
}

@Test("A 90-minute pause opens a date separator; a 30-minute pause does not")
func hourGapOpensSeparator() {
func separators(afterPause pause: TimeInterval) -> Int {
let rows = [
ConversationMessage(id: MessageID(value: 1), senderID: me, content: .text("a"), date: base, unreadSeq: 1),
ConversationMessage(id: MessageID(value: 2), senderID: me, content: .text("b"), date: base.addingTimeInterval(pause), unreadSeq: 2),
]
return separatorCount(ChatItem.from(rows, selfUserID: me))
}

#expect(separators(afterPause: 30 * 60) == 1) // only the one opening the transcript
#expect(separators(afterPause: 90 * 60) == 2) // the pause heads the second message
}

@Test("A run does not carry across a change of day, however short the pause")
func dayChangeBreaksRun() {
// Straddling local midnight, so the two rows are minutes apart but on different dates.
Expand Down
19 changes: 15 additions & 4 deletions FlipcashTests/ChatPreviewMappingTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ struct ChatPreviewMappingTests {

@Test("Messages within the gap share a single opening separator")
func messagesWithinGapShareSeparator() {
// ids 1 and 2 → dates 1s apart, well under the 15-minute gap.
// ids 1 and 2 → dates 1s apart, well under the one-hour gap.
let messages = [
textMessage(id: 1, senderID: meID, text: "a"),
textMessage(id: 2, senderID: meID, text: "b"),
Expand All @@ -253,17 +253,28 @@ struct ChatPreviewMappingTests {
#expect(separators(items).count == 1)
}

@Test("A gap longer than 15 minutes inserts another separator")
@Test("A gap longer than one hour inserts another separator")
func gapInsertsSeparator() {
// ids 1 and 1000 → dates 999s (~16.6 min) apart, beyond the 15-minute gap.
// ids 1 and 5401 → dates 5400s (90 min) apart, beyond the one-hour gap.
let messages = [
textMessage(id: 1, senderID: meID, text: "a"),
textMessage(id: 1000, senderID: meID, text: "b"),
textMessage(id: 5401, senderID: meID, text: "b"),
]
let items = ChatItem.preview(from: messages, selfUserID: meID)
#expect(separators(items).count == 2)
}

@Test("A pause of 30 minutes does not insert another separator")
func shortPauseKeepsOneSeparator() {
// ids 1 and 1801 → dates 1800s (30 min) apart, under the one-hour gap.
let messages = [
textMessage(id: 1, senderID: meID, text: "a"),
textMessage(id: 1801, senderID: meID, text: "b"),
]
let items = ChatItem.preview(from: messages, selfUserID: meID)
#expect(separators(items).count == 1)
}

// MARK: - Cache serialization

@Test("Preview round-trips through Codable unchanged — the notification cache's mechanism")
Expand Down
Loading