Skip to content
This repository was archived by the owner on Jun 7, 2020. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 52 additions & 16 deletions Rocket.Chat.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

78 changes: 65 additions & 13 deletions Rocket.Chat/Controllers/Chat/ChatSections/MessageSection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ final class MessageSection: ChatSection {
self.controllerContext = controllerContext
}

// swiftlint:disable function_body_length
func viewModels() -> [AnyChatItem] {
guard
let object = object.base as? MessageSectionModel,
Expand Down Expand Up @@ -95,25 +96,70 @@ final class MessageSection: ChatSection {
).wrapped)
}
case .textAttachment where attachment.fields.count > 0:
cells.append(TextAttachmentChatItem(
attachment: attachment
).wrapped)
case .textAttachment:
if object.message.text.isEmpty && shouldAppendMessageHeader {
cells.append(TextAttachmentChatItem(
attachment: attachment,
hasText: false,
user: user,
message: object.message
).wrapped)

shouldAppendMessageHeader = false
} else {
cells.append(TextAttachmentChatItem(
attachment: attachment,
hasText: true,
user: nil,
message: nil
).wrapped)
}
case .textAttachment where !attachment.isFile:
cells.append(QuoteChatItem(
attachment: attachment
).wrapped)
case .image:
cells.append(ImageMessageChatItem(
identifier: attachment.identifier,
title: attachment.title,
descriptionText: attachment.descriptionText,
imageURL: attachment.fullImageURL
).wrapped)
if object.message.text.isEmpty && shouldAppendMessageHeader {
cells.append(ImageMessageChatItem(
identifier: attachment.identifier,
title: attachment.title,
descriptionText: attachment.descriptionText,
imageURL: attachment.fullImageURL,
hasText: false,
user: user,
message: object.message
).wrapped)

shouldAppendMessageHeader = false
} else {
cells.append(ImageMessageChatItem(
identifier: attachment.identifier,
title: attachment.title,
descriptionText: attachment.descriptionText,
imageURL: attachment.fullImageURL,
hasText: true,
user: nil,
message: nil
).wrapped)
}
default:
if attachment.isFile {
cells.append(FileMessageChatItem(
attachment: attachment
).wrapped)
if object.message.text.isEmpty && shouldAppendMessageHeader {
cells.append(FileMessageChatItem(
attachment: attachment,
hasText: false,
user: user,
message: object.message
).wrapped)

shouldAppendMessageHeader = false
} else {
cells.append(FileMessageChatItem(
attachment: attachment,
hasText: true,
user: nil,
message: nil
).wrapped)
}
}
}
}
Expand Down Expand Up @@ -155,12 +201,18 @@ final class MessageSection: ChatSection {
cell.delegate = self
} else if let cell = cell as? SequentialMessageCell {
cell.delegate = self
} else if let cell = cell as? FileCell {
cell.delegate = self
} else if let cell = cell as? FileMessageCell {
cell.delegate = self
} else if let cell = cell as? ImageMessageCell {
cell.delegate = self
} else if let cell = cell as? ImageCell {
cell.delegate = self
} else if let cell = cell as? TextAttachmentCell {
cell.delegate = self
} else if let cell = cell as? TextAttachmentMessageCell {
cell.delegate = self
} else if let cell = cell as? QuoteCell {
cell.delegate = self
} else if let cell = cell as? MessageURLCell {
Expand Down
9 changes: 8 additions & 1 deletion Rocket.Chat/Controllers/Chat/MessagesViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,11 @@ final class MessagesViewController: RocketChatViewController {
collectionView.register(VideoCell.nib, forCellWithReuseIdentifier: VideoCell.identifier)
collectionView.register(VideoMessageCell.nib, forCellWithReuseIdentifier: VideoMessageCell.identifier)
collectionView.register(ReactionsCell.nib, forCellWithReuseIdentifier: ReactionsCell.identifier)
collectionView.register(FileCell.nib, forCellWithReuseIdentifier: FileCell.identifier)
collectionView.register(FileMessageCell.nib, forCellWithReuseIdentifier: FileMessageCell.identifier)
collectionView.register(TextAttachmentCell.nib, forCellWithReuseIdentifier: TextAttachmentCell.identifier)
collectionView.register(TextAttachmentMessageCell.nib, forCellWithReuseIdentifier: TextAttachmentMessageCell.identifier)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line Length Violation: Line should be 120 characters or less: currently 128 characters (line_length)

collectionView.register(ImageCell.nib, forCellWithReuseIdentifier: ImageCell.identifier)
collectionView.register(ImageMessageCell.nib, forCellWithReuseIdentifier: ImageMessageCell.identifier)
collectionView.register(QuoteCell.nib, forCellWithReuseIdentifier: QuoteCell.identifier)
collectionView.register(MessageURLCell.nib, forCellWithReuseIdentifier: MessageURLCell.identifier)
Expand Down Expand Up @@ -118,7 +121,11 @@ extension MessagesViewController {
return size
} else {
guard let sizingCell = UINib(nibName: item.relatedReuseIdentifier, bundle: nil).instantiate() as? SizingCell else {
return .zero
fatalError("""
Failed to reference sizing cell instance. Please,
check the relatedReuseIdentifier and make sure all
the chat components conform to SizingCell protocol
""")
}

let horizontalMargins = collectionView.adjustedContentInset.left + collectionView.adjustedContentInset.right
Expand Down
14 changes: 14 additions & 0 deletions Rocket.Chat/Views/Chat/New Chat/Cells/BaseFileMessageCell.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//
// BaseFileMessageCell.swift
// Rocket.Chat
//
// Created by Filipe Alvarenga on 16/10/18.
// Copyright © 2018 Rocket.Chat. All rights reserved.
//

import UIKit
import RocketChatViewController

class BaseFileMessageCell: MessageHeaderCell {
weak var delegate: ChatMessageCellProtocol?
}
30 changes: 30 additions & 0 deletions Rocket.Chat/Views/Chat/New Chat/Cells/BaseImageMessageCell.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//
// BaseImageMessageCell.swift
// Rocket.Chat
//
// Created by Filipe Alvarenga on 16/10/18.
// Copyright © 2018 Rocket.Chat. All rights reserved.
//

import UIKit

class BaseImageMessageCell: MessageHeaderCell {
weak var delegate: ChatMessageCellProtocol?

func loadImage(on imageView: UIImageView, startLoadingBlock: () -> Void, stopLoadingBlock: @escaping () -> Void) {
guard let viewModel = viewModel?.base as? ImageMessageChatItem else {
return
}

if let imageURL = viewModel.imageURL {
startLoadingBlock()
ImageManager.loadImage(with: imageURL, into: imageView) { _, _ in
stopLoadingBlock()

// TODO: In case of error, show some error placeholder

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Todo Violation: TODOs should be resolved (In case of error, show some er...). (todo)

}
} else {
// TODO: Load some error placeholder

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Todo Violation: TODOs should be resolved (Load some error placeholder). (todo)

}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
//
// BaseTextAttachmentMessageCell.swift
// Rocket.Chat
//
// Created by Filipe Alvarenga on 16/10/18.
// Copyright © 2018 Rocket.Chat. All rights reserved.
//

import UIKit

class BaseTextAttachmentMessageCell: MessageHeaderCell {
weak var delegate: ChatMessageCellProtocol?

var subtitleHeightConstraint: NSLayoutConstraint!
var emptySubtitleHeightConstraint: NSLayoutConstraint!
var avatarLeadingInitialConstant: CGFloat = 0
var avatarWidthInitialConstant: CGFloat = 0
var textContainerLeadingInitialConstant: CGFloat = 0
var statusViewLeadingInitialConstant: CGFloat = 0
var statusViewWidthInitialConstant: CGFloat = 0
var fieldsStackViewLeadingInitialConstant: CGFloat = 0
var fieldsStackViewTrailingInitialConstant: CGFloat = 0
var textContainerTrailingInitialConstant: CGFloat = 0
var fieldsStackTopInitialConstant: CGFloat = 0
var fieldsStackHeightInitialConstant: CGFloat = 0
var subtitleHeightInitialConstant: CGFloat = 0
var subtitleTopInitialConstant: CGFloat = 0
var fieldLabelWidth: CGFloat {
return
UIScreen.main.bounds.width -
avatarLeadingInitialConstant -
avatarWidthInitialConstant -
textContainerLeadingInitialConstant -
statusViewLeadingInitialConstant -
statusViewWidthInitialConstant -
fieldsStackViewLeadingInitialConstant -
fieldsStackViewTrailingInitialConstant -
textContainerTrailingInitialConstant -
adjustedHorizontalInsets
}

func configure(stackView: UIStackView) -> CGFloat {
guard let viewModel = viewModel?.base as? TextAttachmentChatItem else {
return 0
}

let maxSize = CGSize(width: fieldLabelWidth, height: .greatestFiniteMagnitude)
var stackViewHeight: CGFloat = 0
var attachmentFieldViews: [AttachmentFieldView] = []

reset(stackView: stackView)

for attachmentField in viewModel.attachment.fields {
guard let attachmentFieldView = AttachmentFieldView.instantiateFromNib() else {
continue
}

let attributedValue = NSMutableAttributedString(string: attachmentField.value).transformMarkdown(with: theme)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line Length Violation: Line should be 120 characters or less: currently 121 characters (line_length)

attachmentFieldView.field.text = attachmentField.title
attachmentFieldView.value.attributedText = attributedValue

let valueTextHeight = attachmentFieldView.value.sizeThatFits(maxSize).height
let fieldViewHeight = attachmentFieldView.fieldHeightConstraint.constant +
attachmentFieldView.valueTopConstraint.constant +
valueTextHeight

stackViewHeight += fieldViewHeight
attachmentFieldView.contentSize = CGSize(width: fieldLabelWidth, height: fieldViewHeight)
attachmentFieldView.invalidateIntrinsicContentSize()
attachmentFieldViews.append(attachmentFieldView)
}

stackViewHeight += stackView.spacing * CGFloat(attachmentFieldViews.count - 1)

attachmentFieldViews.forEach { view in
stackView.addArrangedSubview(view)
}

return stackViewHeight
}

func reset(stackView: UIStackView) {
stackView.arrangedSubviews.forEach { subview in
stackView.removeArrangedSubview(subview)
subview.removeFromSuperview()
}
}

@objc func didTapTextContainerView() {
guard
let viewModel = viewModel,
let textAttachmentViewModel = viewModel.base as? TextAttachmentChatItem
else {
return
}

textAttachmentViewModel.toggleAttachmentFields()
delegate?.viewDidCollapseChange(viewModel: viewModel)
}
}

extension BaseTextAttachmentMessageCell: UIGestureRecognizerDelegate {
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRequireFailureOf otherGestureRecognizer: UIGestureRecognizer) -> Bool {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line Length Violation: Line should be 120 characters or less: currently 146 characters (line_length)

return false
}
}
40 changes: 40 additions & 0 deletions Rocket.Chat/Views/Chat/New Chat/Cells/FileCell.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//
// FileMessageCell.swift
// Rocket.Chat
//
// Created by Filipe Alvarenga on 28/09/18.
// Copyright © 2018 Rocket.Chat. All rights reserved.
//

import Foundation
import RocketChatViewController

final class FileCell: BaseFileMessageCell, SizingCell {
static let identifier = String(describing: FileCell.self)

static let sizingCell: UICollectionViewCell & ChatCell = {
guard let cell = FileCell.instantiateFromNib() else {
return FileCell()
}

return cell
}()

@IBOutlet weak var fileButton: UIButton!

override func configure() {
guard let viewModel = viewModel?.base as? FileMessageChatItem else {
return
}

fileButton.setTitle(viewModel.attachment.title, for: .normal)
}

@IBAction func didTapFileButton() {
guard let viewModel = viewModel?.base as? FileMessageChatItem else {
return
}

delegate?.openFileFromCell(attachment: viewModel.attachment)
}
}
63 changes: 63 additions & 0 deletions Rocket.Chat/Views/Chat/New Chat/Cells/FileCell.xib
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14313.18" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14283.14"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" id="o5P-P6-s4x" customClass="FileCell" customModule="Rocket_Chat" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="375" height="56"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO">
<rect key="frame" x="0.0" y="0.0" width="375" height="56"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<button opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="leading" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Fef-tc-ORb">
<rect key="frame" x="70" y="0.0" width="271" height="56"/>
<color key="backgroundColor" red="0.88235294117647056" green="0.89803921568627454" blue="0.90980392156862744" alpha="1" colorSpace="calibratedRGB"/>
<constraints>
<constraint firstAttribute="height" constant="56" id="gpU-z9-wYR"/>
</constraints>
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="16"/>
<inset key="contentEdgeInsets" minX="10" minY="0.0" maxX="0.0" maxY="0.0"/>
<inset key="titleEdgeInsets" minX="5" minY="0.0" maxX="0.0" maxY="0.0"/>
<state key="normal" title="Button" image="iconFilesGeneric">
<color key="titleColor" red="0.12156862745098039" green="0.13725490196078433" blue="0.16078431372549018" alpha="1" colorSpace="calibratedRGB"/>
</state>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius">
<integer key="value" value="4"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
<connections>
<action selector="didTapFileButton" destination="o5P-P6-s4x" eventType="touchUpInside" id="1Nh-fb-C6j"/>
</connections>
</button>
</subviews>
</view>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="Fef-tc-ORb" firstAttribute="top" secondItem="o5P-P6-s4x" secondAttribute="top" id="HRd-k5-91W"/>
<constraint firstAttribute="bottom" secondItem="Fef-tc-ORb" secondAttribute="bottom" id="k3J-kZ-5HF"/>
<constraint firstItem="Fef-tc-ORb" firstAttribute="leading" secondItem="o5P-P6-s4x" secondAttribute="leading" constant="70" id="oxc-gc-1iG"/>
<constraint firstAttribute="trailing" secondItem="Fef-tc-ORb" secondAttribute="trailing" constant="34" id="uT0-rI-ArF"/>
</constraints>
<viewLayoutGuide key="safeArea" id="Jgr-GV-nUi"/>
<size key="customSize" width="375" height="76"/>
<connections>
<outlet property="fileButton" destination="Fef-tc-ORb" id="MCe-oe-aH8"/>
</connections>
<point key="canvasLocation" x="109.59999999999999" y="-44.977511244377816"/>
</collectionViewCell>
</objects>
<resources>
<image name="iconFilesGeneric" width="20" height="20"/>
</resources>
</document>
Loading