mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 16:10:20 +00:00
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:
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user