Add updating logic to text message (#178)
* Add updating logic to text message * Change Observable to class * Fix avatar hiding * Move willBeShown/wasHidden declarations to common protocol
This commit is contained in:
parent
7541a5ab64
commit
1ef46a0e35
|
|
@ -97,9 +97,7 @@ public class BaseMessagePresenter<BubbleViewT, ViewModelBuilderT, InteractionHan
|
|||
public func configureCell(cell: CellT, decorationAttributes: ChatItemDecorationAttributes, animated: Bool, additionalConfiguration: (() -> Void)?) {
|
||||
cell.performBatchUpdates({ () -> Void in
|
||||
self.messageViewModel.showsTail = decorationAttributes.showsTail
|
||||
if !decorationAttributes.canShowAvatar {
|
||||
self.messageViewModel.avatarImage.value = nil
|
||||
}
|
||||
cell.avatarView.hidden = !decorationAttributes.canShowAvatar
|
||||
cell.bubbleView.userInteractionEnabled = true // just in case something went wrong while showing UIMenuController
|
||||
cell.baseStyle = self.cellStyle
|
||||
cell.messageViewModel = self.messageViewModel
|
||||
|
|
|
|||
|
|
@ -54,6 +54,8 @@ public protocol MessageViewModelProtocol: class { // why class? https://gist.git
|
|||
|
||||
public protocol DecoratedMessageViewModelProtocol: MessageViewModelProtocol {
|
||||
var messageViewModel: MessageViewModelProtocol { get }
|
||||
func willBeShown()
|
||||
func wasHidden()
|
||||
}
|
||||
|
||||
extension DecoratedMessageViewModelProtocol {
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ public class PhotoMessagePresenter<ViewModelBuilderT, InteractionHandlerT where
|
|||
let updateClosure = { [weak self] (old: Any, new: Any) -> () in
|
||||
self?.updateCurrentCell()
|
||||
}
|
||||
viewModel.avatarImage.observe(self, closure: updateClosure)
|
||||
viewModel.image.observe(self, closure: updateClosure)
|
||||
viewModel.transferDirection.observe(self, closure: updateClosure)
|
||||
viewModel.transferProgress.observe(self, closure: updateClosure)
|
||||
|
|
|
|||
|
|
@ -42,13 +42,6 @@ public protocol PhotoMessageViewModelProtocol: DecoratedMessageViewModelProtocol
|
|||
var transferStatus: Observable<TransferStatus> { get set }
|
||||
var image: Observable<UIImage?> { get set }
|
||||
var imageSize: CGSize { get }
|
||||
func willBeShown() // Optional
|
||||
func wasHidden() // Optional
|
||||
}
|
||||
|
||||
public extension PhotoMessageViewModelProtocol {
|
||||
func willBeShown() {}
|
||||
func wasHidden() {}
|
||||
}
|
||||
|
||||
public class PhotoMessageViewModel<PhotoMessageModelT: PhotoMessageModelProtocol>: PhotoMessageViewModelProtocol {
|
||||
|
|
|
|||
|
|
@ -64,6 +64,26 @@ public class TextMessagePresenter<ViewModelBuilderT, InteractionHandlerT where
|
|||
let identifier = self.messageViewModel.isIncoming ? "text-message-incoming" : "text-message-outcoming"
|
||||
return collectionView.dequeueReusableCellWithReuseIdentifier(identifier, forIndexPath: indexPath)
|
||||
}
|
||||
|
||||
public override func createViewModel() -> ViewModelBuilderT.ViewModelT {
|
||||
let viewModel = self.viewModelBuilder.createViewModel(self.messageModel)
|
||||
let updateClosure = { [weak self] (old: Any, new: Any) -> () in
|
||||
self?.updateCurrentCell()
|
||||
}
|
||||
viewModel.avatarImage.observe(self, closure: updateClosure)
|
||||
return viewModel
|
||||
}
|
||||
|
||||
public var textCell: TextMessageCollectionViewCell? {
|
||||
if let cell = self.cell {
|
||||
if let textCell = cell as? TextMessageCollectionViewCell {
|
||||
return textCell
|
||||
} else {
|
||||
assert(false, "Invalid cell was given to presenter!")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
public override func configureCell(cell: BaseMessageCollectionViewCell<TextBubbleView>, decorationAttributes: ChatItemDecorationAttributes, animated: Bool, additionalConfiguration: (() -> Void)?) {
|
||||
guard let cell = cell as? TextMessageCollectionViewCell else {
|
||||
|
|
@ -78,6 +98,20 @@ public class TextMessagePresenter<ViewModelBuilderT, InteractionHandlerT where
|
|||
additionalConfiguration?()
|
||||
}
|
||||
}
|
||||
|
||||
public override func cellWillBeShown() {
|
||||
self.messageViewModel.willBeShown()
|
||||
}
|
||||
|
||||
public override func cellWasHidden() {
|
||||
self.messageViewModel.wasHidden()
|
||||
}
|
||||
|
||||
public func updateCurrentCell() {
|
||||
if let cell = self.textCell, decorationAttributes = self.decorationAttributes {
|
||||
self.configureCell(cell, decorationAttributes: decorationAttributes, animated: self.itemVisibility != .Appearing, additionalConfiguration: nil)
|
||||
}
|
||||
}
|
||||
|
||||
public override func canShowMenu() -> Bool {
|
||||
return true
|
||||
|
|
|
|||
|
|
@ -39,6 +39,14 @@ public class TextMessageViewModel<TextMessageModelT: TextMessageModelProtocol>:
|
|||
self.textMessage = textMessage
|
||||
self.messageViewModel = messageViewModel
|
||||
}
|
||||
|
||||
public func willBeShown() {
|
||||
// Need to declare empty. Otherwise subclass code won't execute (as of Xcode 7.2)
|
||||
}
|
||||
|
||||
public func wasHidden() {
|
||||
// Need to declare empty. Otherwise subclass code won't execute (as of Xcode 7.2)
|
||||
}
|
||||
}
|
||||
|
||||
public class TextMessageViewModelDefaultBuilder<TextMessageModelT: TextMessageModelProtocol>: ViewModelBuilderProtocol {
|
||||
|
|
|
|||
|
|
@ -25,7 +25,8 @@
|
|||
import Foundation
|
||||
|
||||
// Be aware this is not thread safe!
|
||||
public struct Observable<T> {
|
||||
// Why class? https://lists.swift.org/pipermail/swift-users/Week-of-Mon-20160711/002580.html
|
||||
public class Observable<T> {
|
||||
|
||||
public init(_ value: T) {
|
||||
self.value = value
|
||||
|
|
@ -40,12 +41,12 @@ public struct Observable<T> {
|
|||
}
|
||||
}
|
||||
|
||||
public mutating func observe(observer: AnyObject, closure: (old: T, new: T) -> ()) {
|
||||
public func observe(observer: AnyObject, closure: (old: T, new: T) -> ()) {
|
||||
self.observers.append(Observer(owner: observer, closure: closure))
|
||||
self.cleanDeadObservers()
|
||||
}
|
||||
|
||||
private mutating func cleanDeadObservers() {
|
||||
private func cleanDeadObservers() {
|
||||
self.observers = self.observers.filter { $0.owner != nil }
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue