Knock and knocked state for the join room screen (#3424)

* JoinRoomScreen ui for knocking

* code improvement

* updated previews

* added knocked state with tests

* send knock request

* Apply suggestions from code review

Co-authored-by: Doug <6060466+pixlwave@users.noreply.github.com>

* pr comments

---------

Co-authored-by: Doug <6060466+pixlwave@users.noreply.github.com>
This commit is contained in:
Mauro
2024-10-17 16:00:51 +02:00
committed by GitHub
parent 1723542d6a
commit bd4ecdd060
24 changed files with 627 additions and 48 deletions
@@ -415,6 +415,30 @@ class ClientProxy: ClientProxyProtocol {
}
}
func knockRoom(_ roomID: String, message: String?) async -> Result<Void, ClientProxyError> {
do {
// TODO: It should also include a message but the API for is not available yet
let _ = try await client.knock(roomIdOrAlias: roomID)
await waitForRoomToSync(roomID: roomID, timeout: .seconds(30))
return .success(())
} catch {
MXLog.error("Failed knocking roomID: \(roomID) with error: \(error)")
return .failure(.sdkError(error))
}
}
func knockRoomAlias(_ roomAlias: String, message: String?) async -> Result<Void, ClientProxyError> {
do {
// TODO: It should also include a message but the API for is not available yet
let room = try await client.knock(roomIdOrAlias: roomAlias)
await waitForRoomToSync(roomID: room.id(), timeout: .seconds(30))
return .success(())
} catch {
MXLog.error("Failed knocking roomAlias: \(roomAlias) with error: \(error)")
return .failure(.sdkError(error))
}
}
func uploadMedia(_ media: MediaInfo) async -> Result<String, ClientProxyError> {
guard let mimeType = media.mimeType else {
MXLog.error("Failed uploading media, invalid mime type: \(media)")
@@ -846,9 +870,17 @@ class ClientProxy: ClientProxyProtocol {
let roomListItem = try roomListService.room(roomId: roomID)
switch roomListItem.membership() {
case .invited, .knocked:
case .invited:
return try .invited(InvitedRoomProxy(roomListItem: roomListItem,
room: roomListItem.invitedRoom()))
case .knocked:
if appSettings.knockingEnabled {
return try .knocked(KnockedRoomProxy(roomListItem: roomListItem,
room: roomListItem.invitedRoom()))
} else {
return try .invited(InvitedRoomProxy(roomListItem: roomListItem,
room: roomListItem.invitedRoom()))
}
case .joined:
if roomListItem.isTimelineInitialized() == false {
try await roomListItem.initTimeline(eventTypeFilter: eventFilters, internalIdPrefix: nil)
@@ -145,6 +145,10 @@ protocol ClientProxyProtocol: AnyObject, MediaLoaderProtocol {
func joinRoomAlias(_ roomAlias: String) async -> Result<Void, ClientProxyError>
func knockRoom(_ roomID: String, message: String?) async -> Result<Void, ClientProxyError>
func knockRoomAlias(_ roomAlias: String, message: String?) async -> Result<Void, ClientProxyError>
func uploadMedia(_ media: MediaInfo) async -> Result<String, ClientProxyError>
func roomForIdentifier(_ identifier: String) async -> RoomProxyType?
@@ -0,0 +1,82 @@
//
// Copyright 2024 New Vector Ltd.
//
// SPDX-License-Identifier: AGPL-3.0-only
// Please see LICENSE in the repository root for full details.
//
import Foundation
import MatrixRustSDK
import UIKit
class KnockedRoomProxy: KnockedRoomProxyProtocol {
private let roomListItem: RoomListItemProtocol
private let room: RoomProtocol
// A room identifier is constant and lazy stops it from being fetched
// multiple times over FFI
lazy var id: String = room.id()
var canonicalAlias: String? {
room.canonicalAlias()
}
var ownUserID: String {
room.ownUserId()
}
var name: String? {
roomListItem.displayName()
}
var topic: String? {
room.topic()
}
var avatarURL: URL? {
roomListItem.avatarUrl().flatMap(URL.init(string:))
}
var avatar: RoomAvatar {
if isDirect, avatarURL == nil {
let heroes = room.heroes()
if heroes.count == 1 {
return .heroes(heroes.map(UserProfileProxy.init))
}
}
return .room(id: id, name: name, avatarURL: avatarURL)
}
var isDirect: Bool {
room.isDirect()
}
var isPublic: Bool {
room.isPublic()
}
var isSpace: Bool {
room.isSpace()
}
var joinedMembersCount: Int {
Int(room.joinedMembersCount())
}
var activeMembersCount: Int {
Int(room.activeMembersCount())
}
init(roomListItem: RoomListItemProtocol,
room: RoomProtocol) {
self.roomListItem = roomListItem
self.room = room
}
func cancelKnock() async -> Result<Void, RoomProxyError> {
// TODO: Implement this once the API is available
.failure(.invalidURL)
}
}
@@ -21,6 +21,7 @@ enum RoomProxyError: Error {
enum RoomProxyType {
case joined(JoinedRoomProxyProtocol)
case invited(InvitedRoomProxyProtocol)
case knocked(KnockedRoomProxyProtocol)
case left
}
@@ -56,6 +57,11 @@ protocol InvitedRoomProxyProtocol: RoomProxyProtocol {
func acceptInvitation() async -> Result<Void, RoomProxyError>
}
// sourcery: AutoMockable
protocol KnockedRoomProxyProtocol: RoomProxyProtocol {
func cancelKnock() async -> Result<Void, RoomProxyError>
}
enum JoinedRoomProxyAction: Equatable {
case roomInfoUpdate
}