diff --git a/CHANGELOG.md b/CHANGELOG.md index ef689ba6..f063ea60 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### ✅ Added - Link detection in the text views +- Indicator when a message was edited # [4.49.0](https://github.com/GetStream/stream-chat-swiftui/releases/tag/4.49.0) _February 28, 2024_ diff --git a/Package.swift b/Package.swift index 627491f7..8294cc3c 100644 --- a/Package.swift +++ b/Package.swift @@ -17,7 +17,7 @@ let package = Package( ) ], dependencies: [ - .package(url: "https://github.com/GetStream/stream-chat-swift.git", from: "4.49.0"), + .package(url: "https://github.com/GetStream/stream-chat-swift.git", from: "4.50.0"), ], targets: [ .target( diff --git a/Sources/StreamChatSwiftUI/ChatChannel/ChatChannelViewModel.swift b/Sources/StreamChatSwiftUI/ChatChannel/ChatChannelViewModel.swift index fcaa95c9..167773c7 100644 --- a/Sources/StreamChatSwiftUI/ChatChannel/ChatChannelViewModel.swift +++ b/Sources/StreamChatSwiftUI/ChatChannel/ChatChannelViewModel.swift @@ -350,8 +350,11 @@ open class ChatChannelViewModel: ObservableObject, MessagesDataSource { } let delay = previousMessage.createdAt.timeIntervalSince(date) + let showMessageEditedLabel = utils.messageListConfig.isMessageEditedLabelEnabled + && message.textUpdatedAt != nil - if delay > utils.messageListConfig.maxTimeIntervalBetweenMessagesInGroup { + if delay > utils.messageListConfig.maxTimeIntervalBetweenMessagesInGroup + || showMessageEditedLabel { temp[message.id]?.append(firstMessageKey) var prevInfo = temp[previousMessage.id] ?? [] prevInfo.append(lastMessageKey) diff --git a/Sources/StreamChatSwiftUI/ChatChannel/MessageList/MessageIdBuilder.swift b/Sources/StreamChatSwiftUI/ChatChannel/MessageList/MessageIdBuilder.swift index 9020b0ac..86b53751 100644 --- a/Sources/StreamChatSwiftUI/ChatChannel/MessageList/MessageIdBuilder.swift +++ b/Sources/StreamChatSwiftUI/ChatChannel/MessageList/MessageIdBuilder.swift @@ -20,6 +20,9 @@ public class DefaultMessageIdBuilder: MessageIdBuilder { if message.localState != nil { statesId = message.uploadingStatesId } + if message.textUpdatedAt != nil { + statesId = "edited" + } return message.baseId + statesId + message.reactionScoresId + message.repliesCountId + "\(message.updatedAt)" + message.pinStateId } diff --git a/Sources/StreamChatSwiftUI/ChatChannel/MessageList/MessageListConfig.swift b/Sources/StreamChatSwiftUI/ChatChannel/MessageList/MessageListConfig.swift index e872dc9d..2439c86a 100644 --- a/Sources/StreamChatSwiftUI/ChatChannel/MessageList/MessageListConfig.swift +++ b/Sources/StreamChatSwiftUI/ChatChannel/MessageList/MessageListConfig.swift @@ -28,7 +28,8 @@ public struct MessageListConfig { handleTabBarVisibility: Bool = true, messageListAlignment: MessageListAlignment = .standard, uniqueReactionsEnabled: Bool = false, - localLinkDetectionEnabled: Bool = true + localLinkDetectionEnabled: Bool = true, + isMessageEditedLabelEnabled: Bool = true ) { self.messageListType = messageListType self.typingIndicatorPlacement = typingIndicatorPlacement @@ -50,6 +51,7 @@ public struct MessageListConfig { self.messageListAlignment = messageListAlignment self.uniqueReactionsEnabled = uniqueReactionsEnabled self.localLinkDetectionEnabled = localLinkDetectionEnabled + self.isMessageEditedLabelEnabled = isMessageEditedLabelEnabled } public let messageListType: MessageListType @@ -72,6 +74,7 @@ public struct MessageListConfig { public let messageListAlignment: MessageListAlignment public let uniqueReactionsEnabled: Bool public let localLinkDetectionEnabled: Bool + public let isMessageEditedLabelEnabled: Bool } /// Contains information about the message paddings. diff --git a/Sources/StreamChatSwiftUI/ChatChannel/MessageList/MessageListHelperViews.swift b/Sources/StreamChatSwiftUI/ChatChannel/MessageList/MessageListHelperViews.swift index 85e3b637..6c409894 100644 --- a/Sources/StreamChatSwiftUI/ChatChannel/MessageList/MessageListHelperViews.swift +++ b/Sources/StreamChatSwiftUI/ChatChannel/MessageList/MessageListHelperViews.swift @@ -64,8 +64,19 @@ struct MessageDateView: View { var message: ChatMessage + var text: String { + var text = dateFormatter.string(from: message.createdAt) + let showMessageEditedLabel = utils.messageListConfig.isMessageEditedLabelEnabled + && message.textUpdatedAt != nil + && !message.isDeleted + if showMessageEditedLabel { + text = text + " • " + L10n.Message.Cell.edited + } + return text + } + var body: some View { - Text(dateFormatter.string(from: message.createdAt)) + Text(text) .font(fonts.footnote) .foregroundColor(Color(colors.textLowEmphasis)) .animation(nil) diff --git a/Sources/StreamChatSwiftUI/Generated/L10n.swift b/Sources/StreamChatSwiftUI/Generated/L10n.swift index 4a046e63..5bffca0a 100644 --- a/Sources/StreamChatSwiftUI/Generated/L10n.swift +++ b/Sources/StreamChatSwiftUI/Generated/L10n.swift @@ -315,6 +315,8 @@ internal enum L10n { internal static var title: String { L10n.tr("Localizable", "message.bounce.title") } } internal enum Cell { + /// Edited + internal static var edited: String { L10n.tr("Localizable", "message.cell.edited") } /// Pinned by internal static var pinnedBy: String { L10n.tr("Localizable", "message.cell.pinnedBy") } /// unknown diff --git a/Sources/StreamChatSwiftUI/Resources/en.lproj/Localizable.strings b/Sources/StreamChatSwiftUI/Resources/en.lproj/Localizable.strings index 35c8d987..2ccc032a 100644 --- a/Sources/StreamChatSwiftUI/Resources/en.lproj/Localizable.strings +++ b/Sources/StreamChatSwiftUI/Resources/en.lproj/Localizable.strings @@ -47,6 +47,7 @@ "message.gallery.photos" = "Photos"; "message.cell.pinnedBy" = "Pinned by"; "message.cell.unknownPin" = "unknown"; +"message.cell.edited" = "Edited"; "message.reactions.currentUser" = "You"; "alert.actions.cancel" = "Cancel"; diff --git a/StreamChatSwiftUI-XCFramework.podspec b/StreamChatSwiftUI-XCFramework.podspec index 8d9eb5ce..9998b9a0 100644 --- a/StreamChatSwiftUI-XCFramework.podspec +++ b/StreamChatSwiftUI-XCFramework.podspec @@ -19,7 +19,7 @@ Pod::Spec.new do |spec| spec.framework = "Foundation", "UIKit", "SwiftUI" - spec.dependency "StreamChat-XCFramework", "~> 4.49.0" + spec.dependency "StreamChat-XCFramework", "~> 4.50.0" spec.cocoapods_version = ">= 1.11.0" end diff --git a/StreamChatSwiftUI.podspec b/StreamChatSwiftUI.podspec index e2950dd5..d79d41aa 100644 --- a/StreamChatSwiftUI.podspec +++ b/StreamChatSwiftUI.podspec @@ -19,6 +19,6 @@ Pod::Spec.new do |spec| spec.framework = "Foundation", "UIKit", "SwiftUI" - spec.dependency "StreamChat", "~> 4.49.0" + spec.dependency "StreamChat", "~> 4.50.0" end diff --git a/StreamChatSwiftUI.xcodeproj/project.pbxproj b/StreamChatSwiftUI.xcodeproj/project.pbxproj index a872ec24..3a922934 100644 --- a/StreamChatSwiftUI.xcodeproj/project.pbxproj +++ b/StreamChatSwiftUI.xcodeproj/project.pbxproj @@ -3376,7 +3376,7 @@ repositoryURL = "https://github.com/GetStream/stream-chat-swift.git"; requirement = { kind = upToNextMajorVersion; - minimumVersion = 4.49.0; + minimumVersion = 4.50.0; }; }; E3A1C01A282BAC66002D1E26 /* XCRemoteSwiftPackageReference "sentry-cocoa" */ = { diff --git a/StreamChatSwiftUITests/Tests/ChatChannel/MessageContainerView_Tests.swift b/StreamChatSwiftUITests/Tests/ChatChannel/MessageContainerView_Tests.swift index e751ba86..b4cee913 100644 --- a/StreamChatSwiftUITests/Tests/ChatChannel/MessageContainerView_Tests.swift +++ b/StreamChatSwiftUITests/Tests/ChatChannel/MessageContainerView_Tests.swift @@ -33,6 +33,25 @@ class MessageContainerView_Tests: StreamChatTestCase { // Then assertSnapshot(matching: view, as: .image(perceptualPrecision: precision)) } + + func test_messageContainerEdited_snapshot() { + // Given + streamChat = StreamChat(chatClient: chatClient) + let message = ChatMessage.mock( + id: .unique, + cid: .unique, + text: "Message sent by current user", + author: .mock(id: Self.currentUserId, name: "Martin"), + isSentByCurrentUser: true, + textUpdatedAt: Date() + ) + + // When + let view = testMessageViewContainer(message: message) + + // Then + assertSnapshot(matching: view, as: .image(perceptualPrecision: precision)) + } func test_messageContainerViewSentOtherUser_snapshot() { // Given diff --git a/StreamChatSwiftUITests/Tests/ChatChannel/__Snapshots__/MessageContainerView_Tests/test_messageContainerEdited_snapshot.1.png b/StreamChatSwiftUITests/Tests/ChatChannel/__Snapshots__/MessageContainerView_Tests/test_messageContainerEdited_snapshot.1.png new file mode 100644 index 00000000..d9277a15 Binary files /dev/null and b/StreamChatSwiftUITests/Tests/ChatChannel/__Snapshots__/MessageContainerView_Tests/test_messageContainerEdited_snapshot.1.png differ