diff --git a/ConversationsClassic/AppData/Store/ConversationStore.swift b/ConversationsClassic/AppData/Store/ConversationStore.swift index 3d79f2c..17812aa 100644 --- a/ConversationsClassic/AppData/Store/ConversationStore.swift +++ b/ConversationsClassic/AppData/Store/ConversationStore.swift @@ -85,6 +85,13 @@ extension ConversationStore { // // } + + func sendLocation(_ lat: Double, _ lon: Double) async { + print("location!", lat, lon) + // + // + // + } } extension ConversationStore { diff --git a/ConversationsClassic/View/Main/Conversation/Attachments/AttachmentPickerScreen.swift b/ConversationsClassic/View/Main/Conversation/Attachments/AttachmentPickerScreen.swift index eb27f0b..a6c23be 100644 --- a/ConversationsClassic/View/Main/Conversation/Attachments/AttachmentPickerScreen.swift +++ b/ConversationsClassic/View/Main/Conversation/Attachments/AttachmentPickerScreen.swift @@ -42,8 +42,7 @@ struct AttachmentPickerScreen: View { FilesPickerView() case .location: - Color.green - // SharingLocationPickerView() + LocationPickerView() case .contacts: ContactsPickerView() diff --git a/ConversationsClassic/View/Main/Conversation/Attachments/LocationPicker/LocationPickerView.swift b/ConversationsClassic/View/Main/Conversation/Attachments/LocationPicker/LocationPickerView.swift new file mode 100644 index 0000000..92eb472 --- /dev/null +++ b/ConversationsClassic/View/Main/Conversation/Attachments/LocationPicker/LocationPickerView.swift @@ -0,0 +1,139 @@ +import MapKit +import SwiftUI + +struct LocationPickerView: View { + @Environment(\.router) var router + @EnvironmentObject var conversation: ConversationStore + + @StateObject var locationManager = LocationManager() + @State private var region = MKCoordinateRegion() + + var body: some View { + VStack(spacing: 0) { + ZStack { + // MapView + MapView(region: $region) + .onAppear { + DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { + self.region = locationManager.region + } + } + .overlay { + Image(systemName: "mappin") + .foregroundColor(.Material.Elements.active) + .font(.system(size: 30)) + .shadow(color: .white, radius: 2) + } + + // Track button + VStack { + Spacer() + HStack { + Spacer() + Image(systemName: "location.circle") + .resizable() + .frame(width: 40, height: 40) + .foregroundColor(.Material.Elements.active) + .background(Color.Material.Shape.white) + .clipShape(Circle()) + .shadow(color: .white, radius: 2) + .padding(.trailing) + .padding(.bottom, 50) + .tappablePadding(.symmetric(10)) { + self.region = locationManager.region + } + } + } + } + + // Send panel + Rectangle() + .foregroundColor(.Material.Shape.black) + .frame(maxWidth: .infinity) + .frame(height: 50) + .overlay { + HStack { + Text(L10n.Attachment.Send.location) + .foregroundColor(.Material.Text.white) + .font(.body1) + Image(systemName: "arrow.up.circle") + .foregroundColor(.Material.Text.white) + .font(.body1) + .padding(.leading, 8) + } + .padding() + } + .clipped() + .onTapGesture { + Task { + await conversation.sendLocation(region.center.latitude, region.center.longitude) + } + router.dismissEnvironment() + } + } + .onAppear { + locationManager.start() + } + } +} + +struct MapView: UIViewRepresentable { + @Binding var region: MKCoordinateRegion + + func makeUIView(context: Context) -> MKMapView { + let mapView = MKMapView() + mapView.delegate = context.coordinator + mapView.showsUserLocation = false + mapView.userTrackingMode = .none + + return mapView + } + + func updateUIView(_ uiView: MKMapView, context _: Context) { + if uiView.region != region { + uiView.setRegion(region, animated: true) + } + } + + func makeCoordinator() -> Coordinator { + Coordinator(self) + } + + class Coordinator: NSObject, MKMapViewDelegate { + var parent: MapView + + init(_ parent: MapView) { + self.parent = parent + } + } +} + +class LocationManager: NSObject, ObservableObject, CLLocationManagerDelegate { + private let locationManager = CLLocationManager() + @Published var region: MKCoordinateRegion + + override init() { + region = MKCoordinateRegion() + super.init() + locationManager.delegate = self + locationManager.desiredAccuracy = kCLLocationAccuracyBest + } + + func start() { + locationManager.requestWhenInUseAuthorization() + locationManager.startUpdatingLocation() + } + + func stop() { + locationManager.stopUpdatingLocation() + } + + func locationManager(_: CLLocationManager, didUpdateLocations locations: [CLLocation]) { + if let loc = locations.first { + region = MKCoordinateRegion( + center: loc.coordinate, + span: MKCoordinateSpan(latitudeDelta: 0.002, longitudeDelta: 0.002) + ) + } + } +}