Fixes #978 - Message forwarding support

* Add support for message forwarding

* Move the TimelineProvider within the RoomProxy to avoid it going out of sync and have it automatically register for timeline updates on init

* Implement single selection form button style for message forwarding

* Add searching and filter out the source room from the list

* Fixed emoji screen initial search bar height

* Add view models tests

* Add changelog

* Update strings

* Tweaks following code review
This commit is contained in:
Stefan Ceriu
2023-06-21 12:10:14 +03:00
committed by GitHub
parent f624add018
commit 2ae8f471c6
36 changed files with 800 additions and 140 deletions
@@ -32,6 +32,7 @@ enum RoomScreenCoordinatorAction {
case presentRoomDetails
case presentEmojiPicker(itemID: String)
case presentRoomMemberDetails(member: RoomMemberProxyProtocol)
case presentMessageForwarding(itemID: String)
}
final class RoomScreenCoordinator: CoordinatorProtocol {
@@ -54,6 +55,7 @@ final class RoomScreenCoordinator: CoordinatorProtocol {
// MARK: - Public
// swiftlint:disable:next cyclomatic_complexity
func start() {
viewModel.callback = { [weak self] action in
guard let self else { return }
@@ -77,6 +79,8 @@ final class RoomScreenCoordinator: CoordinatorProtocol {
actionsSubject.send(.presentMediaUploadPreviewScreen(url))
case .displayRoomMemberDetails(let member):
actionsSubject.send(.presentRoomMemberDetails(member: member))
case .displayMessageForwarding(let itemID):
actionsSubject.send(.presentMessageForwarding(itemID: itemID))
}
}
}
@@ -28,6 +28,7 @@ enum RoomScreenViewModelAction {
case displayDocumentPicker
case displayMediaUploadPreviewScreen(url: URL)
case displayRoomMemberDetails(member: RoomMemberProxyProtocol)
case displayMessageForwarding(itemID: String)
}
enum RoomScreenComposerMode: Equatable {
@@ -330,12 +330,14 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
}
var actions: [TimelineItemMenuAction] = [
.reply, .copyPermalink
.reply
]
if timelineItem is EventBasedMessageTimelineItemProtocol {
actions.append(contentsOf: [.copy, .quote])
actions.append(contentsOf: [.forward(itemID: itemId), .copy, .quote])
}
actions.append(.copyPermalink)
if item.isEditable {
actions.append(.edit)
@@ -403,6 +405,8 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
let replyDetails = TimelineItemReplyDetails.loaded(sender: eventTimelineItem.sender, contentType: buildReplyContent(for: eventTimelineItem))
state.composerMode = .reply(itemID: eventTimelineItem.id, replyDetails: replyDetails)
case .forward(let itemID):
callback?(.displayMessageForwarding(itemID: itemID))
case .viewSource:
let debugInfo = timelineController.debugInfo(for: eventTimelineItem.id)
MXLog.info(debugInfo)
@@ -37,6 +37,7 @@ enum TimelineItemMenuAction: Identifiable, Hashable {
case copyPermalink
case redact
case reply
case forward(itemID: String)
case viewSource
case retryDecryption(sessionID: String)
case report
@@ -193,6 +194,10 @@ public struct TimelineItemMenu: View {
Button { send(action) } label: {
MenuLabel(title: L10n.actionReply, systemImageName: "arrowshape.turn.up.left")
}
case .forward:
Button { send(action) } label: {
MenuLabel(title: L10n.actionForward, systemImageName: "arrowshape.turn.up.right")
}
case .redact:
Button(role: .destructive) { send(action) } label: {
MenuLabel(title: L10n.actionRemove, systemImageName: "trash")