|
//
// MessageRepository.swift
// PaiAi
//
// Created by zhengjianfei on 16/4/7.
// Copyright © 2016年 FFIB. All rights reserved.
//
import Foundation
import RxCocoa
import RxSwift
protocol MessageInteractionModel {
var path: Interfaces { get }
var deletePath: Interfaces { get }
var readPath: Interfaces { get }
var title: String { get }
}
public enum MessageType: String {
case zan = "zan"
case comment = "comment"
case system = "system"
fileprivate var model: MessageInteractionModel {
switch self {
case .zan: return MessageZanInteractionModel()
case .comment: return MessageCommentInteractionModel()
case .system: return MessageSystemInteractionModel()
}
}
fileprivate struct MessageZanInteractionModel: MessageInteractionModel {
var path: Interfaces { return .mesThumbupList}
var deletePath: Interfaces { return .mesThumbupClear }
var readPath: Interfaces { return .mesThumbupRead }
var title: String { return "赞" }
}
fileprivate struct MessageCommentInteractionModel: MessageInteractionModel {
var path: Interfaces { return .mesCommentList}
var deletePath: Interfaces { return .mesCommentClear }
var readPath: Interfaces { return .mesCommentRead }
var title: String { return "评论" }
}
fileprivate struct MessageSystemInteractionModel: MessageInteractionModel {
var path: Interfaces { return .mesSystemList}
var deletePath: Interfaces { return .mesSystemClear }
var readPath: Interfaces { return .mesSystemRead }
var title: String { return "系统消息" }
}
}
public protocol MessageRepositorable: Repositorable where Content == [MessageItem] {
init(type: MessageType)
}
struct DeleteMessageResource: Resource {
var path: Interfaces
var parameter: Parameter
}
extension DeleteMessageResource: Parsable {
typealias Model = StatusModel
func parse(_ json: JSON) -> StatusModel? {
return StatusModel(json: json)
}
}
struct ReadMessageResource: Resource {
var path: Interfaces
var parameter: Parameter
}
extension ReadMessageResource: Parsable {
typealias Model = StatusModel
func parse(_ json: JSON) -> StatusModel? {
return StatusModel(json: json)
}
}
final class MessageRepository: Resource {
fileprivate var items: BehaviorRelay<[MessageItem]>
fileprivate var hasMore = true
fileprivate var page = 1
fileprivate var loadingSchedule: PublishSubject<Bool>
var path: Interfaces
var parameter: Parameter
fileprivate var contentsResource: Resource?
fileprivate var deleteResource: DeleteMessageResource
fileprivate var readResource: ReadMessageResource
init(type: MessageType) {
items = BehaviorRelay<[MessageItem]>(value: [])
loadingSchedule = PublishSubject<Bool>()
self.path = type.model.path
#warning("user_id 填充")
self.parameter = ["user_id": ""]
deleteResource = DeleteMessageResource(path: type.model.deletePath,
parameter: ["user_id": ""])
readResource = ReadMessageResource(path: type.model.deletePath,
parameter: ["user_id": "", "all": true])
}
func readMessage() {
NetworkApi.share.post(resource: readResource, completion: {_ in })
}
}
extension MessageRepository: Parsable {
func parse(_ json: JSON) -> [MessageItem]? {
guard let data = json["data"],
let messages = data["messages"] as? [[String: AnyObject]],
let left = data["left"] as? Int else { return nil }
hasMore = left > 0
return messages.map { return MessageItem(json: $0) }
}
}
extension MessageRepository: Gettable {
func loadContent(isRefresh: Bool) {
guard hasMore else { return }
page = isRefresh ? 1 : page + 1
contentsResource!.parameter["page"] = page
NetworkApi.share.post(resource: self) { result in
guard case let .success(messageItems) = result else { return }
if isRefresh {
self.items.accept(messageItems)
} else {
self.items.accept(self.items.value + messageItems)
}
}
}
}
extension MessageRepository: Deletable {
func remove(of index: Int) {
let item = items.value[index]
deleteResource.parameter["pk"] = item.pk
NetworkApi.share.post(resource: deleteResource) { result in
guard case .success(_) = result else { return }
var values = self.items.value
values.remove(at: index)
self.items.accept(values)
}
}
func removeAll() {
deleteResource.parameter["all"] = true
NetworkApi.share.post(resource: deleteResource) { result in
guard case .success(_) = result else { return }
self.items.accept([])
}
}
}
extension MessageRepository: MessageRepositorable {
public var content: Observable<[MessageItem]> {
return items.asObservable()
.flatMap { currentItems in
Observable.just(currentItems)
.distinctUntilChanged()
}.share()
}
public var loadingObserver: Observable<Bool> {
return loadingSchedule.asObserver()
.flatMap { current in
Observable.just(current)
}.share()
}
}
|