diff --git a/Twigs.xcodeproj/project.pbxproj b/Twigs.xcodeproj/project.pbxproj index 52303b7..18fd9c8 100644 --- a/Twigs.xcodeproj/project.pbxproj +++ b/Twigs.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 50; + objectVersion = 52; objects = { /* Begin PBXBuildFile section */ @@ -47,6 +47,7 @@ 543ECE42233E82A40018A9D9 /* AuthenticationDataStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 543ECE41233E82A40018A9D9 /* AuthenticationDataStore.swift */; }; 8043EB84271F26ED00498E73 /* CategoryDetailsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8043EB83271F26ED00498E73 /* CategoryDetailsView.swift */; }; 806C7850272B700B00FA1375 /* TwigsApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 806C784F272B700B00FA1375 /* TwigsApp.swift */; }; + 8094A9C327567CAC006C6C62 /* Collections in Frameworks */ = {isa = PBXBuildFile; productRef = 8094A9C227567CAC006C6C62 /* Collections */; }; 809B942327221EC800B1DAE2 /* CategoryFormSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 809B942227221EC800B1DAE2 /* CategoryFormSheet.swift */; }; /* End PBXBuildFile section */ @@ -124,6 +125,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 8094A9C327567CAC006C6C62 /* Collections in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -310,6 +312,9 @@ dependencies = ( ); name = Twigs; + packageProductDependencies = ( + 8094A9C227567CAC006C6C62 /* Collections */, + ); productName = Budget; productReference = 28AC94EA233C373900BFB70A /* Twigs.app */; productType = "com.apple.product-type.application"; @@ -383,6 +388,9 @@ es, ); mainGroup = 28AC94E1233C373900BFB70A; + packageReferences = ( + 8094A9C127567CAC006C6C62 /* XCRemoteSwiftPackageReference "swift-collections" */, + ); productRefGroup = 28AC94EB233C373900BFB70A /* Products */; projectDirPath = ""; projectRoot = ""; @@ -817,6 +825,25 @@ defaultConfigurationName = Release; }; /* End XCConfigurationList section */ + +/* Begin XCRemoteSwiftPackageReference section */ + 8094A9C127567CAC006C6C62 /* XCRemoteSwiftPackageReference "swift-collections" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/apple/swift-collections.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 1.0.0; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + 8094A9C227567CAC006C6C62 /* Collections */ = { + isa = XCSwiftPackageProductDependency; + package = 8094A9C127567CAC006C6C62 /* XCRemoteSwiftPackageReference "swift-collections" */; + productName = Collections; + }; +/* End XCSwiftPackageProductDependency section */ }; rootObject = 28AC94E2233C373900BFB70A /* Project object */; } diff --git a/Twigs.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Twigs.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 8980065..919434a 100644 --- a/Twigs.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/Twigs.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:"> diff --git a/Twigs.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Twigs.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 0000000..e56059c --- /dev/null +++ b/Twigs.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,16 @@ +{ + "object": { + "pins": [ + { + "package": "swift-collections", + "repositoryURL": "https://github.com/apple/swift-collections.git", + "state": { + "branch": null, + "revision": "48254824bb4248676bf7ce56014ff57b142b77eb", + "version": "1.0.2" + } + } + ] + }, + "version": 1 +} diff --git a/Twigs/Transaction/TransactionDataStore.swift b/Twigs/Transaction/TransactionDataStore.swift index 30dd3d6..0a70cd6 100644 --- a/Twigs/Transaction/TransactionDataStore.swift +++ b/Twigs/Transaction/TransactionDataStore.swift @@ -8,11 +8,12 @@ import Foundation import Combine +import Collections class TransactionDataStore: ObservableObject { private var currentRequest: AnyCancellable? = nil private var sumRequests: [String:AnyCancellable] = [:] - @Published var transactions: [String:Result<[Transaction], NetworkError>] = ["": .failure(.loading)] + @Published var transactions: [String:Result, NetworkError>] = ["": .failure(.loading)] @Published var transaction: Result = .failure(.unknown) @@ -45,7 +46,8 @@ class TransactionDataStore: ObservableObject { self.transactions[requestId] = .failure(error) } }, receiveValue: { (transactions) in - self.transactions[requestId] = .success(transactions) + let groupedTransactions = OrderedDictionary(grouping: transactions, by: { $0.date.toLocaleString() }) + self.transactions[requestId] = .success(groupedTransactions) }) return requestId diff --git a/Twigs/Transaction/TransactionListView.swift b/Twigs/Transaction/TransactionListView.swift index 4d43839..b114a3a 100644 --- a/Twigs/Transaction/TransactionListView.swift +++ b/Twigs/Transaction/TransactionListView.swift @@ -18,9 +18,15 @@ struct TransactionListView: View { var body: some View { switch transactionDataStore.transactions[requestId] { case .success(let transactions): - Section { - List(transactions) { transaction in - TransactionListItemView(transaction) + List { + ForEach(transactions.keys, id: \.self) { (key: String) in + Group { + Section(header: Text(key)) { + ForEach(transactions[key]!) { transaction in + TransactionListItemView(transaction) + } + } + } } } .sheet(isPresented: $isAddingTransaction, content: { @@ -75,11 +81,13 @@ struct TransactionListItemView: View { Text(verbatim: transaction.title) .lineLimit(1) .font(.headline) - Text(verbatim: transaction.date.toLocaleString()) - .lineLimit(1) - .font(.subheadline) - .foregroundColor(.secondary) - .multilineTextAlignment(.trailing) + if let description = transaction.description?.trimmingCharacters(in: CharacterSet([" "])), !description.isEmpty { + Text(verbatim: description) + .lineLimit(1) + .font(.subheadline) + .foregroundColor(.secondary) + .multilineTextAlignment(.trailing) + } } Spacer() VStack(alignment: .trailing) {