From ba09884a65b707d355c4427036d9a303b151a251 Mon Sep 17 00:00:00 2001 From: Selim Mustafaev Date: Sun, 27 Oct 2024 22:20:24 +0300 Subject: [PATCH] More filters screen code --- AutoCat.xcodeproj/project.pbxproj | 12 ++++ AutoCat/Controllers/FiltersController.swift | 8 +-- AutoCat/Controllers/SearchController.swift | 40 ++++++----- AutoCat/Controllers/VMResult.swift | 39 +++++++++++ .../FiltersScreen/FiltersCoordinator.swift | 4 +- .../Screens/FiltersScreen/FiltersScreen.swift | 70 ++++++++++++++++++- .../FiltersScreen/FiltersViewModel.swift | 10 +++ AutoCat/SwiftUI/LinkRowView.swift | 24 +++---- AutoCat/SwiftUI/OptionalBinding.swift | 16 +++++ AutoCat/SwiftUI/OptionalDatePicker.swift | 49 +++++++++++++ AutoCat/SwiftUI/TextRowView.swift | 30 ++++---- AutoCatCore/Models/Filter.swift | 24 +++---- 12 files changed, 253 insertions(+), 73 deletions(-) create mode 100644 AutoCat/Controllers/VMResult.swift create mode 100644 AutoCat/SwiftUI/OptionalBinding.swift create mode 100644 AutoCat/SwiftUI/OptionalDatePicker.swift diff --git a/AutoCat.xcodeproj/project.pbxproj b/AutoCat.xcodeproj/project.pbxproj index fd3a4eb..3f8d31b 100644 --- a/AutoCat.xcodeproj/project.pbxproj +++ b/AutoCat.xcodeproj/project.pbxproj @@ -49,6 +49,7 @@ 7A27ADF5249FD2F90035F39E /* FileManagerExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A27ADF4249FD2F90035F39E /* FileManagerExt.swift */; }; 7A27ADF7249FEF690035F39E /* Recorder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A27ADF6249FEF690035F39E /* Recorder.swift */; }; 7A2C96122C3B155B00AE46B5 /* NoteAlertModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A2C96112C3B155B00AE46B5 /* NoteAlertModifier.swift */; }; + 7A2E11292CCE395300E5CA17 /* OptionalDatePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A2E11282CCE395300E5CA17 /* OptionalDatePicker.swift */; }; 7A2E6FA72C42B3AD00C40DA7 /* AutoCatCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7AF6D1EF2677C03B0086EA64 /* AutoCatCore.framework */; }; 7A33381124990DAE00D878F1 /* FiltersController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A33381024990DAE00D878F1 /* FiltersController.swift */; }; 7A3399AB299063370087DF98 /* SearchControllerExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A3399AA299063370087DF98 /* SearchControllerExt.swift */; }; @@ -61,6 +62,8 @@ 7A4322932CB2CCAA00085CF6 /* FiltersViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A4322922CB2CCAA00085CF6 /* FiltersViewModel.swift */; }; 7A4322952CB2CD0F00085CF6 /* FiltersCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A4322942CB2CD0F00085CF6 /* FiltersCoordinator.swift */; }; 7A45FB382C27073700618694 /* StorageService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A45FB372C27073700618694 /* StorageService.swift */; }; + 7A4927D52CCE438600851C01 /* OptionalBinding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A4927D42CCE438600851C01 /* OptionalBinding.swift */; }; + 7A4927D72CCEA6DC00851C01 /* VMResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A4927D62CCEA6DC00851C01 /* VMResult.swift */; }; 7A530B7A24001D3300CBFE6E /* CheckController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A530B7924001D3300CBFE6E /* CheckController.swift */; }; 7A530B7E24017FEE00CBFE6E /* VehicleCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A530B7D24017FEE00CBFE6E /* VehicleCell.swift */; }; 7A599C362C18AC7F00D47C18 /* ApiError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A599C352C18AC7F00D47C18 /* ApiError.swift */; }; @@ -306,6 +309,7 @@ 7A27ADF824A09CAD0035F39E /* CocoaError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CocoaError.swift; sourceTree = ""; }; 7A2C96112C3B155B00AE46B5 /* NoteAlertModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoteAlertModifier.swift; sourceTree = ""; }; 7A2DE69725868AC800A113FC /* VehicleAd.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VehicleAd.swift; sourceTree = ""; }; + 7A2E11282CCE395300E5CA17 /* OptionalDatePicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OptionalDatePicker.swift; sourceTree = ""; }; 7A2E6FA32C42B3AD00C40DA7 /* AutoCatCoreTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AutoCatCoreTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 7A33381024990DAE00D878F1 /* FiltersController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FiltersController.swift; sourceTree = ""; }; 7A333813249A532400D878F1 /* Filter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Filter.swift; sourceTree = ""; }; @@ -319,6 +323,8 @@ 7A4322942CB2CD0F00085CF6 /* FiltersCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FiltersCoordinator.swift; sourceTree = ""; }; 7A43F9F7246C8A6200BA5B49 /* JWT.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JWT.swift; sourceTree = ""; }; 7A45FB372C27073700618694 /* StorageService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StorageService.swift; sourceTree = ""; }; + 7A4927D42CCE438600851C01 /* OptionalBinding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OptionalBinding.swift; sourceTree = ""; }; + 7A4927D62CCEA6DC00851C01 /* VMResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VMResult.swift; sourceTree = ""; }; 7A52AB292580112E002CD910 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; 7A530B7924001D3300CBFE6E /* CheckController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckController.swift; sourceTree = ""; }; 7A530B7D24017FEE00CBFE6E /* VehicleCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VehicleCell.swift; sourceTree = ""; }; @@ -615,6 +621,7 @@ 7AC3554B29696A1C00889457 /* MainTabController.swift */, 7AC3554D29696C4500889457 /* DummyNewController.swift */, 7AC3554F29696D5A00889457 /* NewNumberController.swift */, + 7A4927D62CCEA6DC00851C01 /* VMResult.swift */, ); path = Controllers; sourceTree = ""; @@ -1038,6 +1045,8 @@ 7A1022712C554A1300B84627 /* CustomHostingController.swift */, 7A5D7E0B2C71EB25002C17E7 /* ToggleRowView.swift */, 7AF8606F2CBAA24500954D2F /* NavigationLink.swift */, + 7A2E11282CCE395300E5CA17 /* OptionalDatePicker.swift */, + 7A4927D42CCE438600851C01 /* OptionalBinding.swift */, ); path = SwiftUI; sourceTree = ""; @@ -1290,14 +1299,17 @@ 7AFBE8C02C3024E5003C491D /* ACHud.swift in Sources */, 7A3F07AD2436350B00E59687 /* SearchController.swift in Sources */, 7AABDE26253350C30041AFC6 /* RxSectionedDataSource.swift in Sources */, + 7A4927D72CCEA6DC00851C01 /* VMResult.swift in Sources */, 7AAAFADA2C4D1AFE0050410D /* Zoomable.swift in Sources */, 7A6DD90C24335A6D009DE740 /* FlagLayer.swift in Sources */, + 7A2E11292CCE395300E5CA17 /* OptionalDatePicker.swift in Sources */, 7A761C0B267E8FF90005F28F /* Error.swift in Sources */, 7AC3555029696D5A00889457 /* NewNumberController.swift in Sources */, 7AE26A3524F31B0700625033 /* EventsController.swift in Sources */, 7AB67E8C2435C38700258F61 /* CustomTextField.swift in Sources */, 7AF860702CBAA24500954D2F /* NavigationLink.swift in Sources */, 7A27ADF5249FD2F90035F39E /* FileManagerExt.swift in Sources */, + 7A4927D52CCE438600851C01 /* OptionalBinding.swift in Sources */, 7A17CE4A2A2E820300626A6E /* UIStackView.swift in Sources */, 7A1DC38E2517ED98002E9C99 /* BlockBarButtonItem.swift in Sources */, 7AE26A3324EEF9EC00625033 /* UIViewControllerExt.swift in Sources */, diff --git a/AutoCat/Controllers/FiltersController.swift b/AutoCat/Controllers/FiltersController.swift index 5349ae0..a850cce 100644 --- a/AutoCat/Controllers/FiltersController.swift +++ b/AutoCat/Controllers/FiltersController.swift @@ -134,7 +134,7 @@ class FiltersController: FormViewController { row.title = NSLocalizedString("Added by", comment: "") row.selectorTitle = NSLocalizedString("Added by", comment: "") row.options = AddedBy.allCases.map { $0.description } - row.value = self.filter.addedBy?.description ?? AddedBy.anyone.description + row.value = self.filter.addedBy.description } .onChange { row in if let index = row.options?.firstIndex(of: row.value ?? "") { @@ -144,7 +144,7 @@ class FiltersController: FormViewController { } } .cellUpdate { cell, row in - row.value = self.filter.addedBy?.description ?? AddedBy.anyone.description + row.value = self.filter.addedBy.description } } @@ -210,14 +210,14 @@ class FiltersController: FormViewController { row.value = self.filter.sortBy row.options = SortParameter.allCases } - .onChange { self.filter.sortBy = $0.value } + .onChange { self.filter.sortBy = $0.value ?? .updatedDate } .cellUpdate { $1.value = self.filter.sortBy } <<< SegmentedRow("SortOrder") { row in row.title = NSLocalizedString("Order", comment: "sort order") row.value = self.filter.sortOrder row.options = AutoCatCore.SortOrder.allCases } - .onChange { self.filter.sortOrder = $0.value } + .onChange { self.filter.sortOrder = $0.value ?? .descending } .cellUpdate { $1.value = self.filter.sortOrder } } diff --git a/AutoCat/Controllers/SearchController.swift b/AutoCat/Controllers/SearchController.swift index c3cbe98..0f26657 100644 --- a/AutoCat/Controllers/SearchController.swift +++ b/AutoCat/Controllers/SearchController.swift @@ -184,26 +184,28 @@ class SearchController: UIViewController, UISearchResultsUpdating, UITableViewDe } func showFilter() async throws { - let sb = UIStoryboard(name: "Main", bundle: nil) - let controller = sb.instantiateViewController(identifier: "FiltersController") as FiltersController - controller.filter = self.filter - controller.onDone = { - self.filter = controller.filter - self.datasource.setSortParameter(self.filter.sortBy ?? .updatedDate) - self.filter.needReset = true - self.filter.scope = SearchScope(rawValue: self.searchController.searchBar.selectedScopeButtonIndex) ?? .plateNumber - self.updateSearchResults(with: self.filter) - } - self.navigationController?.pushViewController(controller, animated: true) - -// if let navigationController = self.navigationController { -// let coordinator = FiltersCoordinator(navController: navigationController, filter: filter) -// filter = try await coordinator.start() -// datasource.setSortParameter(self.filter.sortBy ?? .updatedDate) -// filter.needReset = true -// filter.scope = SearchScope(rawValue: self.searchController.searchBar.selectedScopeButtonIndex) ?? .plateNumber -// updateSearchResults(with: self.filter) +// let sb = UIStoryboard(name: "Main", bundle: nil) +// let controller = sb.instantiateViewController(identifier: "FiltersController") as FiltersController +// controller.filter = self.filter +// controller.onDone = { +// self.filter = controller.filter +// self.datasource.setSortParameter(self.filter.sortBy ?? .updatedDate) +// self.filter.needReset = true +// self.filter.scope = SearchScope(rawValue: self.searchController.searchBar.selectedScopeButtonIndex) ?? .plateNumber +// self.updateSearchResults(with: self.filter) // } +// self.navigationController?.pushViewController(controller, animated: true) + + if let navigationController = self.navigationController { + let coordinator = FiltersCoordinator(navController: navigationController, filter: filter) + if let newFilter = try await coordinator.start() { + filter = newFilter + datasource.setSortParameter(self.filter.sortBy) + filter.needReset = true + filter.scope = SearchScope(rawValue: self.searchController.searchBar.selectedScopeButtonIndex) ?? .plateNumber + updateSearchResults(with: self.filter) + } + } } func showOnMap() { diff --git a/AutoCat/Controllers/VMResult.swift b/AutoCat/Controllers/VMResult.swift new file mode 100644 index 0000000..b54309d --- /dev/null +++ b/AutoCat/Controllers/VMResult.swift @@ -0,0 +1,39 @@ +// +// VMResult.swift +// AutoCat +// +// Created by Selim Mustafaev on 27.10.2024. +// Copyright © 2024 Selim Mustafaev. All rights reserved. +// + +import Foundation + +@Observable +class VMResult { + + var value: T + var isDone: Bool + + init(value: T) { + + self.value = value + self.isDone = false + } + + func done() { + isDone = true + } + + func cancel() { + isDone = false + } + + func set(_ value: T) { + self.value = value + isDone = true + } + + func get() -> T? { + isDone ? value : nil + } +} diff --git a/AutoCat/Screens/FiltersScreen/FiltersCoordinator.swift b/AutoCat/Screens/FiltersScreen/FiltersCoordinator.swift index 746746d..ff76661 100644 --- a/AutoCat/Screens/FiltersScreen/FiltersCoordinator.swift +++ b/AutoCat/Screens/FiltersScreen/FiltersCoordinator.swift @@ -21,11 +21,11 @@ class FiltersCoordinator: Coordinator { self.filter = filter } - func start() async throws -> Filter { + func start() async throws -> Filter? { let viewModel = FiltersViewModel(filter: filter) let controller = CustomHostingController(rootView: FiltersScreen(viewModel: viewModel)) viewController?.pushViewController(controller, animated: true) await controller.waitForDisappear() - return viewModel.filter + return viewModel.filterResult } } diff --git a/AutoCat/Screens/FiltersScreen/FiltersScreen.swift b/AutoCat/Screens/FiltersScreen/FiltersScreen.swift index 9600964..2d71b06 100644 --- a/AutoCat/Screens/FiltersScreen/FiltersScreen.swift +++ b/AutoCat/Screens/FiltersScreen/FiltersScreen.swift @@ -41,11 +41,75 @@ struct FiltersScreen: View { } } .pickerStyle(.navigationLink) + + Section { + Picker("Added by", selection: $viewModel.filter.addedBy) { + ForEach(AddedBy.allCases, id: \.self) { + Text($0.description) + } + } + } + + Section("Update time") { + OptionalDatePicker(label: "From", + defaultValue: "Beginning", + date: $viewModel.filter.fromDateUpdated) + OptionalDatePicker(label: "To", + defaultValue: "Now", + date: $viewModel.filter.toDateUpdated) + } + + Section("Added time") { + OptionalDatePicker(label: "From", + defaultValue: "Beginning", + date: $viewModel.filter.fromDate) + OptionalDatePicker(label: "To", + defaultValue: "Now", + date: $viewModel.filter.toDate) + } + + Section("Location adding time") { + OptionalDatePicker(label: "From", + defaultValue: "Beginning", + date: $viewModel.filter.fromLocationDate) + OptionalDatePicker(label: "To", + defaultValue: "Now", + date: $viewModel.filter.toLocationDate) + } + + Section("Sort") { + Section { + Picker("Sort by", selection: $viewModel.filter.sortBy) { + ForEach(SortParameter.allCases, id: \.self) { + Text($0.description) + } + } + Picker("Order", selection: $viewModel.filter.sortOrder) { + ForEach(SortOrder.allCases, id: \.self) { + Text($0.description) + } + } + } + } + + Section { + HStack { + Spacer() + Button("Clear all filters") { + viewModel.clearAllFilters() + } + Spacer() + } + } } .navigationTitle("Filters") - .navigationBarItems(trailing: Button("Done", action: { - - })) + .toolbar { + ToolbarItem(placement: .topBarTrailing) { + Button("Done") { + viewModel.applyFilters() + } + } + } .task { await viewModel.loadData() } diff --git a/AutoCat/Screens/FiltersScreen/FiltersViewModel.swift b/AutoCat/Screens/FiltersScreen/FiltersViewModel.swift index b478f7a..7d7c2fa 100644 --- a/AutoCat/Screens/FiltersScreen/FiltersViewModel.swift +++ b/AutoCat/Screens/FiltersScreen/FiltersViewModel.swift @@ -26,6 +26,8 @@ class FiltersViewModel { } } + @ObservationIgnored var filterResult: Filter? + var models: [StringOption] = [.any] var brands: [StringOption] = [.any] var colors: [StringOption] = [.any] @@ -51,4 +53,12 @@ class FiltersViewModel { models = [.any] + ((try? await api.getModels(of: brand)) ?? []).map { .value($0) } filter.model = .any } + + func clearAllFilters() { + filter.clear() + } + + func applyFilters() { + filterResult = filter + } } diff --git a/AutoCat/SwiftUI/LinkRowView.swift b/AutoCat/SwiftUI/LinkRowView.swift index 7607a7f..eeb0627 100644 --- a/AutoCat/SwiftUI/LinkRowView.swift +++ b/AutoCat/SwiftUI/LinkRowView.swift @@ -14,23 +14,19 @@ struct LinkRowView: View { let value: String? var body: some View { - if #available(iOS 16.0, *) { - ViewThatFits(in: .horizontal) { - SimpleLinkRowView(title: title, value: value) - VStack(alignment: .leading, spacing: 8) { - Text(title) - HStack { - Spacer() - if let url = URL(string: value ?? "") { - Link(url.absoluteString, destination: url) - .multilineTextAlignment(.trailing) - .padding(.leading) - } + ViewThatFits(in: .horizontal) { + SimpleLinkRowView(title: title, value: value) + VStack(alignment: .leading, spacing: 8) { + Text(title) + HStack { + Spacer() + if let url = URL(string: value ?? "") { + Link(url.absoluteString, destination: url) + .multilineTextAlignment(.trailing) + .padding(.leading) } } } - } else { - SimpleLinkRowView(title: title, value: value) } } } diff --git a/AutoCat/SwiftUI/OptionalBinding.swift b/AutoCat/SwiftUI/OptionalBinding.swift new file mode 100644 index 0000000..0266bf7 --- /dev/null +++ b/AutoCat/SwiftUI/OptionalBinding.swift @@ -0,0 +1,16 @@ +// +// OptionalBinding.swift +// AutoCat +// +// Created by Selim Mustafaev on 27.10.2024. +// Copyright © 2024 Selim Mustafaev. All rights reserved. +// + +import SwiftUI + +public func ??(lhs: Binding>, rhs: T) -> Binding where T: Sendable { + Binding( + get: { lhs.wrappedValue ?? rhs }, + set: { lhs.wrappedValue = $0 } + ) +} diff --git a/AutoCat/SwiftUI/OptionalDatePicker.swift b/AutoCat/SwiftUI/OptionalDatePicker.swift new file mode 100644 index 0000000..88023f1 --- /dev/null +++ b/AutoCat/SwiftUI/OptionalDatePicker.swift @@ -0,0 +1,49 @@ +// +// OptionalDatePicker.swift +// AutoCat +// +// Created by Selim Mustafaev on 27.10.2024. +// Copyright © 2024 Selim Mustafaev. All rights reserved. +// + +import SwiftUI + +struct OptionalDatePicker: View { + + let label: LocalizedStringKey + let defaultValue: LocalizedStringKey + @Binding var date: Date? + + var body: some View { + HStack { + Text(label) + Spacer(minLength: 0) + if date != nil { + HStack { + DatePicker("", selection: $date ?? Date(), displayedComponents: [.date]) + .labelsHidden() + Image(systemName: "xmark.circle.fill") + .onTapGesture { + date = nil + } + } + } else { + Text(defaultValue) + .foregroundStyle(.secondary) + } + } + .contentShape(Rectangle()) + .onTapGesture { + if date == nil { + date = Date() + } + } + } +} + +#Preview { + VStack { + OptionalDatePicker(label: "From", defaultValue: "Beginning", date: .constant(nil)) + OptionalDatePicker(label: "To", defaultValue: "Now", date: .constant(Date())) + } +} diff --git a/AutoCat/SwiftUI/TextRowView.swift b/AutoCat/SwiftUI/TextRowView.swift index 2fcfe3b..8dbc5cd 100644 --- a/AutoCat/SwiftUI/TextRowView.swift +++ b/AutoCat/SwiftUI/TextRowView.swift @@ -21,27 +21,23 @@ struct TextRowView: View { } var body: some View { - if #available(iOS 16.0, *) { - ViewThatFits(in: .horizontal) { - SimpleTextRowView(title: title, value: value, showArrow: showArrow) - VStack(alignment: .leading, spacing: 8) { - Text(title) - HStack { - Spacer() - Text(value ?? "") + ViewThatFits(in: .horizontal) { + SimpleTextRowView(title: title, value: value, showArrow: showArrow) + VStack(alignment: .leading, spacing: 8) { + Text(title) + HStack { + Spacer() + Text(value ?? "") + .foregroundStyle(.secondary) + .multilineTextAlignment(.trailing) + .padding(.leading) + if showArrow { + Image(systemName: "chevron.right") + .padding(.leading, 8) .foregroundStyle(.secondary) - .multilineTextAlignment(.trailing) - .padding(.leading) - if showArrow { - Image(systemName: "chevron.right") - .padding(.leading, 8) - .foregroundStyle(.secondary) - } } } } - } else { - SimpleTextRowView(title: title, value: value, showArrow: showArrow) } } } diff --git a/AutoCatCore/Models/Filter.swift b/AutoCatCore/Models/Filter.swift index 46bc809..71be014 100644 --- a/AutoCatCore/Models/Filter.swift +++ b/AutoCatCore/Models/Filter.swift @@ -95,9 +95,9 @@ public struct Filter: Sendable { public var color: StringOption = .any public var year: StringOption = .any public var regions: [Int]? - public var addedBy: AddedBy? - public var sortBy: SortParameter? = .updatedDate - public var sortOrder: SortOrder? = .descending + public var addedBy: AddedBy = .anyone + public var sortBy: SortParameter = .updatedDate + public var sortOrder: SortOrder = .descending public var fromDate: Date? public var toDate: Date? public var fromDateUpdated: Date? @@ -116,7 +116,7 @@ public struct Filter: Sendable { self.color = .any self.year = .any self.regions = nil - self.addedBy = nil + self.addedBy = .anyone self.sortBy = .updatedDate self.sortOrder = .descending self.fromDate = nil @@ -129,7 +129,12 @@ public struct Filter: Sendable { } public func queryDictionary() -> [String: String] { - var dict: [String: String] = ["query": self.searchString] + var dict: [String: String] = [ + "query": self.searchString, + "addedBy": addedBy.rawValue, + "sortBy": sortBy.rawValue, + "sortOrder": sortOrder.rawValue + ] if case let .value(brand) = brand { dict["brand"] = brand @@ -146,15 +151,6 @@ public struct Filter: Sendable { if let regions = self.regions { dict["regions"] = regions.map(String.init).joined(separator: ",") } - if let addedBy = self.addedBy { - dict["addedBy"] = addedBy.rawValue - } - if let sortBy = self.sortBy { - dict["sortBy"] = sortBy.rawValue - } - if let sortOrder = self.sortOrder { - dict["sortOrder"] = sortOrder.rawValue - } if let fromDate = self.fromDate { dict["fromDate"] = String(fromDate.timeIntervalSince1970) }