Commit 813da292 authored by Maurice Kraus's avatar Maurice Kraus
Browse files

fix: this fixes the issue of overwriting the db

This commit addresses the issue of overwriting the avatar and title
models while making a foreign request.
parent 50de3b7c
......@@ -115,7 +115,7 @@ struct AssemblyHelper {
// MARK: - FindOpponentHelper
func makeMakeFindOpponentCellViewModel(resolver: Resolver, friendRepository: FriendRepository, avatarRepository: AvatarRepository, duelRepository: DuelRepository) -> MakeFindOpponentCellViewModel { { (opponent: TruncatedUser, startedDuel: AnyObserver<Void>) in
resolver.resolveFindOpponentCellViewModel(opponent: opponent, startedDuel: startedDuel, friendRepository: friendRepository, avatarRepository: avatarRepository, duelRepository: duelRepository) }
func makeMakeFindOpponentCellViewModel(resolver: Resolver, friendRepository: FriendRepository, avatarRepository: AvatarRepository, duelRepository: DuelRepository, titleRepository: TitleRepository) -> MakeFindOpponentCellViewModel { { (opponent: TruncatedUser, startedDuel: AnyObserver<Void>) in
resolver.resolveFindOpponentCellViewModel(opponent: opponent, startedDuel: startedDuel, friendRepository: friendRepository, avatarRepository: avatarRepository, duelRepository: duelRepository, titleRepository: titleRepository) }
}
}
......@@ -23,17 +23,19 @@ class FavoritesViewModelAssembly: Assembly {
let friendRepository = resolver.resolveFriendRepository(appState: appState, loggedInStatus: loggedInStatus, urlSession: urlSession)
let avatarRepository = resolver.resolveAvatarRepository(appState: appState, urlSession: urlSession)
let duelRepository = resolver.resolveDuelRepository(appState: appState, loggedInStatus: loggedInStatus, urlSession: urlSession)
let titleRepository = resolver.resolveTitleRepository(appState: appState, urlSession: urlSession)
let makeFindOpponentCellViewModel = self.helper.makeMakeFindOpponentCellViewModel(resolver: resolver,
friendRepository: friendRepository,
avatarRepository: avatarRepository,
duelRepository: duelRepository)
duelRepository: duelRepository,
titleRepository: titleRepository)
return FavoritesViewModel(friendRepository: friendRepository, makeFindOpponentCellViewModel: makeFindOpponentCellViewModel, loggedInStatus: loggedInStatus)
}
container.register(FindOpponentCellViewModel.self) { (_, opponent: TruncatedUser, startedDuel: AnyObserver<Void>, friendRepository: FriendRepository, avatarRepository: AvatarRepository, duelRepository: DuelRepository) in
FindOpponentCellViewModel(opponent: opponent, startedDuel: startedDuel, friendRepository: friendRepository, avatarRepository: avatarRepository, duelRepository: duelRepository)
container.register(FindOpponentCellViewModel.self) { (_, opponent: TruncatedUser, startedDuel: AnyObserver<Void>, friendRepository: FriendRepository, avatarRepository: AvatarRepository, duelRepository: DuelRepository, titleRepository: TitleRepository) in
FindOpponentCellViewModel(opponent: opponent, startedDuel: startedDuel, friendRepository: friendRepository, avatarRepository: avatarRepository, duelRepository: duelRepository, titleRepository: titleRepository)
}
}
}
......@@ -53,7 +55,7 @@ extension Resolver {
startedDuel: AnyObserver<Void>,
friendRepository: FriendRepository,
avatarRepository: AvatarRepository,
duelRepository: DuelRepository) -> FindOpponentCellViewModel {
resolve(FindOpponentCellViewModel.self, arguments: opponent, startedDuel, friendRepository, avatarRepository, duelRepository)!
duelRepository: DuelRepository, titleRepository: TitleRepository) -> FindOpponentCellViewModel {
resolve(FindOpponentCellViewModel.self, arguments: opponent, startedDuel, friendRepository, avatarRepository, duelRepository, titleRepository)!
}
}
......@@ -15,8 +15,9 @@ class SelectDuelPoolViewModelAssembly: Assembly {
func assemble(container: Container) {
container.register(SelectDuelPoolViewModelType.self) { (resolver: Resolver, appState: StateRelay, loggedInStatus: Observable<Bool>, urlSession: URLSession, duel: Duel, userProfile: UserProfile, mode: SelectDuelPoolMode) in
let duelRepository = resolver.resolveDuelRepository(appState: appState, loggedInStatus: loggedInStatus, urlSession: urlSession)
let avatarRepository = resolver.resolveAvatarRepository(appState: appState, urlSession: urlSession)
return SelectDuelPoolViewModel(mode: mode, duel: duel, profile: userProfile, duelRepository: duelRepository)
return SelectDuelPoolViewModel(mode: mode, duel: duel, profile: userProfile, duelRepository: duelRepository, avatarRepository: avatarRepository)
}
}
}
......
......@@ -29,8 +29,15 @@ class SelectDuelViewModelAssembly: Assembly {
loginStatus: loggedInStatus)
}
container.register(SelectDuelCellViewModelType.self) { (_: Resolver, userId: Int, avatarRepository: AvatarRepository, duelRepository: DuelRepository, duel: Duel, startDuel: AnyObserver<Duel>) in
SelectDuelCellViewModel(avatarRepository: avatarRepository, duelRepository: duelRepository, duel: duel, userId: userId, startDuelObserver: startDuel)
container.register(SelectDuelCellViewModelType.self) {
(_: Resolver,
userId: Int,
titleRepository: TitleRepository,
avatarRepository: AvatarRepository,
duelRepository: DuelRepository,
duel: Duel,
startDuel: AnyObserver<Duel>) in
SelectDuelCellViewModel(titleRepository: titleRepository, avatarRepository: avatarRepository, duelRepository: duelRepository, duel: duel, userId: userId, startDuelObserver: startDuel)
}
}
}
......@@ -40,7 +47,12 @@ extension Resolver {
resolve(SelectDuelViewModelType.self, arguments: appState, loggedInStatus)!
}
public func resolveSelectDuelCellViewModel(userId: Int, duel: Duel, avatarRepository: AvatarRepository, duelRepository: DuelRepository, startDuel: AnyObserver<Duel>) -> SelectDuelCellViewModel {
resolve(SelectDuelCellViewModelType.self, arguments: userId, avatarRepository, duelRepository, duel, startDuel) as! SelectDuelCellViewModel
public func resolveSelectDuelCellViewModel(userId: Int,
duel: Duel,
titleRepository: TitleRepository,
avatarRepository: AvatarRepository,
duelRepository: DuelRepository,
startDuel: AnyObserver<Duel>) -> SelectDuelCellViewModel {
resolve(SelectDuelCellViewModelType.self, arguments: userId, titleRepository, avatarRepository, duelRepository, duel, startDuel) as! SelectDuelCellViewModel
}
}
......@@ -25,7 +25,8 @@ public class Avatar: Object, Codable {
/// Convenient attribute that indicates whether an avatar is unlocked or locked
internal dynamic var isUnlocked: Bool = false
public private(set) var imageInformation: ImageInformation = ImageInformation(image: KFCrossPlatformImage(named: "blurPlaceholderLogo", in: Bundle.akamuCore, compatibleWith: nil) ?? KFCrossPlatformImage(), isPlaceholder: true)
public private(set) var imageInformation: ImageInformation =
ImageInformation(image: KFCrossPlatformImage(named: "blurPlaceholderLogo", in: Bundle.akamuCore, compatibleWith: nil) ?? KFCrossPlatformImage(), isPlaceholder: true)
private enum CodingKeys: String, CodingKey {
case id
......@@ -74,7 +75,8 @@ extension Avatar: IdentifiableType {
lhs.id == rhs.id &&
lhs.resourceId == rhs.resourceId &&
lhs.level == rhs.level &&
lhs.imageInformation.isPlaceholder == rhs.imageInformation.isPlaceholder
lhs.imageInformation.isPlaceholder == rhs.imageInformation.isPlaceholder &&
lhs.isUnlocked == rhs.isUnlocked
}
}
......@@ -82,6 +84,6 @@ extension Avatar {
static func getDefault() -> Avatar {
logger.warn("Avatar with id was not available, fallback to default")
// TODO: - Need to check a correct image Path
return Avatar(id: 2000, resourceId: 1, level: 0)
return Avatar(id: 2000, resourceId: 1, level: 0, isUnlocked: true)
}
}
......@@ -14,7 +14,7 @@ import UIKit
@objcMembers
public class Duel: Object, Decodable {
public dynamic var id: Int = -1
public dynamic var userNext: TruncatedUser?
public dynamic var nextUserId: Int = -1
public dynamic var timeStarted: Date = Date()
public dynamic var timeModified: Date = Date()
public dynamic var timeEnd: Date?
......@@ -42,10 +42,15 @@ public class Duel: Object, Decodable {
case players = "participants"
}
private enum UserNextCodingKeys: String, CodingKey {
case nextUserId = "id"
}
public required convenience init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let id = try container.decode(Int.self, forKey: .id)
let userNext = try container.decode(TruncatedUser.self, forKey: .userNext)
let userNextContainer = try container.nestedContainer(keyedBy: UserNextCodingKeys.self, forKey: .userNext)
let nextUserId: Int = try userNextContainer.decode(.nextUserId)
let timeStarted = try container.decode(Date.self, forKey: .timeStarted) ?? Date()
let timeModified = try container.decode(Date.self, forKey: .timeModified) ?? Date()
let timeEnd = try container.decodeIfPresent(Date.self, forKey: .timeModified)
......@@ -68,14 +73,14 @@ public class Duel: Object, Decodable {
let playersList = List<DuelPlayer>()
playersList.append(objectsIn: duelPlayers)
self.init(id: id, userNext: userNext, timeStarted: timeStarted, timeModified: timeModified, timeEnd: timeEnd, roundCurrent: roundCurrent, roundMax: roundMax, running: running, rounds: roundsList, players: playersList)
self.init(id: id, nextUserId: nextUserId, timeStarted: timeStarted, timeModified: timeModified, timeEnd: timeEnd, roundCurrent: roundCurrent, roundMax: roundMax, running: running, rounds: roundsList, players: playersList)
}
public convenience init(id: Int, userNext: TruncatedUser, timeStarted: Date, timeModified: Date, timeEnd: Date?, roundCurrent: Int, roundMax: Int, running: Bool, rounds: List<Round>, players: List<DuelPlayer>) {
public convenience init(id: Int, nextUserId: Int, timeStarted: Date, timeModified: Date, timeEnd: Date?, roundCurrent: Int, roundMax: Int, running: Bool, rounds: List<Round>, players: List<DuelPlayer>) {
self.init()
self.id = id
self.running = running
self.userNext = userNext
self.nextUserId = nextUserId
self.roundCurrent = roundCurrent
self.timeStarted = timeStarted
self.timeModified = timeModified
......@@ -98,7 +103,7 @@ public class Duel: Object, Decodable {
}
private static func isEqual(lhs: Duel, rhs: Duel) -> Bool {
lhs.id == rhs.id && lhs.players.toArray() == rhs.players.toArray() && lhs.roundCurrent == rhs.roundCurrent && lhs.rounds.toArray() == rhs.rounds.toArray() && lhs.userNext == rhs.userNext
lhs.id == rhs.id && lhs.players.toArray() == rhs.players.toArray() && lhs.roundCurrent == rhs.roundCurrent && lhs.rounds.toArray() == rhs.rounds.toArray() && lhs.nextUserId == rhs.nextUserId
}
}
......@@ -110,19 +115,19 @@ extension Duel: IdentifiableType {
extension Duel {
public static func getDefault() -> Duel {
let player1 = TruncatedUser(id: 1, username: "Player1", title: Title.getDefault(), avatar: Avatar.getDefault())
let player2 = TruncatedUser(id: 2, username: "Player2", title: Title.getDefault(), avatar: Avatar.getDefault())
let list = List<DuelPlayer>()
let duelPlayer1 = DuelPlayer()
duelPlayer1.duelId = 1
duelPlayer1.score = 10
duelPlayer1.user = player1
duelPlayer1.avatarId = 1
duelPlayer1.titleId = 1
list.append(duelPlayer1)
let duelPlayer2 = DuelPlayer()
duelPlayer2.duelId = 1
duelPlayer2.score = 15
duelPlayer2.user = player2
duelPlayer2.avatarId = 1
duelPlayer2.titleId = 1
list.append(duelPlayer2)
return Duel(id: 1, userNext: player1, timeStarted: Date(), timeModified: Date(), timeEnd: nil, roundCurrent: 0, roundMax: 1, running: true, rounds: List(), players: list)
return Duel(id: 1, nextUserId: 1, timeStarted: Date(), timeModified: Date(), timeEnd: nil, roundCurrent: 0, roundMax: 1, running: true, rounds: List(), players: list)
}
}
......@@ -13,36 +13,54 @@ import RxDataSources
@objcMembers
public class DuelPlayer: Object, Decodable {
/* Only needed for decoding */
private let userId: Int? = nil
private let username: String? = nil
private let title: Title? = nil
private let avatar: Avatar? = nil
/* ------------------------ */
public dynamic var id: String = UUID().uuidString
public dynamic var duelId: Int = -1
public dynamic var user: TruncatedUser?
public dynamic var userId: Int = -1
public dynamic var username: String = ""
public dynamic var titleId: Int = -1
public dynamic var avatarId: Int = -1
public dynamic var score: Int = -1
private enum CodingKeys: String, CodingKey {
case userId = "id"
case username
case title
case avatar
case score
case title, avatar, score, username, userId = "id"
}
init(from decoder: Decoder, duelId: Int) throws {
super.init()
private enum TitleCodingKeys: String, CodingKey {
case titleId = "id"
}
private enum AvatarCodingKeys: String, CodingKey {
case avatarId = "id"
}
convenience init(username: String, userId: Int, avatarId: Int, titleId: Int, score: Int, duelId: Int) {
self.init()
self.username = username
self.userId = userId
self.avatarId = avatarId
self.titleId = titleId
self.score = score
self.duelId = duelId
}
/// Do not use this initializer as it is only present to comply with the protocol.
/// This method will execute a fatal error
public required convenience init(from decoder: Decoder) throws {
fatalError("Do not use this initializer as it is only present to comply with the protocol.")
}
convenience init(from decoder: Decoder, duelId: Int) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let userId: Int = try container.decode(.userId)
let avatarContainer = try container.nestedContainer(keyedBy: AvatarCodingKeys.self, forKey: .avatar)
let titleContainer = try container.nestedContainer(keyedBy: TitleCodingKeys.self, forKey: .title)
let username: String = try container.decode(.username)
let title: Title = try container.decode(.title)
let avatar: Avatar = try container.decode(.avatar)
user = TruncatedUser(id: userId, username: username, title: title, avatar: avatar)
score = try container.decode(.score)
self.duelId = duelId
let userId: Int = try container.decode(.userId)
let avatarId: Int = try avatarContainer.decode(.avatarId)
let titleId: Int = try titleContainer.decode(.titleId)
let score: Int = try container.decode(.score)
self.init(username: username, userId: userId, avatarId: avatarId, titleId: titleId, score: score, duelId: duelId)
}
override public static func primaryKey() -> String? {
......@@ -61,7 +79,7 @@ public class DuelPlayer: Object, Decodable {
}
private static func isEqual(lhs: DuelPlayer, rhs: DuelPlayer) -> Bool {
lhs.id == rhs.id && rhs.score == lhs.score && lhs.user == rhs.user
lhs.id == rhs.id && rhs.score == lhs.score && lhs.userId == rhs.userId && lhs.avatarId == rhs.avatarId && lhs.titleId == rhs.titleId
}
required init() {
......
......@@ -13,7 +13,7 @@ import UIKit
public class Round: Object, Decodable {
@objc public dynamic var id: Int = -1
@objc public dynamic var number: Int = -1
@objc public dynamic var started: TruncatedUser?
@objc public dynamic var startedUserId: Int = -1
@objc public dynamic var pool: Pool?
@objc public dynamic var isAnswered: Bool = false
public var questions = List<Question>()
......@@ -22,11 +22,11 @@ public class Round: Object, Decodable {
"id"
}
convenience init(id: Int, number: Int, started: TruncatedUser, isAnswered: Bool, pool: Pool, questions: List<Question>) {
convenience init(id: Int, number: Int, startedUserId: Int, isAnswered: Bool, pool: Pool, questions: List<Question>) {
self.init()
self.id = id
self.number = number
self.started = started
self.startedUserId = startedUserId
self.pool = pool
self.isAnswered = isAnswered
self.questions = questions
......@@ -40,19 +40,24 @@ public class Round: Object, Decodable {
case pool
case questions
}
private enum UserCodingKeys: String, CodingKey {
case startedUserId = "id"
}
public required convenience init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let id = try container.decode(Int.self, forKey: .id)
let number = try container.decode(Int.self, forKey: .number)
let started = try container.decode(TruncatedUser.self, forKey: .started)
let startedUserContainer = try container.nestedContainer(keyedBy: UserCodingKeys.self, forKey: .started)
let startedId: Int = try startedUserContainer.decode(.startedUserId)
let pool = try container.decode(Pool.self, forKey: .pool)
let isAnswered = try container.decode(Bool.self, forKey: .isAnswered)
let questionArray = try container.decodeIfPresent([Question].self, forKey: .questions)
let questionList = List<Question>()
questionList.append(objectsIn: questionArray ?? [])
self.init(id: id, number: number, started: started, isAnswered: isAnswered, pool: pool, questions: questionList)
self.init(id: id, number: number, startedUserId: startedId, isAnswered: isAnswered, pool: pool, questions: questionList)
}
public static func == (lhs: Round, rhs: Round) -> Bool {
......
......@@ -16,36 +16,44 @@ public typealias Friend = TruncatedUser
public class TruncatedUser: Object, Decodable {
public dynamic var id: Int = -1
public dynamic var username: String = ""
/// Currently selected title of the user
public var title: Title?
/// Currently selected avatar of the user
public var avatar: Avatar?
/// Currently selected titleId of the user
public dynamic var titleId: Int = -1
/// Currently selected avatarId of the user
public dynamic var avatarId: Int = -1
internal dynamic var isFriend: Bool = false
public convenience init(id: Int, username: String, title: Title, avatar: Avatar, isFriend: Bool = false) {
public convenience init(id: Int, username: String, titleId: Int, avatarId: Int, isFriend: Bool = false) {
self.init()
self.id = id
self.username = username
self.title = title
self.avatar = avatar
self.titleId = titleId
self.avatarId = avatarId
self.isFriend = isFriend
}
private enum CodingKeys: String, CodingKey {
case id
case username
case title
case avatar
case id, username, title, avatar
}
private enum TitleCodingKeys: String, CodingKey {
case titleId
}
private enum AvatarCodingKeys: String, CodingKey {
case avatarId
}
public required convenience init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let id = try container.decode(Int.self, forKey: .id)
let username = try container.decode(String.self, forKey: .username)
let avatar = try container.decode(Avatar.self, forKey: .avatar)
let title = try container.decode(Title.self, forKey: .title)
let avatarContainer = try container.nestedContainer(keyedBy: AvatarCodingKeys.self, forKey: .avatar)
let avatarId = try avatarContainer.decode(Int.self, forKey: .avatarId)
self.init(id: id, username: username, title: title, avatar: avatar)
let titleContainer = try container.nestedContainer(keyedBy: TitleCodingKeys.self, forKey: .title)
let titleId = try titleContainer.decode(Int.self, forKey: .titleId)
self.init(id: id, username: username, titleId: titleId, avatarId: avatarId)
}
override public class func primaryKey() -> String? {
......@@ -64,7 +72,7 @@ public class TruncatedUser: Object, Decodable {
}
private static func isEqual(lhs: TruncatedUser, rhs: TruncatedUser) -> Bool {
lhs.id == rhs.id && lhs.username == rhs.username && lhs.isFriend == rhs.isFriend && lhs.avatar == rhs.avatar && lhs.title == rhs.title
lhs.id == rhs.id && lhs.username == rhs.username && lhs.isFriend == rhs.isFriend && lhs.avatarId == rhs.avatarId && lhs.titleId == rhs.titleId
}
}
......
......@@ -42,7 +42,7 @@ public class AkamuDuelRepository: DuelRepository {
.flatMap { (duels: [Duel]) -> Observable<Observable<(Duel, [Pool])>> in
// we want to do these requets in parallel
Observable.from(duels.map { (duel: Duel) in
let duelPools = duel.running && self.userId == duel.userNext?.id ? self.fetchDuelPools(with: duel.id)
let duelPools = duel.running && self.userId == duel.nextUserId ? self.fetchDuelPools(with: duel.id)
.asObservable() : Observable.just([])
return Observable.zip(Observable.just(duel), duelPools)
})
......
......@@ -48,7 +48,7 @@ class AvatarRealmDatastore: DatastoreBase, AvatarDatastore {
.asSingle()
.flatMap { _ -> Single<Void> in
RealmConfig.withRealmAsync("creating multiple avatars") { realm in
realm.add(avatars, update: .all)
realm.add(avatars, update: .modified)
}
}.catchError { _ in
.error(AvatarDatastoreError.creationFailed)
......
......@@ -21,16 +21,16 @@ class FakeFriendRemoteAPI: FriendRemoteAPI {
}
func addFriend(with id: Int) -> Single<Void> {
friends.append(Friend(id: id, username: "Friend\(id)", title: Title.getDefault(), avatar: Avatar.getDefault()))
friends.append(Friend(id: id, username: "Friend\(id)", titleId: 1, avatarId: 1))
return .just(())
}
private var friends = [
Friend(id: 0, username: "Friend1", title: Title.getDefault(), avatar: Avatar.getDefault()),
Friend(id: 1, username: "Friend1", title: Title.getDefault(), avatar: Avatar.getDefault()),
Friend(id: 2, username: "Friend1", title: Title.getDefault(), avatar: Avatar.getDefault()),
Friend(id: 3, username: "Friend1", title: Title.getDefault(), avatar: Avatar.getDefault()),
Friend(id: 4, username: "Friend1", title: Title.getDefault(), avatar: Avatar.getDefault())
Friend(id: 0, username: "Friend1", titleId: 1, avatarId: 1),
Friend(id: 1, username: "Friend1", titleId: 1, avatarId: 1),
Friend(id: 2, username: "Friend1", titleId: 1, avatarId: 1),
Friend(id: 3, username: "Friend1", titleId: 1, avatarId: 1),
Friend(id: 4, username: "Friend1", titleId: 1, avatarId: 1),
]
init() {}
......
......@@ -26,11 +26,11 @@ public struct FindOpponentCellViewModel {
private let errorSubject: PublishSubject<String>
public let isFriend: Driver<Bool>
public let name: String
public let title: String
public let title: Driver<String>
public let avatar: Driver<KFCrossPlatformImage>
public let showError: Driver<String>
init(opponent: TruncatedUser, startedDuel: AnyObserver<Void>, friendRepository: FriendRepository, avatarRepository: AvatarRepository, duelRepository: DuelRepository) {
init(opponent: TruncatedUser, startedDuel: AnyObserver<Void>, friendRepository: FriendRepository, avatarRepository: AvatarRepository, duelRepository: DuelRepository, titleRepository: TitleRepository) {
friendRelay = BehaviorRelay(value: opponent.isFriend)
self.opponent = opponent
self.duelRepository = duelRepository
......@@ -39,8 +39,8 @@ public struct FindOpponentCellViewModel {
disposeBag = DisposeBag()
isFriend = friendRelay.asDriver(onErrorJustReturn: false)
name = opponent.username
title = opponent.title?.name ?? "Kein Title"
avatar = avatarRepository.getAvatar(with: opponent.avatar?.id ?? 0).map { $0.imageInformation.image }.asDriver(onErrorJustReturn: KFCrossPlatformImage())
title = titleRepository.getTitle(with: opponent.titleId).map { $0.name }.asDriver(onErrorJustReturn: I18n.general.error.noTitleAvailable)
avatar = avatarRepository.getAvatar(with: opponent.avatarId).map { $0.imageInformation.image }.asDriver(onErrorJustReturn: KFCrossPlatformImage())
showError = errorSubject.asDriver(onErrorJustReturn: I18n.general.error.unknown)
......
......@@ -30,9 +30,11 @@ public struct AvatarSelectionViewModel: AvatarSelectionViewModelType {
public let setAvatar: AnyObserver<String>
public lazy var onAvatarChange: Action<Int, Void> = { (avatarRepository: AvatarRepository) in
Action { (avatarId: Int) -> Observable<Void> in
avatarRepository.updateUserAvatar(with: avatarId)
.map { _ in }
.asObservable()
avatarRepository.getAvatar(with: avatarId)
.flatMap { (avatar: Avatar) in
!avatar.isUnlocked ?
Observable.empty() : avatarRepository.updateUserAvatar(with: avatarId).map { _ in }.asObservable()
}
}
}(self.avatarRepository)
......@@ -47,27 +49,25 @@ public struct AvatarSelectionViewModel: AvatarSelectionViewModelType {
didSelectAvatar = finishAvatarSelectionSubject.asDriver(onErrorJustReturn: ())
sections = avatarRepository.getAvatars()
.observeOn(Thread.main)
.map { results -> ([Avatar], [Avatar]) in
// TODO: need to find appropriate solution
var unlockedTitleViewModel = [Avatar]()
var lockedTitleViewModel = [Avatar]()
.map { results -> [Avatar] in
var avatars = [Avatar]()
results.forEach { avatar in
avatar.isUnlocked ?
unlockedTitleViewModel.append(avatar) :
unlockedTitleViewModel.append(avatar
avatars.append(avatar) :
avatars.append(avatar
.set(imageInformation: ImageInformation(image:
KFCrossPlatformImage(named: "LockedAvatar",
in: Bundle.akamuCore,
compatibleWith: nil)
?? KFCrossPlatformImage(), isPlaceholder: false)))
}
unlockedTitleViewModel.sort { $0.isUnlocked && !$1.isUnlocked }
return (unlockedTitleViewModel, unlockedTitleViewModel)
}.map { (avatarArrays: ([Avatar], [Avatar])) -> [AvatarSection] in
avatars.sort { $0.id < $1.id && $0.level <= $1.level }
return avatars
}.map { (avatars: [Avatar]) -> [AvatarSection] in
[
AvatarSection(model: I18n.profile.avatarSelection.sectionTitle.unlockedAvatars, items: avatarArrays.0)
//AvatarSection(model: I18n.profile.avatarSelection.sectionTitle.lockedAvatars, items: avatarArrays.1)
AvatarSection(model: I18n.profile.avatarSelection.sectionTitle.unlockedAvatars, items: avatars)
]
}.asDriver(onErrorJustReturn: [AvatarSection(model: I18n.profile.avatarSelection.sectionTitle.error, items: [])])
......
......@@ -27,14 +27,14 @@ public struct SelectDuelCellViewModel: SelectDuelCellViewModelType {
public let opponentAvatarLoading: Driver<Bool>
public let duelScore: Driver<String>
public init(avatarRepository: AvatarRepository, duelRepository: DuelRepository, duel: Duel, userId: Int, startDuelObserver: AnyObserver<Duel>) {
public init(titleRepository: TitleRepository, avatarRepository: AvatarRepository, duelRepository: DuelRepository, duel: Duel, userId: Int, startDuelObserver: AnyObserver<Duel>) {
self.duel = duel
self.userId = userId
self.duelRepository = duelRepository