Skip to content

Commit

Permalink
[CIS-891] Flawless message list scrolling (#1219)
Browse files Browse the repository at this point in the history
* Use table view in message list

* Set  `needsLayout` when base views change content

* Fix gallery view layout issue

* Implement keyboard avoidance

* Updates and selection

* Fix scrolling indicator being on the left

* Fix missing scroll overlay

* Fix missing scroll to bottom button

* Fix message cell background color

* Fix threads

* Dismiss message actions pop-up after reaction

* Put back advanced typing indicators handling

* Fix scroll to bottom button visibility issues

* Fix animations for message list updates

* Remove collection view leftovers

* Step out from table view mentioning in type names

* Fix handling the spacing between rows

* Update UI snapshots

* Update CHANGELOG

Co-authored-by: Vojta Stavik <stavik@outlook.com>
  • Loading branch information
evsaev and VojtaStavik authored Jun 28, 2021
1 parent 49ccd37 commit f4668db
Show file tree
Hide file tree
Showing 21 changed files with 423 additions and 941 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ _June 23, 2021_
- `FileActionContentViewDelegate` methods updated to have optional index path
- `LinkPreviewViewDelegate` methods updated to have optional index path
- `scrollToLatestMessageButton` type changed from `UIButton` to `_ScrollToLatestMessageButton<ExtraData>`
- `UITableView` is now used instead of `UICollectionView` to display the message list [#1219](https://github.com/GetStream/stream-chat-swift/pull/1219)

### ✅ Added
- `mentionText(for:)` function added to `ComposerVC` for customizing the text displayed for mentions [#1188](https://github.com/GetStream/stream-chat-swift/issues/1188) [#1000](https://github.com/GetStream/stream-chat-swift/issues/1000)
Expand Down
2 changes: 0 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,6 @@ var streamChatSourcesExcluded: [String] { [
var streamChatUIFilesExcluded: [String] { [
"ChatMessageList/TypingIndicatorView_Tests.swift",
"ChatMessageList/ChatMessageListVC_Tests.swift",
"ChatMessageList/ChatMessageListCollectionViewLayout_Tests.swift",
"ChatMessageList/ChatMessage/ChatMessageErrorIndicator_Tests.swift",
"ChatMessageList/ChatMessage/ChatMessageBubbleView_Tests.swift",
"ChatMessageList/ChatMessage/ChatMessageLayoutOptionsResolver_Tests.swift",
Expand Down Expand Up @@ -329,7 +328,6 @@ var streamChatUIFilesExcluded: [String] { [
"ChatMessageList/__Snapshots__/ChatMessageListVC+SwiftUI_Tests/test_customNavigationViewValues_arePopulated.rightToLeftLayout-default.png",
"ChatMessageList/__Snapshots__/ChatMessageListVC+SwiftUI_Tests/test_customNavigationViewValues_arePopulated.extraExtraExtraLarge-light.png",
"ChatMessageList/__Snapshots__/ChatMessageListVC+SwiftUI_Tests/test_customNavigationViewValues_arePopulated.default-light.png",
"ChatMessageList/__Snapshots__/ChatMessageListVC+SwiftUI_Tests/test_chatChannelList_isPopulated.default-light.png",
"ChatMessageList/__Snapshots__/ChatMessageListVC+SwiftUI_Tests/test_chatMessageList_isPopulated.default-light.png",
"ChatMessageList/__Snapshots__/TitleContainerView_Tests/test_appearanceCustomization_usingSubclassing.small-dark.png",
"ChatMessageList/__Snapshots__/TitleContainerView_Tests/test_defaultAppearance.default-light-empty.png",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,11 @@ extension _ChatMessageImageGallery {
}

override open func updateContent() {
super.updateContent()

let attachment = content

loadingIndicator.isVisible = true
imageView.layoutIfNeeded()
imageTask = imageView
.loadImage(
from: attachment?.payload.imagePreviewURL,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
//
// Copyright © 2021 Stream.io Inc. All rights reserved.
//

import StreamChat
import UIKit

/// The cell that displays the message content of a dynamic type and layout.
/// Once the cell is set up it is expected to be dequeued for messages with
/// the same content and layout the cell has already been configured with.
public typealias ChatMessageCell = _ChatMessageCell<NoExtraData>

/// The cell that displays the message content of a dynamic type and layout.
/// Once the cell is set up it is expected to be dequeued for messages with
/// the same content and layout the cell has already been configured with.
public final class _ChatMessageCell<ExtraData: ExtraDataTypes>: _TableViewCell {
public static var reuseId: String { "\(self)" }

/// The message content view the cell is showing.
public private(set) var messageContentView: _ChatMessageContentView<ExtraData>?

/// The minimum spacing below the cell.
public var minimumSpacingBelow: CGFloat = 2 {
didSet { updateBottomSpacing() }
}

override public func setUp() {
super.setUp()

selectionStyle = .none
}

override public func setUpAppearance() {
super.setUpAppearance()

backgroundColor = .clear
backgroundView = nil
}

override public func prepareForReuse() {
super.prepareForReuse()

messageContentView?.prepareForReuse()
}

/// Creates a message content view
/// - Parameters:
/// - contentViewClass: The type of message content view.
/// - attachmentViewInjectorType: The type of attachment injector.
/// - options: The layout options describing the message content view layout.
public func setMessageContentIfNeeded(
contentViewClass: _ChatMessageContentView<ExtraData>.Type,
attachmentViewInjectorType: _AttachmentViewInjector<ExtraData>.Type?,
options: ChatMessageLayoutOptions
) {
guard messageContentView == nil else {
log.assert(type(of: messageContentView!) == contentViewClass, """
Attempt to setup different content class: ("\(contentViewClass)")
""")
return
}

messageContentView = contentViewClass.init().withoutAutoresizingMaskConstraints
// We add the content view to the view hierarchy before invoking `setUpLayoutIfNeeded`
// (where the subviews are instantiated and configured) to use `components` and `appearance`
// taken from the responder chain.
contentView.addSubview(messageContentView!)
messageContentView!.pin(anchors: [.leading, .top, .trailing, .bottom], to: contentView)
messageContentView!.setUpLayoutIfNeeded(options: options, attachmentViewInjectorType: attachmentViewInjectorType)
updateBottomSpacing()
}

private func updateBottomSpacing() {
guard let contentView = messageContentView else { return }

contentView.mainContainer.layoutMargins.bottom = max(
contentView.mainContainer.layoutMargins.bottom,
minimumSpacingBelow
)
}
}
Loading

0 comments on commit f4668db

Please sign in to comment.