Skip to content

Commit 49a194c

Browse files
Added support for own capabilities in the UI
1 parent 715e012 commit 49a194c

File tree

9 files changed

+136
-41
lines changed

9 files changed

+136
-41
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
33

44
# Upcoming
55

6+
### ✅ Added
7+
- Support for channel own capabilities in the UI
8+
69
### 🐞 Fixed
710
- Renaming of a channel in ChannelInfo not persisting extra data
811
- Channel list item swipe gesture collision with native gesture

Sources/StreamChatSwiftUI/ChatChannel/ChannelInfo/ChatChannelInfoHelperViews.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ struct ChannelNameUpdateView: View {
118118
TextField(L10n.ChatInfo.Rename.placeholder, text: $viewModel.channelName)
119119
.font(fonts.body)
120120
.foregroundColor(Color(colors.text))
121+
.disabled(!viewModel.canRenameChannel)
121122

122123
Spacer()
123124

Sources/StreamChatSwiftUI/ChatChannel/ChannelInfo/ChatChannelInfoView.swift

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -66,32 +66,34 @@ public struct ChatChannelInfoView: View, KeyboardReadable {
6666
Alert.defaultErrorAlert
6767
}
6868

69-
ChatChannelInfoButton(
70-
title: viewModel.leaveButtonTitle,
71-
iconName: "person.fill.xmark",
72-
foregroundColor: Color(colors.alert)
73-
) {
74-
viewModel.leaveGroupAlertShown = true
75-
}
76-
.alert(isPresented: $viewModel.leaveGroupAlertShown) {
77-
let title = viewModel.leaveButtonTitle
78-
let message = viewModel.leaveConversationDescription
79-
let buttonTitle = viewModel.leaveButtonTitle
80-
81-
return Alert(
82-
title: Text(title),
83-
message: Text(message),
84-
primaryButton: .destructive(Text(buttonTitle)) {
85-
viewModel.leaveConversationTapped {
86-
if shownFromMessageList {
87-
notifyChannelDismiss()
88-
} else {
89-
presentationMode.wrappedValue.dismiss()
69+
if viewModel.shouldShowLeaveConversationButton {
70+
ChatChannelInfoButton(
71+
title: viewModel.leaveButtonTitle,
72+
iconName: "person.fill.xmark",
73+
foregroundColor: Color(colors.alert)
74+
) {
75+
viewModel.leaveGroupAlertShown = true
76+
}
77+
.alert(isPresented: $viewModel.leaveGroupAlertShown) {
78+
let title = viewModel.leaveButtonTitle
79+
let message = viewModel.leaveConversationDescription
80+
let buttonTitle = viewModel.leaveButtonTitle
81+
82+
return Alert(
83+
title: Text(title),
84+
message: Text(message),
85+
primaryButton: .destructive(Text(buttonTitle)) {
86+
viewModel.leaveConversationTapped {
87+
if shownFromMessageList {
88+
notifyChannelDismiss()
89+
} else {
90+
presentationMode.wrappedValue.dismiss()
91+
}
9092
}
91-
}
92-
},
93-
secondaryButton: .cancel()
94-
)
93+
},
94+
secondaryButton: .cancel()
95+
)
96+
}
9597
}
9698
}
9799
}

Sources/StreamChatSwiftUI/ChatChannel/ChannelInfo/ChatChannelInfoViewModel.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,15 @@ public class ChatChannelInfoViewModel: ObservableObject, ChatChannelControllerDe
3636
@Published public var keyboardShown = false
3737
@Published public var addUsersShown = false
3838

39+
public var shouldShowLeaveConversationButton: Bool {
40+
channel.ownCapabilities.contains(.deleteChannel)
41+
|| !channel.isDirectMessageChannel
42+
}
43+
44+
public var canRenameChannel: Bool {
45+
channel.ownCapabilities.contains(.updateChannel)
46+
}
47+
3948
private var channelController: ChatChannelController!
4049
private var memberListController: ChatChannelMemberListController!
4150
private var loadingUsers = false

Sources/StreamChatSwiftUI/ChatChannelList/ChatChannelSwipeableListItem.swift

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -255,14 +255,16 @@ public struct TrailingSwipeActionsView: View {
255255
.foregroundColor(Color(colors.text))
256256
.background(Color(colors.background1))
257257

258-
ActionItemButton(imageName: "trash", action: {
259-
withAnimation {
260-
rightButtonTapped(channel)
261-
}
262-
})
263-
.frame(width: buttonWidth)
264-
.foregroundColor(Color(colors.textInverted))
265-
.background(Color(colors.alert))
258+
if channel.ownCapabilities.contains(.deleteChannel) {
259+
ActionItemButton(imageName: "trash", action: {
260+
withAnimation {
261+
rightButtonTapped(channel)
262+
}
263+
})
264+
.frame(width: buttonWidth)
265+
.foregroundColor(Color(colors.textInverted))
266+
.background(Color(colors.alert))
267+
}
266268
}
267269
}
268270
.opacity(self.offsetX < -5 ? 1 : 0)

Sources/StreamChatSwiftUI/ChatChannelList/DefaultChannelActions.swift

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,15 @@ extension ChannelAction {
5757
}
5858
}
5959

60-
let deleteConversation = deleteAction(
61-
for: channel,
62-
chatClient: chatClient,
63-
onDismiss: onDismiss,
64-
onError: onError
65-
)
66-
actions.append(deleteConversation)
60+
if channel.ownCapabilities.contains(.deleteChannel) {
61+
let deleteConversation = deleteAction(
62+
for: channel,
63+
chatClient: chatClient,
64+
onDismiss: onDismiss,
65+
onError: onError
66+
)
67+
actions.append(deleteConversation)
68+
}
6769

6870
let cancel = ChannelAction(
6971
title: L10n.Alert.Actions.cancel,

Sources/StreamChatSwiftUI/DefaultViewFactory.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ extension ViewFactory {
8888
channelListItem: listItem,
8989
swipedChannelId: swipedChannelId,
9090
channel: channel,
91+
numberOfTrailingItems: channel.ownCapabilities.contains(.deleteChannel) ? 2 : 1,
9192
trailingRightButtonTapped: trailingSwipeRightButtonTapped,
9293
trailingLeftButtonTapped: trailingSwipeLeftButtonTapped,
9394
leadingSwipeButtonTapped: leadingSwipeButtonTapped

StreamChatSwiftUITests/Tests/ChatChannel/ChannelInfo/ChatChannelInfoViewModel_Tests.swift

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,16 +186,86 @@ class ChatChannelInfoViewModel_Tests: StreamChatTestCase {
186186
XCTAssert(viewModel.channelName == newName)
187187
}
188188

189+
func test_chatChannelInfoVM_canRenameGroup() {
190+
// Given
191+
let channel = mockGroup(with: 5)
192+
let viewModel = ChatChannelInfoViewModel(channel: channel)
193+
194+
// When
195+
let canRenameChannel = viewModel.canRenameChannel
196+
197+
// Then
198+
XCTAssert(canRenameChannel == true)
199+
}
200+
201+
func test_chatChannelInfoVM_canNotRenameGroup() {
202+
// Given
203+
let channel = mockGroup(with: 5, updateCapabilities: false)
204+
let viewModel = ChatChannelInfoViewModel(channel: channel)
205+
206+
// When
207+
let canRenameChannel = viewModel.canRenameChannel
208+
209+
// Then
210+
XCTAssert(canRenameChannel == false)
211+
}
212+
213+
func test_chatChannelInfoVM_leaveButtonShownInGroup() {
214+
// Given
215+
let channel = mockGroup(with: 5)
216+
let viewModel = ChatChannelInfoViewModel(channel: channel)
217+
218+
// When
219+
let leaveButton = viewModel.shouldShowLeaveConversationButton
220+
221+
// Then
222+
XCTAssert(leaveButton == true)
223+
}
224+
225+
func test_chatChannelInfoVM_leaveButtonShownInDM() {
226+
// Given
227+
let channel = ChatChannel.mock(
228+
cid: .unique,
229+
name: "Test",
230+
ownCapabilities: [.deleteChannel]
231+
)
232+
let viewModel = ChatChannelInfoViewModel(channel: channel)
233+
234+
// When
235+
let leaveButton = viewModel.shouldShowLeaveConversationButton
236+
237+
// Then
238+
XCTAssert(leaveButton == true)
239+
}
240+
241+
func test_chatChannelInfoVM_leaveButtonHiddenInDM() {
242+
// Given
243+
let channel = ChatChannel.mockDMChannel()
244+
let viewModel = ChatChannelInfoViewModel(channel: channel)
245+
246+
// When
247+
let leaveButton = viewModel.shouldShowLeaveConversationButton
248+
249+
// Then
250+
XCTAssert(leaveButton == false)
251+
}
252+
189253
// MARK: - private
190254

191-
private func mockGroup(with memberCount: Int) -> ChatChannel {
255+
private func mockGroup(with memberCount: Int, updateCapabilities: Bool = true) -> ChatChannel {
192256
let cid: ChannelId = .unique
193257
let activeMembers = ChannelInfoMockUtils.setupMockMembers(
194258
count: memberCount,
195259
currentUserId: chatClient.currentUserId!
196260
)
261+
var capabilities = Set<ChannelCapability>()
262+
if updateCapabilities {
263+
capabilities.insert(.updateChannel)
264+
capabilities.insert(.deleteChannel)
265+
}
197266
let channel = ChatChannel.mock(
198267
cid: cid,
268+
ownCapabilities: capabilities,
199269
lastActiveMembers: activeMembers,
200270
memberCount: activeMembers.count
201271
)

StreamChatSwiftUITests/Tests/ChatChannel/ChannelInfo/ChatChannelInfoView_Tests.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ class ChatChannelInfoView_Tests: StreamChatTestCase {
7979
let group = ChatChannel.mock(
8080
cid: .unique,
8181
name: "Test Group",
82+
ownCapabilities: [.deleteChannel, .updateChannel],
8283
lastActiveMembers: members,
8384
memberCount: members.count
8485
)
@@ -101,6 +102,7 @@ class ChatChannelInfoView_Tests: StreamChatTestCase {
101102
let group = ChatChannel.mock(
102103
cid: .unique,
103104
name: "Test Group",
105+
ownCapabilities: [.deleteChannel, .updateChannel],
104106
lastActiveMembers: members,
105107
memberCount: members.count
106108
)
@@ -123,6 +125,7 @@ class ChatChannelInfoView_Tests: StreamChatTestCase {
123125
let group = ChatChannel.mock(
124126
cid: .unique,
125127
name: "Test Group",
128+
ownCapabilities: [.deleteChannel, .updateChannel],
126129
lastActiveMembers: members,
127130
memberCount: members.count
128131
)
@@ -147,6 +150,7 @@ class ChatChannelInfoView_Tests: StreamChatTestCase {
147150
let group = ChatChannel.mock(
148151
cid: .unique,
149152
name: "Test Group",
153+
ownCapabilities: [.deleteChannel, .updateChannel],
150154
lastActiveMembers: members,
151155
memberCount: members.count
152156
)
@@ -175,6 +179,7 @@ class ChatChannelInfoView_Tests: StreamChatTestCase {
175179
let group = ChatChannel.mock(
176180
cid: .unique,
177181
name: "Test Group",
182+
ownCapabilities: [.deleteChannel, .updateChannel],
178183
lastActiveMembers: members,
179184
memberCount: members.count
180185
)

0 commit comments

Comments
 (0)