From 197f93037a556098e0e7e88e2cdb079f21e815f2 Mon Sep 17 00:00:00 2001 From: Selim Mustafaev Date: Sun, 15 Dec 2024 23:45:30 +0300 Subject: [PATCH] Copying events --- AutoCat/Info.plist | 13 ++++ .../Screens/EventsScreen/EventsScreen.swift | 21 +++++- .../EventsScreen/EventsViewModel.swift | 65 +++++++++++++++++++ 3 files changed, 98 insertions(+), 1 deletion(-) diff --git a/AutoCat/Info.plist b/AutoCat/Info.plist index b4959a8..54e4199 100644 --- a/AutoCat/Info.plist +++ b/AutoCat/Info.plist @@ -2,6 +2,19 @@ + UTExportedTypeDeclarations + + + UTTypeConformsTo + + public.json + + UTTypeIdentifier + pro.aliencat.vehicle.event + UTTypeTagSpecification + + + LSApplicationQueriesSchemes yandexmaps diff --git a/AutoCat/Screens/EventsScreen/EventsScreen.swift b/AutoCat/Screens/EventsScreen/EventsScreen.swift index 04554de..17a51fd 100644 --- a/AutoCat/Screens/EventsScreen/EventsScreen.swift +++ b/AutoCat/Screens/EventsScreen/EventsScreen.swift @@ -28,6 +28,13 @@ struct EventsScreen: View { .hud($viewModel.hud) .navigationTitle(viewModel.vehicle.number) .toolbar { + if viewModel.isPasteAvailable { + ToolbarItem(placement: .primaryAction) { + Button("", systemImage: "document.on.clipboard") { + viewModel.confirmPaste() + } + } + } ToolbarItem(placement: .primaryAction) { Button("", systemImage: "plus") { Task { await viewModel.addNewEvent() } @@ -39,6 +46,18 @@ struct EventsScreen: View { } } } + .alert("Paste event", + isPresented: $viewModel.showPasteAlert, + presenting: viewModel.pastedEvent) { event in + Button("Cancel", role: .cancel, action: {}) + Button("OK") { + viewModel.pasteEvent(event) + } + .keyboardShortcut(.defaultAction) + } message: { event in + Text(viewModel.getConfirmMessge(from: event)) + } + } var map: some View { @@ -92,7 +111,7 @@ struct EventsScreen: View { } Button() { - + viewModel.copyEvent(event) } label: { Label(useLabels ? "Copy" : "", systemImage: "doc.on.doc") } diff --git a/AutoCat/Screens/EventsScreen/EventsViewModel.swift b/AutoCat/Screens/EventsScreen/EventsViewModel.swift index d329274..c66059d 100644 --- a/AutoCat/Screens/EventsScreen/EventsViewModel.swift +++ b/AutoCat/Screens/EventsScreen/EventsViewModel.swift @@ -9,6 +9,15 @@ import SwiftUI import AutoCatCore import CoreLocation +import UniformTypeIdentifiers +import MobileCoreServices + +extension UTType { + + static var vehicleEvent: UTType { + UTType(exportedAs: "pro.aliencat.vehicle.event", conformingTo: .json) + } +} @MainActor @Observable @@ -28,9 +37,17 @@ class EventsViewModel: ACHudContainer { var mode: EventsScreenMode = .map var events: [EventModel] = [] + var showPasteAlert: Bool = false + var pastedEvent: VehicleEventDto? + + var isPasteAvailable: Bool { + UIPasteboard.general.data(forPasteboardType: UTType.vehicleEvent.identifier) != nil + } + init(vehicle: VehicleDto) { self.vehicle = vehicle + updateEvents() } @@ -111,4 +128,52 @@ class EventsViewModel: ACHudContainer { self.vehicle = vehicle } } + + func getMapLink(for event: VehicleEventDto) -> URL? { + var urlString = "http://maps.apple.com/?sll=\(event.latitude),\(event.longitude)" + if let address = event.address?.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) { + urlString = urlString + "&address=" + address + } + return URL(string: urlString) + } + + func copyEvent(_ event: EventModel) { + guard let eventDto = vehicle.events.first(where: { $0.id == event.id }) else { + return + } + + let sharedData: [String: Any?] = [ + UTType.url.identifier: getMapLink(for: eventDto), + UTType.vehicleEvent.identifier: try? JSONEncoder().encode(eventDto) + ] + + let items = sharedData.compactMapValues { $0 } + + if !items.isEmpty { + UIPasteboard.general.items = [items] + } + } + + func confirmPaste() { + guard let data = UIPasteboard.general.data(forPasteboardType: UTType.vehicleEvent.identifier), + var eventDto = try? JSONDecoder().decode(VehicleEventDto.self, from: data) + else { + return + } + + eventDto.id = UUID().uuidString + pastedEvent = eventDto + showPasteAlert = true + } + + func getConfirmMessge(from event: VehicleEventDto) -> String { + let date = Formatters.marker.string(from: Date(timeIntervalSince1970: event.date)) + let location = event.address ?? "\(event.latitude), \(event.longitude)" + + return date + "\n" + location + } + + func pasteEvent(_ event: VehicleEventDto) { + + } }