Adding events
This commit is contained in:
parent
b0718aadf1
commit
b36620eba0
@ -136,6 +136,7 @@
|
|||||||
7A96AE2F246B2BCD00297C33 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7A96AE2E246B2BCD00297C33 /* WebKit.framework */; };
|
7A96AE2F246B2BCD00297C33 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7A96AE2E246B2BCD00297C33 /* WebKit.framework */; };
|
||||||
7A99406426E4BFAE002E9CB6 /* VehicleNoteCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A99406326E4BFAE002E9CB6 /* VehicleNoteCell.swift */; };
|
7A99406426E4BFAE002E9CB6 /* VehicleNoteCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A99406326E4BFAE002E9CB6 /* VehicleNoteCell.swift */; };
|
||||||
7A9FEEC82529AB23001CA50E /* RxRealmDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A9FEEC72529AB23001CA50E /* RxRealmDataSource.swift */; };
|
7A9FEEC82529AB23001CA50E /* RxRealmDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A9FEEC72529AB23001CA50E /* RxRealmDataSource.swift */; };
|
||||||
|
7AA514E02D0B75B3001CAC50 /* StorageService+Events.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AA514DF2D0B75B3001CAC50 /* StorageService+Events.swift */; };
|
||||||
7AA7BC3325A5DFB80053A5D5 /* Kingfisher in Frameworks */ = {isa = PBXBuildFile; productRef = 7AF58D332402A91C00CE01A0 /* Kingfisher */; };
|
7AA7BC3325A5DFB80053A5D5 /* Kingfisher in Frameworks */ = {isa = PBXBuildFile; productRef = 7AF58D332402A91C00CE01A0 /* Kingfisher */; };
|
||||||
7AA7BC3525A5DFB80053A5D5 /* ExceptionCatcher in Frameworks */ = {isa = PBXBuildFile; productRef = 7A813DC02508C4D900CC93B9 /* ExceptionCatcher */; };
|
7AA7BC3525A5DFB80053A5D5 /* ExceptionCatcher in Frameworks */ = {isa = PBXBuildFile; productRef = 7A813DC02508C4D900CC93B9 /* ExceptionCatcher */; };
|
||||||
7AA7BC3625A5DFB80053A5D5 /* PKHUD in Frameworks */ = {isa = PBXBuildFile; productRef = 7AABDE1C2532F3EB0041AFC6 /* PKHUD */; };
|
7AA7BC3625A5DFB80053A5D5 /* PKHUD in Frameworks */ = {isa = PBXBuildFile; productRef = 7AABDE1C2532F3EB0041AFC6 /* PKHUD */; };
|
||||||
@ -413,6 +414,7 @@
|
|||||||
7A96AE32246C095700297C33 /* Base64FS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Base64FS.swift; sourceTree = "<group>"; };
|
7A96AE32246C095700297C33 /* Base64FS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Base64FS.swift; sourceTree = "<group>"; };
|
||||||
7A99406326E4BFAE002E9CB6 /* VehicleNoteCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VehicleNoteCell.swift; sourceTree = "<group>"; };
|
7A99406326E4BFAE002E9CB6 /* VehicleNoteCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VehicleNoteCell.swift; sourceTree = "<group>"; };
|
||||||
7A9FEEC72529AB23001CA50E /* RxRealmDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RxRealmDataSource.swift; sourceTree = "<group>"; };
|
7A9FEEC72529AB23001CA50E /* RxRealmDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RxRealmDataSource.swift; sourceTree = "<group>"; };
|
||||||
|
7AA514DF2D0B75B3001CAC50 /* StorageService+Events.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "StorageService+Events.swift"; sourceTree = "<group>"; };
|
||||||
7AAAFAD22C4D0FD00050410D /* ACImageSliderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ACImageSliderView.swift; sourceTree = "<group>"; };
|
7AAAFAD22C4D0FD00050410D /* ACImageSliderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ACImageSliderView.swift; sourceTree = "<group>"; };
|
||||||
7AAAFAD92C4D1AFE0050410D /* Zoomable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Zoomable.swift; sourceTree = "<group>"; };
|
7AAAFAD92C4D1AFE0050410D /* Zoomable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Zoomable.swift; sourceTree = "<group>"; };
|
||||||
7AAAFADB2C4D1E130050410D /* ACImageSliderView+Modifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ACImageSliderView+Modifier.swift"; sourceTree = "<group>"; };
|
7AAAFADB2C4D1E130050410D /* ACImageSliderView+Modifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ACImageSliderView+Modifier.swift"; sourceTree = "<group>"; };
|
||||||
@ -962,6 +964,7 @@
|
|||||||
7AB587312C42D38E00FA7B66 /* StorageServiceProtocol.swift */,
|
7AB587312C42D38E00FA7B66 /* StorageServiceProtocol.swift */,
|
||||||
7A45FB372C27073700618694 /* StorageService.swift */,
|
7A45FB372C27073700618694 /* StorageService.swift */,
|
||||||
7AB587332C42D3FA00FA7B66 /* StorageService+Notes.swift */,
|
7AB587332C42D3FA00FA7B66 /* StorageService+Notes.swift */,
|
||||||
|
7AA514DF2D0B75B3001CAC50 /* StorageService+Events.swift */,
|
||||||
);
|
);
|
||||||
path = StorageService;
|
path = StorageService;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -1495,6 +1498,7 @@
|
|||||||
7A64A2032C19DA1000284124 /* VehicleDto.swift in Sources */,
|
7A64A2032C19DA1000284124 /* VehicleDto.swift in Sources */,
|
||||||
7AB587322C42D38E00FA7B66 /* StorageServiceProtocol.swift in Sources */,
|
7AB587322C42D38E00FA7B66 /* StorageServiceProtocol.swift in Sources */,
|
||||||
7A3E12D72C7B42B700EE710D /* UserDefaults+Settings.swift in Sources */,
|
7A3E12D72C7B42B700EE710D /* UserDefaults+Settings.swift in Sources */,
|
||||||
|
7AA514E02D0B75B3001CAC50 /* StorageService+Events.swift in Sources */,
|
||||||
7A64A2222C19E99E00284124 /* DebugInfoDto.swift in Sources */,
|
7A64A2222C19E99E00284124 /* DebugInfoDto.swift in Sources */,
|
||||||
7A5D84BC2C1AD81000C2209B /* VehicleOwnershipPeriod.swift in Sources */,
|
7A5D84BC2C1AD81000C2209B /* VehicleOwnershipPeriod.swift in Sources */,
|
||||||
7A64A2202C19E93500284124 /* VehicleNoteDto.swift in Sources */,
|
7A64A2202C19E93500284124 /* VehicleNoteDto.swift in Sources */,
|
||||||
|
|||||||
@ -22,9 +22,16 @@ class EventsCoordinator {
|
|||||||
func start(vehicle: VehicleDto) async -> VehicleDto {
|
func start(vehicle: VehicleDto) async -> VehicleDto {
|
||||||
|
|
||||||
let viewModel = EventsViewModel(vehicle: vehicle)
|
let viewModel = EventsViewModel(vehicle: vehicle)
|
||||||
|
viewModel.coordinator = self
|
||||||
let controller = CustomHostingController(rootView: EventsScreen(viewModel: viewModel))
|
let controller = CustomHostingController(rootView: EventsScreen(viewModel: viewModel))
|
||||||
navController.pushViewController(controller, animated: true)
|
navController.pushViewController(controller, animated: true)
|
||||||
await controller.waitForDisappear()
|
await controller.waitForDisappear()
|
||||||
return viewModel.vehicle
|
return viewModel.vehicle
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func addNewEvent() async -> VehicleEventDto? {
|
||||||
|
|
||||||
|
let coordinator = LocationEditCoordinator(navController: navController)
|
||||||
|
return await coordinator.start()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,8 +25,14 @@ struct EventsScreen: View {
|
|||||||
list
|
list
|
||||||
.zIndex(viewModel.mode == .list ? 1 : 0)
|
.zIndex(viewModel.mode == .list ? 1 : 0)
|
||||||
}
|
}
|
||||||
|
.hud($viewModel.hud)
|
||||||
.navigationTitle(viewModel.vehicle.number)
|
.navigationTitle(viewModel.vehicle.number)
|
||||||
.toolbar {
|
.toolbar {
|
||||||
|
ToolbarItem(placement: .primaryAction) {
|
||||||
|
Button("", systemImage: "plus") {
|
||||||
|
Task { await viewModel.addNewEvent() }
|
||||||
|
}
|
||||||
|
}
|
||||||
ToolbarItem(placement: .primaryAction) {
|
ToolbarItem(placement: .primaryAction) {
|
||||||
Button("", systemImage: viewModel.mode.switchIcon) {
|
Button("", systemImage: viewModel.mode.switchIcon) {
|
||||||
viewModel.mode.toggle()
|
viewModel.mode.toggle()
|
||||||
|
|||||||
@ -12,12 +12,16 @@ import CoreLocation
|
|||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
@Observable
|
@Observable
|
||||||
class EventsViewModel {
|
class EventsViewModel: ACHudContainer {
|
||||||
|
|
||||||
@ObservationIgnored @Service var api: ApiServiceProtocol
|
typealias VehicleOperation = () async throws -> VehicleDto
|
||||||
|
|
||||||
|
@ObservationIgnored @Service var apiService: ApiServiceProtocol
|
||||||
@ObservationIgnored @Service var storageService: StorageServiceProtocol
|
@ObservationIgnored @Service var storageService: StorageServiceProtocol
|
||||||
@ObservationIgnored @Service var settingsService: SettingsServiceProtocol
|
@ObservationIgnored @Service var settingsService: SettingsServiceProtocol
|
||||||
|
|
||||||
|
weak var coordinator: EventsCoordinator?
|
||||||
|
|
||||||
var hud: ACHud?
|
var hud: ACHud?
|
||||||
|
|
||||||
var vehicle: VehicleDto
|
var vehicle: VehicleDto
|
||||||
@ -49,4 +53,33 @@ class EventsViewModel {
|
|||||||
let coordinate = CLLocationCoordinate2DMake(event.latitude, event.longitude)
|
let coordinate = CLLocationCoordinate2DMake(event.latitude, event.longitude)
|
||||||
return MarkerModel(date: dateString, coordinate: coordinate)
|
return MarkerModel(date: dateString, coordinate: coordinate)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func addNewEvent() async {
|
||||||
|
if let event = await coordinator?.addNewEvent() {
|
||||||
|
await eventOperation {
|
||||||
|
try await self.storageService.add(event: event, to: self.vehicle.getNumber())
|
||||||
|
} apiOperation: {
|
||||||
|
try await self.apiService.add(event: event, to: self.vehicle.getNumber())
|
||||||
|
}
|
||||||
|
updateEvents()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func eventOperation(_ storageOperation: @escaping VehicleOperation, apiOperation: @escaping VehicleOperation) async {
|
||||||
|
|
||||||
|
if vehicle.unrecognized {
|
||||||
|
await wrapWithToast(showProgress: false) { [weak self] in
|
||||||
|
guard let self else { return }
|
||||||
|
vehicle = try await storageOperation()
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
await wrapWithToast { [weak self] in
|
||||||
|
guard let self else { return }
|
||||||
|
let vehicle = try await apiOperation()
|
||||||
|
try await storageService.updateVehicleIfExists(dto: vehicle)
|
||||||
|
self.vehicle = vehicle
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,7 +11,7 @@ import SwiftUI
|
|||||||
import AutoCatCore
|
import AutoCatCore
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
final class LocationEditCoordinator: Coordinator {
|
final class LocationEditCoordinator {
|
||||||
|
|
||||||
let viewController: UINavigationController?
|
let viewController: UINavigationController?
|
||||||
let event: VehicleEventDto
|
let event: VehicleEventDto
|
||||||
@ -21,7 +21,7 @@ final class LocationEditCoordinator: Coordinator {
|
|||||||
self.event = event ?? VehicleEventDto(lat: 0, lon: 0)
|
self.event = event ?? VehicleEventDto(lat: 0, lon: 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func start() async throws -> VehicleEventDto? {
|
func start() async -> VehicleEventDto? {
|
||||||
|
|
||||||
let viewModel = LocationEditViewModel(event: event)
|
let viewModel = LocationEditViewModel(event: event)
|
||||||
viewModel.coordinator = self
|
viewModel.coordinator = self
|
||||||
|
|||||||
@ -15,6 +15,10 @@ public protocol ApiServiceProtocol: Sendable {
|
|||||||
func edit(note: VehicleNoteDto) async throws -> VehicleDto
|
func edit(note: VehicleNoteDto) async throws -> VehicleDto
|
||||||
func remove(note id: String) async throws -> VehicleDto
|
func remove(note id: String) async throws -> VehicleDto
|
||||||
|
|
||||||
|
func add(event: VehicleEventDto, to number: String) async throws -> VehicleDto
|
||||||
|
func remove(event id: String) async throws -> VehicleDto
|
||||||
|
func edit(event: VehicleEventDto) async throws -> VehicleDto
|
||||||
|
|
||||||
func getBrands() async throws -> [String]
|
func getBrands() async throws -> [String]
|
||||||
func getModels(of brand: String) async throws -> [String]
|
func getModels(of brand: String) async throws -> [String]
|
||||||
func getColors() async throws -> [String]
|
func getColors() async throws -> [String]
|
||||||
|
|||||||
@ -0,0 +1,26 @@
|
|||||||
|
//
|
||||||
|
// StorageService+Events.swift
|
||||||
|
// AutoCatCore
|
||||||
|
//
|
||||||
|
// Created by Selim Mustafaev on 12.12.2024.
|
||||||
|
// Copyright © 2024 Selim Mustafaev. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public extension StorageService {
|
||||||
|
|
||||||
|
func add(event: VehicleEventDto, to number: String) async throws -> VehicleDto {
|
||||||
|
|
||||||
|
guard let vehicle = realm.object(ofType: Vehicle.self, forPrimaryKey: number) else {
|
||||||
|
throw StorageError.vehicleNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
try await realm.asyncWrite {
|
||||||
|
vehicle.events.append(VehicleEvent(dto: event))
|
||||||
|
vehicle.updatedDate = Date().timeIntervalSince1970
|
||||||
|
}
|
||||||
|
|
||||||
|
return vehicle.dto
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -16,4 +16,7 @@ public protocol StorageServiceProtocol: Sendable {
|
|||||||
func editNote(id: String, text: String, for number: String) async throws -> VehicleDto
|
func editNote(id: String, text: String, for number: String) async throws -> VehicleDto
|
||||||
func updateVehicleIfExists(dto: VehicleDto) async throws
|
func updateVehicleIfExists(dto: VehicleDto) async throws
|
||||||
func loadVehicle(number: String) async throws -> VehicleDto
|
func loadVehicle(number: String) async throws -> VehicleDto
|
||||||
|
func add(event: VehicleEventDto, to number: String) async throws -> VehicleDto
|
||||||
|
// func remove(event id: String) async throws -> VehicleDto
|
||||||
|
// func edit(event: VehicleEventDto) async throws -> VehicleDto
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user