diff --git a/Example/LUX/MultiSizeCollectionVIewLayout.playground/Contents.swift b/Example/LUX/MultiSizeCollectionVIewLayout.playground/Contents.swift index e1fd3c0..79a3662 100644 --- a/Example/LUX/MultiSizeCollectionVIewLayout.playground/Contents.swift +++ b/Example/LUX/MultiSizeCollectionVIewLayout.playground/Contents.swift @@ -20,7 +20,7 @@ enum House: String, Codable, CaseIterable { } struct Emperor: Codable { var name: String? - var imageUrlString: String? = "https://preview.redd.it/e6c2zqbu9gf51.jpg?width=500&format=pjpg&auto=webp&s=9c1e6dcf6d163ae036d534fc315a190223e77ed8" + var imageUrlString: String? = "https://picsum.photos/200/200" } struct Reign: Codable { var id: Int diff --git a/Example/Podfile.lock b/Example/Podfile.lock index 3a415b5..cdf7d6a 100644 --- a/Example/Podfile.lock +++ b/Example/Podfile.lock @@ -93,9 +93,9 @@ PODS: - Prelude (~> 3.0) - PlaygroundVCHelpers (0.0.2) - Prelude (3.0.0) - - SDWebImage (5.12.1): - - SDWebImage/Core (= 5.12.1) - - SDWebImage/Core (5.12.1) + - SDWebImage (5.12.2): + - SDWebImage/Core (= 5.12.2) + - SDWebImage/Core (5.12.2) - Slippers/Core (0.1.1) DEPENDENCIES: @@ -164,7 +164,7 @@ SPEC CHECKSUMS: LUX: a0a8013d109a4d4887f75fcc91637221e6749abb PlaygroundVCHelpers: c7cc8994d2851ebd1590217101b4c6888d1c9cc8 Prelude: fe4cc0fd961d34edf48fe6b04d05c863449efb0a - SDWebImage: 4dc3e42d9ec0c1028b960a33ac6b637bb432207b + SDWebImage: 240e5c12b592fb1268c1d03b8c90d90e8c2ffe82 Slippers: 5a3c6f24a556a59a091e2cb60e588472827be87c PODFILE CHECKSUM: 940b727264080c97240a108fc65ed553ccdfa5dc diff --git a/Example/Tests/ListViewModelTests.swift b/Example/Tests/ListViewModelTests.swift index 2be4f16..2dc4ae5 100644 --- a/Example/Tests/ListViewModelTests.swift +++ b/Example/Tests/ListViewModelTests.swift @@ -60,4 +60,5 @@ class ListViewModelTests: XCTestCase { XCTAssert(wasFiltered) cancel.cancel() } + } diff --git a/Example/Tests/LoginViewModelTests.swift b/Example/Tests/LoginViewModelTests.swift index d968646..0791892 100644 --- a/Example/Tests/LoginViewModelTests.swift +++ b/Example/Tests/LoginViewModelTests.swift @@ -248,5 +248,37 @@ class LoginViewModelTests: XCTestCase { viewModel.rightViewPressed() XCTAssertTrue(wasCalled) } + + func testUsernameAndPasswordChangedAndSaved() { + var wasCalled = false + var calledSaveToken = false + var shouldAdvance = false + + let call = CombineNetCall(configuration: ServerConfiguration(host: "lithobyte.co", apiRoute: "api/v1"), Endpoint()) + call.firingFunc = { + _ in wasCalled = true + call.responder?.data = "Hi".data(using: .utf8) + } + let viewModel = LUXLoginViewModel(credsCall: call, loginModelToJson: { _, _ in Human() }) { + _ in calledSaveToken = true + return true + } + let cancel = viewModel.outputs.advanceAuthedPublisher.sink { _ in + shouldAdvance = true + } + + viewModel.inputs.usernameChanged(username: "Jacob") + viewModel.inputs.passwordChanged(password: "Password") + viewModel.inputs.submitButtonPressed() + + XCTAssertEqual(viewModel.username, "Jacob") + XCTAssertEqual(viewModel.password, "Password") + XCTAssert(wasCalled) + XCTAssert(calledSaveToken) + XCTAssert(shouldAdvance) + cancel.cancel() + } + + } diff --git a/LUX/Classes/Base/CollectionViews/LUXPinterestStyleLayout.swift b/LUX/Classes/Base/CollectionViews/LUXPinterestStyleLayout.swift new file mode 100644 index 0000000..f7494d0 --- /dev/null +++ b/LUX/Classes/Base/CollectionViews/LUXPinterestStyleLayout.swift @@ -0,0 +1,159 @@ +// +// LUXPinterestStyleLayout.swift +// LUX +// +// Created by Remmington Damper on 12/12/21. +// + +import UIKit + + +public class LUXPinterestStyleLayout: UICollectionViewLayout { + private var _columnCount: Int? { didSet { invalidateLayout() }} + public func setColumnCount(_ count: Int) { _columnCount = count } + + private var _cellPadding: CGFloat = 0 {didSet { invalidateLayout() }} + public func setCellPadding(_ padding: CGFloat = 0) { _cellPadding = padding } + + private var cache: [UICollectionViewLayoutAttributes] = [] + + private var _baseItemWidth: CGFloat? { didSet { invalidateLayout() }} + public func setBaseItemWidth(_ width: CGFloat) { _baseItemWidth = width } + + public var setWidthForColumn: Int? + public var widthForColumn: ((Int) -> CGFloat?)? = { _ in return nil } + + private var contentHeight: CGFloat = 0.0 + private var contentWidth: CGFloat { + guard let collectionView = collectionView else { + return 0 + } + let insets = collectionView.contentInset + return collectionView.bounds.width - (insets.left + insets.right) + } + + private var _contentSize: CGSize? { didSet { invalidateLayout() }} + public func setContentSize(_ size: CGSize) { _contentSize = size } + + private var itemCount: Int { calculateItemCount() } + + open var heightForCellAtIndexPath: ((UICollectionView, IndexPath) -> CGFloat)? + + + open func setContentSizeFromCache() { + if let last = cache.last { + _contentSize = CGSize(width: contentWidth, height: last.frame.minY + last.frame.height) + } + } + + public override var collectionViewContentSize: CGSize { + return _contentSize ?? CGSize(width: contentWidth, height: contentHeight) + } + + open func calculateItemCount() -> Int { + var count = 0 + if let cv = collectionView { + for i in 0.. [CGFloat] { + var columnCount: Int = 0 + var xOffSet: [CGFloat] = [] + var offSet: CGFloat = 0 + + if let columnCount = _columnCount { + if let width = widthForColumn { + xOffSet = [0] + let columnWidth = contentWidth / CGFloat(columnCount) + offSet = columnWidth + for column in 0.. [UICollectionViewLayoutAttributes]? { + var attributes: [UICollectionViewLayoutAttributes] = [] + for attribute in cache { + if attribute.frame.intersects(rect) { + attributes.append(attribute) + } + } + return attributes + } + + public override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? { + return cache[indexPath.item] + } + +}