Skip to content

Commit 73a5b4e

Browse files
Added message actions for user blocking (#532)
1 parent 9938819 commit 73a5b4e

File tree

7 files changed

+165
-3
lines changed

7 files changed

+165
-3
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+
- Added message actions for user blocking [#532](https://github.com/GetStream/stream-chat-swiftui/pull/532)
8+
69
### 🐞 Fixed
710
- Smoother and more performant view updates in channel and message lists [#522](https://github.com/GetStream/stream-chat-swiftui/pull/522)
811

Sources/StreamChatSwiftUI/ChatChannel/MessageList/MessageListConfig.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ public struct MessageListConfig {
3030
uniqueReactionsEnabled: Bool = false,
3131
localLinkDetectionEnabled: Bool = true,
3232
isMessageEditedLabelEnabled: Bool = true,
33-
markdownSupportEnabled: Bool = true
33+
markdownSupportEnabled: Bool = true,
34+
userBlockingEnabled: Bool = false
3435
) {
3536
self.messageListType = messageListType
3637
self.typingIndicatorPlacement = typingIndicatorPlacement
@@ -54,6 +55,7 @@ public struct MessageListConfig {
5455
self.localLinkDetectionEnabled = localLinkDetectionEnabled
5556
self.isMessageEditedLabelEnabled = isMessageEditedLabelEnabled
5657
self.markdownSupportEnabled = markdownSupportEnabled
58+
self.userBlockingEnabled = userBlockingEnabled
5759
}
5860

5961
public let messageListType: MessageListType
@@ -78,6 +80,7 @@ public struct MessageListConfig {
7880
public let localLinkDetectionEnabled: Bool
7981
public let isMessageEditedLabelEnabled: Bool
8082
public let markdownSupportEnabled: Bool
83+
public let userBlockingEnabled: Bool
8184
}
8285

8386
/// Contains information about the message paddings.

Sources/StreamChatSwiftUI/ChatChannel/Reactions/MessageActions/DefaultMessageActions.swift

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,32 @@ extension MessageAction {
178178
messageActions.append(muteAction)
179179
}
180180
}
181+
182+
if InjectedValues[\.utils].messageListConfig.userBlockingEnabled {
183+
let userController = chatClient.currentUserController()
184+
let blockedUserIds = userController.dataStore.currentUser()?.blockedUserIds ?? []
185+
if blockedUserIds.contains(message.author.id) {
186+
let unblockAction = unblockUserAction(
187+
for: message,
188+
channel: channel,
189+
chatClient: chatClient,
190+
userToUnblock: message.author,
191+
onFinish: onFinish,
192+
onError: onError
193+
)
194+
messageActions.append(unblockAction)
195+
} else {
196+
let blockAction = blockUserAction(
197+
for: message,
198+
channel: channel,
199+
chatClient: chatClient,
200+
userToBlock: message.author,
201+
onFinish: onFinish,
202+
onError: onError
203+
)
204+
messageActions.append(blockAction)
205+
}
206+
}
181207
}
182208

183209
return messageActions
@@ -519,6 +545,46 @@ extension MessageAction {
519545

520546
return muteUser
521547
}
548+
549+
private static func blockUserAction(
550+
for message: ChatMessage,
551+
channel: ChatChannel,
552+
chatClient: ChatClient,
553+
userToBlock: ChatUser,
554+
onFinish: @escaping (MessageActionInfo) -> Void,
555+
onError: @escaping (Error) -> Void
556+
) -> MessageAction {
557+
let blockController = chatClient.userController(userId: userToBlock.id)
558+
let blockAction = {
559+
blockController.block { error in
560+
if let error = error {
561+
onError(error)
562+
} else {
563+
onFinish(
564+
MessageActionInfo(
565+
message: message,
566+
identifier: "block"
567+
)
568+
)
569+
}
570+
}
571+
}
572+
573+
let blockUser = MessageAction(
574+
id: MessageActionId.block,
575+
title: L10n.Message.Actions.userBlock,
576+
iconName: "circle.slash",
577+
action: blockAction,
578+
confirmationPopup: ConfirmationPopup(
579+
title: L10n.Message.Actions.userBlock,
580+
message: L10n.Message.Actions.UserBlock.confirmationMessage,
581+
buttonTitle: L10n.Alert.Actions.ok
582+
),
583+
isDestructive: true
584+
)
585+
586+
return blockUser
587+
}
522588

523589
private static func unmuteAction(
524590
for message: ChatMessage,
@@ -555,6 +621,46 @@ extension MessageAction {
555621

556622
return unmuteUser
557623
}
624+
625+
private static func unblockUserAction(
626+
for message: ChatMessage,
627+
channel: ChatChannel,
628+
chatClient: ChatClient,
629+
userToUnblock: ChatUser,
630+
onFinish: @escaping (MessageActionInfo) -> Void,
631+
onError: @escaping (Error) -> Void
632+
) -> MessageAction {
633+
let blockController = chatClient.userController(userId: userToUnblock.id)
634+
let unblockAction = {
635+
blockController.unblock { error in
636+
if let error = error {
637+
onError(error)
638+
} else {
639+
onFinish(
640+
MessageActionInfo(
641+
message: message,
642+
identifier: "unblock"
643+
)
644+
)
645+
}
646+
}
647+
}
648+
649+
let unblockUser = MessageAction(
650+
id: MessageActionId.unblock,
651+
title: L10n.Message.Actions.userUnblock,
652+
iconName: "circle.slash",
653+
action: unblockAction,
654+
confirmationPopup: ConfirmationPopup(
655+
title: L10n.Message.Actions.userUnblock,
656+
message: L10n.Message.Actions.UserUnblock.confirmationMessage,
657+
buttonTitle: L10n.Alert.Actions.ok
658+
),
659+
isDestructive: false
660+
)
661+
662+
return unblockUser
663+
}
558664

559665
private static func resendMessageAction(
560666
for message: ChatMessage,
@@ -669,4 +775,6 @@ public enum MessageActionId {
669775
public static let unpin = "unpin_message_action"
670776
public static let resend = "resend_message_action"
671777
public static let markUnread = "mark_unread_action"
778+
public static let block = "block_user_action"
779+
public static let unblock = "unblock_user_action"
672780
}

Sources/StreamChatSwiftUI/Generated/L10n.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,14 @@ internal enum L10n {
371371
/// Flag Message
372372
internal static var confirmationTitle: String { L10n.tr("Localizable", "message.actions.flag.confirmation-title") }
373373
}
374+
internal enum UserBlock {
375+
/// Are you sure you want to block this user?
376+
internal static var confirmationMessage: String { L10n.tr("Localizable", "message.actions.user-block.confirmation-message") }
377+
}
378+
internal enum UserUnblock {
379+
/// Are you sure you want to unblock this user?
380+
internal static var confirmationMessage: String { L10n.tr("Localizable", "message.actions.user-unblock.confirmation-message") }
381+
}
374382
}
375383
internal enum Bounce {
376384
/// Message was bounced

Sources/StreamChatSwiftUI/Resources/en.lproj/Localizable.strings

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@
4040
"message.actions.mark-unread" = "Mark Unread";
4141
"message.actions.flag.confirmation-title" = "Flag Message";
4242
"message.actions.flag.confirmation-message" = "Do you want to send a copy of this message to a moderator for further investigation?";
43+
"message.actions.user-block.confirmation-message" = "Are you sure you want to block this user?";
44+
"message.actions.user-unblock.confirmation-message" = "Are you sure you want to unblock this user?";
4345

4446
"messageList.typingIndicator.typing-unknown" = "Someone is typing";
4547

StreamChatSwiftUI.xcodeproj/project.pbxproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3704,8 +3704,8 @@
37043704
isa = XCRemoteSwiftPackageReference;
37053705
repositoryURL = "https://github.com/GetStream/stream-chat-swift.git";
37063706
requirement = {
3707-
kind = upToNextMajorVersion;
3708-
minimumVersion = 4.58.0;
3707+
branch = develop;
3708+
kind = branch;
37093709
};
37103710
};
37113711
E3A1C01A282BAC66002D1E26 /* XCRemoteSwiftPackageReference "sentry-cocoa" */ = {

StreamChatSwiftUITests/Tests/ChatChannel/MessageActions_Tests.swift

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,44 @@ class MessageActions_Tests: StreamChatTestCase {
7272
XCTAssert(messageActions[5].title == "Flag Message")
7373
XCTAssert(messageActions[6].title == "Mute User")
7474
}
75+
76+
func test_messageActions_otherUserDefaultBlockingEnabled() {
77+
// Given
78+
streamChat = StreamChat(
79+
chatClient: chatClient,
80+
utils: .init(messageListConfig: .init(userBlockingEnabled: true))
81+
)
82+
let channel = ChatChannel.mockDMChannel()
83+
let message = ChatMessage.mock(
84+
id: .unique,
85+
cid: channel.cid,
86+
text: "Test",
87+
author: .mock(id: .unique),
88+
isSentByCurrentUser: false
89+
)
90+
let factory = DefaultViewFactory.shared
91+
92+
// When
93+
let messageActions = MessageAction.defaultActions(
94+
factory: factory,
95+
for: message,
96+
channel: channel,
97+
chatClient: chatClient,
98+
onFinish: { _ in },
99+
onError: { _ in }
100+
)
101+
102+
// Then
103+
XCTAssert(messageActions.count == 8)
104+
XCTAssert(messageActions[0].title == "Reply")
105+
XCTAssert(messageActions[1].title == "Thread Reply")
106+
XCTAssert(messageActions[2].title == "Pin to conversation")
107+
XCTAssert(messageActions[3].title == "Copy Message")
108+
XCTAssert(messageActions[4].title == "Mark Unread")
109+
XCTAssert(messageActions[5].title == "Flag Message")
110+
XCTAssert(messageActions[6].title == "Mute User")
111+
XCTAssert(messageActions[7].title == "Block User")
112+
}
75113

76114
func test_messageActions_currentUserPinned() {
77115
// Given

0 commit comments

Comments
 (0)