From 42ab8708bb78ae35b44a3a9a1355c6591c0e9e1e Mon Sep 17 00:00:00 2001 From: Eugene Kazaev Date: Tue, 5 Jan 2021 14:51:20 +0000 Subject: [PATCH] Release version 1.0.0 --- .swiftformat | 2 +- .swiftlint.yml | 1 + ChatLayout.podspec | 10 +- .../Classes/Core/ChatItemAlignment.swift | 2 +- ChatLayout/Classes/Core/ChatLayout.swift | 12 +-- .../Classes/Core/ChatLayoutAttributes.swift | 2 +- .../Classes/Core/ChatLayoutDelegate.swift | 2 +- .../Core/ChatLayoutInvalidationContext.swift | 2 +- .../Core/ChatLayoutPositionSnapshot.swift | 2 +- .../Classes/Core/ChatLayoutSettings.swift | 2 +- .../Core/Extensions/CGRect+Extension.swift | 2 +- .../Core/Extensions/IndexPath+Extension.swift | 2 +- ChatLayout/Classes/Core/Model/ItemKind.swift | 2 +- ChatLayout/Classes/Core/Model/ItemModel.swift | 2 +- ChatLayout/Classes/Core/Model/ItemPath.swift | 2 +- ChatLayout/Classes/Core/Model/ItemSize.swift | 2 +- .../Classes/Core/Model/LayoutModel.swift | 2 +- .../Classes/Core/Model/ModelState.swift | 2 +- .../Classes/Core/Model/SectionModel.swift | 8 +- .../Classes/Core/Model/StateController.swift | 98 +++++++++++-------- .../Extras/CellLayoutContainerView.swift | 2 +- .../ContainerCollectionReusableView.swift | 2 +- .../Extras/ContainerCollectionViewCell.swift | 2 +- .../Classes/Extras/EdgeAligningView.swift | 2 +- .../Classes/Extras/ImageMaskedView.swift | 2 +- .../Classes/Extras/MessageContainerView.swift | 2 +- .../Extras/RoundedCornersContainerView.swift | 2 +- .../Classes/Extras/StaticViewFactory.swift | 2 +- Example/.swiftlint.yml | 73 ++++++++++++++ Example/ChatLayout/AppDelegate.swift | 2 +- .../Builder/ChatViewControllerBuilder.swift | 2 +- Example/ChatLayout/Chat/Constants.swift | 2 +- .../Chat/Controller/ChatController.swift | 2 +- .../Controller/ChatControllerDelegate.swift | 2 +- .../Controller/DefaultChatController.swift | 9 +- Example/ChatLayout/Chat/Model/Caches.swift | 2 +- .../Model/Caching/AsyncKeyValueCaching.swift | 2 +- .../Chat/Model/Caching/CacheError.swift | 2 +- .../Model/Caching/Data/IterativeCache.swift | 6 +- .../Model/Caching/Data/MemoryDataCache.swift | 2 +- .../Caching/Data/PersistentDataCache.swift | 2 +- .../Caching/Data/PersistentlyCacheable.swift | 2 +- .../Caching/Image/CacheableImageKey.swift | 2 +- .../Caching/Image/ImageForUrlCache.swift | 2 +- .../Chat/Model/Caching/KeyValueCaching.swift | 2 +- .../Caching/Metadata/MetaDataCache.swift | 6 +- .../Chat/Model/ChatDateFormatter.swift | 2 +- .../Chat/Model/Data Objects/Cell.swift | 2 +- .../Chat/Model/Data Objects/Message.swift | 2 +- .../Chat/Model/Data Objects/RawMessage.swift | 2 +- .../Chat/Model/Data Objects/Section.swift | 2 +- .../Chat/Model/Data Objects/TypingState.swift | 2 +- .../Chat/Model/Data Objects/User.swift | 2 +- .../Model/DefaultRandomDataProvider.swift | 9 +- .../ChatLayout/Chat/Model/TextGenerator.swift | 2 +- .../Avatar View/AvatarPlaceholderView.swift | 2 +- .../Chat/View/Avatar View/AvatarView.swift | 2 +- .../Avatar View/AvatarViewController.swift | 2 +- .../Chat/View/ChatViewController.swift | 5 +- .../ChatCollectionDataSource.swift | 2 +- .../DefaultChatCollectionDataSource.swift | 4 +- .../EditingAccessoryController.swift | 2 +- .../EditingAccessoryView.swift | 2 +- .../Helpers/DifferenceKit+Extension.swift | 2 +- .../Chat/View/Helpers/SetActor.swift | 2 +- .../Chat/View/Image/ImageController.swift | 2 +- .../Chat/View/Image/ImageMessageSource.swift | 2 +- .../Chat/View/Image/ImageView.swift | 2 +- .../Chat/View/Image/ImageViewState.swift | 2 +- .../Image/Loader/CachingImageLoader.swift | 2 +- .../Image/Loader/DefaultImageLoader.swift | 2 +- .../Chat/View/Image/Loader/ImageLoader.swift | 2 +- .../Chat/View/Keyboard/KeyboardInfo.swift | 2 +- .../Chat/View/Keyboard/KeyboardListener.swift | 2 +- .../Keyboard/KeyboardListenerDelegate.swift | 2 +- .../Chat/View/Other/BubbleController.swift | 2 +- .../View/Other/DefaultBubbleController.swift | 2 +- .../Chat/View/Other/EditNotifier.swift | 2 +- .../View/Other/EditNotifierDelegate.swift | 2 +- .../FullCellContentBubbleController.swift | 2 +- .../View/Other/TextBubbleController.swift | 2 +- .../ChatLayout/Chat/View/ReloadDelegate.swift | 2 +- .../Chat/View/Status View/StatusView.swift | 2 +- .../TextMessageController.swift | 2 +- .../Text Message View/TextMessageView.swift | 2 +- .../Chat/View/URL/URLController.swift | 2 +- .../ChatLayout/Chat/View/URL/URLSource.swift | 2 +- .../ChatLayout/Chat/View/URL/URLView.swift | 2 +- .../ChatLayout/ProcessInfo+Extension.swift | 2 +- Example/ChatLayout/SceneDelegate.swift | 2 +- Example/Tests/HelpersTests.swift | 2 +- Example/Tests/MockCollectionLayout.swift | 9 +- .../MockUICollectionViewUpdateItem.swift | 4 +- .../Tests/StateControllerInternalTests.swift | 2 +- .../StateControllerProcessUpdatesTests.swift | 4 +- README.md | 5 - 96 files changed, 268 insertions(+), 155 deletions(-) create mode 120000 .swiftlint.yml create mode 100644 Example/.swiftlint.yml diff --git a/.swiftformat b/.swiftformat index bcdd9cec..c9a0b1da 100644 --- a/.swiftformat +++ b/.swiftformat @@ -11,7 +11,7 @@ --exponentgrouping disabled --fractiongrouping disabled --fragment false ---header "\nChatLayout\n{file}\nhttps://github.com/ekazaev/ChatLayout\n\nCreated by Eugene Kazaev in {year}.\nDistributed under the MIT license.\n" +--header "\nChatLayout\n{file}\nhttps://github.com/ekazaev/ChatLayout\n\nCreated by Eugene Kazaev in 2020-{year}.\nDistributed under the MIT license.\n" --hexgrouping none --hexliteralcase uppercase --ifdef no-indent diff --git a/.swiftlint.yml b/.swiftlint.yml new file mode 120000 index 00000000..7471365c --- /dev/null +++ b/.swiftlint.yml @@ -0,0 +1 @@ +./Example/.swiftlint.yml \ No newline at end of file diff --git a/ChatLayout.podspec b/ChatLayout.podspec index 1c0e5db3..b6a3d44f 100644 --- a/ChatLayout.podspec +++ b/ChatLayout.podspec @@ -1,13 +1,13 @@ Pod::Spec.new do |s| s.name = 'ChatLayout' - s.version = '0.6.3' - s.summary = 'An alternative solution to MessageKit. It uses custom UICollectionViewLayout to provide you full control over the presentation.' + s.version = '1.0.0' + s.summary = 'Chat UI Library. An alternative solution to MessageKit. It uses custom UICollectionViewLayout to provide you full control over the presentation.' s.swift_version = '5.2' s.description = <<-DESC -ChatLayout is an alternative solution to MessageKit. It uses custom -UICollectionViewLayout to provide you full control over the presentation as well as all the tools available in -UICollectionView. It supports dynamic cells and supplementary view sizes. +ChatLayout is a Chat UI Library. It uses custom UICollectionViewLayout to provide you full control over the +presentation as well as all the tools available in UICollectionView. It supports dynamic cells and +supplementary view sizes. DESC s.homepage = 'https://github.com/ekazaev/ChatLayout' diff --git a/ChatLayout/Classes/Core/ChatItemAlignment.swift b/ChatLayout/Classes/Core/ChatItemAlignment.swift index 785e6519..79f45fd4 100644 --- a/ChatLayout/Classes/Core/ChatItemAlignment.swift +++ b/ChatLayout/Classes/Core/ChatItemAlignment.swift @@ -3,7 +3,7 @@ // ChatItemAlignment.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/ChatLayout/Classes/Core/ChatLayout.swift b/ChatLayout/Classes/Core/ChatLayout.swift index b137ae40..afebf386 100644 --- a/ChatLayout/Classes/Core/ChatLayout.swift +++ b/ChatLayout/Classes/Core/ChatLayout.swift @@ -3,7 +3,7 @@ // ChatLayout.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // @@ -413,7 +413,7 @@ public final class ChatLayout: UICollectionViewLayout { guard let collectionView = collectionView, oldBounds.width != collectionView.bounds.width, keepContentOffsetAtBottomOnBatchUpdates, - controller.isLayoutBiggerThanScreen(at: state) else { + controller.isLayoutBiggerThanVisibleBounds(at: state) else { return } let newBounds = collectionView.bounds @@ -617,7 +617,7 @@ public final class ChatLayout: UICollectionViewLayout { controller.proposedCompensatingOffset = 0 if keepContentOffsetAtBottomOnBatchUpdates, - controller.isLayoutBiggerThanScreen(at: state), + controller.isLayoutBiggerThanVisibleBounds(at: state), controller.batchUpdateCompensatingOffset != 0, let collectionView = collectionView { let compensatingOffset: CGFloat @@ -692,7 +692,7 @@ public final class ChatLayout: UICollectionViewLayout { attributes = controller.itemAttributes(for: itemPath, kind: .cell, at: .beforeUpdate)?.typedCopy() ?? ChatLayoutAttributes(forCellWith: itemIndexPath) controller.offsetByTotalCompensation(attributes: attributes, for: state, backward: false) if keepContentOffsetAtBottomOnBatchUpdates, - controller.isLayoutBiggerThanScreen(at: state), + controller.isLayoutBiggerThanVisibleBounds(at: state), let attributes = attributes { attributes.frame = attributes.frame.offsetBy(dx: 0, dy: attributes.frame.height / 2) } @@ -784,7 +784,7 @@ public final class ChatLayout: UICollectionViewLayout { attributes = controller.itemAttributes(for: elementPath, kind: kind, at: .beforeUpdate)?.typedCopy() ?? ChatLayoutAttributes(forSupplementaryViewOfKind: elementKind, with: elementIndexPath) controller.offsetByTotalCompensation(attributes: attributes, for: state, backward: false) if keepContentOffsetAtBottomOnBatchUpdates, - controller.isLayoutBiggerThanScreen(at: state), + controller.isLayoutBiggerThanVisibleBounds(at: state), let attributes = attributes { attributes.frame = attributes.frame.offsetBy(dx: 0, dy: attributes.frame.height / 2) } @@ -885,7 +885,7 @@ extension ChatLayout { extension ChatLayout: ChatLayoutRepresentation { - func numberOfItems(inSection section: Int) -> Int { + func numberOfItems(in section: Int) -> Int { guard let collectionView = collectionView else { return .zero } diff --git a/ChatLayout/Classes/Core/ChatLayoutAttributes.swift b/ChatLayout/Classes/Core/ChatLayoutAttributes.swift index bf544bb5..5c7aaef3 100644 --- a/ChatLayout/Classes/Core/ChatLayoutAttributes.swift +++ b/ChatLayout/Classes/Core/ChatLayoutAttributes.swift @@ -3,7 +3,7 @@ // ChatLayoutAttributes.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/ChatLayout/Classes/Core/ChatLayoutDelegate.swift b/ChatLayout/Classes/Core/ChatLayoutDelegate.swift index 40e5044e..4b77517f 100644 --- a/ChatLayout/Classes/Core/ChatLayoutDelegate.swift +++ b/ChatLayout/Classes/Core/ChatLayoutDelegate.swift @@ -3,7 +3,7 @@ // ChatLayoutDelegate.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/ChatLayout/Classes/Core/ChatLayoutInvalidationContext.swift b/ChatLayout/Classes/Core/ChatLayoutInvalidationContext.swift index e531a442..b2b89e84 100644 --- a/ChatLayout/Classes/Core/ChatLayoutInvalidationContext.swift +++ b/ChatLayout/Classes/Core/ChatLayoutInvalidationContext.swift @@ -3,7 +3,7 @@ // ChatLayoutInvalidationContext.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/ChatLayout/Classes/Core/ChatLayoutPositionSnapshot.swift b/ChatLayout/Classes/Core/ChatLayoutPositionSnapshot.swift index d3a8b209..50781f50 100644 --- a/ChatLayout/Classes/Core/ChatLayoutPositionSnapshot.swift +++ b/ChatLayout/Classes/Core/ChatLayoutPositionSnapshot.swift @@ -3,7 +3,7 @@ // ChatLayoutPositionSnapshot.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/ChatLayout/Classes/Core/ChatLayoutSettings.swift b/ChatLayout/Classes/Core/ChatLayoutSettings.swift index c9715e81..dfd8f5ae 100644 --- a/ChatLayout/Classes/Core/ChatLayoutSettings.swift +++ b/ChatLayout/Classes/Core/ChatLayoutSettings.swift @@ -3,7 +3,7 @@ // ChatLayoutSettings.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/ChatLayout/Classes/Core/Extensions/CGRect+Extension.swift b/ChatLayout/Classes/Core/Extensions/CGRect+Extension.swift index 36ddee40..6a9c37b8 100644 --- a/ChatLayout/Classes/Core/Extensions/CGRect+Extension.swift +++ b/ChatLayout/Classes/Core/Extensions/CGRect+Extension.swift @@ -3,7 +3,7 @@ // CGRect+Extension.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/ChatLayout/Classes/Core/Extensions/IndexPath+Extension.swift b/ChatLayout/Classes/Core/Extensions/IndexPath+Extension.swift index 9d6f58c1..233e349f 100644 --- a/ChatLayout/Classes/Core/Extensions/IndexPath+Extension.swift +++ b/ChatLayout/Classes/Core/Extensions/IndexPath+Extension.swift @@ -3,7 +3,7 @@ // IndexPath+Extension.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/ChatLayout/Classes/Core/Model/ItemKind.swift b/ChatLayout/Classes/Core/Model/ItemKind.swift index a1f97f53..19b225fe 100644 --- a/ChatLayout/Classes/Core/Model/ItemKind.swift +++ b/ChatLayout/Classes/Core/Model/ItemKind.swift @@ -3,7 +3,7 @@ // ItemKind.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/ChatLayout/Classes/Core/Model/ItemModel.swift b/ChatLayout/Classes/Core/Model/ItemModel.swift index c1f17959..a1ebf299 100644 --- a/ChatLayout/Classes/Core/Model/ItemModel.swift +++ b/ChatLayout/Classes/Core/Model/ItemModel.swift @@ -3,7 +3,7 @@ // ItemModel.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/ChatLayout/Classes/Core/Model/ItemPath.swift b/ChatLayout/Classes/Core/Model/ItemPath.swift index 69a1fa58..7b9d99f1 100644 --- a/ChatLayout/Classes/Core/Model/ItemPath.swift +++ b/ChatLayout/Classes/Core/Model/ItemPath.swift @@ -3,7 +3,7 @@ // ItemPath.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/ChatLayout/Classes/Core/Model/ItemSize.swift b/ChatLayout/Classes/Core/Model/ItemSize.swift index 4ebeacb0..913e582d 100644 --- a/ChatLayout/Classes/Core/Model/ItemSize.swift +++ b/ChatLayout/Classes/Core/Model/ItemSize.swift @@ -3,7 +3,7 @@ // ItemSize.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/ChatLayout/Classes/Core/Model/LayoutModel.swift b/ChatLayout/Classes/Core/Model/LayoutModel.swift index 88fe29b3..f8861327 100644 --- a/ChatLayout/Classes/Core/Model/LayoutModel.swift +++ b/ChatLayout/Classes/Core/Model/LayoutModel.swift @@ -3,7 +3,7 @@ // LayoutModel.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/ChatLayout/Classes/Core/Model/ModelState.swift b/ChatLayout/Classes/Core/Model/ModelState.swift index 3575e3d6..c56c3f25 100644 --- a/ChatLayout/Classes/Core/Model/ModelState.swift +++ b/ChatLayout/Classes/Core/Model/ModelState.swift @@ -3,7 +3,7 @@ // ModelState.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/ChatLayout/Classes/Core/Model/SectionModel.swift b/ChatLayout/Classes/Core/Model/SectionModel.swift index 7883cbaa..10cfe883 100644 --- a/ChatLayout/Classes/Core/Model/SectionModel.swift +++ b/ChatLayout/Classes/Core/Model/SectionModel.swift @@ -3,7 +3,7 @@ // SectionModel.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // @@ -29,7 +29,11 @@ struct SectionModel { } var frame: CGRect { - return CGRect(x: 0, y: offsetY, width: collectionLayout.visibleBounds.width - collectionLayout.settings.additionalInsets.left - collectionLayout.settings.additionalInsets.right, height: height) + let additionalInsets = collectionLayout.settings.additionalInsets + return CGRect(x: 0, + y: offsetY, + width: collectionLayout.visibleBounds.width - additionalInsets.left - additionalInsets.right, + height: height) } var height: CGFloat { diff --git a/ChatLayout/Classes/Core/Model/StateController.swift b/ChatLayout/Classes/Core/Model/StateController.swift index 1cadaf3e..d795ef3c 100644 --- a/ChatLayout/Classes/Core/Model/StateController.swift +++ b/ChatLayout/Classes/Core/Model/StateController.swift @@ -3,14 +3,14 @@ // StateController.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // import Foundation import UIKit -/// This protocol exists only to serve an ability to unit test. +/// This protocol exists only to serve an ability to unit test `StateController`. protocol ChatLayoutRepresentation: AnyObject { var settings: ChatLayoutSettings { get } @@ -25,7 +25,7 @@ protocol ChatLayoutRepresentation: AnyObject { var keepContentOffsetAtBottomOnBatchUpdates: Bool { get } - func numberOfItems(inSection section: Int) -> Int + func numberOfItems(in section: Int) -> Int func configuration(for element: ItemKind, at itemPath: ItemPath) -> ItemModel.Configuration @@ -37,6 +37,12 @@ protocol ChatLayoutRepresentation: AnyObject { final class StateController { + private enum CompensatingAction { + case insert + case delete + case frameUpdate(previousFrame: CGRect, newFrame: CGRect) + } + // This thing exists here as `UICollectionView` calls `targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint)` only once at the // beginning of the animated updates. But we must compensate the other changes that happened during the update. var batchUpdateCompensatingOffset: CGFloat = 0 @@ -120,7 +126,10 @@ final class StateController { } } - func itemAttributes(for itemPath: ItemPath, kind: ItemKind, predefinedFrame: CGRect? = nil, at state: ModelState) -> ChatLayoutAttributes? { + func itemAttributes(for itemPath: ItemPath, + kind: ItemKind, + predefinedFrame: CGRect? = nil, + at state: ModelState) -> ChatLayoutAttributes? { let attributes: ChatLayoutAttributes let itemIndexPath = itemPath.indexPath switch kind { @@ -204,20 +213,23 @@ final class StateController { // This occurs when getting layout attributes for initial / final animations return nil } + let section = layout(at: state).sections[itemPath.section] var itemFrame = item.frame let dx: CGFloat let visibleBounds = layoutRepresentation.visibleBounds + let additionalInsets = layoutRepresentation.settings.additionalInsets switch item.alignment { case .leading: - dx = layoutRepresentation.settings.additionalInsets.left + dx = additionalInsets.left case .trailing: - dx = visibleBounds.size.width - itemFrame.width - layoutRepresentation.settings.additionalInsets.right + dx = visibleBounds.size.width - itemFrame.width - additionalInsets.right case .center: - dx = layoutRepresentation.settings.additionalInsets.left + (visibleBounds.size.width - layoutRepresentation.settings.additionalInsets.right - layoutRepresentation.settings.additionalInsets.left) / 2 - itemFrame.width / 2 + let availableWidth = visibleBounds.size.width - additionalInsets.right - additionalInsets.left + dx = additionalInsets.left + availableWidth / 2 - itemFrame.width / 2 case .fullWidth: - dx = layoutRepresentation.settings.additionalInsets.left + dx = additionalInsets.left itemFrame.size.width = layoutRepresentation.layoutFrame.size.width } @@ -255,7 +267,10 @@ final class StateController { func section(at index: Int, at state: ModelState) -> SectionModel { guard index < layout(at: state).sections.count else { - preconditionFailure("Section index \(index) is bigger than the amount of sections \(layout(at: state).sections.count)") + preconditionFailure(""" + Section index \(index) is bigger than the amount of + sections \(layout(at: state).sections.count) + """) } return layout(at: state).sections[index] } @@ -343,7 +358,8 @@ final class StateController { layout.setAndAssemble(item: item, sectionIndex: itemPath.section, itemIndex: itemPath.item) } storage[state] = layout - compensateOffsetIfNeeded(for: itemPath, kind: kind, action: .frameUpdate(previousFrame: previousFrame, newFrame: item.frame)) + let frameUpdateAction = CompensatingAction.frameUpdate(previousFrame: previousFrame, newFrame: item.frame) + compensateOffsetIfNeeded(for: itemPath, kind: kind, action: frameUpdateAction) } func update(alignment: ChatItemAlignment, for itemPath: ItemPath, kind: ItemKind, at state: ModelState) { @@ -406,7 +422,7 @@ final class StateController { } if indexPath.item == NSNotFound { - let items = (0.. ItemModel in + let items = (0.. ItemModel in let itemIndexPath = IndexPath(item: index, section: indexPath.section) return ItemModel(with: layoutRepresentation.configuration(for: .cell, at: itemIndexPath.itemPath)) } @@ -478,7 +494,7 @@ final class StateController { section.set(footer: footer) let oldItems = section.items - let items: [ItemModel] = (0.. Bool { - return contentHeight(at: state).rounded() > (layoutRepresentation.visibleBounds.height + (withFullCompensation ? batchUpdateCompensatingOffset + proposedCompensatingOffset : 0)).rounded() + func isLayoutBiggerThanVisibleBounds(at state: ModelState, withFullCompensation: Bool = false) -> Bool { + let visibleBoundsHeight = layoutRepresentation.visibleBounds.height + (withFullCompensation ? batchUpdateCompensatingOffset + proposedCompensatingOffset : 0) + return contentHeight(at: state).rounded() > visibleBoundsHeight.rounded() } private func allAttributes(at state: ModelState, visibleRect: CGRect? = nil) -> [ChatLayoutAttributes] { @@ -703,16 +720,17 @@ final class StateController { return true } var itemWillBeVisible: Bool { + let offsetVisibleBounds = layoutRepresentation.visibleBounds.offsetBy(dx: 0, dy: proposedCompensatingOffset + batchUpdateCompensatingOffset) if insertedIndexes.contains(itemPath.indexPath), let itemFrame = self.itemFrame(for: itemPath, kind: .cell, at: state, isFinal: true), - itemFrame.intersects(layoutRepresentation.visibleBounds.offsetBy(dx: 0, dy: proposedCompensatingOffset + batchUpdateCompensatingOffset)) { + itemFrame.intersects(offsetVisibleBounds) { return true } if let itemIdentifier = self.itemIdentifier(for: itemPath, kind: .cell, at: .afterUpdate), let initialIndexPath = self.itemPath(by: itemIdentifier, at: .beforeUpdate)?.indexPath, movedIndexes.contains(initialIndexPath) || reloadedIndexes.contains(initialIndexPath), let itemFrame = self.itemFrame(for: itemPath, kind: .cell, at: state, isFinal: true), - itemFrame.intersects(layoutRepresentation.visibleBounds.offsetBy(dx: 0, dy: proposedCompensatingOffset + batchUpdateCompensatingOffset)) { + itemFrame.intersects(offsetVisibleBounds) { return true } return false @@ -738,8 +756,7 @@ final class StateController { return self.itemAttributes(for: path, kind: kind, predefinedFrame: frame, at: state) } } else { - // Here just to test without caching just in case - var attributes = ContiguousArray() + var attributes = [ChatLayoutAttributes]() attributes.reserveCapacity(layout.sections.count * 1000) layout.sections.enumerated().forEach { sectionIndex, section in let sectionPath = ItemPath(item: 0, section: sectionIndex) @@ -757,42 +774,37 @@ final class StateController { } } - return Array(attributes) + return attributes } } - private enum CompensatingAction { - case insert - case delete - case frameUpdate(previousFrame: CGRect, newFrame: CGRect) - } - private func compensateOffsetIfNeeded(for itemPath: ItemPath, kind: ItemKind, action: CompensatingAction) { guard layoutRepresentation.keepContentOffsetAtBottomOnBatchUpdates else { return } + let minY = (layoutRepresentation.visibleBounds.lowerPoint.y + batchUpdateCompensatingOffset + proposedCompensatingOffset).rounded() switch action { case .insert: - guard isLayoutBiggerThanScreen(at: .afterUpdate), + guard isLayoutBiggerThanVisibleBounds(at: .afterUpdate), let itemFrame = itemFrame(for: itemPath, kind: kind, at: .afterUpdate) else { return } - if itemFrame.minY.rounded() - layoutRepresentation.settings.interItemSpacing <= (layoutRepresentation.visibleBounds.lowerPoint.y + batchUpdateCompensatingOffset + proposedCompensatingOffset).rounded() { + if itemFrame.minY.rounded() - layoutRepresentation.settings.interItemSpacing <= minY { proposedCompensatingOffset += itemFrame.height + layoutRepresentation.settings.interItemSpacing } case let .frameUpdate(previousFrame, newFrame): - guard isLayoutBiggerThanScreen(at: .afterUpdate, withFullCompensation: true) else { + guard isLayoutBiggerThanVisibleBounds(at: .afterUpdate, withFullCompensation: true) else { return } - if newFrame.minY.rounded() <= (layoutRepresentation.visibleBounds.lowerPoint.y + batchUpdateCompensatingOffset + proposedCompensatingOffset).rounded() { + if newFrame.minY.rounded() <= minY { batchUpdateCompensatingOffset += newFrame.height - previousFrame.height } case .delete: - guard isLayoutBiggerThanScreen(at: .beforeUpdate), + guard isLayoutBiggerThanVisibleBounds(at: .beforeUpdate), let deletedFrame = itemFrame(for: itemPath, kind: kind, at: .beforeUpdate) else { return } - if deletedFrame.minY.rounded() <= (layoutRepresentation.visibleBounds.lowerPoint.y + batchUpdateCompensatingOffset + proposedCompensatingOffset).rounded() { + if deletedFrame.minY.rounded() <= minY { // Changing content offset for deleted items using `invalidateLayout(with:) causes UI glitches. // So we are using targetContentOffset(forProposedContentOffset:) which is going to be called after. proposedCompensatingOffset -= (deletedFrame.height + layoutRepresentation.settings.interItemSpacing) @@ -805,32 +817,33 @@ final class StateController { guard layoutRepresentation.keepContentOffsetAtBottomOnBatchUpdates else { return } + let minY = (layoutRepresentation.visibleBounds.lowerPoint.y + batchUpdateCompensatingOffset + proposedCompensatingOffset).rounded() switch action { case .insert: - guard isLayoutBiggerThanScreen(at: .afterUpdate), + guard isLayoutBiggerThanVisibleBounds(at: .afterUpdate), sectionIndex < layout(at: .afterUpdate).sections.count else { return } let section = layout(at: .afterUpdate).sections[sectionIndex] - if section.offsetY.rounded() - layoutRepresentation.settings.interSectionSpacing <= (layoutRepresentation.visibleBounds.lowerPoint.y + batchUpdateCompensatingOffset + proposedCompensatingOffset).rounded() { + if section.offsetY.rounded() - layoutRepresentation.settings.interSectionSpacing <= minY { proposedCompensatingOffset += section.height + layoutRepresentation.settings.interSectionSpacing } case let .frameUpdate(previousFrame, newFrame): guard sectionIndex < layout(at: .afterUpdate).sections.count, - isLayoutBiggerThanScreen(at: .afterUpdate, withFullCompensation: true) else { + isLayoutBiggerThanVisibleBounds(at: .afterUpdate, withFullCompensation: true) else { return } - if newFrame.minY.rounded() <= (layoutRepresentation.visibleBounds.lowerPoint.y + batchUpdateCompensatingOffset + proposedCompensatingOffset).rounded() { + if newFrame.minY.rounded() <= minY { batchUpdateCompensatingOffset += newFrame.height - previousFrame.height } case .delete: - guard isLayoutBiggerThanScreen(at: .afterUpdate), + guard isLayoutBiggerThanVisibleBounds(at: .afterUpdate), sectionIndex < layout(at: .afterUpdate).sections.count else { return } let section = layout(at: .beforeUpdate).sections[sectionIndex] - if section.locationHeight.rounded() <= (layoutRepresentation.visibleBounds.lowerPoint.y + batchUpdateCompensatingOffset + proposedCompensatingOffset).rounded() { + if section.locationHeight.rounded() <= minY { // Changing content offset for deleted items using `invalidateLayout(with:) causes UI glitches. // So we are using targetContentOffset(forProposedContentOffset:) which is going to be called after. proposedCompensatingOffset -= (section.height + layoutRepresentation.settings.interSectionSpacing) @@ -839,10 +852,13 @@ final class StateController { } - private func offsetByCompensation(frame: CGRect, at itemPath: ItemPath, for state: ModelState, backward: Bool = false) -> CGRect { + private func offsetByCompensation(frame: CGRect, + at itemPath: ItemPath, + for state: ModelState, + backward: Bool = false) -> CGRect { guard layoutRepresentation.keepContentOffsetAtBottomOnBatchUpdates, state == .afterUpdate, - isLayoutBiggerThanScreen(at: .afterUpdate) else { + isLayoutBiggerThanVisibleBounds(at: .afterUpdate) else { return frame } return frame.offsetBy(dx: 0, dy: proposedCompensatingOffset * (backward ? -1 : 1)) diff --git a/ChatLayout/Classes/Extras/CellLayoutContainerView.swift b/ChatLayout/Classes/Extras/CellLayoutContainerView.swift index ce82b37c..3d0cb1dc 100644 --- a/ChatLayout/Classes/Extras/CellLayoutContainerView.swift +++ b/ChatLayout/Classes/Extras/CellLayoutContainerView.swift @@ -3,7 +3,7 @@ // CellLayoutContainerView.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/ChatLayout/Classes/Extras/ContainerCollectionReusableView.swift b/ChatLayout/Classes/Extras/ContainerCollectionReusableView.swift index 6670d2d2..c1ba998a 100644 --- a/ChatLayout/Classes/Extras/ContainerCollectionReusableView.swift +++ b/ChatLayout/Classes/Extras/ContainerCollectionReusableView.swift @@ -3,7 +3,7 @@ // ContainerCollectionReusableView.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/ChatLayout/Classes/Extras/ContainerCollectionViewCell.swift b/ChatLayout/Classes/Extras/ContainerCollectionViewCell.swift index 22ba85e1..73866844 100644 --- a/ChatLayout/Classes/Extras/ContainerCollectionViewCell.swift +++ b/ChatLayout/Classes/Extras/ContainerCollectionViewCell.swift @@ -3,7 +3,7 @@ // ContainerCollectionViewCell.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/ChatLayout/Classes/Extras/EdgeAligningView.swift b/ChatLayout/Classes/Extras/EdgeAligningView.swift index 6a75d641..7aa6a7bc 100644 --- a/ChatLayout/Classes/Extras/EdgeAligningView.swift +++ b/ChatLayout/Classes/Extras/EdgeAligningView.swift @@ -3,7 +3,7 @@ // EdgeAligningView.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/ChatLayout/Classes/Extras/ImageMaskedView.swift b/ChatLayout/Classes/Extras/ImageMaskedView.swift index a48587c3..9f54f760 100644 --- a/ChatLayout/Classes/Extras/ImageMaskedView.swift +++ b/ChatLayout/Classes/Extras/ImageMaskedView.swift @@ -3,7 +3,7 @@ // ImageMaskedView.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/ChatLayout/Classes/Extras/MessageContainerView.swift b/ChatLayout/Classes/Extras/MessageContainerView.swift index ff8684a3..50ba6e46 100644 --- a/ChatLayout/Classes/Extras/MessageContainerView.swift +++ b/ChatLayout/Classes/Extras/MessageContainerView.swift @@ -3,7 +3,7 @@ // MessageContainerView.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/ChatLayout/Classes/Extras/RoundedCornersContainerView.swift b/ChatLayout/Classes/Extras/RoundedCornersContainerView.swift index 49e34050..492c8ad6 100644 --- a/ChatLayout/Classes/Extras/RoundedCornersContainerView.swift +++ b/ChatLayout/Classes/Extras/RoundedCornersContainerView.swift @@ -3,7 +3,7 @@ // RoundedCornersContainerView.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/ChatLayout/Classes/Extras/StaticViewFactory.swift b/ChatLayout/Classes/Extras/StaticViewFactory.swift index 79fba1cd..98d1ffcb 100644 --- a/ChatLayout/Classes/Extras/StaticViewFactory.swift +++ b/ChatLayout/Classes/Extras/StaticViewFactory.swift @@ -3,7 +3,7 @@ // StaticViewFactory.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/Example/.swiftlint.yml b/Example/.swiftlint.yml new file mode 100644 index 00000000..2e784982 --- /dev/null +++ b/Example/.swiftlint.yml @@ -0,0 +1,73 @@ +disabled_rules: # rule identifiers to exclude from running + - colon + - comma + - control_statement + - nesting +opt_in_rules: # some rules are only opt-in + - empty_count + # Find all the available rules by running: + # swiftlint rules +included: # paths to include during linting. `--path` is ignored if present. + - Example + - RouteComposer +excluded: # paths to ignore during linting. Takes precedence over `included`. + - Carthage + - Pods + - Source/ExcludedFolder + - Source/ExcludedFile.swift + - Source/*/ExcludedFile.swift # Exclude files with a wildcard + +# configurable rules can be customized from this configuration file +# binary rules can set their severity level +force_cast: warning # implicitly +force_try: + severity: warning # explicitly +# rules that have both warning and error levels, can set just the warning level +# implicitly +line_length: 180 + +# they can set both implicitly with an array +type_body_length: + - 400 # warning + - 500 # error + +function_body_length: + - 150 # warning + - 200 # error + +cyclomatic_complexity: + - 15 # warning + - 25 # error + + +# or they can set both explicitly +file_length: + warning: 500 + error: 1200 + +# naming rules can set warnings/errors for min_length and max_length +# additionally they can set excluded names +type_name: + min_length: 4 # only warning + max_length: # warning and error + warning: 40 + error: 50 + excluded: iPhone # excluded via string + +identifier_name: + min_length: # only min_length + error: 3 # only error + excluded: # excluded via string array + - id + - vc + - key + - url + - URL + - GlobalAPIKey + +function_parameter_count: 6 + +large_tuple: + - 4 + - 10 +reporter: "xcode" # reporter type (xcode, json, csv, checkstyle, junit, html, emoji, sonarqube) \ No newline at end of file diff --git a/Example/ChatLayout/AppDelegate.swift b/Example/ChatLayout/AppDelegate.swift index 20aacfdd..f2b29f0c 100644 --- a/Example/ChatLayout/AppDelegate.swift +++ b/Example/ChatLayout/AppDelegate.swift @@ -3,7 +3,7 @@ // AppDelegate.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/Example/ChatLayout/Chat/Builder/ChatViewControllerBuilder.swift b/Example/ChatLayout/Chat/Builder/ChatViewControllerBuilder.swift index e7f6516e..4f11cb80 100644 --- a/Example/ChatLayout/Chat/Builder/ChatViewControllerBuilder.swift +++ b/Example/ChatLayout/Chat/Builder/ChatViewControllerBuilder.swift @@ -3,7 +3,7 @@ // ChatViewControllerBuilder.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/Example/ChatLayout/Chat/Constants.swift b/Example/ChatLayout/Chat/Constants.swift index 3e3a9be8..7d847325 100644 --- a/Example/ChatLayout/Chat/Constants.swift +++ b/Example/ChatLayout/Chat/Constants.swift @@ -3,7 +3,7 @@ // Constants.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/Example/ChatLayout/Chat/Controller/ChatController.swift b/Example/ChatLayout/Chat/Controller/ChatController.swift index d044ef1b..306eab0d 100644 --- a/Example/ChatLayout/Chat/Controller/ChatController.swift +++ b/Example/ChatLayout/Chat/Controller/ChatController.swift @@ -3,7 +3,7 @@ // ChatController.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/Example/ChatLayout/Chat/Controller/ChatControllerDelegate.swift b/Example/ChatLayout/Chat/Controller/ChatControllerDelegate.swift index 72d370de..a6285f8c 100644 --- a/Example/ChatLayout/Chat/Controller/ChatControllerDelegate.swift +++ b/Example/ChatLayout/Chat/Controller/ChatControllerDelegate.swift @@ -3,7 +3,7 @@ // ChatControllerDelegate.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/Example/ChatLayout/Chat/Controller/DefaultChatController.swift b/Example/ChatLayout/Chat/Controller/DefaultChatController.swift index 4d322d07..e7fd10e4 100644 --- a/Example/ChatLayout/Chat/Controller/DefaultChatController.swift +++ b/Example/ChatLayout/Chat/Controller/DefaultChatController.swift @@ -3,7 +3,7 @@ // DefaultChatController.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // @@ -79,7 +79,12 @@ final class DefaultChatController: ChatController { return } let messagesSplitByDay = self.messages - .map { Message(id: $0.id, date: $0.date, data: self.convert($0.data), owner: User(id: $0.userId), type: $0.userId == self.userId ? .outgoing : .incoming, status: $0.status) } + .map { Message(id: $0.id, + date: $0.date, + data: self.convert($0.data), + owner: User(id: $0.userId), + type: $0.userId == self.userId ? .outgoing : .incoming, + status: $0.status) } .reduce(into: [[Message]]()) { result, message in guard var section = result.last, let prevMessage = section.last else { diff --git a/Example/ChatLayout/Chat/Model/Caches.swift b/Example/ChatLayout/Chat/Model/Caches.swift index 395ab0f6..543ff5d6 100644 --- a/Example/ChatLayout/Chat/Model/Caches.swift +++ b/Example/ChatLayout/Chat/Model/Caches.swift @@ -3,7 +3,7 @@ // Caches.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/Example/ChatLayout/Chat/Model/Caching/AsyncKeyValueCaching.swift b/Example/ChatLayout/Chat/Model/Caching/AsyncKeyValueCaching.swift index da6c9805..f76fb43d 100644 --- a/Example/ChatLayout/Chat/Model/Caching/AsyncKeyValueCaching.swift +++ b/Example/ChatLayout/Chat/Model/Caching/AsyncKeyValueCaching.swift @@ -3,7 +3,7 @@ // AsyncKeyValueCaching.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/Example/ChatLayout/Chat/Model/Caching/CacheError.swift b/Example/ChatLayout/Chat/Model/Caching/CacheError.swift index 8b3941a7..21565ea5 100644 --- a/Example/ChatLayout/Chat/Model/Caching/CacheError.swift +++ b/Example/ChatLayout/Chat/Model/Caching/CacheError.swift @@ -3,7 +3,7 @@ // CacheError.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/Example/ChatLayout/Chat/Model/Caching/Data/IterativeCache.swift b/Example/ChatLayout/Chat/Model/Caching/Data/IterativeCache.swift index 54b8c0d2..88c6153d 100644 --- a/Example/ChatLayout/Chat/Model/Caching/Data/IterativeCache.swift +++ b/Example/ChatLayout/Chat/Model/Caching/Data/IterativeCache.swift @@ -3,14 +3,16 @@ // IterativeCache.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // import Foundation import UIKit -public final class IterativeCache: AsyncKeyValueCaching where FastCache.CachingKey == SlowCache.CachingKey, FastCache.Entity == SlowCache.Entity { +public final class IterativeCache: AsyncKeyValueCaching + where + FastCache.CachingKey == SlowCache.CachingKey, FastCache.Entity == SlowCache.Entity { public let mainCache: FastCache diff --git a/Example/ChatLayout/Chat/Model/Caching/Data/MemoryDataCache.swift b/Example/ChatLayout/Chat/Model/Caching/Data/MemoryDataCache.swift index e7e59cbd..7efff54b 100644 --- a/Example/ChatLayout/Chat/Model/Caching/Data/MemoryDataCache.swift +++ b/Example/ChatLayout/Chat/Model/Caching/Data/MemoryDataCache.swift @@ -3,7 +3,7 @@ // MemoryDataCache.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/Example/ChatLayout/Chat/Model/Caching/Data/PersistentDataCache.swift b/Example/ChatLayout/Chat/Model/Caching/Data/PersistentDataCache.swift index d21828ed..982b7a2f 100644 --- a/Example/ChatLayout/Chat/Model/Caching/Data/PersistentDataCache.swift +++ b/Example/ChatLayout/Chat/Model/Caching/Data/PersistentDataCache.swift @@ -3,7 +3,7 @@ // PersistentDataCache.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/Example/ChatLayout/Chat/Model/Caching/Data/PersistentlyCacheable.swift b/Example/ChatLayout/Chat/Model/Caching/Data/PersistentlyCacheable.swift index 0c566506..0e655ed0 100644 --- a/Example/ChatLayout/Chat/Model/Caching/Data/PersistentlyCacheable.swift +++ b/Example/ChatLayout/Chat/Model/Caching/Data/PersistentlyCacheable.swift @@ -3,7 +3,7 @@ // PersistentlyCacheable.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/Example/ChatLayout/Chat/Model/Caching/Image/CacheableImageKey.swift b/Example/ChatLayout/Chat/Model/Caching/Image/CacheableImageKey.swift index 0e51d498..5cff5231 100644 --- a/Example/ChatLayout/Chat/Model/Caching/Image/CacheableImageKey.swift +++ b/Example/ChatLayout/Chat/Model/Caching/Image/CacheableImageKey.swift @@ -3,7 +3,7 @@ // CacheableImageKey.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/Example/ChatLayout/Chat/Model/Caching/Image/ImageForUrlCache.swift b/Example/ChatLayout/Chat/Model/Caching/Image/ImageForUrlCache.swift index 87f48f07..f17ee539 100644 --- a/Example/ChatLayout/Chat/Model/Caching/Image/ImageForUrlCache.swift +++ b/Example/ChatLayout/Chat/Model/Caching/Image/ImageForUrlCache.swift @@ -3,7 +3,7 @@ // ImageForUrlCache.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/Example/ChatLayout/Chat/Model/Caching/KeyValueCaching.swift b/Example/ChatLayout/Chat/Model/Caching/KeyValueCaching.swift index 53b90fc4..ae47c4ff 100644 --- a/Example/ChatLayout/Chat/Model/Caching/KeyValueCaching.swift +++ b/Example/ChatLayout/Chat/Model/Caching/KeyValueCaching.swift @@ -3,7 +3,7 @@ // KeyValueCaching.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/Example/ChatLayout/Chat/Model/Caching/Metadata/MetaDataCache.swift b/Example/ChatLayout/Chat/Model/Caching/Metadata/MetaDataCache.swift index abdd64ea..41cb3c87 100644 --- a/Example/ChatLayout/Chat/Model/Caching/Metadata/MetaDataCache.swift +++ b/Example/ChatLayout/Chat/Model/Caching/Metadata/MetaDataCache.swift @@ -3,7 +3,7 @@ // MetaDataCache.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // @@ -26,7 +26,9 @@ final class MetaDataCache: AsyncKeyValueCaching whe func getEntity(for url: URL) throws -> LPLinkMetadata { let data = try cache.getEntity(for: url) + // swiftlint:disable force_try force_cast let entity = try! NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as! LPLinkMetadata + // swiftlint:enable force_try force_cast return entity } @@ -46,7 +48,9 @@ final class MetaDataCache: AsyncKeyValueCaching whe } func store(entity: LPLinkMetadata, for key: URL) throws { + // swiftlint:disable force_try let codedData = try! NSKeyedArchiver.archivedData(withRootObject: entity, requiringSecureCoding: true) + // swiftlint:enable force_try try cache.store(entity: codedData, for: key) } diff --git a/Example/ChatLayout/Chat/Model/ChatDateFormatter.swift b/Example/ChatLayout/Chat/Model/ChatDateFormatter.swift index 6a9e0135..85456995 100644 --- a/Example/ChatLayout/Chat/Model/ChatDateFormatter.swift +++ b/Example/ChatLayout/Chat/Model/ChatDateFormatter.swift @@ -3,7 +3,7 @@ // ChatDateFormatter.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/Example/ChatLayout/Chat/Model/Data Objects/Cell.swift b/Example/ChatLayout/Chat/Model/Data Objects/Cell.swift index d8440b7e..47cbeacc 100644 --- a/Example/ChatLayout/Chat/Model/Data Objects/Cell.swift +++ b/Example/ChatLayout/Chat/Model/Data Objects/Cell.swift @@ -3,7 +3,7 @@ // Cell.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/Example/ChatLayout/Chat/Model/Data Objects/Message.swift b/Example/ChatLayout/Chat/Model/Data Objects/Message.swift index 463c6769..4a0c9d4a 100644 --- a/Example/ChatLayout/Chat/Model/Data Objects/Message.swift +++ b/Example/ChatLayout/Chat/Model/Data Objects/Message.swift @@ -3,7 +3,7 @@ // Message.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/Example/ChatLayout/Chat/Model/Data Objects/RawMessage.swift b/Example/ChatLayout/Chat/Model/Data Objects/RawMessage.swift index d34dd383..bdb61465 100644 --- a/Example/ChatLayout/Chat/Model/Data Objects/RawMessage.swift +++ b/Example/ChatLayout/Chat/Model/Data Objects/RawMessage.swift @@ -3,7 +3,7 @@ // RawMessage.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/Example/ChatLayout/Chat/Model/Data Objects/Section.swift b/Example/ChatLayout/Chat/Model/Data Objects/Section.swift index d49c508f..4f68d57e 100644 --- a/Example/ChatLayout/Chat/Model/Data Objects/Section.swift +++ b/Example/ChatLayout/Chat/Model/Data Objects/Section.swift @@ -3,7 +3,7 @@ // Section.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/Example/ChatLayout/Chat/Model/Data Objects/TypingState.swift b/Example/ChatLayout/Chat/Model/Data Objects/TypingState.swift index 22569e8a..021f368f 100644 --- a/Example/ChatLayout/Chat/Model/Data Objects/TypingState.swift +++ b/Example/ChatLayout/Chat/Model/Data Objects/TypingState.swift @@ -3,7 +3,7 @@ // TypingState.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/Example/ChatLayout/Chat/Model/Data Objects/User.swift b/Example/ChatLayout/Chat/Model/Data Objects/User.swift index 2f9968e4..7838cd58 100644 --- a/Example/ChatLayout/Chat/Model/Data Objects/User.swift +++ b/Example/ChatLayout/Chat/Model/Data Objects/User.swift @@ -3,7 +3,7 @@ // User.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/Example/ChatLayout/Chat/Model/DefaultRandomDataProvider.swift b/Example/ChatLayout/Chat/Model/DefaultRandomDataProvider.swift index 94d366a6..e9dbc611 100644 --- a/Example/ChatLayout/Chat/Model/DefaultRandomDataProvider.swift +++ b/Example/ChatLayout/Chat/Model/DefaultRandomDataProvider.swift @@ -3,7 +3,7 @@ // DefaultRandomDataProvider.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // @@ -190,7 +190,12 @@ final class DefaultRandomDataProvider: RandomDataProvider { case (7, true): return RawMessage(id: UUID(), date: date, data: .image(.image(images[Int.random(in: 0.. Void)? = nil) { // I ask content size from the layout because on IOs 12 collection view contains not updated one - let contentOffsetAtBottom = CGPoint(x: collectionView.contentOffset.x, y: chatLayout.collectionViewContentSize.height - collectionView.frame.height + collectionView.adjustedContentInset.bottom) + let contentOffsetAtBottom = CGPoint(x: collectionView.contentOffset.x, + y: chatLayout.collectionViewContentSize.height - collectionView.frame.height + collectionView.adjustedContentInset.bottom) currentInterfaceActions.options.insert(.scrollingToTop) UIView.animate(withDuration: 0.25, animations: { [weak self] in diff --git a/Example/ChatLayout/Chat/View/Data Source/ChatCollectionDataSource.swift b/Example/ChatLayout/Chat/View/Data Source/ChatCollectionDataSource.swift index cc95f0f4..146a920f 100644 --- a/Example/ChatLayout/Chat/View/Data Source/ChatCollectionDataSource.swift +++ b/Example/ChatLayout/Chat/View/Data Source/ChatCollectionDataSource.swift @@ -3,7 +3,7 @@ // ChatCollectionDataSource.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/Example/ChatLayout/Chat/View/Data Source/DefaultChatCollectionDataSource.swift b/Example/ChatLayout/Chat/View/Data Source/DefaultChatCollectionDataSource.swift index 40618142..ffc2ed97 100644 --- a/Example/ChatLayout/Chat/View/Data Source/DefaultChatCollectionDataSource.swift +++ b/Example/ChatLayout/Chat/View/Data Source/DefaultChatCollectionDataSource.swift @@ -3,7 +3,7 @@ // DefaultChatCollectionDataSource.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // @@ -327,6 +327,7 @@ extension DefaultChatCollectionDataSource: ChatLayoutDelegate { return } switch sections[indexPath.section].cells[indexPath.item] { + // Uncomment to see the effect // case .messageGroup: // originalAttributes.center.x -= originalAttributes.frame.width // case let .message(message, bubbleType: _): @@ -347,6 +348,7 @@ extension DefaultChatCollectionDataSource: ChatLayoutDelegate { return } switch oldSections[indexPath.section].cells[indexPath.item] { + // Uncomment to see the effect // case .messageGroup: // originalAttributes.center.x -= originalAttributes.frame.width // case let .message(message, bubbleType: _): diff --git a/Example/ChatLayout/Chat/View/Editing Accessory View/EditingAccessoryController.swift b/Example/ChatLayout/Chat/View/Editing Accessory View/EditingAccessoryController.swift index dd361a18..c719fc1b 100644 --- a/Example/ChatLayout/Chat/View/Editing Accessory View/EditingAccessoryController.swift +++ b/Example/ChatLayout/Chat/View/Editing Accessory View/EditingAccessoryController.swift @@ -3,7 +3,7 @@ // EditingAccessoryController.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/Example/ChatLayout/Chat/View/Editing Accessory View/EditingAccessoryView.swift b/Example/ChatLayout/Chat/View/Editing Accessory View/EditingAccessoryView.swift index eaa12a03..7fac0122 100644 --- a/Example/ChatLayout/Chat/View/Editing Accessory View/EditingAccessoryView.swift +++ b/Example/ChatLayout/Chat/View/Editing Accessory View/EditingAccessoryView.swift @@ -3,7 +3,7 @@ // EditingAccessoryView.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/Example/ChatLayout/Chat/View/Helpers/DifferenceKit+Extension.swift b/Example/ChatLayout/Chat/View/Helpers/DifferenceKit+Extension.swift index 1d86ee17..b20c461d 100644 --- a/Example/ChatLayout/Chat/View/Helpers/DifferenceKit+Extension.swift +++ b/Example/ChatLayout/Chat/View/Helpers/DifferenceKit+Extension.swift @@ -3,7 +3,7 @@ // DifferenceKit+Extension.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/Example/ChatLayout/Chat/View/Helpers/SetActor.swift b/Example/ChatLayout/Chat/View/Helpers/SetActor.swift index 4771215b..15652661 100644 --- a/Example/ChatLayout/Chat/View/Helpers/SetActor.swift +++ b/Example/ChatLayout/Chat/View/Helpers/SetActor.swift @@ -3,7 +3,7 @@ // SetActor.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/Example/ChatLayout/Chat/View/Image/ImageController.swift b/Example/ChatLayout/Chat/View/Image/ImageController.swift index fa5116b0..e0197569 100644 --- a/Example/ChatLayout/Chat/View/Image/ImageController.swift +++ b/Example/ChatLayout/Chat/View/Image/ImageController.swift @@ -3,7 +3,7 @@ // ImageController.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/Example/ChatLayout/Chat/View/Image/ImageMessageSource.swift b/Example/ChatLayout/Chat/View/Image/ImageMessageSource.swift index 5d94c75f..a3475912 100644 --- a/Example/ChatLayout/Chat/View/Image/ImageMessageSource.swift +++ b/Example/ChatLayout/Chat/View/Image/ImageMessageSource.swift @@ -3,7 +3,7 @@ // ImageMessageSource.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/Example/ChatLayout/Chat/View/Image/ImageView.swift b/Example/ChatLayout/Chat/View/Image/ImageView.swift index b053e3a4..ba72242c 100644 --- a/Example/ChatLayout/Chat/View/Image/ImageView.swift +++ b/Example/ChatLayout/Chat/View/Image/ImageView.swift @@ -3,7 +3,7 @@ // ImageView.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/Example/ChatLayout/Chat/View/Image/ImageViewState.swift b/Example/ChatLayout/Chat/View/Image/ImageViewState.swift index 47922076..8a5a02ec 100644 --- a/Example/ChatLayout/Chat/View/Image/ImageViewState.swift +++ b/Example/ChatLayout/Chat/View/Image/ImageViewState.swift @@ -3,7 +3,7 @@ // ImageViewState.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/Example/ChatLayout/Chat/View/Image/Loader/CachingImageLoader.swift b/Example/ChatLayout/Chat/View/Image/Loader/CachingImageLoader.swift index b75e91ea..f58378d0 100644 --- a/Example/ChatLayout/Chat/View/Image/Loader/CachingImageLoader.swift +++ b/Example/ChatLayout/Chat/View/Image/Loader/CachingImageLoader.swift @@ -3,7 +3,7 @@ // CachingImageLoader.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/Example/ChatLayout/Chat/View/Image/Loader/DefaultImageLoader.swift b/Example/ChatLayout/Chat/View/Image/Loader/DefaultImageLoader.swift index f6dbaf46..c1250d8a 100644 --- a/Example/ChatLayout/Chat/View/Image/Loader/DefaultImageLoader.swift +++ b/Example/ChatLayout/Chat/View/Image/Loader/DefaultImageLoader.swift @@ -3,7 +3,7 @@ // DefaultImageLoader.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/Example/ChatLayout/Chat/View/Image/Loader/ImageLoader.swift b/Example/ChatLayout/Chat/View/Image/Loader/ImageLoader.swift index 43daabfe..2984825a 100644 --- a/Example/ChatLayout/Chat/View/Image/Loader/ImageLoader.swift +++ b/Example/ChatLayout/Chat/View/Image/Loader/ImageLoader.swift @@ -3,7 +3,7 @@ // ImageLoader.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/Example/ChatLayout/Chat/View/Keyboard/KeyboardInfo.swift b/Example/ChatLayout/Chat/View/Keyboard/KeyboardInfo.swift index d9ac6c80..30bf2716 100644 --- a/Example/ChatLayout/Chat/View/Keyboard/KeyboardInfo.swift +++ b/Example/ChatLayout/Chat/View/Keyboard/KeyboardInfo.swift @@ -3,7 +3,7 @@ // KeyboardInfo.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/Example/ChatLayout/Chat/View/Keyboard/KeyboardListener.swift b/Example/ChatLayout/Chat/View/Keyboard/KeyboardListener.swift index 7c1a3de0..82112d9d 100644 --- a/Example/ChatLayout/Chat/View/Keyboard/KeyboardListener.swift +++ b/Example/ChatLayout/Chat/View/Keyboard/KeyboardListener.swift @@ -3,7 +3,7 @@ // KeyboardListener.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/Example/ChatLayout/Chat/View/Keyboard/KeyboardListenerDelegate.swift b/Example/ChatLayout/Chat/View/Keyboard/KeyboardListenerDelegate.swift index a8526681..536c0607 100644 --- a/Example/ChatLayout/Chat/View/Keyboard/KeyboardListenerDelegate.swift +++ b/Example/ChatLayout/Chat/View/Keyboard/KeyboardListenerDelegate.swift @@ -3,7 +3,7 @@ // KeyboardListenerDelegate.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/Example/ChatLayout/Chat/View/Other/BubbleController.swift b/Example/ChatLayout/Chat/View/Other/BubbleController.swift index cce4b81a..7b7b2dbf 100644 --- a/Example/ChatLayout/Chat/View/Other/BubbleController.swift +++ b/Example/ChatLayout/Chat/View/Other/BubbleController.swift @@ -3,7 +3,7 @@ // BubbleController.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/Example/ChatLayout/Chat/View/Other/DefaultBubbleController.swift b/Example/ChatLayout/Chat/View/Other/DefaultBubbleController.swift index dfb9460c..cc07430a 100644 --- a/Example/ChatLayout/Chat/View/Other/DefaultBubbleController.swift +++ b/Example/ChatLayout/Chat/View/Other/DefaultBubbleController.swift @@ -3,7 +3,7 @@ // DefaultBubbleController.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/Example/ChatLayout/Chat/View/Other/EditNotifier.swift b/Example/ChatLayout/Chat/View/Other/EditNotifier.swift index 18532287..c466691d 100644 --- a/Example/ChatLayout/Chat/View/Other/EditNotifier.swift +++ b/Example/ChatLayout/Chat/View/Other/EditNotifier.swift @@ -3,7 +3,7 @@ // EditNotifier.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/Example/ChatLayout/Chat/View/Other/EditNotifierDelegate.swift b/Example/ChatLayout/Chat/View/Other/EditNotifierDelegate.swift index 75c455d5..3ca66696 100644 --- a/Example/ChatLayout/Chat/View/Other/EditNotifierDelegate.swift +++ b/Example/ChatLayout/Chat/View/Other/EditNotifierDelegate.swift @@ -3,7 +3,7 @@ // EditNotifierDelegate.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/Example/ChatLayout/Chat/View/Other/FullCellContentBubbleController.swift b/Example/ChatLayout/Chat/View/Other/FullCellContentBubbleController.swift index add0353a..31d4ccf4 100644 --- a/Example/ChatLayout/Chat/View/Other/FullCellContentBubbleController.swift +++ b/Example/ChatLayout/Chat/View/Other/FullCellContentBubbleController.swift @@ -3,7 +3,7 @@ // FullCellContentBubbleController.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/Example/ChatLayout/Chat/View/Other/TextBubbleController.swift b/Example/ChatLayout/Chat/View/Other/TextBubbleController.swift index b5104655..88915e7c 100644 --- a/Example/ChatLayout/Chat/View/Other/TextBubbleController.swift +++ b/Example/ChatLayout/Chat/View/Other/TextBubbleController.swift @@ -3,7 +3,7 @@ // TextBubbleController.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/Example/ChatLayout/Chat/View/ReloadDelegate.swift b/Example/ChatLayout/Chat/View/ReloadDelegate.swift index abc91708..c53bead5 100644 --- a/Example/ChatLayout/Chat/View/ReloadDelegate.swift +++ b/Example/ChatLayout/Chat/View/ReloadDelegate.swift @@ -3,7 +3,7 @@ // ReloadDelegate.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/Example/ChatLayout/Chat/View/Status View/StatusView.swift b/Example/ChatLayout/Chat/View/Status View/StatusView.swift index a15772d0..0f49aa3c 100644 --- a/Example/ChatLayout/Chat/View/Status View/StatusView.swift +++ b/Example/ChatLayout/Chat/View/Status View/StatusView.swift @@ -3,7 +3,7 @@ // StatusView.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/Example/ChatLayout/Chat/View/Text Message View/TextMessageController.swift b/Example/ChatLayout/Chat/View/Text Message View/TextMessageController.swift index c4d295f1..86119549 100644 --- a/Example/ChatLayout/Chat/View/Text Message View/TextMessageController.swift +++ b/Example/ChatLayout/Chat/View/Text Message View/TextMessageController.swift @@ -3,7 +3,7 @@ // TextMessageController.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/Example/ChatLayout/Chat/View/Text Message View/TextMessageView.swift b/Example/ChatLayout/Chat/View/Text Message View/TextMessageView.swift index 7a24e1d0..a0a0a0a0 100644 --- a/Example/ChatLayout/Chat/View/Text Message View/TextMessageView.swift +++ b/Example/ChatLayout/Chat/View/Text Message View/TextMessageView.swift @@ -3,7 +3,7 @@ // TextMessageView.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/Example/ChatLayout/Chat/View/URL/URLController.swift b/Example/ChatLayout/Chat/View/URL/URLController.swift index eb907aa2..32f9e4c4 100644 --- a/Example/ChatLayout/Chat/View/URL/URLController.swift +++ b/Example/ChatLayout/Chat/View/URL/URLController.swift @@ -3,7 +3,7 @@ // URLController.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/Example/ChatLayout/Chat/View/URL/URLSource.swift b/Example/ChatLayout/Chat/View/URL/URLSource.swift index b443c620..837daddf 100644 --- a/Example/ChatLayout/Chat/View/URL/URLSource.swift +++ b/Example/ChatLayout/Chat/View/URL/URLSource.swift @@ -3,7 +3,7 @@ // URLSource.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/Example/ChatLayout/Chat/View/URL/URLView.swift b/Example/ChatLayout/Chat/View/URL/URLView.swift index d06657a3..c1e45728 100644 --- a/Example/ChatLayout/Chat/View/URL/URLView.swift +++ b/Example/ChatLayout/Chat/View/URL/URLView.swift @@ -3,7 +3,7 @@ // URLView.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/Example/ChatLayout/ProcessInfo+Extension.swift b/Example/ChatLayout/ProcessInfo+Extension.swift index 296a5547..1c780c9d 100644 --- a/Example/ChatLayout/ProcessInfo+Extension.swift +++ b/Example/ChatLayout/ProcessInfo+Extension.swift @@ -3,7 +3,7 @@ // ProcessInfo+Extension.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/Example/ChatLayout/SceneDelegate.swift b/Example/ChatLayout/SceneDelegate.swift index 96b0bc30..38161e9c 100644 --- a/Example/ChatLayout/SceneDelegate.swift +++ b/Example/ChatLayout/SceneDelegate.swift @@ -3,7 +3,7 @@ // SceneDelegate.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/Example/Tests/HelpersTests.swift b/Example/Tests/HelpersTests.swift index 93a80a5d..860642dc 100644 --- a/Example/Tests/HelpersTests.swift +++ b/Example/Tests/HelpersTests.swift @@ -3,7 +3,7 @@ // HelpersTests.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // diff --git a/Example/Tests/MockCollectionLayout.swift b/Example/Tests/MockCollectionLayout.swift index eea22aeb..0fb022f7 100644 --- a/Example/Tests/MockCollectionLayout.swift +++ b/Example/Tests/MockCollectionLayout.swift @@ -3,7 +3,7 @@ // MockCollectionLayout.swift // https://github.com/ekazaev/ChatLayout // -// Created by Eugene Kazaev in 2020. +// Created by Eugene Kazaev in 2020-2021. // Distributed under the MIT license. // @@ -17,7 +17,10 @@ class MockCollectionLayout: ChatLayoutRepresentation, ChatLayoutDelegate { var shouldPresentHeaderAtSection: [Int: Bool] = [0: true, 1: true, 2: true] var shouldPresentFooterAtSection: [Int: Bool] = [0: true, 1: true, 2: true] + // swiftlint:disable weak_delegate lazy var delegate: ChatLayoutDelegate? = self + // swiftlint:enable weak_delegate + var settings = ChatLayoutSettings(estimatedItemSize: CGSize(width: 300, height: 40), interItemSpacing: 7, interSectionSpacing: 3) var viewSize = CGSize(width: 300, height: 400) @@ -39,7 +42,7 @@ class MockCollectionLayout: ChatLayoutRepresentation, ChatLayoutDelegate { let keepContentOffsetAtBottomOnBatchUpdates: Bool = true - func numberOfItems(inSection section: Int) -> Int { + func numberOfItems(in section: Int) -> Int { return numberOfItemsInSection[section] ?? 0 } @@ -71,7 +74,7 @@ class MockCollectionLayout: ChatLayoutRepresentation, ChatLayoutDelegate { let footer = ItemModel(with: configuration(for: .footer, at: headerIndexPath)) var items: [ItemModel] = [] - for itemIndex in 0..