|
//
// GroupViewModel.swift
// PaiaiDataKit
//
// Created by FFIB on 2017/1/4.
// Copyright © 2017年 FFIB. All rights reserved.
//
import Foundation
import RxSwift
import RxCocoa
import RxDataSources
public protocol GroupViewModelDelegate: class {
func didSelect(_ items: [PhotoItem], currIndex: Int)
func navigateToGroupDetail(_ item: GroupItem)
}
public class GroupViewModel {
private let disposeBag = DisposeBag()
private var repository: GroupPhotoRepository
private var _isLoading = PublishSubject<Void>()
private let _items: BehaviorRelay<[PhotoItem]>
private let _hasData = BehaviorRelay<Bool>(value: false)
public var groupItem: BehaviorRelay<GroupItem>
public var group_name: Observable<String> {
return groupItem.asObservable().flatMapLatest({ (item) -> Observable<String> in
return Observable.just(item.group_name)
})
}
public var group_avatar: Observable<String> {
return groupItem.asObservable().flatMapLatest({ (item) -> Observable<String> in
return Observable.just("Group\(item.group_default_avatar)")
})
}
public var isLoading: Observable<Void> {
return _isLoading.asObservable()
}
public var hasData: Observable<Bool> {
return _hasData.asObservable()
}
public var contents: Observable<[AnimatableSectionModel<Int, PhotoItem>]> {
return _items.map({ model in
return [AnimatableSectionModel(model: 0, items: model)]
})
}
public weak var delegate: GroupViewModelDelegate?
public init(groupItem: GroupItem, items: [PhotoItem] = []) {
self._items = BehaviorRelay<[PhotoItem]>(value: items)
self.repository = GroupPhotoRepository(groupId: groupItem.group_id)
self.groupItem = BehaviorRelay<GroupItem>(value: groupItem)
RecentGroupInfo.share.add(groupItem)
setNotification()
}
public func reload() {
repository.load()
.subscribe(onSuccess: {[weak self] (result) in
guard let `self` = self else { return }
self._isLoading.onNext(())
self._items.accept(result)
self._hasData.accept(result.count > 0)
}, onError: {[weak self] (_) in
guard let `self` = self else { return }
self._isLoading.onNext(())
}).disposed(by: disposeBag)
}
public func submit(data: Data) {
repository.upload(data: data).subscribe(onSuccess: { [weak self] result in
guard let `self` = self else { return }
self._items.accept(result)
var item = self.groupItem.value
item.group_photo_num = result.count
let userInfo = [GroupItemsOperator.key: GroupItemsOperator.update(self.groupItem.value.group_id, item)]
NotificationCenter.default.post(name: .GroupItemsChanged,
object: nil,
userInfo: userInfo)
Toast.show(message: "照片已上传")
self._isLoading.onNext(())
}, onError: {[weak self] _ in
guard let `self` = self else { return }
Toast.show(message: "照片失败")
self._isLoading.onNext(())
}).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)
}
private func setNotification() {
NotificationCenter.default.rx.notification(.GroupItemsChanged).subscribe(onNext: {
(notification) in
guard let itemOperator = notification.userInfo?[GroupItemsOperator.key] as? GroupItemsOperator,
case let .update(_, val) = itemOperator else { return }
self.groupItem.accept(val)
RecentGroupInfo.share.add(val)
var items = self._items.value
items = items.map({ item in
var tmp = item
tmp.group_name = val.group_name
return tmp
})
self._items.accept(items)
}).disposed(by: disposeBag)
NotificationCenter.default.rx.notification(.PhotoItemsChanged).subscribe(onNext: {
(notification) in
guard let itemOperator = notification.userInfo?[PhotoItemsOperator.key] as? PhotoItemsOperator,
case let .update(id, val) = itemOperator,
let index = self._items.value.firstIndex(where: { $0.photo_id == id }) else { return }
var items = self._items.value
items[index] = val
self._items.accept(items)
}).disposed(by: disposeBag)
}
}
/// GroupViewModelDelegate
public extension GroupViewModel {
func didSelect(_ index: Int) {
delegate?.didSelect(_items.value, currIndex: index)
}
@objc func navigateToGroupDetail() {
delegate?.navigateToGroupDetail(groupItem.value)
}
}
|