|
//
// HomeViewModel.swift
// PaiaiDataKit
//
// Created by FFIB on 2016/12/29.
// Copyright © 2016年 FFIB. All rights reserved.
//
import Foundation
import RxSwift
import RxCocoa
import RxDataSources
public protocol HomeViewModelDelegate: class {
func scanQR()
func createGroup()
func didSelect(_ items: [PhotoItem], currIndex: Int)
}
public class HomeViewModel {
private var page: Int = 1
private var repository: HomeRepository
private var _isLoading = PublishSubject<Bool>()
private var _hasMoreData = BehaviorRelay<Bool>(value: true)
private let _items = BehaviorRelay<[PhotoItem]>(value: [])
public var scanBtnTapped = PublishSubject<Void>()
public var createBtnTapped = PublishSubject<Void>()
public var isLoading: Observable<Bool> {
return _isLoading.asObservable()
}
public var hasMoreData: Observable<Bool> {
return _hasMoreData.asObservable()
}
public var contents: Observable<[AnimatableSectionModel<String, PhotoItem>]> {
return _items.map({ model in
return [AnimatableSectionModel(model: "photoItem", items: model)]
})
}
private let disposeBag = DisposeBag()
public weak var delegate: HomeViewModelDelegate?
public init() {
self.repository = HomeRepository()
scanBtnTapped.subscribe({ [unowned self] _ in
self.delegate?.scanQR()
}).disposed(by: disposeBag)
createBtnTapped.subscribe({ [unowned self] _ in
self.delegate?.createGroup()
}).disposed(by: disposeBag)
setNotification()
}
public func reload() {
page = 1
repository.load(page: page)
.subscribe(onSuccess: {[weak self] (result) in
guard let `self` = self else { return }
self._isLoading.onNext(true)
self._items.accept(result.data)
self._hasMoreData.accept(result.hasMore)
}, onError: {[weak self] (_) in
guard let `self` = self else { return }
self._isLoading.onNext(true)
}).disposed(by: disposeBag)
}
public func preload() {
guard _hasMoreData.value else { return }
page += 1
repository.load(page: page)
.subscribe(onSuccess: {[weak self] (result) in
guard let `self` = self else { return }
self._isLoading.onNext(false)
self._hasMoreData.accept(result.hasMore)
self._items.accept(self._items.value + result.data)
}, onError: {[weak self] (_) in
guard let `self` = self else { return }
self.page -= 1
self._isLoading.onNext(false)
}).disposed(by: disposeBag)
}
public func layoutSizeForIndexPath(_ indexPath: IndexPath) -> CGSize {
let item = _items.value[indexPath.row]
let width = item.photo_thumbnail_w
let height = item.photo_thumbnail_h
/// header 42, footer: 32
return CGSize(width: width, height: height + 74)
}
public func clear() {
_items.accept([])
}
private func setNotification() {
NotificationCenter.default.rx.notification(.GroupItemsChanged).subscribe(onNext: {
[unowned self] (notification) in
guard let userInfo = notification.userInfo,
let itemOperator = userInfo["operator"] as? GroupItemsOperator else { return }
var items = self._items.value
switch itemOperator {
case let .update(groupId, val):
items = items.map({ (item) -> PhotoItem in
if item.group_id == groupId {
var tmp = item
tmp.group_name = val.group_name
return tmp
}
return item
})
self._items.accept(items)
case let .remove(id):
items.removeAll(where: { $0.group_id == id })
self._items.accept(items)
}
}).disposed(by: disposeBag)
NotificationCenter.default.rx.notification(.PhotoItemsChanged).subscribe(onNext: {
[unowned self] (notification) in
guard let itemOperator = notification.userInfo?["operator"] as? PhotoItemsOperator,
case let .update(photoId, val) = itemOperator,
let index = self._items.value.firstIndex(where: { $0.photo_id == photoId })
else { return }
var items = self._items.value
items[index] = val
self._items.accept(items)
}).disposed(by: disposeBag)
}
}
//coordinator delegate
extension HomeViewModel {
public func didSelect(_ currIndex: Int) {
delegate?.didSelect(_items.value, currIndex: currIndex)
}
}
|