diff --git a/ConversationsClassic/View/Screens/Attachments/AttachmentLocationPickerView.swift b/ConversationsClassic/View/Screens/Attachments/AttachmentLocationPickerView.swift index c40af55..1eac91b 100644 --- a/ConversationsClassic/View/Screens/Attachments/AttachmentLocationPickerView.swift +++ b/ConversationsClassic/View/Screens/Attachments/AttachmentLocationPickerView.swift @@ -1,75 +1,57 @@ import CoreLocation import MapKit import SwiftUI -import UIKit struct AttachmentLocationPickerView: View { - @StateObject private var locationManager = LocationManager() - @State private var region = MKCoordinateRegion( - center: CLLocationCoordinate2D(latitude: 34.011_286, longitude: -116.166_868), - span: MKCoordinateSpan(latitudeDelta: 0.2, longitudeDelta: 0.2) - ) - @State private var showingAlert = false - @State private var userInteraction = false + @StateObject var locationManager = LocationManager() + @State private var region = MKCoordinateRegion() + @State var userInteracted: Bool = false var body: some View { - MapView(coordinateRegion: $region, interactionState: $userInteraction) - .onAppear { - locationManager.start() - } - .onChange(of: locationManager.lastLocation) { newLocation in - if let newLocation, !userInteraction { - region.center = newLocation.coordinate - } - } - .onChange(of: locationManager.authorizationStatus) { newStatus in - if newStatus == .denied { - showingAlert = true - } - } - .alert(isPresented: $showingAlert) { - Alert( - title: Text("Location Permission Denied"), - message: Text("Please enable location permissions in settings."), - dismissButton: .default(Text("OK")) { - openAppSettings() - } - ) - } - .overlay { - Image(systemName: "mappin") - .font(.title) - .foregroundColor(.Material.Elements.active) - .padding() - if userInteraction { - VStack { - Spacer() - HStack { - Spacer() - Image(systemName: "location.north.circle.fill") - .font(.title) - .foregroundColor(.Material.Elements.active) - .padding() - .tappablePadding(.symmetric(10)) { - userInteraction = false - region.center = locationManager.lastLocation?.coordinate ?? region.center - } + Map( + coordinateRegion: $region, + interactionModes: .all, + showsUserLocation: false, + userTrackingMode: .none + ) + .onAppear { + locationManager.start() + } + .onDisappear { + locationManager.stop() + } + .onChange(of: locationManager.region) { region in + if !userInteracted { + let currentLoc = CLLocation(latitude: self.region.center.latitude, longitude: self.region.center.longitude) + let newLoc = CLLocation(latitude: region.center.latitude, longitude: region.center.longitude) + if newLoc.distance(from: currentLoc) > 10 { + DispatchQueue.main.async { + withAnimation { + self.region = region } } } } + } + .overlay { + Image(systemName: "mappin") + .font(.title2) + .foregroundColor(.Material.Elements.active) + } + .onChange(of: region) { region in + print("Region changed: \(region.center)") + } } } class LocationManager: NSObject, ObservableObject, CLLocationManagerDelegate { + @Published var region = MKCoordinateRegion() private let locationManager = CLLocationManager() - @Published var lastLocation: CLLocation? - @Published var authorizationStatus: CLAuthorizationStatus override init() { - authorizationStatus = locationManager.authorizationStatus super.init() locationManager.delegate = self + locationManager.desiredAccuracy = kCLLocationAccuracyBest } func start() { @@ -77,43 +59,21 @@ class LocationManager: NSObject, ObservableObject, CLLocationManagerDelegate { locationManager.startUpdatingLocation() } + func stop() { + locationManager.stopUpdatingLocation() + } + func locationManager(_: CLLocationManager, didUpdateLocations locations: [CLLocation]) { - lastLocation = locations.first - } - - func locationManager(_: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) { - authorizationStatus = status + guard let location = locations.last else { return } + region = MKCoordinateRegion(center: location.coordinate, span: MKCoordinateSpan(latitudeDelta: 0.001, longitudeDelta: 0.001)) } } -struct MapView: UIViewRepresentable { - @Binding var coordinateRegion: MKCoordinateRegion - @Binding var interactionState: Bool - - func makeUIView(context: Context) -> MKMapView { - let mapView = MKMapView() - mapView.delegate = context.coordinator - mapView.addGestureRecognizer(UIPanGestureRecognizer(target: context.coordinator, action: #selector(Coordinator.mapWasDragged))) - return mapView - } - - func updateUIView(_ uiView: MKMapView, context _: Context) { - uiView.setRegion(coordinateRegion, animated: true) - } - - func makeCoordinator() -> Coordinator { - Coordinator(self) - } - - class Coordinator: NSObject, MKMapViewDelegate { - var parent: MapView - - init(_ parent: MapView) { - self.parent = parent - } - - @objc func mapWasDragged() { - parent.interactionState = true - } +extension MKCoordinateRegion: Equatable { + public static func == (lhs: MKCoordinateRegion, rhs: MKCoordinateRegion) -> Bool { + lhs.center.latitude == rhs.center.latitude && + lhs.center.longitude == rhs.center.longitude && + lhs.span.latitudeDelta == rhs.span.latitudeDelta && + lhs.span.longitudeDelta == rhs.span.longitudeDelta } } diff --git a/ConversationsClassic/View/Screens/Conversation/ConversationMessageRow.swift b/ConversationsClassic/View/Screens/Conversation/ConversationMessageRow.swift index 8d5d10a..3db46bd 100644 --- a/ConversationsClassic/View/Screens/Conversation/ConversationMessageRow.swift +++ b/ConversationsClassic/View/Screens/Conversation/ConversationMessageRow.swift @@ -36,11 +36,11 @@ struct ConversationMessageRow: View { offset = CGSize(width: width, height: 0) } .onEnded { value in + let targetWidth: CGFloat = -90 withAnimation(.easeOut(duration: 0.1)) { - if value.translation.width <= -90 { + if value.translation.width <= targetWidth { Vibration.success.vibrate() DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) { - store.dispatch(.conversationAction(.setReplyText(message.body ?? ""))) withAnimation(.easeOut(duration: 0.1)) { offset = .zero } @@ -49,6 +49,11 @@ struct ConversationMessageRow: View { offset = .zero } } + if value.translation.width <= targetWidth { + DispatchQueue.main.asyncAfter(deadline: .now() + 0.02) { + store.dispatch(.conversationAction(.setReplyText(message.body ?? ""))) + } + } } ) }