-
-
Save Denismih/e286f499fddbe8e5355abe578016db29 to your computer and use it in GitHub Desktop.
Chatto ImageMessage
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// MARK: - ImageMessageModel | |
import Chatto | |
import ChattoAdditions | |
protocol ImageMessageModelProtocol: PhotoMessageModelProtocol { | |
var url: URL? { get set } | |
} | |
public class ImageMessageModel: PhotoMessageModel<MessageModel>, ImageMessageModelProtocol { | |
var url: URL? | |
var placeholder: UIImage | |
init(messageModel: MessageModel, imageSize: CGSize, placeholder: UIImage, url: URL?) { | |
self.url = url | |
self.placeholder = placeholder | |
super.init(messageModel: messageModel, imageSize: imageSize, image: placeholder) | |
} | |
} | |
extension ImageMessageModel { | |
static var chatItemType: ChatItemType { | |
return "image" | |
} | |
} | |
// MARK: - ImageMessageViewModel | |
import ChattoAdditions | |
import Kingfisher | |
protocol ImageMessageViewModelProtocol: PhotoMessageViewModelProtocol { | |
var imageUrl: URL? { get set } | |
var placeholder: UIImage { get set } | |
} | |
class ImageMessageViewModelBuilder: ViewModelBuilderProtocol { | |
let messageViewModelBuilder = MessageViewModelDefaultBuilder() | |
func createViewModel(_ model: ImageMessageModel) -> ImageMessageViewModel { | |
let messageViewModel = self.messageViewModelBuilder.createMessageViewModel(model) | |
let photoMessageViewModel = ImageMessageViewModel(photoMessage: model, messageViewModel: messageViewModel) | |
photoMessageViewModel.imageUrl = model.url | |
return photoMessageViewModel | |
} | |
func canCreateViewModel(fromModel model: Any) -> Bool { | |
return model is ImageMessageModel | |
} | |
} | |
class ImageMessageViewModel: PhotoMessageViewModel<ImageMessageModel>, ImageMessageViewModelProtocol { | |
var imageUrl: URL? | |
var placeholder: UIImage | |
override init(photoMessage: ImageMessageModel, messageViewModel: MessageViewModelProtocol) { | |
placeholder = photoMessage.placeholder | |
super.init(photoMessage: photoMessage, messageViewModel: messageViewModel) | |
} | |
override func willBeShown() { | |
updateImage() | |
} | |
private func updateImage() { | |
if image.value == placeholder, let imageUrl = imageUrl { | |
if ImageCache.default.imageCachedType(forKey: imageUrl.absoluteString) == CacheType.none { | |
transferDirection.value = .download | |
transferStatus.value = .transfering | |
ImageDownloader.default.downloadImage(with: imageUrl, progressBlock: { [weak self] (receivedSize, totalSize) in | |
if totalSize > 0 { | |
self?.transferProgress.value = Double(receivedSize) / Double(totalSize) | |
} | |
}, completionHandler: { [weak self] (image, error, url, data) in | |
if let image = image { | |
self?.transferStatus.value = .success | |
self?.image.value = image | |
ImageCache.default.store(image, forKey: imageUrl.absoluteString) | |
} else { | |
self?.transferStatus.value = .failed | |
} | |
}) | |
} else { | |
ImageCache.default.retrieveImage(forKey: imageUrl.absoluteString, options: nil) { [weak self] | |
image, cacheType in | |
if let image = image { | |
self?.transferStatus.value = .success | |
self?.image.value = image | |
} else { | |
self?.transferStatus.value = .failed | |
} | |
} | |
} | |
} | |
} | |
} | |
// MARK: - ImageMessagePresenterBuilder & ImageMessagePresenter | |
import Chatto | |
import ChattoAdditions | |
class ImageMessagePresenterBuilder<ViewModelBuilderT: ViewModelBuilderProtocol, InteractionHandlerT: BaseMessageInteractionHandlerProtocol>: PhotoMessagePresenterBuilder<ViewModelBuilderT, InteractionHandlerT> where | |
ViewModelBuilderT.ViewModelT: ImageMessageViewModelProtocol, | |
InteractionHandlerT.ViewModelT == ViewModelBuilderT.ViewModelT{ | |
override func createPresenterWithChatItem(_ chatItem: ChatItemProtocol) -> ChatItemPresenterProtocol { | |
assert(self.canHandleChatItem(chatItem)) | |
return ImageMessagePresenter<ViewModelBuilderT, InteractionHandlerT>( | |
messageModel: chatItem as! ModelT, | |
viewModelBuilder: self.viewModelBuilder, | |
interactionHandler: self.interactionHandler, | |
sizingCell: sizingCell, | |
baseCellStyle: self.baseCellStyle, | |
photoCellStyle: self.photoCellStyle | |
) | |
} | |
} | |
class ImageMessagePresenter<ViewModelBuilderT: ViewModelBuilderProtocol, InteractionHandlerT: BaseMessageInteractionHandlerProtocol>: PhotoMessagePresenter<ViewModelBuilderT, InteractionHandlerT> where | |
ViewModelBuilderT.ViewModelT: ImageMessageViewModelProtocol, | |
InteractionHandlerT.ViewModelT == ViewModelBuilderT.ViewModelT { | |
} | |
// MARK: - ImageMessageHandler | |
import Foundation | |
import ChattoAdditions | |
class ImageMessageHandler: BaseMessageInteractionHandlerProtocol { | |
typealias ViewModelT = ImageMessageViewModel | |
func userDidTapOnFailIcon(viewModel: ImageMessageViewModel, failIconView: UIView) { | |
print("Function: \(#function), line: \(#line)") | |
} | |
func userDidTapOnAvatar(viewModel: ImageMessageViewModel) { | |
print("Function: \(#function), line: \(#line)") | |
} | |
func userDidTapOnBubble(viewModel: ImageMessageViewModel) { | |
print("Function: \(#function), line: \(#line)") | |
} | |
func userDidBeginLongPressOnBubble(viewModel: ImageMessageViewModel) { | |
print("Function: \(#function), line: \(#line)") | |
} | |
func userDidEndLongPressOnBubble(viewModel: ImageMessageViewModel) { | |
print("Function: \(#function), line: \(#line)") | |
} | |
func userDidSelectMessage(viewModel: ImageMessageViewModel) { | |
print("Function: \(#function), line: \(#line)") | |
} | |
func userDidDeselectMessage(viewModel: ImageMessageViewModel) { | |
print("Function: \(#function), line: \(#line)") | |
} | |
} | |
// MARK: - ChattoViewController | |
import Chatto | |
import ChattoAdditions | |
class ChattoViewController: BaseChatViewController { | |
... | |
override func createPresenterBuilders() -> [ChatItemType: [ChatItemPresenterBuilderProtocol]] { | |
let imageMessagePresenter = ImageMessagePresenterBuilder( | |
viewModelBuilder: ImageMessageViewModelBuilder(), | |
interactionHandler: ImageMessageHandler() | |
) | |
imageMessagePresenter.baseCellStyle = MessageCollectionViewCellAvatarStyle() | |
return [ | |
ImageMessageModel.chatItemType: [imageMessagePresenter], | |
] | |
} | |
... | |
} | |
// MARK: - ChatDataSource | |
class ChatDataSource: ChatDataSourceProtocol { | |
... | |
let model = MessageModel(uid: objectId, | |
senderId: senderId, | |
type: ImageMessageModel.chatItemType, | |
isIncoming: true, | |
date: createdAt, | |
status: .success) | |
let chatItem = ImageMessageModel(messageModel: model, | |
imageSize: size, | |
placeholder: UIImage(named: "placeholder")!, | |
url: <your url>) | |
chatItems.append(chatItem) | |
delegate?.chatDataSourceDidUpdate(self) | |
... | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment