From 1ef46a0e35eaac560cbd66a8d6a279fe7c47643b Mon Sep 17 00:00:00 2001 From: Max Konovalov Date: Mon, 1 Aug 2016 01:53:52 +0400 Subject: [PATCH] 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 --- .../BaseMessage/BaseMessagePresenter.swift | 4 +-- .../BaseMessage/BaseMessageViewModel.swift | 2 ++ .../PhotoMessages/PhotoMessagePresenter.swift | 1 + .../PhotoMessages/PhotoMessageViewModel.swift | 7 ---- .../TextMessages/TextMessagePresenter.swift | 34 +++++++++++++++++++ .../TextMessages/TextMessageViewModel.swift | 8 +++++ ChattoAdditions/Source/Observable.swift | 7 ++-- 7 files changed, 50 insertions(+), 13 deletions(-) diff --git a/ChattoAdditions/Source/Chat Items/BaseMessage/BaseMessagePresenter.swift b/ChattoAdditions/Source/Chat Items/BaseMessage/BaseMessagePresenter.swift index c988dc7..95bc994 100644 --- a/ChattoAdditions/Source/Chat Items/BaseMessage/BaseMessagePresenter.swift +++ b/ChattoAdditions/Source/Chat Items/BaseMessage/BaseMessagePresenter.swift @@ -97,9 +97,7 @@ public class BaseMessagePresenter 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 diff --git a/ChattoAdditions/Source/Chat Items/BaseMessage/BaseMessageViewModel.swift b/ChattoAdditions/Source/Chat Items/BaseMessage/BaseMessageViewModel.swift index 2115dbe..0c30558 100644 --- a/ChattoAdditions/Source/Chat Items/BaseMessage/BaseMessageViewModel.swift +++ b/ChattoAdditions/Source/Chat Items/BaseMessage/BaseMessageViewModel.swift @@ -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 { diff --git a/ChattoAdditions/Source/Chat Items/PhotoMessages/PhotoMessagePresenter.swift b/ChattoAdditions/Source/Chat Items/PhotoMessages/PhotoMessagePresenter.swift index 1410cd6..16b3309 100644 --- a/ChattoAdditions/Source/Chat Items/PhotoMessages/PhotoMessagePresenter.swift +++ b/ChattoAdditions/Source/Chat Items/PhotoMessages/PhotoMessagePresenter.swift @@ -65,6 +65,7 @@ public class PhotoMessagePresenter () 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) diff --git a/ChattoAdditions/Source/Chat Items/PhotoMessages/PhotoMessageViewModel.swift b/ChattoAdditions/Source/Chat Items/PhotoMessages/PhotoMessageViewModel.swift index 881f43a..76e003e 100644 --- a/ChattoAdditions/Source/Chat Items/PhotoMessages/PhotoMessageViewModel.swift +++ b/ChattoAdditions/Source/Chat Items/PhotoMessages/PhotoMessageViewModel.swift @@ -42,13 +42,6 @@ public protocol PhotoMessageViewModelProtocol: DecoratedMessageViewModelProtocol var transferStatus: Observable { get set } var image: Observable { get set } var imageSize: CGSize { get } - func willBeShown() // Optional - func wasHidden() // Optional -} - -public extension PhotoMessageViewModelProtocol { - func willBeShown() {} - func wasHidden() {} } public class PhotoMessageViewModel: PhotoMessageViewModelProtocol { diff --git a/ChattoAdditions/Source/Chat Items/TextMessages/TextMessagePresenter.swift b/ChattoAdditions/Source/Chat Items/TextMessages/TextMessagePresenter.swift index 149f13a..d79f7e1 100644 --- a/ChattoAdditions/Source/Chat Items/TextMessages/TextMessagePresenter.swift +++ b/ChattoAdditions/Source/Chat Items/TextMessages/TextMessagePresenter.swift @@ -64,6 +64,26 @@ public class TextMessagePresenter 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, decorationAttributes: ChatItemDecorationAttributes, animated: Bool, additionalConfiguration: (() -> Void)?) { guard let cell = cell as? TextMessageCollectionViewCell else { @@ -78,6 +98,20 @@ public class TextMessagePresenter Bool { return true diff --git a/ChattoAdditions/Source/Chat Items/TextMessages/TextMessageViewModel.swift b/ChattoAdditions/Source/Chat Items/TextMessages/TextMessageViewModel.swift index f558aa5..8fc65f6 100644 --- a/ChattoAdditions/Source/Chat Items/TextMessages/TextMessageViewModel.swift +++ b/ChattoAdditions/Source/Chat Items/TextMessages/TextMessageViewModel.swift @@ -39,6 +39,14 @@ public class TextMessageViewModel: 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: ViewModelBuilderProtocol { diff --git a/ChattoAdditions/Source/Observable.swift b/ChattoAdditions/Source/Observable.swift index 8fc16d0..f99045e 100644 --- a/ChattoAdditions/Source/Observable.swift +++ b/ChattoAdditions/Source/Observable.swift @@ -25,7 +25,8 @@ import Foundation // Be aware this is not thread safe! -public struct Observable { +// Why class? https://lists.swift.org/pipermail/swift-users/Week-of-Mon-20160711/002580.html +public class Observable { public init(_ value: T) { self.value = value @@ -40,12 +41,12 @@ public struct Observable { } } - 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 } }