Skip to content

Commit a40d7cb

Browse files
committed
Merge branch 'develop' into v5
# Conflicts: # Sources/StreamChatSwiftUI/ChatChannel/MessageList/ImageAttachmentView.swift
2 parents 8edb22c + 48c177d commit a40d7cb

File tree

10 files changed

+99
-49
lines changed

10 files changed

+99
-49
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
99
- Add participant actions in channel info view [#982](https://github.com/GetStream/stream-chat-swiftui/pull/982)
1010
- Add support for overriding `onImageTap` in `LinkAttachmentView` [#986](https://github.com/GetStream/stream-chat-swiftui/pull/986)
1111
- Add support for customizing text colors in `LinkAttachmentView` [#992](https://github.com/GetStream/stream-chat-swiftui/pull/992)
12+
- Expose `MediaAttachment` properties and initializer [#1000](https://github.com/GetStream/stream-chat-swiftui/pull/1000)
13+
- Add `ColorPalette.navigationBarGlyph` for configuring the glyph color for buttons in navigation bars [#999](https://github.com/GetStream/stream-chat-swiftui/pull/999)
14+
- Allow overriding `ChatChannelInfoViewModel` properties: `shouldShowLeaveConversationButton`, `canRenameChannel`, and `shouldShowAddUserButton` [#995](https://github.com/GetStream/stream-chat-swiftui/pull/995)
1215

1316
### 🐞 Fixed
1417
- Fix openChannel not working when searching or another chat shown [#975](https://github.com/GetStream/stream-chat-swiftui/pull/975)
@@ -19,6 +22,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
1922
- Fix random scroll after marking a message unread [#989](https://github.com/GetStream/stream-chat-swiftui/pull/989)
2023
- Fix marking channel read when the user scrolls to the bottom after marking a message as unread [#989](https://github.com/GetStream/stream-chat-swiftui/pull/989)
2124
- Fix replying to unread messages marking them instantly as read [#989](https://github.com/GetStream/stream-chat-swiftui/pull/989)
25+
- Fix rendering of the add users button on iOS 26 [#999](https://github.com/GetStream/stream-chat-swiftui/pull/999)
26+
- Use `ColorPalette.navigationBarTint` for the background of the add users button [#999](https://github.com/GetStream/stream-chat-swiftui/pull/999)
27+
- Fix showing all the channel members in the more channel actions view [#1001](https://github.com/GetStream/stream-chat-swiftui/pull/1001)
2228

2329
# [4.89.1](https://github.com/GetStream/stream-chat-swiftui/releases/tag/4.89.1)
2430
_September 23, 2025_

DemoAppSwiftUI/ChannelHeader/CustomChannelHeader.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public struct CustomChannelHeader: ToolbarContent {
3131
.resizable()
3232
.scaledToFit()
3333
.frame(width: 24, height: 24)
34-
.foregroundColor(Color.white)
34+
.foregroundColor(Color(colors.navigationBarGlyph))
3535
.padding(.all, 8)
3636
.background(colors.navigationBarTintColor)
3737
.clipShape(Circle())

Sources/StreamChatSwiftUI/ChatChannel/ChannelInfo/ChatChannelInfoView.swift

Lines changed: 59 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -141,38 +141,7 @@ public struct ChatChannelInfoView<Factory: ViewFactory>: View, KeyboardReadable
141141
}
142142
}
143143
}
144-
.toolbarThemed {
145-
ToolbarItem(placement: .principal) {
146-
Group {
147-
if viewModel.showSingleMemberDMView {
148-
Text(viewModel.displayedParticipants.first?.chatUser.name ?? "")
149-
.font(fonts.bodyBold)
150-
.foregroundColor(Color(colors.navigationBarTitle))
151-
} else {
152-
ChannelTitleView(
153-
channel: viewModel.channel,
154-
shouldShowTypingIndicator: false
155-
)
156-
.id(viewModel.channelId)
157-
}
158-
}
159-
}
160-
161-
ToolbarItem(placement: .navigationBarTrailing) {
162-
if viewModel.shouldShowAddUserButton {
163-
Button {
164-
viewModel.addUsersShown = true
165-
} label: {
166-
Image(systemName: "person.badge.plus")
167-
.customizable()
168-
.foregroundColor(Color.white)
169-
.padding(.all, 8)
170-
.background(colors.tintColor)
171-
.clipShape(Circle())
172-
}
173-
}
174-
}
175-
}
144+
.modifier(ChatChannelInfoViewHeaderViewModifier(viewModel: viewModel))
176145
.onReceive(keyboardWillChangePublisher) { visible in
177146
viewModel.keyboardShown = visible
178147
}
@@ -184,3 +153,61 @@ public struct ChatChannelInfoView<Factory: ViewFactory>: View, KeyboardReadable
184153
viewModel.addUsersShown || viewModel.selectedParticipant != nil
185154
}
186155
}
156+
157+
struct ChatChannelInfoViewHeaderViewModifier: ViewModifier {
158+
@Injected(\.colors) private var colors
159+
@Injected(\.fonts) private var fonts
160+
161+
let viewModel: ChatChannelInfoViewModel
162+
163+
func body(content: Content) -> some View {
164+
if #available(iOS 26.0, *) {
165+
content
166+
.toolbarThemed {
167+
toolbar(glyphSize: 24)
168+
#if compiler(>=6.2)
169+
.sharedBackgroundVisibility(.hidden)
170+
#endif
171+
}
172+
} else {
173+
content
174+
.toolbarThemed {
175+
toolbar()
176+
}
177+
}
178+
}
179+
180+
@ToolbarContentBuilder func toolbar(glyphSize: CGFloat? = nil) -> some ToolbarContent {
181+
ToolbarItem(placement: .principal) {
182+
Group {
183+
if viewModel.showSingleMemberDMView {
184+
Text(viewModel.displayedParticipants.first?.chatUser.name ?? "")
185+
.font(fonts.bodyBold)
186+
.foregroundColor(Color(colors.navigationBarTitle))
187+
} else {
188+
ChannelTitleView(
189+
channel: viewModel.channel,
190+
shouldShowTypingIndicator: false
191+
)
192+
.id(viewModel.channelId)
193+
}
194+
}
195+
}
196+
197+
ToolbarItem(placement: .navigationBarTrailing) {
198+
if viewModel.shouldShowAddUserButton {
199+
Button {
200+
viewModel.addUsersShown = true
201+
} label: {
202+
Image(systemName: "person.badge.plus")
203+
.customizable()
204+
.frame(width: glyphSize, height: glyphSize)
205+
.foregroundColor(Color(colors.navigationBarGlyph))
206+
.padding(.all, 8)
207+
.background(colors.navigationBarTintColor)
208+
.clipShape(Circle())
209+
}
210+
}
211+
}
212+
}
213+
}

Sources/StreamChatSwiftUI/ChatChannel/ChannelInfo/ChatChannelInfoViewModel.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,19 +36,19 @@ import SwiftUI
3636
@Published public var addUsersShown = false
3737
@Published public var selectedParticipant: ParticipantInfo?
3838

39-
public var shouldShowLeaveConversationButton: Bool {
39+
open var shouldShowLeaveConversationButton: Bool {
4040
if channel.isDirectMessageChannel {
4141
channel.ownCapabilities.contains(.deleteChannel)
4242
} else {
4343
channel.ownCapabilities.contains(.leaveChannel)
4444
}
4545
}
4646

47-
public var canRenameChannel: Bool {
47+
open var canRenameChannel: Bool {
4848
channel.ownCapabilities.contains(.updateChannel)
4949
}
5050

51-
public var shouldShowAddUserButton: Bool {
51+
open var shouldShowAddUserButton: Bool {
5252
if channel.isDirectMessageChannel {
5353
false
5454
} else {

Sources/StreamChatSwiftUI/ChatChannel/MessageList/ImageAttachmentView.swift

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -423,9 +423,15 @@ extension ChatMessage {
423423
}
424424

425425
public struct MediaAttachment: Identifiable, Equatable {
426-
let url: URL
427-
let type: MediaAttachmentType
428-
var uploadingState: AttachmentUploadingState?
426+
public let url: URL
427+
public let type: MediaAttachmentType
428+
public var uploadingState: AttachmentUploadingState?
429+
430+
public init(url: URL, type: MediaAttachmentType, uploadingState: AttachmentUploadingState? = nil) {
431+
self.url = url
432+
self.type = type
433+
self.uploadingState = uploadingState
434+
}
429435

430436
public var id: String {
431437
url.absoluteString
@@ -476,9 +482,14 @@ extension MediaAttachment {
476482
}
477483
}
478484

479-
enum MediaAttachmentType {
480-
case image
481-
case video
485+
public struct MediaAttachmentType: RawRepresentable {
486+
public let rawValue: String
487+
public init(rawValue: String) {
488+
self.rawValue = rawValue
489+
}
490+
491+
public static let image = Self(rawValue: "image")
492+
public static let video = Self(rawValue: "video")
482493
}
483494

484495
/// Options for the gallery view.

Sources/StreamChatSwiftUI/ChatChannelList/MoreChannelActionsViewModel.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,7 @@ import UIKit
5353
) {
5454
self.channelActions = channelActions
5555
self.channel = channel
56-
members = channel.lastActiveMembers.filter { [unowned self] member in
57-
member.id != chatClient.currentUserId
58-
}
56+
members = channel.lastActiveMembers
5957
}
6058

6159
/// Returns an image for a member.

Sources/StreamChatSwiftUI/ColorPalette.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import UIKit
88
/// Provides the colors used throughout the SDK.
99
@MainActor public struct ColorPalette {
1010
public init() {
11+
navigationBarGlyph = .white
1112
navigationBarTitle = text
1213
navigationBarSubtitle = textLowEmphasis
1314
navigationBarTintColor = tintColor
@@ -104,6 +105,8 @@ import UIKit
104105

105106
// MARK: - Navigation Bar
106107

108+
public var navigationBarGlyph: UIColor
109+
107110
public var navigationBarTitle: UIColor {
108111
didSet {
109112
StreamConcurrency.onMain { [navigationBarTitle] in
Loading

StreamChatSwiftUITests/Tests/ChatChannelList/MoreChannelActionsViewModel_Tests.swift

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,23 @@ import XCTest
1616
streamChat = StreamChat(chatClient: chatClient, utils: utils)
1717
}
1818

19-
func test_moreActionsVM_membersLoaded() {
19+
func test_moreActionsVM_membersLoaded() throws {
2020
// Given
21+
let currentUserId = try XCTUnwrap(streamChat?.chatClient.currentUserId)
2122
let memberId: String = .unique
2223
let viewModel = makeMoreActionsViewModel(
23-
members: [.mock(id: memberId, isOnline: true)]
24+
members: [
25+
.mock(id: memberId, isOnline: true),
26+
.mock(id: currentUserId, isOnline: true)
27+
]
2428
)
2529

2630
// When
2731
let members = viewModel.members
2832

2933
// Then
30-
XCTAssert(members.count == 1)
31-
XCTAssert(members[0].id == memberId)
34+
XCTAssert(members.count == 2)
35+
XCTAssert(members.map(\.id) == [memberId, currentUserId])
3236
}
3337

3438
func test_moreActionsVM_chatHeaderInfo() {

StreamChatSwiftUITests/Tests/StreamChatTestCase.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import XCTest
4141
appearance.colors.navigationBarTitle = .blue
4242
appearance.colors.navigationBarSubtitle = .cyan
4343
appearance.colors.navigationBarBackground = .yellow
44+
appearance.colors.navigationBarGlyph = .green
4445
}
4546
}
4647
}

0 commit comments

Comments
 (0)