diff --git a/ElementX/Sources/Screens/HomeScreen/HomeScreenModels.swift b/ElementX/Sources/Screens/HomeScreen/HomeScreenModels.swift index 4aae45339..3657c3398 100644 --- a/ElementX/Sources/Screens/HomeScreen/HomeScreenModels.swift +++ b/ElementX/Sources/Screens/HomeScreen/HomeScreenModels.swift @@ -64,7 +64,7 @@ struct HomeScreenRoom: Identifiable { var displayName: String? let topic: String? - let lastMessage: String? + var lastMessage: String? var avatar: UIImage? diff --git a/ElementX/Sources/Screens/HomeScreen/HomeScreenViewModel.swift b/ElementX/Sources/Screens/HomeScreen/HomeScreenViewModel.swift index 77a5da5e6..00006ab65 100644 --- a/ElementX/Sources/Screens/HomeScreen/HomeScreenViewModel.swift +++ b/ElementX/Sources/Screens/HomeScreen/HomeScreenViewModel.swift @@ -28,7 +28,7 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol private var roomUpdateListeners = Set() private var roomList: [RoomProxyProtocol]? { didSet { - self.state.isLoadingRooms = (roomList == nil) + self.state.isLoadingRooms = (roomList?.count ?? 0 == 0) } } @@ -50,8 +50,7 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol case .logout: self.completion?(.logout) case .loadRoomData(let roomIdentifier): - self.loadAvatarForRoomWithIdentifier(roomIdentifier) - self.loadRoomDisplayNameForRoomWithIdentifier(roomIdentifier) + self.loadRoomDataForIdentifier(roomIdentifier) case .loadUserAvatar: self.completion?(.loadUserAvatar) case .selectRoom(let roomIdentifier): @@ -60,27 +59,25 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol } func updateWithRoomList(_ roomList: [RoomProxyProtocol]) { + self.roomList = roomList + + state.rooms = roomList.map { roomProxy in + roomFromProxy(roomProxy) + } roomUpdateListeners.removeAll() - self.roomList = roomList - roomList.forEach({ roomProxy in - roomProxy.paginateBackwards(count: 1, callback: nil) roomProxy.callbacks.sink { [weak self] callback in switch callback { case .updatedLastMessage: - self?.updateRoomForProxy(roomProxy) + self?.loadLastMessageForRoomWithIdentifier(roomProxy.id) default: break } } .store(in: &roomUpdateListeners) }) - - state.rooms = roomList.map { roomProxy in - roomFromProxy(roomProxy) - } } func updateWithUserAvatar(_ avatar: UIImage?) { @@ -89,6 +86,12 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol // MARK: - Private + private func loadRoomDataForIdentifier(_ roomIdentifier: String) { + loadAvatarForRoomWithIdentifier(roomIdentifier) + loadRoomDisplayNameForRoomWithIdentifier(roomIdentifier) + loadLastMessageForRoomWithIdentifier(roomIdentifier) + } + private func loadAvatarForRoomWithIdentifier(_ roomIdentifier: String) { guard let room = roomList?.filter({ $0.id == roomIdentifier }).first, let cacheKey = room.avatarURL?.path else { @@ -126,6 +129,14 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol } } + private func updateAvatar(_ avatar: UIImage?, forRoomWithIdentifier roomIdentifier: String) { + guard let index = self.state.rooms.firstIndex(where: { $0.id == roomIdentifier }) else { + return + } + + self.state.rooms[index].avatar = avatar + } + private func loadRoomDisplayNameForRoomWithIdentifier(_ roomIdentifier: String) { guard let room = roomList?.filter({ $0.id == roomIdentifier }).first else { return @@ -151,24 +162,37 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol self.state.rooms[index].displayName = displayName } - private func updateAvatar(_ avatar: UIImage?, forRoomWithIdentifier roomIdentifier: String) { + private func loadLastMessageForRoomWithIdentifier(_ roomIdentifier: String) { + guard let room = roomList?.filter({ $0.id == roomIdentifier }).first else { + return + } + + if let lastMessage = room.lastMessage { + self.updateLastMessage(lastMessage, forRoomWithIdentifier: roomIdentifier) + } else { + room.paginateBackwards(count: 1) { result in + switch result { + case .success(let messages): + guard let lastMessage = messages.last else { + return + } + + self.updateLastMessage(lastMessage.content(), forRoomWithIdentifier: roomIdentifier) + default: + break + } + } + } + } + + private func updateLastMessage(_ lastMessage: String, forRoomWithIdentifier roomIdentifier: String) { guard let index = self.state.rooms.firstIndex(where: { $0.id == roomIdentifier }) else { return } - self.state.rooms[index].avatar = avatar + self.state.rooms[index].lastMessage = lastMessage } - - private func updateRoomForProxy(_ roomProxy: RoomProxyProtocol) { - state.rooms.updateEach { room in - if room.id != roomProxy.id { - return - } - - room = roomFromProxy(roomProxy) - } - } - + private func roomFromProxy(_ roomProxy: RoomProxyProtocol) -> HomeScreenRoom { HomeScreenRoom(id: roomProxy.id, displayName: roomProxy.name, diff --git a/ElementX/Sources/Screens/HomeScreen/View/HomeScreen.swift b/ElementX/Sources/Screens/HomeScreen/View/HomeScreen.swift index 3ad46552e..f67d7a722 100644 --- a/ElementX/Sources/Screens/HomeScreen/View/HomeScreen.swift +++ b/ElementX/Sources/Screens/HomeScreen/View/HomeScreen.swift @@ -114,7 +114,6 @@ struct RoomCell: View { .frame(width: 40, height: 40) .mask(Circle()) } else { - let _ = context.send(viewAction: .loadRoomData(roomIdentifier: room.id)) Image(systemName: "person.3") .frame(width: 40, height: 40) } @@ -140,6 +139,9 @@ struct RoomCell: View { } } .frame(minHeight: 60.0) + .onAppear { + context.send(viewAction: .loadRoomData(roomIdentifier: room.id)) + } } } diff --git a/ElementX/Sources/Screens/LoginScreen/LoginScreenViewModel.swift b/ElementX/Sources/Screens/LoginScreen/LoginScreenViewModel.swift index 841f89295..0e9f99631 100644 --- a/ElementX/Sources/Screens/LoginScreen/LoginScreenViewModel.swift +++ b/ElementX/Sources/Screens/LoginScreen/LoginScreenViewModel.swift @@ -34,8 +34,8 @@ class LoginScreenViewModel: LoginScreenViewModelType, LoginScreenViewModelProtoc // MARK: - Setup init() { - super.init(initialViewState: LoginScreenViewState(bindings: LoginScreenViewStateBindings(username: "", - password: ""))) + super.init(initialViewState: LoginScreenViewState(bindings: LoginScreenViewStateBindings(username: "@stefan.ceriu-element01:matrix.org", + password: "radeon"))) } // MARK: - Public diff --git a/ElementX/Sources/Services/Authentication/AuthenticationCoordinator.swift b/ElementX/Sources/Services/Authentication/AuthenticationCoordinator.swift index 3ae3efa77..996efa429 100644 --- a/ElementX/Sources/Services/Authentication/AuthenticationCoordinator.swift +++ b/ElementX/Sources/Services/Authentication/AuthenticationCoordinator.swift @@ -134,6 +134,8 @@ class AuthenticationCoordinator: Coordinator { completion(.success(())) } } catch { + MXLog.error("Failed logging in with error: \(error)") + DispatchQueue.main.async { completion(.failure(.failedLoggingIn)) } @@ -156,6 +158,8 @@ class AuthenticationCoordinator: Coordinator { completion(.success(())) } } catch { + MXLog.error("Failed restoring login with error: \(error)") + DispatchQueue.main.async { completion(.failure(.failedRestoringLogin)) } diff --git a/ElementX/Sources/Services/Authentication/UserSession.swift b/ElementX/Sources/Services/Authentication/UserSession.swift index e08613f33..4dc7e7483 100644 --- a/ElementX/Sources/Services/Authentication/UserSession.swift +++ b/ElementX/Sources/Services/Authentication/UserSession.swift @@ -101,6 +101,8 @@ class UserSession: ClientDelegate { self.rooms = rooms } } + + client.setDelegate(delegate: nil) } // MARK: Private diff --git a/ElementX/Sources/Services/RoomProxy.swift b/ElementX/Sources/Services/RoomProxy.swift index fe7148479..cf3586846 100644 --- a/ElementX/Sources/Services/RoomProxy.swift +++ b/ElementX/Sources/Services/RoomProxy.swift @@ -82,6 +82,10 @@ class RoomProxy: RoomProxyProtocol, Equatable { var lastMessage: String? { didSet { + if lastMessage == oldValue { + return + } + callbacks.send(.updatedLastMessage) } } @@ -141,7 +145,7 @@ class RoomProxy: RoomProxyProtocol, Equatable { callback?(.success(messages)) if self.lastMessage == nil { - self.lastMessage = messages.last?.content() + self.lastMessage = messages.last?.content() ?? "" } } }