Adding search by vin and notes (in addition to plate numbers)

This commit is contained in:
Selim Mustafaev 2025-05-20 22:02:19 +03:00
parent 48c700fc13
commit c4e28a0656
6 changed files with 32 additions and 23 deletions

View File

@ -1661,7 +1661,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = AutoCat/AutoCat.entitlements; CODE_SIGN_ENTITLEMENTS = AutoCat/AutoCat.entitlements;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 166; CURRENT_PROJECT_VERSION = 167;
DEVELOPMENT_TEAM = 46DTTB8X4S; DEVELOPMENT_TEAM = 46DTTB8X4S;
INFOPLIST_FILE = AutoCat/Info.plist; INFOPLIST_FILE = AutoCat/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = AutoCat; INFOPLIST_KEY_CFBundleDisplayName = AutoCat;
@ -1690,7 +1690,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = AutoCat/AutoCat.entitlements; CODE_SIGN_ENTITLEMENTS = AutoCat/AutoCat.entitlements;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 166; CURRENT_PROJECT_VERSION = 167;
DEVELOPMENT_TEAM = 46DTTB8X4S; DEVELOPMENT_TEAM = 46DTTB8X4S;
INFOPLIST_FILE = AutoCat/Info.plist; INFOPLIST_FILE = AutoCat/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = AutoCat; INFOPLIST_KEY_CFBundleDisplayName = AutoCat;

View File

@ -27,7 +27,7 @@ struct MapScreen: View {
} }
var body: some View { var body: some View {
Map { Map(position: $viewModel.currentPosition) {
ForEach(viewModel.markers) { ForEach(viewModel.markers) {
Marker($0.title, coordinate: $0.coordinate) Marker($0.title, coordinate: $0.coordinate)
} }

View File

@ -28,6 +28,7 @@ final class MapViewModel: ACHudContainer {
let clusterManager = ClusterManager<MapMarkerModel>() let clusterManager = ClusterManager<MapMarkerModel>()
var mapSize: CGSize = .zero var mapSize: CGSize = .zero
var currentRegion: MKCoordinateRegion = .init() var currentRegion: MKCoordinateRegion = .init()
var currentPosition: MapCameraPosition = .automatic
var isFilter: Bool { var isFilter: Bool {
switch mapInput { switch mapInput {
@ -75,7 +76,7 @@ final class MapViewModel: ACHudContainer {
title = String.localizedStringWithFormat(NSLocalizedString("events found", comment: ""), events.count) title = String.localizedStringWithFormat(NSLocalizedString("events found", comment: ""), events.count)
await clusterManager.add(markers) await clusterManager.add(markers)
await reloadMarkers() await reloadMarkers()
currentRegion = getRegion(for: markers) currentPosition = getRegion(for: markers)
} }
} }
@ -114,9 +115,9 @@ final class MapViewModel: ACHudContainer {
} }
} }
func getRegion(for markers: [MapMarkerModel]) -> MKCoordinateRegion { func getRegion(for markers: [MapMarkerModel]) -> MapCameraPosition {
guard !markers.isEmpty else { guard !markers.isEmpty else {
return .init() return .automatic
} }
let latitudes = markers.map(\.coordinate.latitude) let latitudes = markers.map(\.coordinate.latitude)
@ -127,15 +128,17 @@ final class MapViewModel: ACHudContainer {
let minLong = longitudes.min() ?? 0 let minLong = longitudes.min() ?? 0
let maxLong = longitudes.max() ?? 0 let maxLong = longitudes.max() ?? 0
return .init( let region = MKCoordinateRegion(
center: .init( center: .init(
latitude: (maxLat - minLat)/2, latitude: (maxLat + minLat)/2,
longitude: (maxLong - minLong)/2 longitude: (maxLong + minLong)/2
), ),
span: .init( span: .init(
latitudeDelta: (maxLat - minLat)*1.2, latitudeDelta: (maxLat - minLat)*1.3,
longitudeDelta: (maxLong - minLong)*1.2 longitudeDelta: (maxLong - minLong)*1.3
) )
) )
return .region(region)
} }
} }

View File

@ -33,7 +33,14 @@ struct SearchScreen: View {
} }
.listStyle(.plain) .listStyle(.plain)
.hud($viewModel.hud) .hud($viewModel.hud)
.searchable(text: $viewModel.searchText, prompt: "Search plate numbers") .searchable(
text: $viewModel.searchText,
tokens: $viewModel.currentScopes,
suggestedTokens: .constant(SearchScope.allCases),
prompt: "Search plate numbers"
) { scope in
Text(scope.title)
}
.searchPresentationToolbarBehavior(.avoidHidingContent) .searchPresentationToolbarBehavior(.avoidHidingContent)
.makeTextFieldDumb() .makeTextFieldDumb()
.titleModeInline() .titleModeInline()

View File

@ -46,6 +46,7 @@ final class SearchViewModel: ACHudContainer {
didSet { didSet {
if searchText != oldValue { if searchText != oldValue {
filter.searchString = searchText filter.searchString = searchText
filter.scope = currentScopes.first ?? .plateNumber
searchTask = Task { [filter] in searchTask = Task { [filter] in
do { do {
try await Task.sleep(for: .milliseconds(500)) try await Task.sleep(for: .milliseconds(500))
@ -56,6 +57,8 @@ final class SearchViewModel: ACHudContainer {
} }
} }
var currentScopes: [SearchScope] = []
@ObservationIgnored @ObservationIgnored
@AutoCancellable @AutoCancellable
var searchTask: Task<Void, Never>? var searchTask: Task<Void, Never>?

View File

@ -38,11 +38,11 @@ public enum SortOrder: String, CustomStringConvertible, CaseIterable, Sendable {
} }
} }
public enum SearchScope: Int, CaseIterable, Sendable, Hashable { public enum SearchScope: String, CaseIterable, Sendable, Hashable, Identifiable {
case plateNumber = 0 case plateNumber
case vin = 1 case vin
case notes = 2 case notes
public var title: String { public var title: String {
switch self { switch self {
@ -52,12 +52,8 @@ public enum SearchScope: Int, CaseIterable, Sendable, Hashable {
} }
} }
public var stringValue: String { public var id: String {
switch self { rawValue
case .plateNumber: return "plateNumber"
case .vin: return "vin"
case .notes: return "notes"
}
} }
} }
@ -170,7 +166,7 @@ public struct Filter: Sendable, Hashable {
dict["toLocationDate"] = String(toLocationDate.timeIntervalSince1970) dict["toLocationDate"] = String(toLocationDate.timeIntervalSince1970)
} }
dict["scope"] = scope.stringValue dict["scope"] = scope.rawValue
return dict return dict
} }