wip
This commit is contained in:
parent
d4e4c18762
commit
528e474d91
|
@ -1,75 +1,57 @@
|
||||||
import CoreLocation
|
import CoreLocation
|
||||||
import MapKit
|
import MapKit
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
import UIKit
|
|
||||||
|
|
||||||
struct AttachmentLocationPickerView: View {
|
struct AttachmentLocationPickerView: View {
|
||||||
@StateObject private var locationManager = LocationManager()
|
@StateObject var locationManager = LocationManager()
|
||||||
@State private var region = MKCoordinateRegion(
|
@State private var region = MKCoordinateRegion()
|
||||||
center: CLLocationCoordinate2D(latitude: 34.011_286, longitude: -116.166_868),
|
@State var userInteracted: Bool = false
|
||||||
span: MKCoordinateSpan(latitudeDelta: 0.2, longitudeDelta: 0.2)
|
|
||||||
)
|
|
||||||
@State private var showingAlert = false
|
|
||||||
@State private var userInteraction = false
|
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
MapView(coordinateRegion: $region, interactionState: $userInteraction)
|
Map(
|
||||||
|
coordinateRegion: $region,
|
||||||
|
interactionModes: .all,
|
||||||
|
showsUserLocation: false,
|
||||||
|
userTrackingMode: .none
|
||||||
|
)
|
||||||
.onAppear {
|
.onAppear {
|
||||||
locationManager.start()
|
locationManager.start()
|
||||||
}
|
}
|
||||||
.onChange(of: locationManager.lastLocation) { newLocation in
|
.onDisappear {
|
||||||
if let newLocation, !userInteraction {
|
locationManager.stop()
|
||||||
region.center = newLocation.coordinate
|
}
|
||||||
|
.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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.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 {
|
.overlay {
|
||||||
Image(systemName: "mappin")
|
Image(systemName: "mappin")
|
||||||
.font(.title)
|
.font(.title2)
|
||||||
.foregroundColor(.Material.Elements.active)
|
.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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
.onChange(of: region) { region in
|
||||||
|
print("Region changed: \(region.center)")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class LocationManager: NSObject, ObservableObject, CLLocationManagerDelegate {
|
class LocationManager: NSObject, ObservableObject, CLLocationManagerDelegate {
|
||||||
|
@Published var region = MKCoordinateRegion()
|
||||||
private let locationManager = CLLocationManager()
|
private let locationManager = CLLocationManager()
|
||||||
@Published var lastLocation: CLLocation?
|
|
||||||
@Published var authorizationStatus: CLAuthorizationStatus
|
|
||||||
|
|
||||||
override init() {
|
override init() {
|
||||||
authorizationStatus = locationManager.authorizationStatus
|
|
||||||
super.init()
|
super.init()
|
||||||
locationManager.delegate = self
|
locationManager.delegate = self
|
||||||
|
locationManager.desiredAccuracy = kCLLocationAccuracyBest
|
||||||
}
|
}
|
||||||
|
|
||||||
func start() {
|
func start() {
|
||||||
|
@ -77,43 +59,21 @@ class LocationManager: NSObject, ObservableObject, CLLocationManagerDelegate {
|
||||||
locationManager.startUpdatingLocation()
|
locationManager.startUpdatingLocation()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func stop() {
|
||||||
|
locationManager.stopUpdatingLocation()
|
||||||
|
}
|
||||||
|
|
||||||
func locationManager(_: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
|
func locationManager(_: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
|
||||||
lastLocation = locations.first
|
guard let location = locations.last else { return }
|
||||||
}
|
region = MKCoordinateRegion(center: location.coordinate, span: MKCoordinateSpan(latitudeDelta: 0.001, longitudeDelta: 0.001))
|
||||||
|
|
||||||
func locationManager(_: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
|
|
||||||
authorizationStatus = status
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MapView: UIViewRepresentable {
|
extension MKCoordinateRegion: Equatable {
|
||||||
@Binding var coordinateRegion: MKCoordinateRegion
|
public static func == (lhs: MKCoordinateRegion, rhs: MKCoordinateRegion) -> Bool {
|
||||||
@Binding var interactionState: Bool
|
lhs.center.latitude == rhs.center.latitude &&
|
||||||
|
lhs.center.longitude == rhs.center.longitude &&
|
||||||
func makeUIView(context: Context) -> MKMapView {
|
lhs.span.latitudeDelta == rhs.span.latitudeDelta &&
|
||||||
let mapView = MKMapView()
|
lhs.span.longitudeDelta == rhs.span.longitudeDelta
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,11 +36,11 @@ struct ConversationMessageRow: View {
|
||||||
offset = CGSize(width: width, height: 0)
|
offset = CGSize(width: width, height: 0)
|
||||||
}
|
}
|
||||||
.onEnded { value in
|
.onEnded { value in
|
||||||
|
let targetWidth: CGFloat = -90
|
||||||
withAnimation(.easeOut(duration: 0.1)) {
|
withAnimation(.easeOut(duration: 0.1)) {
|
||||||
if value.translation.width <= -90 {
|
if value.translation.width <= targetWidth {
|
||||||
Vibration.success.vibrate()
|
Vibration.success.vibrate()
|
||||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
|
||||||
store.dispatch(.conversationAction(.setReplyText(message.body ?? "")))
|
|
||||||
withAnimation(.easeOut(duration: 0.1)) {
|
withAnimation(.easeOut(duration: 0.1)) {
|
||||||
offset = .zero
|
offset = .zero
|
||||||
}
|
}
|
||||||
|
@ -49,6 +49,11 @@ struct ConversationMessageRow: View {
|
||||||
offset = .zero
|
offset = .zero
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if value.translation.width <= targetWidth {
|
||||||
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.02) {
|
||||||
|
store.dispatch(.conversationAction(.setReplyText(message.body ?? "")))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue