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
+47 -30
View File
@@ -46,6 +46,11 @@ class RoomProxy: RoomProxyProtocol {
updatesSubject.eraseToAnyPublisher()
}
var innerTimelineProvider: RoomTimelineProviderProtocol!
var timelineProvider: RoomTimelineProviderProtocol {
innerTimelineProvider
}
deinit {
Task { @MainActor [roomTimelineObservationToken, roomListItem] in
roomTimelineObservationToken?.cancel()
@@ -59,6 +64,30 @@ class RoomProxy: RoomProxyProtocol {
self.roomListItem = roomListItem
self.room = room
self.backgroundTaskService = backgroundTaskService
let settings = RoomSubscription(requiredState: [RequiredState(key: "m.room.name", value: ""),
RequiredState(key: "m.room.topic", value: ""),
RequiredState(key: "m.room.avatar", value: ""),
RequiredState(key: "m.room.canonical_alias", value: ""),
RequiredState(key: "m.room.join_rules", value: "")],
timelineLimit: UInt32(SlidingSyncConstants.defaultTimelineLimit))
roomListItem.subscribe(settings: settings)
let timelineListener = RoomTimelineListener { [weak self] timelineDiff in
self?.updatesSubject.send(timelineDiff)
}
self.timelineListener = timelineListener
let result = room.addTimelineListener(listener: timelineListener)
roomTimelineObservationToken = result.itemsStream
innerTimelineProvider = RoomTimelineProvider(currentItems: result.items, updatePublisher: updatesPublisher)
Task {
await fetchMembers()
await updateMembers()
}
}
lazy var id: String = room.id()
@@ -162,36 +191,6 @@ class RoomProxy: RoomProxyProtocol {
}
}
func registerTimelineListenerIfNeeded() -> Result<[TimelineItem], RoomProxyError> {
guard timelineListener == nil else {
return .failure(.roomListenerAlreadyRegistered)
}
let settings = RoomSubscription(requiredState: [RequiredState(key: "m.room.name", value: ""),
RequiredState(key: "m.room.topic", value: ""),
RequiredState(key: "m.room.avatar", value: ""),
RequiredState(key: "m.room.canonical_alias", value: ""),
RequiredState(key: "m.room.join_rules", value: "")],
timelineLimit: UInt32(SlidingSyncConstants.defaultTimelineLimit))
roomListItem.subscribe(settings: settings)
let timelineListener = RoomTimelineListener { [weak self] timelineDiff in
self?.updatesSubject.send(timelineDiff)
}
self.timelineListener = timelineListener
let result = room.addTimelineListener(listener: timelineListener)
roomTimelineObservationToken = result.itemsStream
Task {
await fetchMembers()
await updateMembers()
}
return .success(result.items)
}
func paginateBackwards(requestSize: UInt, untilNumberOfItems: UInt) async -> Result<Void, RoomProxyError> {
do {
try await Task.dispatch(on: .global()) {
@@ -219,6 +218,24 @@ class RoomProxy: RoomProxyProtocol {
}
}
}
func messageEventContent(for eventID: String) -> RoomMessageEventContent? {
try? room.getTimelineEventContentByEventId(eventId: eventID)
}
func sendMessageEventContent(_ messageContent: RoomMessageEventContent) async -> Result<Void, RoomProxyError> {
sendMessageBackgroundTask = backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
defer {
sendMessageBackgroundTask?.stop()
}
let transactionId = genTransactionId()
return await Task.dispatch(on: userInitiatedDispatchQueue) {
self.room.send(msg: messageContent, txnId: transactionId)
return .success(())
}
}
func sendMessage(_ message: String, inReplyTo eventID: String? = nil) async -> Result<Void, RoomProxyError> {
sendMessageBackgroundTask = backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
@@ -20,7 +20,6 @@ import MatrixRustSDK
enum RoomProxyError: Error {
case noMoreMessagesToBackPaginate
case roomListenerAlreadyRegistered
case failedPaginatingBackwards
case failedRetrievingMemberAvatarURL
case failedRetrievingMemberDisplayName
@@ -73,22 +72,23 @@ protocol RoomProxyProtocol {
var activeMembersCount: Int { get }
/// Publishes the room's updates.
/// The publisher starts publishing after the first call to `registerTimelineListenerIfNeeded()`
/// The thread on which this publisher sends the output isn't defined.
var updatesPublisher: AnyPublisher<TimelineDiff, Never> { get }
var timelineProvider: RoomTimelineProviderProtocol { get }
func loadAvatarURLForUserId(_ userId: String) async -> Result<URL?, RoomProxyError>
func loadDisplayNameForUserId(_ userId: String) async -> Result<String?, RoomProxyError>
/// Registers a timeline listener if not registered already.
/// Updates for this object will be published on the `updatesPublisher` publisher.
func registerTimelineListenerIfNeeded() -> Result<[TimelineItem], RoomProxyError>
func paginateBackwards(requestSize: UInt, untilNumberOfItems: UInt) async -> Result<Void, RoomProxyError>
func sendReadReceipt(for eventID: String) async -> Result<Void, RoomProxyError>
func messageEventContent(for eventID: String) -> RoomMessageEventContent?
func sendMessageEventContent(_ messageContent: RoomMessageEventContent) async -> Result<Void, RoomProxyError>
func sendMessage(_ message: String, inReplyTo eventID: String?) async -> Result<Void, RoomProxyError>
func sendReaction(_ reaction: String, to eventID: String) async -> Result<Void, RoomProxyError>