From 2350e93db33d18f247491f9ba635c4e16a7c56e1 Mon Sep 17 00:00:00 2001 From: Nuno Vieira Date: Fri, 6 Dec 2024 16:14:04 +0000 Subject: [PATCH 1/3] Fix message thread reply footnote view not shown if parent message not in cache (#681) * First solution: Provide the reply in the parentMessage parameter and do workaround * Revert "First solution: Provide the reply in the parentMessage parameter and do workaround" This reverts commit cfb4b2ed9eeee59c066a54f47577e5c17b52f097. * Final solution: Create a Lazy view that waits for the parent message to be fetched This solution requires the least amount of changes and there is also no breaking change * Update CHANGELOG.md * Remove unused properties * PR feedback * Fix Xcode 15 * Fix Xcode 15 * Use on appear instead * Please.... --- CHANGELOG.md | 2 + .../MessageList/MessageContainerView.swift | 14 +++++++ .../MessageList/MessageRepliesView.swift | 42 +++++++++++++++++++ 3 files changed, 58 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 83acba62..8cf27ff8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). # Upcoming +### 🐞 Fixed +- Fix message thread reply footnote view not shown if parent message not in cache [#681](https://github.com/GetStream/stream-chat-swiftui/pull/681) ### ⚡ Performance - Improve message search performance [#680](https://github.com/GetStream/stream-chat-swiftui/pull/680) diff --git a/Sources/StreamChatSwiftUI/ChatChannel/MessageList/MessageContainerView.swift b/Sources/StreamChatSwiftUI/ChatChannel/MessageList/MessageContainerView.swift index ea39a48d..594fb3bf 100644 --- a/Sources/StreamChatSwiftUI/ChatChannel/MessageList/MessageContainerView.swift +++ b/Sources/StreamChatSwiftUI/ChatChannel/MessageList/MessageContainerView.swift @@ -185,6 +185,20 @@ public struct MessageContainerView: View { ) .accessibilityElement(children: .contain) .accessibility(identifier: "MessageRepliesView") + } else if message.showReplyInChannel, let parentId = message.parentMessageId { + /// In case the parent message is not available in the local cache, we need to fetch it from the remote server. + /// The lazy view uses the `factory.makeMessageRepliesShownInChannelView` internally once the parent message is fetched. + LazyMessageRepliesView( + factory: factory, + channel: channel, + message: message, + parentMessageController: chatClient.messageController( + cid: channel.cid, + messageId: parentId + ) + ) + .accessibilityElement(children: .contain) + .accessibility(identifier: "MessageRepliesView") } } diff --git a/Sources/StreamChatSwiftUI/ChatChannel/MessageList/MessageRepliesView.swift b/Sources/StreamChatSwiftUI/ChatChannel/MessageList/MessageRepliesView.swift index 8aec642c..69dcd7ab 100644 --- a/Sources/StreamChatSwiftUI/ChatChannel/MessageList/MessageRepliesView.swift +++ b/Sources/StreamChatSwiftUI/ChatChannel/MessageList/MessageRepliesView.swift @@ -116,3 +116,45 @@ public struct MessageRepliesView: View { } } } + +/// Lazy view that uses the message controller to fetch the parent message before creating message replies view. +/// This is needed when the parent message is not available in the local cache. +/// Changing the `parentMessage` to `nil` in the `MessageRepliesView` would case multiple changes including breaking changes. +struct LazyMessageRepliesView: View { + @StateObject private var parentMessageObserver: ChatMessageController.ObservableObject + + var factory: Factory + var channel: ChatChannel + var message: ChatMessage + + init( + factory: Factory, + channel: ChatChannel, + message: ChatMessage, + parentMessageController: ChatMessageController + ) { + _parentMessageObserver = StateObject(wrappedValue: parentMessageController.observableObject) + self.factory = factory + self.channel = channel + self.message = message + } + + var body: some View { + VStack { + if let parentMessage = parentMessageObserver.message { + factory.makeMessageRepliesShownInChannelView( + channel: channel, + message: message, + parentMessage: parentMessage, + replyCount: parentMessage.replyCount + ) + } else { + EmptyView() + } + }.onAppear { + if parentMessageObserver.message == nil { + parentMessageObserver.controller.synchronize() + } + } + } +} From 91e461903e57b1c867ae78d6d85a73f7cde71255 Mon Sep 17 00:00:00 2001 From: Toomas Vahter Date: Mon, 9 Dec 2024 09:54:56 +0200 Subject: [PATCH 2/3] Make CreatePollView public (#685) --- CHANGELOG.md | 2 ++ .../ChatChannel/Polls/CreatePollView.swift | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8cf27ff8..05799e46 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Fix message thread reply footnote view not shown if parent message not in cache [#681](https://github.com/GetStream/stream-chat-swiftui/pull/681) ### ⚡ Performance - Improve message search performance [#680](https://github.com/GetStream/stream-chat-swiftui/pull/680) +### ✅ Added +- Make `CreatePollView` public [#685](https://github.com/GetStream/stream-chat-swiftui/pull/685) # [4.68.0](https://github.com/GetStream/stream-chat-swiftui/releases/tag/4.68.0) _December 03, 2024_ diff --git a/Sources/StreamChatSwiftUI/ChatChannel/Polls/CreatePollView.swift b/Sources/StreamChatSwiftUI/ChatChannel/Polls/CreatePollView.swift index 8a90e1eb..e98d4805 100644 --- a/Sources/StreamChatSwiftUI/ChatChannel/Polls/CreatePollView.swift +++ b/Sources/StreamChatSwiftUI/ChatChannel/Polls/CreatePollView.swift @@ -34,7 +34,7 @@ struct ComposerPollView: View { } } -struct CreatePollView: View { +public struct CreatePollView: View { @Injected(\.colors) var colors @Injected(\.fonts) var fonts @@ -47,7 +47,7 @@ struct CreatePollView: View { @State private var listId = UUID() - init(chatController: ChatChannelController, messageController: ChatMessageController?) { + public init(chatController: ChatChannelController, messageController: ChatMessageController?) { _viewModel = StateObject( wrappedValue: CreatePollViewModel( chatController: chatController, @@ -56,7 +56,7 @@ struct CreatePollView: View { ) } - var body: some View { + public var body: some View { NavigationView { List { VStack(alignment: .leading, spacing: 8) { From 194eea5c269b7c62c933a81ebfe67c76b40da630 Mon Sep 17 00:00:00 2001 From: Alexey Alter-Pesotskiy Date: Mon, 9 Dec 2024 12:38:43 +0000 Subject: [PATCH 3/3] [CI] Create a lane to update StreamChat dependency (#687) --- Package.swift | 2 +- fastlane/Fastfile | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/Package.swift b/Package.swift index 45e6b6fa..08e4bf6d 100644 --- a/Package.swift +++ b/Package.swift @@ -16,7 +16,7 @@ let package = Package( ) ], dependencies: [ - .package(url: "https://github.com/GetStream/stream-chat-swift.git", from: "4.67.0"), + .package(url: "https://github.com/GetStream/stream-chat-swift.git", from: "4.68.0"), ], targets: [ .target( diff --git a/fastlane/Fastfile b/fastlane/Fastfile index fa1a516d..a7f5de82 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -146,6 +146,40 @@ private_lane :appstore_api_key do ) end +desc "Updates StreamChat dependency locally. Usage: `bundle exec fastlane update_stream_chat version:4.56.0`" +lane :update_stream_chat do |options| + raise UI.user_error!('Provide a version.') unless options[:version] + + Dir.chdir('..') do + file = 'Package.swift' + current_stream_chat_version = File.read(file)[/stream-chat-swift\.git", from: "([\d.]+)"\)/, 1] + File.write(file, File.read(file).gsub(/(stream-chat-swift\.git", from: ")[\d.]+"/, "\\1#{options[:version]}\"")) + + file = 'StreamChatSwiftUI-XCFramework.podspec' + File.write(file, File.read(file).gsub(/(StreamChat-XCFramework', '~> )[\d.]+'/, "\\1#{options[:version]}'")) + + file = 'StreamChatSwiftUI.podspec' + File.write(file, File.read(file).gsub(/(StreamChat', '~> )[\d.]+'/, "\\1#{options[:version]}'")) + + file = 'StreamChatSwiftUI.xcodeproj/project.pbxproj' + content = File.read(file) + if content.include?("minimumVersion = #{current_stream_chat_version}") + File.write(file, content.gsub("minimumVersion = #{current_stream_chat_version}", "minimumVersion = #{options[:version]}")) + elsif content.include?('branch = develop') + File.write(file, content.gsub('kind = branch', "minimumVersion = #{options[:version]}").gsub('branch = develop', 'kind = upToNextMajorVersion')) + else + UI.user_error!("Something went wrong after trying to modify #{file}.") + end + end + + pr_create( + title: "Update StreamChat dependency to #{options[:version]}", + base_branch: 'develop', + head_branch: "ci/update-stream-chat-dependency-#{Time.now.to_i}", + github_repo: github_repo + ) +end + lane :pod_lint do lint_required = true Dir.chdir('..') do