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 {
|
enum HomeScreenViewAction {
|
||||||
case logout
|
case logout
|
||||||
case loadUserAvatar
|
case loadUserAvatar
|
||||||
case loadRoomAvatar(roomId: String)
|
case loadRoomData(roomId: String)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct HomeScreenViewState: BindableState {
|
struct HomeScreenViewState: BindableState {
|
||||||
@ -54,7 +54,8 @@ struct HomeScreenViewState: BindableState {
|
|||||||
|
|
||||||
struct HomeScreenRoom: Identifiable {
|
struct HomeScreenRoom: Identifiable {
|
||||||
let id: String
|
let id: String
|
||||||
let displayName: String
|
|
||||||
|
var displayName: String?
|
||||||
|
|
||||||
let topic: String?
|
let topic: String?
|
||||||
let lastMessage: String?
|
let lastMessage: String?
|
||||||
|
@ -52,8 +52,9 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
|||||||
switch viewAction {
|
switch viewAction {
|
||||||
case .logout:
|
case .logout:
|
||||||
self.completion?(.logout)
|
self.completion?(.logout)
|
||||||
case .loadRoomAvatar(let roomId):
|
case .loadRoomData(let roomId):
|
||||||
self.loadAvatarForRoomWithIdentifier(roomId)
|
self.loadAvatarForRoomWithIdentifier(roomId)
|
||||||
|
self.loadRoomDisplayNameForRoomWithIdentifier(roomId)
|
||||||
case .loadUserAvatar:
|
case .loadUserAvatar:
|
||||||
self.completion?(.loadUserAvatar)
|
self.completion?(.loadUserAvatar)
|
||||||
}
|
}
|
||||||
@ -63,7 +64,7 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
|||||||
self.roomList = roomList
|
self.roomList = roomList
|
||||||
state.rooms = roomList.map { roomModel in
|
state.rooms = roomList.map { roomModel in
|
||||||
HomeScreenRoom(id: roomModel.identifier,
|
HomeScreenRoom(id: roomModel.identifier,
|
||||||
displayName: roomModel.displayName,
|
displayName: roomModel.name,
|
||||||
topic: roomModel.topic,
|
topic: roomModel.topic,
|
||||||
lastMessage: roomModel.lastMessage,
|
lastMessage: roomModel.lastMessage,
|
||||||
isDirect: roomModel.isDirect,
|
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) {
|
private func updateAvatar(_ avatar: UIImage?, forRoomWithIdentifier roomIdentifier: String) {
|
||||||
guard let index = self.state.rooms.firstIndex(where: { $0.id == roomIdentifier }) else {
|
guard let index = self.state.rooms.firstIndex(where: { $0.id == roomIdentifier }) else {
|
||||||
return
|
return
|
||||||
|
@ -114,7 +114,7 @@ struct RoomCell: View {
|
|||||||
.frame(width: 40, height: 40)
|
.frame(width: 40, height: 40)
|
||||||
.mask(Circle())
|
.mask(Circle())
|
||||||
} else {
|
} else {
|
||||||
let _ = context.send(viewAction: .loadRoomAvatar(roomId: room.id))
|
let _ = context.send(viewAction: .loadRoomData(roomId: room.id))
|
||||||
Image(systemName: "person.3")
|
Image(systemName: "person.3")
|
||||||
.frame(width: 40, height: 40)
|
.frame(width: 40, height: 40)
|
||||||
}
|
}
|
||||||
@ -143,7 +143,7 @@ struct RoomCell: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func roomName(_ room: HomeScreenRoom) -> String {
|
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 isPublic = Bool.random()
|
||||||
let isEncrypted = Bool.random()
|
let isEncrypted = Bool.random()
|
||||||
|
|
||||||
|
func loadDisplayName(_ completion: @escaping (Result<String, Error>) -> Void) {
|
||||||
|
completion(.success(displayName))
|
||||||
|
}
|
||||||
|
|
||||||
func loadAvatar(_ completion: (Result<UIImage?, Error>) -> Void) {
|
func loadAvatar(_ completion: (Result<UIImage?, Error>) -> Void) {
|
||||||
completion(.success(UIImage(systemName: "wand.and.stars")))
|
completion(.success(UIImage(systemName: "wand.and.stars")))
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ import UIKit
|
|||||||
import MatrixRustSDK
|
import MatrixRustSDK
|
||||||
|
|
||||||
enum RoomModelError: Error {
|
enum RoomModelError: Error {
|
||||||
|
case failedRetrievingDisplayName
|
||||||
case failedRetrievingAvatar
|
case failedRetrievingAvatar
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,6 +75,22 @@ struct RoomModel: RoomModelProtocol {
|
|||||||
return URL(string: urlString)
|
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) {
|
func loadAvatar(_ completion: @escaping (Result<UIImage?, Error>) -> Void) {
|
||||||
DispatchQueue.global(qos: .background).async {
|
DispatchQueue.global(qos: .background).async {
|
||||||
do {
|
do {
|
||||||
|
@ -14,7 +14,6 @@ protocol RoomModelProtocol {
|
|||||||
var isSpace: Bool { get }
|
var isSpace: Bool { get }
|
||||||
var isEncrypted: Bool { get }
|
var isEncrypted: Bool { get }
|
||||||
|
|
||||||
var displayName: String { get }
|
|
||||||
var name: String? { get }
|
var name: String? { get }
|
||||||
|
|
||||||
var topic: String? { get }
|
var topic: String? { get }
|
||||||
@ -22,5 +21,6 @@ protocol RoomModelProtocol {
|
|||||||
|
|
||||||
var avatarURL: URL? { get }
|
var avatarURL: URL? { get }
|
||||||
|
|
||||||
|
func loadDisplayName(_ completion: @escaping (Result<String, Error>) -> Void)
|
||||||
func loadAvatar(_ completion: @escaping (Result<UIImage?, Error>) -> Void)
|
func loadAvatar(_ completion: @escaping (Result<UIImage?, Error>) -> Void)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user