Skip to content

Commit 0bc559a

Browse files
added message thread in message actions
1 parent 862ecea commit 0bc559a

File tree

12 files changed

+77
-31
lines changed

12 files changed

+77
-31
lines changed

Sources/StreamChatSwiftUI/ChatChannel/ChatChannelView.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ public struct ChatChannelView<Factory: ViewFactory>: View {
7676
.overlay(
7777
viewModel.reactionsShown ?
7878
factory.makeReactionsOverlayView(
79+
channel: viewModel.channel,
7980
currentSnapshot: viewModel.currentSnapshot!,
8081
messageDisplayInfo: messageDisplayInfo!,
8182
onBackgroundTap: {
@@ -86,5 +87,8 @@ public struct ChatChannelView<Factory: ViewFactory>: View {
8687
.edgesIgnoringSafeArea(.all)
8788
: nil
8889
)
90+
.onAppear {
91+
viewModel.reactionsShown = false
92+
}
8993
}
9094
}

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

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
//
44

55
import StreamChat
6+
import SwiftUI
67

78
extension MessageAction {
89
/// Returns the default message actions.
@@ -12,38 +13,35 @@ extension MessageAction {
1213
/// - chatClient: the chat client.
1314
/// - onDimiss: called when the action is executed.
1415
/// - Returns: array of `MessageAction`.
15-
public static func defaultActions(
16+
public static func defaultActions<Factory: ViewFactory>(
17+
factory: Factory,
1618
for message: ChatMessage,
19+
channel: ChatChannel,
1720
chatClient: ChatClient,
1821
onDismiss: @escaping () -> Void,
1922
onError: @escaping (Error) -> Void
2023
) -> [MessageAction] {
21-
guard let channelId = message.cid else {
22-
return []
23-
}
24-
2524
var messageActions = [MessageAction]()
2625

2726
if !message.isPartOfThread {
28-
let replyThreadAction = {
29-
onDismiss()
30-
}
31-
32-
let replyThread = MessageAction(
27+
var replyThread = MessageAction(
3328
title: L10n.Message.Actions.threadReply,
3429
iconName: "icn_thread_reply",
35-
action: replyThreadAction,
30+
action: onDismiss,
3631
confirmationPopup: nil,
3732
isDestructive: false
3833
)
3934

35+
let destination = factory.makeMessageThreadDestination()
36+
replyThread.navigationDestination = AnyView(destination(channel, message))
37+
4038
messageActions.append(replyThread)
4139
}
4240

4341
if message.isSentByCurrentUser {
4442
let deleteAction = deleteMessageAction(
4543
for: message,
46-
channelId: channelId,
44+
channel: channel,
4745
chatClient: chatClient,
4846
onDismiss: onDismiss,
4947
onError: onError
@@ -53,7 +51,7 @@ extension MessageAction {
5351
} else {
5452
let flagAction = flagMessageAction(
5553
for: message,
56-
channelId: channelId,
54+
channel: channel,
5755
chatClient: chatClient,
5856
onDismiss: onDismiss,
5957
onError: onError
@@ -67,13 +65,13 @@ extension MessageAction {
6765

6866
private static func deleteMessageAction(
6967
for message: ChatMessage,
70-
channelId: ChannelId,
68+
channel: ChatChannel,
7169
chatClient: ChatClient,
7270
onDismiss: @escaping () -> Void,
7371
onError: @escaping (Error) -> Void
7472
) -> MessageAction {
7573
let messageController = chatClient.messageController(
76-
cid: channelId,
74+
cid: channel.cid,
7775
messageId: message.id
7876
)
7977

@@ -106,13 +104,13 @@ extension MessageAction {
106104

107105
private static func flagMessageAction(
108106
for message: ChatMessage,
109-
channelId: ChannelId,
107+
channel: ChatChannel,
110108
chatClient: ChatClient,
111109
onDismiss: @escaping () -> Void,
112110
onError: @escaping (Error) -> Void
113111
) -> MessageAction {
114112
let messageController = chatClient.messageController(
115-
cid: channelId,
113+
cid: channel.cid,
116114
messageId: message.id
117115
)
118116

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

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,32 @@ public struct MessageActionsView: View {
2121
VStack(spacing: 0) {
2222
ForEach(viewModel.messageActions) { action in
2323
VStack(spacing: 0) {
24-
Button {
25-
if action.confirmationPopup != nil {
26-
viewModel.alertAction = action
27-
} else {
28-
action.action()
24+
if let destination = action.navigationDestination {
25+
NavigationLink {
26+
destination
27+
} label: {
28+
ActionItemView(
29+
title: action.title,
30+
iconName: action.iconName,
31+
isDestructive: action.isDestructive,
32+
boldTitle: false
33+
)
34+
}
35+
} else {
36+
Button {
37+
if action.confirmationPopup != nil {
38+
viewModel.alertAction = action
39+
} else {
40+
action.action()
41+
}
42+
} label: {
43+
ActionItemView(
44+
title: action.title,
45+
iconName: action.iconName,
46+
isDestructive: action.isDestructive,
47+
boldTitle: false
48+
)
2949
}
30-
} label: {
31-
ActionItemView(
32-
title: action.title,
33-
iconName: action.iconName,
34-
isDestructive: action.isDestructive,
35-
boldTitle: false
36-
)
3750
}
3851

3952
Divider()

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ public struct MessageAction: Identifiable, Equatable {
3030
public var action: () -> Void
3131
public let confirmationPopup: ConfirmationPopup?
3232
public let isDestructive: Bool
33+
public var navigationDestination: AnyView?
3334

3435
public init(
3536
title: String,

Sources/StreamChatSwiftUI/ChatChannel/Reactions/ReactionsOverlayView.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@
22
// Copyright © 2021 Stream.io Inc. All rights reserved.
33
//
44

5+
import StreamChat
56
import SwiftUI
67

78
public struct ReactionsOverlayView<Factory: ViewFactory>: View {
89
@StateObject var viewModel: ReactionsOverlayViewModel
910

1011
var factory: Factory
12+
var channel: ChatChannel
1113
var currentSnapshot: UIImage
1214
var messageDisplayInfo: MessageDisplayInfo
1315
var onBackgroundTap: () -> Void
@@ -19,6 +21,7 @@ public struct ReactionsOverlayView<Factory: ViewFactory>: View {
1921

2022
public init(
2123
factory: Factory,
24+
channel: ChatChannel,
2225
currentSnapshot: UIImage,
2326
messageDisplayInfo: MessageDisplayInfo,
2427
onBackgroundTap: @escaping () -> Void
@@ -28,12 +31,14 @@ public struct ReactionsOverlayView<Factory: ViewFactory>: View {
2831
message: messageDisplayInfo.message
2932
)
3033
)
34+
self.channel = channel
3135
self.factory = factory
3236
self.currentSnapshot = currentSnapshot
3337
self.messageDisplayInfo = messageDisplayInfo
3438
self.onBackgroundTap = onBackgroundTap
3539
messageActionsCount = factory.supportedMessageActions(
3640
for: messageDisplayInfo.message,
41+
channel: channel,
3742
onDismiss: {},
3843
onError: { _ in }
3944
).count
@@ -85,6 +90,7 @@ public struct ReactionsOverlayView<Factory: ViewFactory>: View {
8590

8691
factory.makeMessageActionsView(
8792
for: messageDisplayInfo.message,
93+
channel: channel,
8894
onDismiss: onBackgroundTap,
8995
onError: { _ in
9096
viewModel.errorShown = true

Sources/StreamChatSwiftUI/DefaultViewFactory.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,11 +396,14 @@ extension ViewFactory {
396396

397397
public func supportedMessageActions(
398398
for message: ChatMessage,
399+
channel: ChatChannel,
399400
onDismiss: @escaping () -> Void,
400401
onError: @escaping (Error) -> Void
401402
) -> [MessageAction] {
402403
MessageAction.defaultActions(
404+
factory: self,
403405
for: message,
406+
channel: channel,
404407
chatClient: chatClient,
405408
onDismiss: onDismiss,
406409
onError: onError
@@ -409,11 +412,13 @@ extension ViewFactory {
409412

410413
public func makeMessageActionsView(
411414
for message: ChatMessage,
415+
channel: ChatChannel,
412416
onDismiss: @escaping () -> Void,
413417
onError: @escaping (Error) -> Void
414418
) -> some View {
415419
let messageActions = supportedMessageActions(
416420
for: message,
421+
channel: channel,
417422
onDismiss: onDismiss,
418423
onError: onError
419424
)
@@ -428,12 +433,14 @@ extension ViewFactory {
428433
}
429434

430435
public func makeReactionsOverlayView(
436+
channel: ChatChannel,
431437
currentSnapshot: UIImage,
432438
messageDisplayInfo: MessageDisplayInfo,
433439
onBackgroundTap: @escaping () -> Void
434440
) -> some View {
435441
ReactionsOverlayView(
436442
factory: self,
443+
channel: channel,
437444
currentSnapshot: currentSnapshot,
438445
messageDisplayInfo: messageDisplayInfo,
439446
onBackgroundTap: onBackgroundTap

Sources/StreamChatSwiftUI/ViewFactory.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,11 +375,13 @@ public protocol ViewFactory: AnyObject {
375375
/// Returns the supported message actions.
376376
/// - Parameters:
377377
/// - message: the message where the actions are applied.
378+
/// - channel: the channel of the message.
378379
/// - onDismiss: handler when the more actions view is dismissed.
379380
/// - onError: handler when an error happened.
380381
/// - Returns: list of `MessageAction` items.
381382
func supportedMessageActions(
382383
for message: ChatMessage,
384+
channel: ChatChannel,
383385
onDismiss: @escaping () -> Void,
384386
onError: @escaping (Error) -> Void
385387
) -> [MessageAction]
@@ -388,11 +390,13 @@ public protocol ViewFactory: AnyObject {
388390
/// Creates the message actions view.
389391
/// - Parameters:
390392
/// - message: the message where the actions are applied.
393+
/// - channel: the channel of the message.
391394
/// - onDismiss: handler when the more actions view is dismissed.
392395
/// - onError: handler when an error happened.
393396
/// - Returns: view displayed in the message actions slot.
394397
func makeMessageActionsView(
395398
for message: ChatMessage,
399+
channel: ChatChannel,
396400
onDismiss: @escaping () -> Void,
397401
onError: @escaping (Error) -> Void
398402
) -> MessageActionsViewType
@@ -408,11 +412,13 @@ public protocol ViewFactory: AnyObject {
408412
associatedtype ReactionsOverlayViewType
409413
/// Creates the reactions overlay view.
410414
/// - Parameters:
415+
/// - channel: the channel of the message.
411416
/// - currentSnapshot: current snapshot of the screen (in case blur effect is needed).
412417
/// - messageDisplayInfo: information about the displayed message.
413418
/// - onBackgroundTap: called when the background is tapped (to dismiss the view).
414419
/// - Returns: view displayed in the reactions overlay slot.
415420
func makeReactionsOverlayView(
421+
channel: ChatChannel,
416422
currentSnapshot: UIImage,
417423
messageDisplayInfo: MessageDisplayInfo,
418424
onBackgroundTap: @escaping () -> Void

StreamChatSwiftUITests/Tests/ChatChannel/MessageActionsViewModel_Tests.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,20 @@ class MessageActionsViewModel_Tests: XCTestCase {
2424
func test_messageActionsViewModel_confirmationAlertShown() {
2525
// Given
2626
let actions = MessageAction.defaultActions(
27+
factory: DefaultViewFactory.shared,
2728
for: .mock(
2829
id: .unique,
2930
cid: .unique,
3031
text: "test",
3132
author: .mock(id: .unique)
3233
),
34+
channel: .mockDMChannel(),
3335
chatClient: chatClient,
3436
onDismiss: {},
3537
onError: { _ in }
3638
)
3739
let viewModel = MessageActionsViewModel(messageActions: actions)
38-
let action = actions[0]
40+
let action = actions[1]
3941

4042
// When
4143
viewModel.alertAction = action

StreamChatSwiftUITests/Tests/ChatChannel/MessageComposerViewModel_Tests.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,10 @@ class MessageComposerViewModel_Tests: XCTestCase {
315315

316316
private func makeComposerViewModel() -> MessageComposerViewModel {
317317
let channelController = makeChannelController()
318-
let viewModel = MessageComposerViewModel(channelController: channelController)
318+
let viewModel = MessageComposerViewModel(
319+
channelController: channelController,
320+
messageController: nil
321+
)
319322
return viewModel
320323
}
321324

StreamChatSwiftUITests/Tests/ChatChannel/ReactionsOverlayView_Tests.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ class ReactionsOverlayView_Tests: XCTestCase {
3535
let view = VerticallyCenteredView {
3636
ReactionsOverlayView(
3737
factory: DefaultViewFactory.shared,
38+
channel: .mockDMChannel(),
3839
currentSnapshot: UIImage(systemName: "checkmark")!,
3940
messageDisplayInfo: MessageDisplayInfo(
4041
message: .mock(id: .unique, cid: .unique, text: "test", author: .mock(id: .unique)),

0 commit comments

Comments
 (0)