Room details screen (#348)

* Create screen module

* Display details on header tap

* Add strings

* Add room avatar size on details

* Update members method signature

* Use room proxy values

* Create room members screen

* Display room members on tap

* Update previews and mock room proxy

* Commit project file

* Various tweaks and cleanup following code review

* More small tweaks + UI and screenshot tests

Co-authored-by: Stefan Ceriu <stefanc@matrix.org>
This commit is contained in:
ismailgulek
2022-12-19 15:39:33 +03:00
committed by GitHub
parent 4b29318147
commit 1a47fd1a8d
43 changed files with 1192 additions and 33 deletions
@@ -22,16 +22,14 @@ struct MockRoomProxy: RoomProxyProtocol {
let id = UUID().uuidString
let name: String? = nil
let displayName: String?
let topic: String? = nil
let avatarURL: String? = nil
let isDirect = Bool.random()
let isSpace = Bool.random()
let isPublic = Bool.random()
let isEncrypted = Bool.random()
let isTombstoned = Bool.random()
var topic: String?
var avatarURL: String?
var isDirect = Bool.random()
var isSpace = Bool.random()
var isPublic = Bool.random()
var isEncrypted = Bool.random()
var isTombstoned = Bool.random()
var members: [RoomMemberProxy]?
let timelineProvider: RoomTimelineProviderProtocol = MockRoomTimelineProvider()
@@ -76,4 +74,11 @@ struct MockRoomProxy: RoomProxyProtocol {
func redact(_ eventID: String) async -> Result<Void, RoomProxyError> {
.failure(.failedRedactingEvent)
}
func members() async -> Result<[RoomMemberProxy], RoomProxyError> {
if let members {
return .success(members)
}
return .failure(.failedRetrievingMembers)
}
}
@@ -0,0 +1,93 @@
//
// Copyright 2022 New Vector Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import Foundation
import MatrixRustSDK
struct RoomMemberProxy {
private let member: RoomMember
init(with member: RoomMember) {
self.member = member
}
var userId: String {
member.userId
}
var displayName: String? {
member.displayName
}
var avatarUrl: String? {
member.avatarUrl
}
var membership: MembershipState {
member.membership
}
var isNameAmbiguous: Bool {
member.isNameAmbiguous
}
var powerLevel: Int64 {
member.powerLevel
}
var normalizedPowerLevel: Int64 {
member.normalizedPowerLevel
}
}
extension RoomMemberProxy: Identifiable {
var id: String {
userId
}
}
// Mocks
extension RoomMemberProxy {
static var mockAlice: RoomMemberProxy {
RoomMemberProxy(with: .init(userId: "alice@matrix.org",
displayName: "Alice",
avatarUrl: nil,
membership: .join,
isNameAmbiguous: false,
powerLevel: 50,
normalizedPowerLevel: 50))
}
static var mockBob: RoomMemberProxy {
RoomMemberProxy(with: .init(userId: "bob@matrix.org",
displayName: "Bob",
avatarUrl: nil,
membership: .join,
isNameAmbiguous: false,
powerLevel: 50,
normalizedPowerLevel: 50))
}
static var mockCharlie: RoomMemberProxy {
RoomMemberProxy(with: .init(userId: "charlie@matrix.org",
displayName: "Charlie",
avatarUrl: nil,
membership: .join,
isNameAmbiguous: false,
powerLevel: 50,
normalizedPowerLevel: 50))
}
}
@@ -224,6 +224,17 @@ class RoomProxy: RoomProxyProtocol {
.value
}
func members() async -> Result<[RoomMemberProxy], RoomProxyError> {
await Task.dispatch(on: .global()) {
do {
let members = try self.room.members()
return .success(members.map { RoomMemberProxy(with: $0) })
} catch {
return .failure(.failedRetrievingMembers)
}
}
}
func update(avatarURL: String?, forUserId userId: String) {
memberAvatars[userId] = avatarURL
}
@@ -25,6 +25,7 @@ enum RoomProxyError: Error {
case failedSendingMessage
case failedRedactingEvent
case failedAddingTimelineListener
case failedRetrievingMembers
}
@MainActor
@@ -62,6 +63,8 @@ protocol RoomProxyProtocol {
func editMessage(_ newMessage: String, originalEventId: String) async -> Result<Void, RoomProxyError>
func redact(_ eventID: String) async -> Result<Void, RoomProxyError>
func members() async -> Result<[RoomMemberProxy], RoomProxyError>
}
extension RoomProxyProtocol {
@@ -23,7 +23,7 @@ class RoomTimelineController: RoomTimelineControllerProtocol {
private let timelineProvider: RoomTimelineProviderProtocol
private let timelineItemFactory: RoomTimelineItemFactoryProtocol
private let mediaProvider: MediaProviderProtocol
private let roomProxy: RoomProxyProtocol
let roomProxy: RoomProxyProtocol
private var cancellables = Set<AnyCancellable>()
private var timelineItemsUpdateTask: Task<Void, Never>? {
@@ -162,10 +162,9 @@ class UserSessionFlowCoordinator: CoordinatorProtocol {
mediaProvider: userSession.mediaProvider)
let parameters = RoomScreenCoordinatorParameters(navigationStackCoordinator: detailNavigationStackCoordinator,
roomProxy: roomProxy,
timelineController: timelineController,
mediaProvider: userSession.mediaProvider,
roomName: roomProxy.displayName ?? roomProxy.name,
roomAvatarUrl: roomProxy.avatarURL,
emojiProvider: emojiProvider)
let coordinator = RoomScreenCoordinator(parameters: parameters)