Skip to content

Commit 0973a91

Browse files
Add PositionInMessagesSection enum
This represents the position in a MessagesSection (the collection of messages on a given date). This is useful to add styling to the first, or last message of the day.
1 parent 3275e4d commit 0973a91

File tree

6 files changed

+73
-7
lines changed

6 files changed

+73
-7
lines changed

Sources/ExyteChat/ChatView/MessageView/ChatMessageView.swift

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ struct ChatMessageView<MessageContent: View>: View {
4040
viewModel: viewModel,
4141
message: row.message,
4242
positionInUserGroup: row.positionInUserGroup,
43+
positionInMessagesSection: row.positionInMessagesSection,
4344
chatType: chatType,
4445
avatarSize: avatarSize,
4546
tapAvatarClosure: tapAvatarClosure,

Sources/ExyteChat/ChatView/MessageView/MessageView.swift

+2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ struct MessageView: View {
1515

1616
let message: Message
1717
let positionInUserGroup: PositionInUserGroup
18+
let positionInMessagesSection: PositionInMessagesSection
1819
let chatType: ChatType
1920
let avatarSize: CGFloat
2021
let tapAvatarClosure: ChatView.TapAvatarClosure?
@@ -365,6 +366,7 @@ struct MessageView_Preview: PreviewProvider {
365366
viewModel: ChatViewModel(),
366367
message: replyedMessage,
367368
positionInUserGroup: .single,
369+
positionInMessagesSection: .single,
368370
chatType: .conversation,
369371
avatarSize: 32,
370372
tapAvatarClosure: nil,

Sources/ExyteChat/ChatView/UIList.swift

+3-1
Original file line numberDiff line numberDiff line change
@@ -581,7 +581,9 @@ struct UIList<MessageContent: View, InputView: View>: UIViewRepresentable {
581581

582582
func formatRow(_ row: MessageRow) -> String {
583583
if let status = row.message.status {
584-
return String("id: \(row.id) text: \(row.message.text) status: \(status) date: \(row.message.createdAt) position: \(row.positionInUserGroup) trigger: \(row.message.triggerRedraw)")
584+
return String(
585+
"id: \(row.id) text: \(row.message.text) status: \(status) date: \(row.message.createdAt) position in user group: \(row.positionInUserGroup) position in messages section: \(row.positionInMessagesSection) trigger: \(row.message.triggerRedraw)"
586+
)
585587
}
586588
return ""
587589
}

Sources/ExyteChat/ChatView/WrappingMessages.swift

+13-1
Original file line numberDiff line numberDiff line change
@@ -111,10 +111,21 @@ extension ChatView {
111111
positionInUserGroup = .last
112112
}
113113

114+
let positionInMessagesSection: PositionInMessagesSection
115+
if messages.count == 1 {
116+
positionInMessagesSection = .single
117+
} else if !prevMessageExists {
118+
positionInMessagesSection = .first
119+
} else if !nextMessageExists {
120+
positionInMessagesSection = .last
121+
} else {
122+
positionInMessagesSection = .middle
123+
}
124+
114125
if replyMode == .quote {
115126
return MessageRow(
116127
message: $0.element, positionInUserGroup: positionInUserGroup,
117-
commentsPosition: nil)
128+
positionInMessagesSection: positionInMessagesSection, commentsPosition: nil)
118129
}
119130

120131
let nextMessageIsAReply = nextMessage?.replyMessage != nil
@@ -164,6 +175,7 @@ extension ChatView {
164175

165176
return MessageRow(
166177
message: $0.element, positionInUserGroup: positionInUserGroup,
178+
positionInMessagesSection: positionInMessagesSection,
167179
commentsPosition: commentsPosition)
168180
}
169181
.reversed()

Sources/ExyteChat/Model/MessageRow.swift

+13
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,17 @@ public enum PositionInUserGroup { // group from the same user
1515
}
1616
}
1717

18+
public enum PositionInMessagesSection { // messages within the same day
19+
case first
20+
case middle
21+
case last
22+
case single
23+
24+
var isTop: Bool {
25+
self == .first || self == .single
26+
}
27+
}
28+
1829
// for comments reply mode only
1930

2031
public struct CommentsPosition: Equatable {
@@ -61,11 +72,13 @@ public enum PositionInChat {
6172
struct MessageRow: Equatable {
6273
let message: Message
6374
let positionInUserGroup: PositionInUserGroup
75+
let positionInMessagesSection: PositionInMessagesSection
6476
let commentsPosition: CommentsPosition?
6577

6678
static func == (lhs: Self, rhs: Self) -> Bool {
6779
lhs.id == rhs.id
6880
&& lhs.positionInUserGroup == rhs.positionInUserGroup
81+
&& lhs.positionInMessagesSection == rhs.positionInMessagesSection
6982
&& lhs.commentsPosition == rhs.commentsPosition
7083
&& lhs.message.status == rhs.message.status
7184
&& lhs.message.triggerRedraw == rhs.message.triggerRedraw

Tests/ExyteChatTests/WrappingMessagesTest.swift

+41-5
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ extension Tag {
2323
@Tag static var messageOrder: Self
2424
@Tag static var answerMode: Self
2525
@Tag static var quoteMode: Self
26-
@Tag static var positionInUserGroup: Self
26+
@Tag static var positionInUserGroupAndMessagesSection: Self
2727
@Tag static var positionInCommentsGroup: Self
2828
}
2929

@@ -221,7 +221,8 @@ struct WrappingMessagesTest {
221221
}
222222

223223
@Test(
224-
"Single message has single position in user group", .tags(.positionInUserGroup),
224+
"Single message has single position in user group",
225+
.tags(.positionInUserGroupAndMessagesSection),
225226
arguments: ChatType.allCases, ReplyMode.allCases)
226227
func singleMessageHasSinglePositionInUserGroup(for chatType: ChatType, and replyMode: ReplyMode)
227228
async throws
@@ -235,11 +236,13 @@ struct WrappingMessagesTest {
235236
#expect(sections.first?.rows.first?.id == singleMessage.id)
236237

237238
#expect(sections.first?.rows.first?.positionInUserGroup == .single)
239+
#expect(sections.first?.rows.first?.positionInMessagesSection == .single)
238240
}
239241

240242
@Test(
241243
"Multiple messages from single user have top, middle and bottom positions in user group",
242-
.tags(.positionInUserGroup), arguments: ChatType.allCases, ReplyMode.allCases)
244+
.tags(.positionInUserGroupAndMessagesSection), arguments: ChatType.allCases,
245+
ReplyMode.allCases)
243246
func multipleMessagesFromSingleUserHaveCorrectUserGroupPositions(
244247
for chatType: ChatType, and replyMode: ReplyMode
245248
) async throws {
@@ -262,18 +265,29 @@ struct WrappingMessagesTest {
262265
switch chatType {
263266
case .comments:
264267
#expect(sections.first?.rows[0].positionInUserGroup == .first)
268+
#expect(sections.first?.rows[0].positionInMessagesSection == .first)
269+
265270
#expect(sections.first?.rows[1].positionInUserGroup == .middle)
271+
#expect(sections.first?.rows[1].positionInMessagesSection == .middle)
272+
266273
#expect(sections.first?.rows[2].positionInUserGroup == .last)
274+
#expect(sections.first?.rows[2].positionInMessagesSection == .last)
267275
case .conversation:
268276
#expect(sections.first?.rows[2].positionInUserGroup == .first)
277+
#expect(sections.first?.rows[2].positionInMessagesSection == .first)
278+
269279
#expect(sections.first?.rows[1].positionInUserGroup == .middle)
280+
#expect(sections.first?.rows[1].positionInMessagesSection == .middle)
281+
270282
#expect(sections.first?.rows[0].positionInUserGroup == .last)
283+
#expect(sections.first?.rows[0].positionInMessagesSection == .last)
271284
}
272285
}
273286

274287
@Test(
275288
"Message from another user, in between many messages by another, splits the user group",
276-
.tags(.positionInUserGroup), arguments: ChatType.allCases, ReplyMode.allCases)
289+
.tags(.positionInUserGroupAndMessagesSection), arguments: ChatType.allCases,
290+
ReplyMode.allCases)
277291
func messageFromAnotherUserSplitsUserGroup(for chatType: ChatType, and replyMode: ReplyMode)
278292
async throws
279293
{
@@ -297,22 +311,41 @@ struct WrappingMessagesTest {
297311
switch chatType {
298312
case .comments:
299313
#expect(sections.first?.rows[0].positionInUserGroup == .first)
314+
#expect(sections.first?.rows[0].positionInMessagesSection == .first)
315+
300316
#expect(sections.first?.rows[1].positionInUserGroup == .last)
317+
#expect(sections.first?.rows[1].positionInMessagesSection == .middle)
318+
301319
#expect(sections.first?.rows[2].positionInUserGroup == .single)
320+
#expect(sections.first?.rows[2].positionInMessagesSection == .middle)
321+
302322
#expect(sections.first?.rows[3].positionInUserGroup == .first)
323+
#expect(sections.first?.rows[3].positionInMessagesSection == .middle)
324+
303325
#expect(sections.first?.rows[4].positionInUserGroup == .last)
326+
#expect(sections.first?.rows[4].positionInMessagesSection == .last)
304327
case .conversation:
305328
#expect(sections.first?.rows[4].positionInUserGroup == .first)
329+
#expect(sections.first?.rows[4].positionInMessagesSection == .first)
330+
306331
#expect(sections.first?.rows[3].positionInUserGroup == .last)
332+
#expect(sections.first?.rows[3].positionInMessagesSection == .middle)
333+
307334
#expect(sections.first?.rows[2].positionInUserGroup == .single)
335+
#expect(sections.first?.rows[2].positionInMessagesSection == .middle)
336+
308337
#expect(sections.first?.rows[1].positionInUserGroup == .first)
338+
#expect(sections.first?.rows[1].positionInMessagesSection == .middle)
339+
309340
#expect(sections.first?.rows[0].positionInUserGroup == .last)
341+
#expect(sections.first?.rows[0].positionInMessagesSection == .last)
310342
}
311343
}
312344

313345
@Test(
314346
"Messages from the same user on different days should not be in the same user group",
315-
.tags(.positionInUserGroup), arguments: ChatType.allCases, ReplyMode.allCases)
347+
.tags(.positionInUserGroupAndMessagesSection), arguments: ChatType.allCases,
348+
ReplyMode.allCases)
316349
func messagesOnDifferentDaysShouldBeInDifferentUserGroups(
317350
for chatType: ChatType, and replyMode: ReplyMode
318351
) async throws {
@@ -329,7 +362,10 @@ struct WrappingMessagesTest {
329362
#expect(sections[0].rows.first?.id == message1.id)
330363

331364
#expect(sections[1].rows.first?.positionInUserGroup == .single)
365+
#expect(sections[1].rows.first?.positionInMessagesSection == .single)
366+
332367
#expect(sections[0].rows.first?.positionInUserGroup == .single)
368+
#expect(sections[0].rows.first?.positionInMessagesSection == .single)
333369
}
334370

335371
@Test(

0 commit comments

Comments
 (0)