Skip to content

Instantly share code, notes, and snippets.

@AdieOlami
Created November 10, 2019 13:05
Show Gist options
  • Save AdieOlami/9725ba8f9bd8482c6406e5bf1a6a9e60 to your computer and use it in GitHub Desktop.
Save AdieOlami/9725ba8f9bd8482c6406e5bf1a6a9e60 to your computer and use it in GitHub Desktop.
class MyInfoViewModel: ViewModel, ViewModelType {
struct Input {
let trigger: Observable<Void>
let segmentSelection: Observable<EventSegments>
let selection: Driver<MyInfoSectionItem>
let deleted: Driver<MyInfoSectionItem>
}
struct Output {
let items: BehaviorRelay<[MyInfoSection]>
let selectedEvent: Driver<MyInfoSectionItem>
let deletedEvent: Driver<MyInfoSectionItem>
}
let nightModeEnabled: BehaviorRelay<Bool>
var cellDisposeBag = DisposeBag()
let deleteCommand = PublishRelay<IndexPath>()
override init(provider: Api) {
nightModeEnabled = BehaviorRelay(value: ThemeType.currentTheme().isDark)
super.init(provider: provider)
}
let identiferElements = BehaviorRelay<[IdentifierResponse]>(value: [])
let deviceElements = BehaviorRelay<[DeviceResponse]>(value: [])
let addressElements = BehaviorRelay<[AddressResponse]>(value: [])
let cardElements = BehaviorRelay<[CardResponse]>(value: [])
func transform(input: Input) -> Output {
let elements = BehaviorRelay<[MyInfoSection]>(value: [])
// let identiferDeleted = PublishSubject<IdentifierResponse>()
let identiferDeleted = BehaviorSubject<IdentifierResponse>(value: IdentifierResponse())
let cardDeleted = PublishSubject<CardResponse>()
let deviceDeleted = PublishSubject<DeviceResponse>()
let addressDeleted = PublishSubject<AddressResponse>()
let removeCache = PublishSubject<Void>()
let cacheRemoved = removeCache.flatMapLatest { () -> Observable<Void> in
return LibsManager.shared.removeKingfisherCache()
}
let refresh = Observable.of(input.trigger, cacheRemoved, nightModeEnabled.mapToVoid()).merge()
Observable.zip(identiferElements, deviceElements, addressElements, cardElements, refresh).map {(identifers, devices, addresses, cards, _) -> [MyInfoSection] in
var items: [MyInfoSection] = []
let identiferRepository = identifers.map({ (repository) -> MyInfoSectionItem in
let cellViewModel = IdentifiersCellViewModel(with: repository)
return MyInfoSectionItem.identifiersItem(viewModel: cellViewModel)
})
if identiferRepository.isNotEmpty {
items.append(MyInfoSection.setting(title: "Identifier", items: identiferRepository))
}
let deviceRepository = devices.map({ (repository) -> MyInfoSectionItem in
let cellViewModel = DevicesCellViewModel(with: repository)
return MyInfoSectionItem.devicesItem(viewModel: cellViewModel)
})
if deviceRepository.isNotEmpty {
items.append(MyInfoSection.setting(title: "Active Devices", items: deviceRepository))
}
let addressRepository = addresses.map({ (repository) -> MyInfoSectionItem in
let cellViewModel = AddressesCellViewModel(with: repository)
return MyInfoSectionItem.addressesItem(viewModel: cellViewModel)
})
if addressRepository.isNotEmpty {
items.append(MyInfoSection.setting(title: "Saved Addresses", items: addressRepository))
}
let cardRepository = cards.map({ (repository) -> MyInfoSectionItem in
let cellViewModel = CardsCellViewModel(with: repository)
return MyInfoSectionItem.cardsItem(viewModel: cellViewModel)
})
if cardRepository.isNotEmpty {
items.append(MyInfoSection.setting(title: "Saved Payment Methods", items: cardRepository))
}
return items
}.bind(to: elements).disposed(by: rx.disposeBag)
identifierTriggered(input)
deviceTriggered(input)
addressTriggered(input)
cardTriggered(input)
let selectedEvent = input.selection
let deletedEvent = input.deleted
deletedEvent.drive(onNext: { (item) in
switch item {
case .identifiersItem(let viewModel):
log(viewModel, .fuck)
identiferDeleted.onNext(viewModel.repository)
case .devicesItem(let viewModel):
deviceDeleted.onNext(viewModel.repository)
case .addressesItem(let viewModel):
addressDeleted.onNext(viewModel.repository)
case .cardsItem(let viewModel):
cardDeleted.onNext(viewModel.repository)
}
}).disposed(by: rx.disposeBag)
identiferDeleted.asObservable().flatMapLatest({ [weak self] (value) -> Observable<ResponseBase> in
log(value, .fuck)
guard let self = self, let id = value.id else { return Observable.just(ResponseBase()) }
return self.provider.deleteAddress(id: id)
.trackActivity(self.loading)
.trackError(self.error)
}).subscribe(onNext: { (res) in
log(res, .fuck)
}).disposed(by: rx.disposeBag)
addressDeleted.asObservable().flatMapLatest({ [weak self] (value) -> Observable<ResponseBase> in
log(value, .fuck)
guard let self = self, let id = value.id else { return Observable.just(ResponseBase()) }
return self.provider.deleteAddress(id: id)
.trackActivity(self.loading)
.trackError(self.error)
}).subscribe(onNext: { [weak self] (res) in
log(res, .fuck)
guard let self = self, let err = res.error else {return}
if !err {
log("FALSE ERROR", .fuck)
self.addressTriggered(input)
}
}).disposed(by: rx.disposeBag)
nightModeEnabled.subscribe(onNext: { (isEnabled) in
var theme = ThemeType.currentTheme()
if theme.isDark != isEnabled {
theme = theme.toggled()
}
themeService.switch(theme)
}).disposed(by: rx.disposeBag)
nightModeEnabled.skip(1).subscribe(onNext: { (isEnabled) in
// analytics.log(.appNightMode(enabled: isEnabled))
// analytics.updateUser(nightMode: isEnabled)
}).disposed(by: rx.disposeBag)
cacheRemoved.subscribe(onNext: { () in
// analytics.log(.appCacheRemoved)
}).disposed(by: rx.disposeBag)
return Output(items: elements, selectedEvent: selectedEvent, deletedEvent: deletedEvent)
}
// MARK: - Identifer Triggred
func identifierTriggered(_ input: Input) {
input.trigger.flatMapLatest { [weak self] () -> Observable<FastResponseArray<IdentifierResponse>> in
guard let self = self else { return Observable.just(FastResponseArray<IdentifierResponse>()) }
return self.provider.getIdentifier()
.trackActivity(self.loading)
.trackError(self.error)
}.subscribe(onNext: { [weak self] (repository) in
guard let self = self, let data = repository.data else { return }
self.identiferElements.accept(data)
}).disposed(by: rx.disposeBag)
}
// MARK: - Device Triggred
func deviceTriggered(_ input: Input) {
input.trigger.flatMapLatest { [weak self] () -> Observable<FastResponseArray<DeviceResponse>> in
guard let self = self else { return Observable.just(FastResponseArray<DeviceResponse>()) }
return self.provider.getDevices()
.trackActivity(self.loading)
.trackError(self.error)
}.subscribe(onNext: { [weak self] (repository) in
guard let self = self, let data = repository.data else { return }
self.deviceElements.accept(data)
}).disposed(by: rx.disposeBag)
}
// MARK: - Address Triggred
func addressTriggered(_ input: Input) {
input.trigger.flatMapLatest { [weak self] () -> Observable<FastResponseArray<AddressResponse>> in
guard let self = self else { return Observable.just(FastResponseArray<AddressResponse>()) }
return self.provider.getAddresses()
.trackActivity(self.loading)
.trackError(self.error)
}.subscribe(onNext: { [weak self] (repository) in
guard let self = self, let data = repository.data else { return }
self.addressElements.accept(data)
}, onError: { err in
log(err, .lin)
}).disposed(by: rx.disposeBag)
}
// MARK: - Card Triggred
func cardTriggered(_ input: Input) {
input.trigger.flatMapLatest { [weak self] () -> Observable<FastResponseArray<CardResponse>> in
guard let self = self else { return Observable.just(FastResponseArray<CardResponse>()) }
return self.provider.getCards()
.trackActivity(self.loading)
.trackError(self.error)
}.subscribe(onNext: { [weak self] (repository) in
guard let self = self, let data = repository.data else { return }
self.cardElements.accept(data)
}, onError: { err in
log(err, .lin)
}).disposed(by: rx.disposeBag)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment