Commit e1deed4e authored by Maurice Kraus's avatar Maurice Kraus Committed by Maurice Kraus
Browse files

fix(core): this fixes the crash when clicking multiple avatars

parent aada2797
......@@ -58,7 +58,7 @@ public struct AkamuAvatarRepository: AvatarRepository {
}
public func updateUserAvatar(with id: Int) -> Single<Void> {
profileObservable
return profileObservable
.take(1)
.asSingle()
.flatMap { (profile) -> Single<Void> in
......
......@@ -80,15 +80,22 @@ class ServerUserRemoteAPI: UserRemoteAPI {
}
func updateUser(with changes: TemporaryUpdateUser) -> Single<Void> {
logger.debug("update user request")
Single.deferred { [weak self] in
guard let self = self else {
logger.debug("Did not update the user on remote because the class was deallocated")
return Single.just(())
}
let endpoint: UserEndpoint = .patch(token: remoteSession.token, patchedUser: changes)
logger.debug("update user request")
guard let request = endpoint.request else {
logger.warn("Patch user request could not be created")
return .error(EndpointError.malformedRequest)
}
let endpoint: UserEndpoint = .patch(token: self.remoteSession.token, patchedUser: changes)
return urlSession.rx.noResponse(request: request)
guard let request = endpoint.request else {
logger.warn("Patch user request could not be created")
return .error(EndpointError.malformedRequest)
}
return self.urlSession.rx.noResponse(request: request)
}
}
}
......@@ -57,7 +57,10 @@ public class AkamuUserRepository: UserRepository {
logger.warn("Could not update remote user")
return Single.error(DataLayerError.deallocated("Could not update due to self deallocation"))
}
return self.userRemoteAPI.updateUser(with: tuple.1).flatMap { .just(tuple.0) }
return self.userRemoteAPI
.updateUser(with: tuple.1)
.subscribeOn(Thread.background)
.flatMap { .just(tuple.0) }
}
}
}
......@@ -28,15 +28,25 @@ public struct AvatarSelectionViewModel: AvatarSelectionViewModelType {
// Input
public let setAvatar: AnyObserver<String>
public lazy var onAvatarChange: Action<Int, Void> = { (avatarRepository: AvatarRepository) in
Action { (avatarId: Int) -> Observable<Void> in
avatarRepository.getAvatar(with: avatarId)
.flatMap { (avatar: Avatar) in
!avatar.isUnlocked ?
Observable.empty() : avatarRepository.updateUserAvatar(with: avatarId).map { _ in }.asObservable()
public lazy var onAvatarChange: Action<Int, OnAvatarChangeReturnType> = { (avatarRepository: AvatarRepository, userProfile: Observable<UserProfile>) in
Action { (avatarId: Int) -> Observable<OnAvatarChangeReturnType> in
Observable.zip(userProfile, avatarRepository.getAvatar(with: avatarId))
// we don't want to execute this
.take(1)
// code again when the user profile is updated
.flatMap { (tup: (UserProfile, Avatar)) -> Observable<OnAvatarChangeReturnType> in
let (profile, avatar) = tup
if !avatar.isUnlocked {
return .just(.locked)
} else if avatar.id == profile.avatarId {
return .just(.current)
} else {
return avatarRepository.updateUserAvatar(with: avatarId).asObservable()
.map { _ in .valid }
}
}
}
}(self.avatarRepository)
}(self.avatarRepository, self.userProfile)
public init(userProfile: Observable<UserProfile>, avatarRepository: AvatarRepository, loggedInStatus: Observable<Bool>) {
disposeBag = DisposeBag()
......@@ -71,8 +81,16 @@ public struct AvatarSelectionViewModel: AvatarSelectionViewModelType {
]
}.asDriver(onErrorJustReturn: [AvatarSection(model: I18n.profile.avatarSelection.sectionTitle.error, items: [])])
onAvatarChange
.completions
Observable.zip(onAvatarChange.elements, onAvatarChange.completions)
.filter { (tuple) -> Bool in
// TODO: show user information why the window doesn't close
// (for example red ring around avatar)
if case OnAvatarChangeReturnType.valid = tuple.0 {
return true
} else {
return false
}
}.map { _ in }
.bind(to: finishAvatarSelectionSubject)
.disposed(by: disposeBag)
}
......
......@@ -13,11 +13,16 @@ import RxCocoa
import RxDataSources
import RxSwift
public typealias AvatarSection = AnimatableSectionModel<String, Avatar>
public enum OnAvatarChangeReturnType {
case locked
case current
case valid
}
public typealias AvatarSection = AnimatableSectionModel<String, Avatar>
public protocol AvatarSelectionViewModelType {
// Input
var onAvatarChange: Action<Int, Void> { mutating get }
var onAvatarChange: Action<Int, OnAvatarChangeReturnType> { mutating get }
var onRefresh: CocoaAction { mutating get }
var setAvatar: AnyObserver<String> { get }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment