Fix issues with waterfall widget
This commit is contained in:
parent
e92226f4fd
commit
80b2d2f4e9
|
@ -191,9 +191,12 @@
|
|||
F8B0885E29942E31002AB40A /* ThirdPartyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8B0885D29942E31002AB40A /* ThirdPartyView.swift */; };
|
||||
F8B0886029943498002AB40A /* OtherSectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8B0885F29943498002AB40A /* OtherSectionView.swift */; };
|
||||
F8B08862299435C9002AB40A /* SupportView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8B08861299435C9002AB40A /* SupportView.swift */; };
|
||||
F8B758DE2AB9DD85000C8068 /* ColumnData.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8B758DD2AB9DD85000C8068 /* ColumnData.swift */; };
|
||||
F8D5444329D4066C002225D6 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8D5444229D4066C002225D6 /* AppDelegate.swift */; };
|
||||
F8DF38E429DD68820047F1AA /* ViewOffsetKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8DF38E329DD68820047F1AA /* ViewOffsetKey.swift */; };
|
||||
F8DF38E629DDB98A0047F1AA /* SocialsSectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8DF38E529DDB98A0047F1AA /* SocialsSectionView.swift */; };
|
||||
F8E36E462AB8745300769C55 /* Sizable.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8E36E452AB8745300769C55 /* Sizable.swift */; };
|
||||
F8E36E482AB874A500769C55 /* StatusModel+Sizeable.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8E36E472AB874A500769C55 /* StatusModel+Sizeable.swift */; };
|
||||
F8E6D03329CDD52500416CCA /* EditProfileView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8E6D03229CDD52500416CCA /* EditProfileView.swift */; };
|
||||
F8F6E44229BC58F20004795E /* Vernissage.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = F88C2476295C37BB0006098B /* Vernissage.xcdatamodeld */; };
|
||||
F8F6E44C29BCC1F70004795E /* PhotoSmallWidgetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8F6E44629BCC0DC0004795E /* PhotoSmallWidgetView.swift */; };
|
||||
|
@ -393,12 +396,15 @@
|
|||
F8B08861299435C9002AB40A /* SupportView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SupportView.swift; sourceTree = "<group>"; };
|
||||
F8B3699A29D86EB600BE3808 /* .swiftlint.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = .swiftlint.yml; sourceTree = "<group>"; };
|
||||
F8B3699B29D86EBD00BE3808 /* .gitignore */ = {isa = PBXFileReference; lastKnownFileType = text; path = .gitignore; sourceTree = "<group>"; };
|
||||
F8B758DD2AB9DD85000C8068 /* ColumnData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColumnData.swift; sourceTree = "<group>"; };
|
||||
F8C937A929882CA90004D782 /* Vernissage-001.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Vernissage-001.xcdatamodel"; sourceTree = "<group>"; };
|
||||
F8CAE64129B8F1AF001E0372 /* Vernissage-005.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Vernissage-005.xcdatamodel"; sourceTree = "<group>"; };
|
||||
F8D5444229D4066C002225D6 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||
F8DF38E329DD68820047F1AA /* ViewOffsetKey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewOffsetKey.swift; sourceTree = "<group>"; };
|
||||
F8DF38E529DDB98A0047F1AA /* SocialsSectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SocialsSectionView.swift; sourceTree = "<group>"; };
|
||||
F8DF38E729DDC3D20047F1AA /* eu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = eu; path = eu.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
F8E36E452AB8745300769C55 /* Sizable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Sizable.swift; sourceTree = "<group>"; };
|
||||
F8E36E472AB874A500769C55 /* StatusModel+Sizeable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "StatusModel+Sizeable.swift"; sourceTree = "<group>"; };
|
||||
F8E6D03229CDD52500416CCA /* EditProfileView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditProfileView.swift; sourceTree = "<group>"; };
|
||||
F8EF371429C624DA00669F45 /* Vernissage-006.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Vernissage-006.xcdatamodel"; sourceTree = "<group>"; };
|
||||
F8EF3C8B29FC3A5F00CBFF7C /* Vernissage-012.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Vernissage-012.xcdatamodel"; sourceTree = "<group>"; };
|
||||
|
@ -535,6 +541,8 @@
|
|||
F8DF38E329DD68820047F1AA /* ViewOffsetKey.swift */,
|
||||
F871F21C29EF0D7000A351EF /* NavigationMenuItemDetails.swift */,
|
||||
F8624D3C29F2D3AC00204986 /* SelectedMenuItemDetails.swift */,
|
||||
F8E36E452AB8745300769C55 /* Sizable.swift */,
|
||||
F8B758DD2AB9DD85000C8068 /* ColumnData.swift */,
|
||||
);
|
||||
path = Models;
|
||||
sourceTree = "<group>";
|
||||
|
@ -653,6 +661,7 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
F858906A29E1CC7A00D4BDED /* UIApplication+Window.swift */,
|
||||
F8E36E472AB874A500769C55 /* StatusModel+Sizeable.swift */,
|
||||
);
|
||||
path = Extensions;
|
||||
sourceTree = "<group>";
|
||||
|
@ -1185,6 +1194,7 @@
|
|||
F87AEB922986C44E00434FB6 /* AuthorizationSession.swift in Sources */,
|
||||
F86A4301299A97F500DF7645 /* ProductIdentifiers.swift in Sources */,
|
||||
F89D6C4229717FDC001DA3D4 /* AccountsSectionView.swift in Sources */,
|
||||
F8E36E482AB874A500769C55 /* StatusModel+Sizeable.swift in Sources */,
|
||||
F80048082961E6DE00E6868A /* StatusDataHandler.swift in Sources */,
|
||||
F866F6A0296040A8002E8F88 /* ApplicationSettings+CoreDataClass.swift in Sources */,
|
||||
F8210DEA2966E4F9001D9973 /* AnimatePlaceholderModifier.swift in Sources */,
|
||||
|
@ -1201,6 +1211,7 @@
|
|||
F883402029B62AE900C3E096 /* SearchView.swift in Sources */,
|
||||
F88FAD2A295F43B8009B20C9 /* AccountData+CoreDataClass.swift in Sources */,
|
||||
F871F21D29EF0D7000A351EF /* NavigationMenuItemDetails.swift in Sources */,
|
||||
F8E36E462AB8745300769C55 /* Sizable.swift in Sources */,
|
||||
F85DBF8F296732E20069BF89 /* AccountsView.swift in Sources */,
|
||||
F805DCF129DBEF83006A1FD9 /* ReportView.swift in Sources */,
|
||||
F8B0886029943498002AB40A /* OtherSectionView.swift in Sources */,
|
||||
|
@ -1220,6 +1231,7 @@
|
|||
F891E7CE29C35BF50022C449 /* ImageRowItem.swift in Sources */,
|
||||
F86B7221296C49A300EE59EC /* EmptyButtonStyle.swift in Sources */,
|
||||
F80048042961850500E6868A /* AttachmentData+CoreDataProperties.swift in Sources */,
|
||||
F8B758DE2AB9DD85000C8068 /* ColumnData.swift in Sources */,
|
||||
F88E4D4A297EA0490057491A /* RouterPath.swift in Sources */,
|
||||
F88E4D48297E90CD0057491A /* TrendStatusesView.swift in Sources */,
|
||||
F800480A2961EA1900E6868A /* AttachmentDataHandler.swift in Sources */,
|
||||
|
@ -1325,18 +1337,19 @@
|
|||
CODE_SIGN_ENTITLEMENTS = VernissageWidget/VernissageWidgetExtension.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 143;
|
||||
CURRENT_PROJECT_VERSION = 204;
|
||||
DEVELOPMENT_TEAM = B2U9FEKYP8;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_FILE = VernissageWidget/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = VernissageWidget;
|
||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 16.6;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.9.0;
|
||||
MARKETING_VERSION = 1.10.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = dev.mczachurski.vernissage.widget;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
|
@ -1353,18 +1366,19 @@
|
|||
ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground;
|
||||
CODE_SIGN_ENTITLEMENTS = VernissageWidget/VernissageWidgetExtension.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 143;
|
||||
CURRENT_PROJECT_VERSION = 204;
|
||||
DEVELOPMENT_TEAM = B2U9FEKYP8;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_FILE = VernissageWidget/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = VernissageWidget;
|
||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 16.6;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.9.0;
|
||||
MARKETING_VERSION = 1.10.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = dev.mczachurski.vernissage.widget;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
|
@ -1380,19 +1394,19 @@
|
|||
CODE_SIGN_ENTITLEMENTS = VernissageShare/VernissageShareExtension.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 143;
|
||||
CURRENT_PROJECT_VERSION = 204;
|
||||
DEVELOPMENT_TEAM = B2U9FEKYP8;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_FILE = VernissageShare/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = VernissageShareExtension;
|
||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 16.4;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 16.6;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.9.0;
|
||||
MARKETING_VERSION = 1.10.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = dev.mczachurski.vernissage.share;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
|
@ -1407,19 +1421,19 @@
|
|||
buildSettings = {
|
||||
CODE_SIGN_ENTITLEMENTS = VernissageShare/VernissageShareExtension.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 143;
|
||||
CURRENT_PROJECT_VERSION = 204;
|
||||
DEVELOPMENT_TEAM = B2U9FEKYP8;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_FILE = VernissageShare/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = VernissageShareExtension;
|
||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 16.4;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 16.6;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.9.0;
|
||||
MARKETING_VERSION = 1.10.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = dev.mczachurski.vernissage.share;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
|
@ -1480,7 +1494,7 @@
|
|||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 16.2;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 16.6;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
|
@ -1535,7 +1549,7 @@
|
|||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 16.2;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 16.6;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
MTL_FAST_MATH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
|
@ -1556,7 +1570,7 @@
|
|||
CODE_SIGN_ENTITLEMENTS = Vernissage/Vernissage.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 201;
|
||||
CURRENT_PROJECT_VERSION = 204;
|
||||
DEVELOPMENT_ASSET_PATHS = "\"Vernissage/Preview Content\"";
|
||||
DEVELOPMENT_TEAM = B2U9FEKYP8;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
|
@ -1570,7 +1584,7 @@
|
|||
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
|
||||
INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait;
|
||||
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 16.6;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
|
@ -1598,7 +1612,7 @@
|
|||
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
|
||||
CODE_SIGN_ENTITLEMENTS = Vernissage/Vernissage.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 201;
|
||||
CURRENT_PROJECT_VERSION = 204;
|
||||
DEVELOPMENT_ASSET_PATHS = "\"Vernissage/Preview Content\"";
|
||||
DEVELOPMENT_TEAM = B2U9FEKYP8;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
|
@ -1612,7 +1626,7 @@
|
|||
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
|
||||
INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait;
|
||||
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 16.6;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
//
|
||||
// https://mczachurski.dev
|
||||
// Copyright © 2023 Marcin Czachurski and the repository contributors.
|
||||
// Licensed under the Apache License 2.0.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import ClientKit
|
||||
|
||||
extension StatusModel: Sizable {
|
||||
public var height: Double {
|
||||
return Double(self.mediaAttachments.first?.metaImageHeight ?? 500)
|
||||
}
|
||||
|
||||
public var width: Double {
|
||||
return Double(self.mediaAttachments.first?.metaImageWidth ?? 500)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
//
|
||||
// https://mczachurski.dev
|
||||
// Copyright © 2023 Marcin Czachurski and the repository contributors.
|
||||
// Licensed under the Apache License 2.0.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
class ColumnData<T>: Identifiable where T: Identifiable, T: Hashable, T: Sizable {
|
||||
public let id = UUID().uuidString
|
||||
public var data: [T] = []
|
||||
public var height: Double = 0.0
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
//
|
||||
// https://mczachurski.dev
|
||||
// Copyright © 2023 Marcin Czachurski and the repository contributors.
|
||||
// Licensed under the Apache License 2.0.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
public protocol Sizable {
|
||||
var height: Double { get }
|
||||
var width: Double { get }
|
||||
}
|
|
@ -8,30 +8,35 @@ import SwiftUI
|
|||
import WidgetsKit
|
||||
|
||||
struct WaterfallGrid<Data, ID, Content>: View where Data: RandomAccessCollection, Data: Equatable, Content: View,
|
||||
ID: Hashable, Data.Element: Equatable, Data.Element: Identifiable, Data.Element: Hashable {
|
||||
ID: Hashable, Data.Element: Equatable, Data.Element: Identifiable, Data.Element: Hashable, Data.Element: Sizable {
|
||||
@Binding private var columns: Int
|
||||
@Binding private var hideLoadMore: Bool
|
||||
|
||||
@Binding private var data: Data
|
||||
private let dataId: KeyPath<Data.Element, ID>
|
||||
|
||||
private let content: (Data.Element) -> Content
|
||||
|
||||
@State private var columnsData: [[Data.Element]] = []
|
||||
@State private var columnsData: [ColumnData<Data.Element>] = []
|
||||
@State private var processedItems: [Data.Element.ID] = []
|
||||
@State private var isDuringLoading: Bool = false
|
||||
|
||||
private let onLoadMore: () async -> Void
|
||||
|
||||
var body: some View {
|
||||
HStack(alignment: .top, spacing: 20) {
|
||||
ForEach(self.columnsData, id: \.self) { array in
|
||||
ForEach(self.columnsData, id: \.id) { columnData in
|
||||
LazyVStack(spacing: 8) {
|
||||
ForEach(array, id: \.id) { item in
|
||||
ForEach(columnData.data, id: \.id) { item in
|
||||
self.content(item)
|
||||
}
|
||||
|
||||
if self.shouldShowSpinner(array: array) {
|
||||
if self.hideLoadMore == false {
|
||||
LoadingIndicator()
|
||||
.task {
|
||||
await self.onLoadMore()
|
||||
if isDuringLoading == false {
|
||||
isDuringLoading = true
|
||||
await self.onLoadMore()
|
||||
isDuringLoading = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -41,7 +46,7 @@ struct WaterfallGrid<Data, ID, Content>: View where Data: RandomAccessCollection
|
|||
self.recalculateArrays()
|
||||
}
|
||||
.onChange(of: self.data) { _ in
|
||||
self.recalculateArrays()
|
||||
self.appendToArrays()
|
||||
}
|
||||
.onChange(of: self.columns) { _ in
|
||||
self.recalculateArrays()
|
||||
|
@ -49,52 +54,66 @@ struct WaterfallGrid<Data, ID, Content>: View where Data: RandomAccessCollection
|
|||
}
|
||||
|
||||
private func recalculateArrays() {
|
||||
var internalArray: [[Data.Element]] = []
|
||||
self.columnsData = []
|
||||
self.processedItems = []
|
||||
|
||||
for _ in 0 ..< self.columns {
|
||||
internalArray.append([])
|
||||
self.columnsData.append(ColumnData())
|
||||
}
|
||||
|
||||
for (index, item) in self.data.enumerated() {
|
||||
let arrayIndex = index % self.columns
|
||||
internalArray[arrayIndex].append(item)
|
||||
}
|
||||
for item in self.data {
|
||||
let index = self.minimumHeightIndex()
|
||||
|
||||
self.columnsData = internalArray
|
||||
self.columnsData[index].data.append(item)
|
||||
self.columnsData[index].height = self.columnsData[index].height + self.calculateHeight(item: item)
|
||||
self.processedItems.append(item.id)
|
||||
}
|
||||
}
|
||||
|
||||
private func shouldShowSpinner(array: [Data.Element]) -> Bool {
|
||||
if self.hideLoadMore {
|
||||
return false
|
||||
}
|
||||
private func appendToArrays() {
|
||||
for item in self.data where self.processedItems.contains(where: { $0 == item.id }) == false {
|
||||
let index = self.minimumHeightIndex()
|
||||
|
||||
return self.columnsData[1].first == array.first
|
||||
self.columnsData[index].data.append(item)
|
||||
self.columnsData[index].height = self.columnsData[index].height + self.calculateHeight(item: item)
|
||||
self.processedItems.append(item.id)
|
||||
}
|
||||
}
|
||||
|
||||
private func calculateHeight(item: Sizable) -> Double {
|
||||
return item.height / item.width
|
||||
}
|
||||
|
||||
private func minimumHeight() -> Double {
|
||||
return self.columnsData.map({ $0.height }).min() ?? .zero
|
||||
}
|
||||
|
||||
private func minimumHeightIndex() -> Int {
|
||||
let minimumHeight = self.minimumHeight()
|
||||
return self.columnsData.lastIndex(where: { $0.height == minimumHeight }) ?? 0
|
||||
}
|
||||
}
|
||||
|
||||
extension WaterfallGrid {
|
||||
init(_ data: Binding<Data>, id: KeyPath<Data.Element, ID>, columns: Binding<Int>,
|
||||
hideLoadMore: Binding<Bool>, content: @escaping (Data.Element) -> Content, onLoadMore: @escaping () async -> Void) {
|
||||
self._data = data
|
||||
self.dataId = id
|
||||
self.content = content
|
||||
self.onLoadMore = onLoadMore
|
||||
|
||||
self._data = data
|
||||
self._columns = columns
|
||||
self._hideLoadMore = hideLoadMore
|
||||
self.onLoadMore = onLoadMore
|
||||
}
|
||||
}
|
||||
|
||||
extension WaterfallGrid where ID == Data.Element.ID, Data.Element: Identifiable {
|
||||
init(_ data: Binding<Data>, columns: Binding<Int>,
|
||||
hideLoadMore: Binding<Bool>, content: @escaping (Data.Element) -> Content, onLoadMore: @escaping () async -> Void) {
|
||||
self._data = data
|
||||
self.dataId = \Data.Element.id
|
||||
self.content = content
|
||||
self.onLoadMore = onLoadMore
|
||||
|
||||
self._data = data
|
||||
self._columns = columns
|
||||
self._hideLoadMore = hideLoadMore
|
||||
self.onLoadMore = onLoadMore
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue