mirror of
https://github.com/element-hq/element-x-ios.git
synced 2025-03-10 21:39:12 +00:00
Added room avatar caching and room list loading state.
This commit is contained in:
parent
ad80b91b16
commit
c35438cbb8
@ -19,6 +19,7 @@
|
|||||||
182BC47727C4CD6D00A30C33 /* ActivityDismissal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 182BC46E27C4CD6D00A30C33 /* ActivityDismissal.swift */; };
|
182BC47727C4CD6D00A30C33 /* ActivityDismissal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 182BC46E27C4CD6D00A30C33 /* ActivityDismissal.swift */; };
|
||||||
182BC47927C4CE2200A30C33 /* LabelledActivityIndicatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 182BC47827C4CE2200A30C33 /* LabelledActivityIndicatorView.swift */; };
|
182BC47927C4CE2200A30C33 /* LabelledActivityIndicatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 182BC47827C4CE2200A30C33 /* LabelledActivityIndicatorView.swift */; };
|
||||||
182BC47B27C4D05200A30C33 /* FullscreenLoadingActivityPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 182BC47A27C4D05200A30C33 /* FullscreenLoadingActivityPresenter.swift */; };
|
182BC47B27C4D05200A30C33 /* FullscreenLoadingActivityPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 182BC47A27C4D05200A30C33 /* FullscreenLoadingActivityPresenter.swift */; };
|
||||||
|
182BC48127C4EBBB00A30C33 /* Kingfisher in Frameworks */ = {isa = PBXBuildFile; productRef = 182BC48027C4EBBB00A30C33 /* Kingfisher */; };
|
||||||
1850253F27B6918D002E6B18 /* ElementXTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1850253E27B6918D002E6B18 /* ElementXTests.swift */; };
|
1850253F27B6918D002E6B18 /* ElementXTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1850253E27B6918D002E6B18 /* ElementXTests.swift */; };
|
||||||
1850254927B6918D002E6B18 /* ElementXUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1850254827B6918D002E6B18 /* ElementXUITests.swift */; };
|
1850254927B6918D002E6B18 /* ElementXUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1850254827B6918D002E6B18 /* ElementXUITests.swift */; };
|
||||||
1850254B27B6918D002E6B18 /* ElementXUITestsLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1850254A27B6918D002E6B18 /* ElementXUITestsLaunchTests.swift */; };
|
1850254B27B6918D002E6B18 /* ElementXUITestsLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1850254A27B6918D002E6B18 /* ElementXUITestsLaunchTests.swift */; };
|
||||||
@ -154,6 +155,7 @@
|
|||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
182BC48127C4EBBB00A30C33 /* Kingfisher in Frameworks */,
|
||||||
1863A3FC27BA5A9100B52E4D /* KeychainAccess in Frameworks */,
|
1863A3FC27BA5A9100B52E4D /* KeychainAccess in Frameworks */,
|
||||||
1850255927B69388002E6B18 /* MatrixRustSDK in Frameworks */,
|
1850255927B69388002E6B18 /* MatrixRustSDK in Frameworks */,
|
||||||
1863A40627BA6DFC00B52E4D /* SwiftyBeaver in Frameworks */,
|
1863A40627BA6DFC00B52E4D /* SwiftyBeaver in Frameworks */,
|
||||||
@ -489,6 +491,7 @@
|
|||||||
1850255827B69388002E6B18 /* MatrixRustSDK */,
|
1850255827B69388002E6B18 /* MatrixRustSDK */,
|
||||||
1863A3FB27BA5A9100B52E4D /* KeychainAccess */,
|
1863A3FB27BA5A9100B52E4D /* KeychainAccess */,
|
||||||
1863A40527BA6DFC00B52E4D /* SwiftyBeaver */,
|
1863A40527BA6DFC00B52E4D /* SwiftyBeaver */,
|
||||||
|
182BC48027C4EBBB00A30C33 /* Kingfisher */,
|
||||||
);
|
);
|
||||||
productName = ElementX;
|
productName = ElementX;
|
||||||
productReference = 1850252427B6918C002E6B18 /* ElementX.app */;
|
productReference = 1850252427B6918C002E6B18 /* ElementX.app */;
|
||||||
@ -566,6 +569,7 @@
|
|||||||
1850255727B69388002E6B18 /* XCRemoteSwiftPackageReference "matrix-rust-components-swift" */,
|
1850255727B69388002E6B18 /* XCRemoteSwiftPackageReference "matrix-rust-components-swift" */,
|
||||||
1863A3FA27BA5A9100B52E4D /* XCRemoteSwiftPackageReference "KeychainAccess" */,
|
1863A3FA27BA5A9100B52E4D /* XCRemoteSwiftPackageReference "KeychainAccess" */,
|
||||||
1863A40427BA6DFC00B52E4D /* XCRemoteSwiftPackageReference "SwiftyBeaver" */,
|
1863A40427BA6DFC00B52E4D /* XCRemoteSwiftPackageReference "SwiftyBeaver" */,
|
||||||
|
182BC47F27C4EBBB00A30C33 /* XCRemoteSwiftPackageReference "Kingfisher" */,
|
||||||
);
|
);
|
||||||
productRefGroup = 1850252527B6918C002E6B18 /* Products */;
|
productRefGroup = 1850252527B6918C002E6B18 /* Products */;
|
||||||
projectDirPath = "";
|
projectDirPath = "";
|
||||||
@ -1021,6 +1025,14 @@
|
|||||||
/* End XCConfigurationList section */
|
/* End XCConfigurationList section */
|
||||||
|
|
||||||
/* Begin XCRemoteSwiftPackageReference section */
|
/* Begin XCRemoteSwiftPackageReference section */
|
||||||
|
182BC47F27C4EBBB00A30C33 /* XCRemoteSwiftPackageReference "Kingfisher" */ = {
|
||||||
|
isa = XCRemoteSwiftPackageReference;
|
||||||
|
repositoryURL = "https://github.com/onevcat/Kingfisher";
|
||||||
|
requirement = {
|
||||||
|
kind = upToNextMajorVersion;
|
||||||
|
minimumVersion = 7.0.0;
|
||||||
|
};
|
||||||
|
};
|
||||||
1850255727B69388002E6B18 /* XCRemoteSwiftPackageReference "matrix-rust-components-swift" */ = {
|
1850255727B69388002E6B18 /* XCRemoteSwiftPackageReference "matrix-rust-components-swift" */ = {
|
||||||
isa = XCRemoteSwiftPackageReference;
|
isa = XCRemoteSwiftPackageReference;
|
||||||
repositoryURL = "https://github.com/matrix-org/matrix-rust-components-swift.git";
|
repositoryURL = "https://github.com/matrix-org/matrix-rust-components-swift.git";
|
||||||
@ -1048,6 +1060,11 @@
|
|||||||
/* End XCRemoteSwiftPackageReference section */
|
/* End XCRemoteSwiftPackageReference section */
|
||||||
|
|
||||||
/* Begin XCSwiftPackageProductDependency section */
|
/* Begin XCSwiftPackageProductDependency section */
|
||||||
|
182BC48027C4EBBB00A30C33 /* Kingfisher */ = {
|
||||||
|
isa = XCSwiftPackageProductDependency;
|
||||||
|
package = 182BC47F27C4EBBB00A30C33 /* XCRemoteSwiftPackageReference "Kingfisher" */;
|
||||||
|
productName = Kingfisher;
|
||||||
|
};
|
||||||
1850255827B69388002E6B18 /* MatrixRustSDK */ = {
|
1850255827B69388002E6B18 /* MatrixRustSDK */ = {
|
||||||
isa = XCSwiftPackageProductDependency;
|
isa = XCSwiftPackageProductDependency;
|
||||||
package = 1850255727B69388002E6B18 /* XCRemoteSwiftPackageReference "matrix-rust-components-swift" */;
|
package = 1850255727B69388002E6B18 /* XCRemoteSwiftPackageReference "matrix-rust-components-swift" */;
|
||||||
|
@ -11,12 +11,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"package": "MatrixRustSDK",
|
"package": "Kingfisher",
|
||||||
"repositoryURL": "https://github.com/matrix-org/matrix-rust-components-swift.git",
|
"repositoryURL": "https://github.com/onevcat/Kingfisher",
|
||||||
"state": {
|
"state": {
|
||||||
"branch": "main",
|
"branch": null,
|
||||||
"revision": "cb680b1783849ecabd0bdf61f65faff767ce32c8",
|
"revision": "0c02c46cfdc0656ce74fd0963a75e5000a0b7f23",
|
||||||
"version": null
|
"version": "7.1.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
import Kingfisher
|
||||||
|
|
||||||
class AppCoordinator: AuthenticationCoordinatorDelegate, Coordinator {
|
class AppCoordinator: AuthenticationCoordinatorDelegate, Coordinator {
|
||||||
private let window: UIWindow
|
private let window: UIWindow
|
||||||
@ -76,7 +77,7 @@ class AppCoordinator: AuthenticationCoordinatorDelegate, Coordinator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let parameters = HomeScreenCoordinatorParameters(userSession: userSession)
|
let parameters = HomeScreenCoordinatorParameters(userSession: userSession)
|
||||||
let coordinator = HomeScreenCoordinator(parameters: parameters)
|
let coordinator = HomeScreenCoordinator(parameters: parameters, imageCache: ImageCache.default)
|
||||||
|
|
||||||
coordinator.completion = { [weak self] result in
|
coordinator.completion = { [weak self] result in
|
||||||
switch result {
|
switch result {
|
||||||
|
@ -50,7 +50,7 @@ class UserSession: ClientDelegate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getUserAvatar(_ completion: @escaping (Result<UIImage?, Error>) -> Void) {
|
func loadUserAvatar(_ completion: @escaping (Result<UIImage?, Error>) -> Void) {
|
||||||
DispatchQueue.global(qos: .background).async {
|
DispatchQueue.global(qos: .background).async {
|
||||||
do {
|
do {
|
||||||
let avatarData = try self.client.avatar()
|
let avatarData = try self.client.avatar()
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
import Combine
|
import Combine
|
||||||
|
import Kingfisher
|
||||||
|
|
||||||
struct HomeScreenCoordinatorParameters {
|
struct HomeScreenCoordinatorParameters {
|
||||||
let userSession: UserSession
|
let userSession: UserSession
|
||||||
@ -45,11 +46,11 @@ final class HomeScreenCoordinator: Coordinator, Presentable {
|
|||||||
|
|
||||||
// MARK: - Setup
|
// MARK: - Setup
|
||||||
|
|
||||||
init(parameters: HomeScreenCoordinatorParameters) {
|
init(parameters: HomeScreenCoordinatorParameters, imageCache: Kingfisher.ImageCache) {
|
||||||
self.parameters = parameters
|
self.parameters = parameters
|
||||||
|
|
||||||
let userDisplayName = self.parameters.userSession.userDisplayName ?? self.parameters.userSession.userIdentifier
|
let userDisplayName = self.parameters.userSession.userDisplayName ?? self.parameters.userSession.userIdentifier
|
||||||
viewModel = HomeScreenViewModel(userDisplayName: userDisplayName)
|
viewModel = HomeScreenViewModel(userDisplayName: userDisplayName, imageCache: imageCache)
|
||||||
|
|
||||||
let view = HomeScreen(context: viewModel.context)
|
let view = HomeScreen(context: viewModel.context)
|
||||||
hostingController = UIHostingController(rootView: view)
|
hostingController = UIHostingController(rootView: view)
|
||||||
@ -61,7 +62,7 @@ final class HomeScreenCoordinator: Coordinator, Presentable {
|
|||||||
case .logout:
|
case .logout:
|
||||||
self.completion?(.logout)
|
self.completion?(.logout)
|
||||||
case .loadUserAvatar:
|
case .loadUserAvatar:
|
||||||
self.parameters.userSession.getUserAvatar({ result in
|
self.parameters.userSession.loadUserAvatar({ result in
|
||||||
switch result {
|
switch result {
|
||||||
case .success(let avatar):
|
case .success(let avatar):
|
||||||
self.viewModel.updateWithUserAvatar(avatar)
|
self.viewModel.updateWithUserAvatar(avatar)
|
||||||
|
@ -33,6 +33,7 @@ struct HomeScreenViewState: BindableState {
|
|||||||
var userAvatar: UIImage?
|
var userAvatar: UIImage?
|
||||||
|
|
||||||
var rooms: [HomeScreenRoom] = []
|
var rooms: [HomeScreenRoom] = []
|
||||||
|
var isLoadingRooms: Bool = false
|
||||||
|
|
||||||
var directRooms: [HomeScreenRoom] {
|
var directRooms: [HomeScreenRoom] {
|
||||||
rooms.filter { $0.isDirect }
|
rooms.filter { $0.isDirect }
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
import Kingfisher
|
||||||
|
|
||||||
@available(iOS 14, *)
|
@available(iOS 14, *)
|
||||||
typealias HomeScreenViewModelType = StateStoreViewModel<HomeScreenViewState,
|
typealias HomeScreenViewModelType = StateStoreViewModel<HomeScreenViewState,
|
||||||
@ -27,7 +28,12 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
|||||||
|
|
||||||
// MARK: Private
|
// MARK: Private
|
||||||
|
|
||||||
private var roomList: [RoomModelProtocol]?
|
private var roomList: [RoomModelProtocol]? {
|
||||||
|
didSet {
|
||||||
|
self.state.isLoadingRooms = (roomList == nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private let imageCache: ImageCache
|
||||||
|
|
||||||
// MARK: Public
|
// MARK: Public
|
||||||
|
|
||||||
@ -35,8 +41,9 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
|||||||
|
|
||||||
// MARK: - Setup
|
// MARK: - Setup
|
||||||
|
|
||||||
init(userDisplayName: String) {
|
init(userDisplayName: String, imageCache: Kingfisher.ImageCache) {
|
||||||
super.init(initialViewState: HomeScreenViewState(userDisplayName: userDisplayName))
|
self.imageCache = imageCache
|
||||||
|
super.init(initialViewState: HomeScreenViewState(userDisplayName: userDisplayName, isLoadingRooms: true))
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Public
|
// MARK: - Public
|
||||||
@ -46,24 +53,7 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
|||||||
case .logout:
|
case .logout:
|
||||||
self.completion?(.logout)
|
self.completion?(.logout)
|
||||||
case .loadRoomAvatar(let roomId):
|
case .loadRoomAvatar(let roomId):
|
||||||
guard let room = roomList?.filter({ $0.identifier == roomId }).first else {
|
self.loadAvatarForRoomWithIdentifier(roomId)
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
room.getAvatar { [weak self] result in
|
|
||||||
guard let self = self else { return }
|
|
||||||
|
|
||||||
switch result {
|
|
||||||
case .success(let image):
|
|
||||||
guard let index = self.state.rooms.firstIndex(where: { $0.id == roomId }) else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
self.state.rooms[index].avatar = image
|
|
||||||
default:
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case .loadUserAvatar:
|
case .loadUserAvatar:
|
||||||
self.completion?(.loadUserAvatar)
|
self.completion?(.loadUserAvatar)
|
||||||
}
|
}
|
||||||
@ -84,4 +74,51 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
|||||||
func updateWithUserAvatar(_ avatar: UIImage?) {
|
func updateWithUserAvatar(_ avatar: UIImage?) {
|
||||||
self.state.userAvatar = avatar
|
self.state.userAvatar = avatar
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - Private
|
||||||
|
|
||||||
|
private func loadAvatarForRoomWithIdentifier(_ roomIdentifier: String) {
|
||||||
|
guard let room = roomList?.filter({ $0.identifier == roomIdentifier }).first,
|
||||||
|
let cacheKey = room.avatarURL?.path else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if imageCache.isCached(forKey: cacheKey) {
|
||||||
|
imageCache.retrieveImage(forKey: cacheKey) { [weak self] result in
|
||||||
|
guard let self = self else { return }
|
||||||
|
switch result {
|
||||||
|
case .success(let value):
|
||||||
|
self.updateAvatar(value.image, forRoomWithIdentifier: roomIdentifier)
|
||||||
|
case .failure(let error):
|
||||||
|
MXLog.error("Failed retrieving avatar from cache with error: \(error)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
room.loadAvatar { [weak self] result in
|
||||||
|
guard let self = self else { return }
|
||||||
|
|
||||||
|
switch result {
|
||||||
|
case .success(let avatar):
|
||||||
|
guard let avatar = avatar else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
self.imageCache.store(avatar, forKey: cacheKey)
|
||||||
|
self.updateAvatar(avatar, forRoomWithIdentifier: roomIdentifier)
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
import Kingfisher
|
||||||
|
|
||||||
struct HomeScreen: View {
|
struct HomeScreen: View {
|
||||||
|
|
||||||
@ -31,6 +32,7 @@ struct HomeScreen: View {
|
|||||||
.resizable()
|
.resizable()
|
||||||
.scaledToFill()
|
.scaledToFill()
|
||||||
.frame(width: 40, height: 40, alignment: .center)
|
.frame(width: 40, height: 40, alignment: .center)
|
||||||
|
.mask(Circle())
|
||||||
} else {
|
} else {
|
||||||
let _ = context.send(viewAction: .loadUserAvatar)
|
let _ = context.send(viewAction: .loadUserAvatar)
|
||||||
}
|
}
|
||||||
@ -40,21 +42,30 @@ struct HomeScreen: View {
|
|||||||
}
|
}
|
||||||
.padding(.vertical, 32.0)
|
.padding(.vertical, 32.0)
|
||||||
|
|
||||||
List {
|
if context.viewState.isLoadingRooms {
|
||||||
Section("People") {
|
VStack {
|
||||||
ForEach(context.viewState.directRooms) { room in
|
Text("Loading rooms")
|
||||||
RoomCell(room: room, context: context)
|
ProgressView()
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
|
List {
|
||||||
Section("Rooms") {
|
Section("People") {
|
||||||
ForEach(context.viewState.nondirectRooms) { room in
|
ForEach(context.viewState.directRooms) { room in
|
||||||
RoomCell(room: room, context: context)
|
RoomCell(room: room, context: context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Section("Rooms") {
|
||||||
|
ForEach(context.viewState.nondirectRooms) { room in
|
||||||
|
RoomCell(room: room, context: context)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.headerProminence(.increased)
|
||||||
|
.listStyle(.plain)
|
||||||
}
|
}
|
||||||
.headerProminence(.increased)
|
|
||||||
.listStyle(.plain)
|
Spacer()
|
||||||
}
|
}
|
||||||
.navigationBarTitleDisplayMode(.inline)
|
.navigationBarTitleDisplayMode(.inline)
|
||||||
.toolbar {
|
.toolbar {
|
||||||
@ -81,6 +92,7 @@ struct RoomCell: View {
|
|||||||
.resizable()
|
.resizable()
|
||||||
.scaledToFill()
|
.scaledToFill()
|
||||||
.frame(width: 40, height: 40)
|
.frame(width: 40, height: 40)
|
||||||
|
.mask(Circle())
|
||||||
} else {
|
} else {
|
||||||
let _ = context.send(viewAction: .loadRoomAvatar(roomId: room.id))
|
let _ = context.send(viewAction: .loadRoomAvatar(roomId: room.id))
|
||||||
Image(systemName: "person.3")
|
Image(systemName: "person.3")
|
||||||
@ -119,7 +131,7 @@ struct RoomCell: View {
|
|||||||
|
|
||||||
struct HomeScreen_Previews: PreviewProvider {
|
struct HomeScreen_Previews: PreviewProvider {
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
let viewModel = HomeScreenViewModel(userDisplayName: "Johnny Appleseed")
|
let viewModel = HomeScreenViewModel(userDisplayName: "Johnny Appleseed", imageCache: ImageCache.default)
|
||||||
|
|
||||||
let rooms = [MockRoomModel(displayName: "Alfa"),
|
let rooms = [MockRoomModel(displayName: "Alfa"),
|
||||||
MockRoomModel(displayName: "Beta"),
|
MockRoomModel(displayName: "Beta"),
|
||||||
@ -127,6 +139,8 @@ struct HomeScreen_Previews: PreviewProvider {
|
|||||||
|
|
||||||
viewModel.updateWithRoomList(rooms)
|
viewModel.updateWithRoomList(rooms)
|
||||||
|
|
||||||
|
viewModel.updateWithUserAvatar(UIImage(systemName: "person.fill.questionmark"))
|
||||||
|
|
||||||
return HomeScreen(context: viewModel.context)
|
return HomeScreen(context: viewModel.context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ struct MockRoomModel: RoomModelProtocol {
|
|||||||
let isPublic = Bool.random()
|
let isPublic = Bool.random()
|
||||||
let isEncrypted = Bool.random()
|
let isEncrypted = Bool.random()
|
||||||
|
|
||||||
func getAvatar(_ 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")))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,7 @@ struct RoomModel: RoomModelProtocol {
|
|||||||
return URL(string: urlString)
|
return URL(string: urlString)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getAvatar(_ 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 {
|
||||||
let avatarData = try room.avatar()
|
let avatarData = try room.avatar()
|
||||||
|
@ -22,5 +22,5 @@ protocol RoomModelProtocol {
|
|||||||
|
|
||||||
var avatarURL: URL? { get }
|
var avatarURL: URL? { get }
|
||||||
|
|
||||||
func getAvatar(_ completion: @escaping (Result<UIImage?, Error>) -> Void)
|
func loadAvatar(_ completion: @escaping (Result<UIImage?, Error>) -> Void)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user