mirror of
https://github.com/element-hq/element-x-ios.git
synced 2025-03-10 21:39:12 +00:00
Fetching the room display names in background to avoid blocking the main thread.
This commit is contained in:
parent
97cb8adcee
commit
e50f0257d2
@ -25,7 +25,7 @@ enum HomeScreenViewModelResult {
|
||||
enum HomeScreenViewAction {
|
||||
case logout
|
||||
case loadUserAvatar
|
||||
case loadRoomAvatar(roomId: String)
|
||||
case loadRoomData(roomId: String)
|
||||
}
|
||||
|
||||
struct HomeScreenViewState: BindableState {
|
||||
@ -54,7 +54,8 @@ struct HomeScreenViewState: BindableState {
|
||||
|
||||
struct HomeScreenRoom: Identifiable {
|
||||
let id: String
|
||||
let displayName: String
|
||||
|
||||
var displayName: String?
|
||||
|
||||
let topic: String?
|
||||
let lastMessage: String?
|
||||
|
@ -52,8 +52,9 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
||||
switch viewAction {
|
||||
case .logout:
|
||||
self.completion?(.logout)
|
||||
case .loadRoomAvatar(let roomId):
|
||||
case .loadRoomData(let roomId):
|
||||
self.loadAvatarForRoomWithIdentifier(roomId)
|
||||
self.loadRoomDisplayNameForRoomWithIdentifier(roomId)
|
||||
case .loadUserAvatar:
|
||||
self.completion?(.loadUserAvatar)
|
||||
}
|
||||
@ -63,7 +64,7 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
||||
self.roomList = roomList
|
||||
state.rooms = roomList.map { roomModel in
|
||||
HomeScreenRoom(id: roomModel.identifier,
|
||||
displayName: roomModel.displayName,
|
||||
displayName: roomModel.name,
|
||||
topic: roomModel.topic,
|
||||
lastMessage: roomModel.lastMessage,
|
||||
isDirect: roomModel.isDirect,
|
||||
@ -114,6 +115,31 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
||||
}
|
||||
}
|
||||
|
||||
private func loadRoomDisplayNameForRoomWithIdentifier(_ roomIdentifier: String) {
|
||||
guard let room = roomList?.filter({ $0.identifier == roomIdentifier }).first else {
|
||||
return
|
||||
}
|
||||
|
||||
room.loadDisplayName { [weak self] result in
|
||||
guard let self = self else { return }
|
||||
|
||||
switch result {
|
||||
case .success(let displayName):
|
||||
self.updateDisplayName(displayName, forRoomWithIdentifier: roomIdentifier)
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func updateDisplayName(_ displayName: String, forRoomWithIdentifier roomIdentifier: String) {
|
||||
guard let index = self.state.rooms.firstIndex(where: { $0.id == roomIdentifier }) else {
|
||||
return
|
||||
}
|
||||
|
||||
self.state.rooms[index].displayName = displayName
|
||||
}
|
||||
|
||||
private func updateAvatar(_ avatar: UIImage?, forRoomWithIdentifier roomIdentifier: String) {
|
||||
guard let index = self.state.rooms.firstIndex(where: { $0.id == roomIdentifier }) else {
|
||||
return
|
||||
|
@ -114,7 +114,7 @@ struct RoomCell: View {
|
||||
.frame(width: 40, height: 40)
|
||||
.mask(Circle())
|
||||
} else {
|
||||
let _ = context.send(viewAction: .loadRoomAvatar(roomId: room.id))
|
||||
let _ = context.send(viewAction: .loadRoomData(roomId: room.id))
|
||||
Image(systemName: "person.3")
|
||||
.frame(width: 40, height: 40)
|
||||
}
|
||||
@ -143,7 +143,7 @@ struct RoomCell: View {
|
||||
}
|
||||
|
||||
private func roomName(_ room: HomeScreenRoom) -> String {
|
||||
room.displayName + (room.isEncrypted ? "🛡": "")
|
||||
room.displayName ?? room.id + (room.isEncrypted ? "🛡": "")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,10 @@ struct MockRoomModel: RoomModelProtocol {
|
||||
let isPublic = Bool.random()
|
||||
let isEncrypted = Bool.random()
|
||||
|
||||
func loadDisplayName(_ completion: @escaping (Result<String, Error>) -> Void) {
|
||||
completion(.success(displayName))
|
||||
}
|
||||
|
||||
func loadAvatar(_ completion: (Result<UIImage?, Error>) -> Void) {
|
||||
completion(.success(UIImage(systemName: "wand.and.stars")))
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import UIKit
|
||||
import MatrixRustSDK
|
||||
|
||||
enum RoomModelError: Error {
|
||||
case failedRetrievingDisplayName
|
||||
case failedRetrievingAvatar
|
||||
}
|
||||
|
||||
@ -74,6 +75,22 @@ struct RoomModel: RoomModelProtocol {
|
||||
return URL(string: urlString)
|
||||
}
|
||||
|
||||
func loadDisplayName(_ completion: @escaping (Result<String, Error>) -> Void) {
|
||||
DispatchQueue.global(qos: .background).async {
|
||||
do {
|
||||
let displayName = try room.displayName()
|
||||
|
||||
DispatchQueue.main.async {
|
||||
completion(.success(displayName))
|
||||
}
|
||||
} catch {
|
||||
DispatchQueue.main.async {
|
||||
completion(.failure(RoomModelError.failedRetrievingDisplayName))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func loadAvatar(_ completion: @escaping (Result<UIImage?, Error>) -> Void) {
|
||||
DispatchQueue.global(qos: .background).async {
|
||||
do {
|
||||
|
@ -14,7 +14,6 @@ protocol RoomModelProtocol {
|
||||
var isSpace: Bool { get }
|
||||
var isEncrypted: Bool { get }
|
||||
|
||||
var displayName: String { get }
|
||||
var name: String? { get }
|
||||
|
||||
var topic: String? { get }
|
||||
@ -22,5 +21,6 @@ protocol RoomModelProtocol {
|
||||
|
||||
var avatarURL: URL? { get }
|
||||
|
||||
func loadDisplayName(_ completion: @escaping (Result<String, Error>) -> Void)
|
||||
func loadAvatar(_ completion: @escaping (Result<UIImage?, Error>) -> Void)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user