145 lines
4.9 KiB
Swift
145 lines
4.9 KiB
Swift
//
|
|
// NotificationContentViewController.swift
|
|
// EQNNotificationContent
|
|
//
|
|
// Created by Andrea Busi on 24/07/25.
|
|
// Copyright © 2025 Earthquake Network. All rights reserved.
|
|
//
|
|
|
|
import UIKit
|
|
import MapKit
|
|
import UserNotifications
|
|
import UserNotificationsUI
|
|
|
|
class NotificationContentViewController: UIViewController {
|
|
|
|
// MARK: - UI
|
|
|
|
@IBOutlet private weak var titleLabel: UILabel!
|
|
@IBOutlet private weak var descriptionLabel: UILabel!
|
|
@IBOutlet private weak var waveLabel: UILabel!
|
|
@IBOutlet private weak var mapView: MKMapView!
|
|
@IBOutlet private weak var tapToOpenButton: UIButton!
|
|
|
|
private var animator: MapSeismicWaveAnimator?
|
|
|
|
// MARK: - View
|
|
|
|
override func viewDidLoad() {
|
|
super.viewDidLoad()
|
|
|
|
let tapRecognizer = UITapGestureRecognizer(
|
|
target: self,
|
|
action: #selector(openAppTapped(_:))
|
|
)
|
|
view.addGestureRecognizer(tapRecognizer)
|
|
|
|
mapView
|
|
.register(
|
|
EQNCustomAnnotationView.self,
|
|
forAnnotationViewWithReuseIdentifier: EQNCustomAnnotationView.SingleLineIdentifier
|
|
)
|
|
mapView
|
|
.register(
|
|
EQNCustomAnnotationView.self,
|
|
forAnnotationViewWithReuseIdentifier: EQNCustomAnnotationView.SmallIdentifier
|
|
)
|
|
tapToOpenButton.setTitle("tap_to_open".localized, for: .normal)
|
|
}
|
|
|
|
override func viewWillDisappear(_ animated: Bool) {
|
|
super.viewWillDisappear(animated)
|
|
|
|
animator?.stop()
|
|
}
|
|
|
|
// MARK: - Actions
|
|
|
|
@IBAction private func openAppTapped(_ sender: Any) {
|
|
extensionContext?.performNotificationDefaultAction()
|
|
}
|
|
}
|
|
|
|
extension NotificationContentViewController: UNNotificationContentExtension {
|
|
|
|
func didReceive(_ notification: UNNotification) {
|
|
let content = notification.request.content
|
|
|
|
titleLabel.text = content.title
|
|
descriptionLabel.text = content.body
|
|
|
|
let notification = EQNRealtimePushNotification.from(
|
|
userInfo: content.userInfo,
|
|
title: "",
|
|
displayTitle: content.title,
|
|
displayBody: content.body
|
|
)
|
|
if let notification {
|
|
let coordinate = notification.coordinate.coordinate
|
|
let span = MKCoordinateSpan(latitudeDelta: 6, longitudeDelta: 6)
|
|
let region = MKCoordinateRegion(
|
|
center: coordinate,
|
|
span: span
|
|
)
|
|
mapView.setCenter(coordinate, animated: false)
|
|
mapView.setRegion(region, animated: true)
|
|
|
|
switch notification.type.lowercased() {
|
|
case "eqn":
|
|
let annotation = EQNMapAnnotationPastquake(
|
|
title: "",
|
|
coordinate: coordinate,
|
|
intensity: notification.intensity
|
|
)
|
|
mapView.addAnnotation(annotation)
|
|
case "manual":
|
|
let annotation = EQNMapAnnotationUserReport(
|
|
magnitude: notification.magnitude,
|
|
coordinate: coordinate
|
|
)
|
|
mapView.addAnnotation(annotation)
|
|
default:
|
|
break
|
|
}
|
|
|
|
// create animator to manage wave animation and countdown
|
|
animator = MapSeismicWaveAnimator(
|
|
realtimeAlert: notification,
|
|
mapView: mapView,
|
|
waveTimeLabel: waveLabel
|
|
)
|
|
animator?.start()
|
|
// set color based on intensity
|
|
descriptionLabel.textColor = notification.relativeIntensityColor
|
|
}
|
|
}
|
|
}
|
|
|
|
extension NotificationContentViewController: MKMapViewDelegate {
|
|
|
|
func mapView(_ mapView: MKMapView, viewFor annotation: any MKAnnotation) -> MKAnnotationView? {
|
|
switch annotation {
|
|
case let pastquake as EQNMapAnnotationPastquake:
|
|
let annotationView = mapView.dequeueReusableAnnotationView(
|
|
withIdentifier: EQNCustomAnnotationView.SingleLineIdentifier
|
|
) as! EQNCustomAnnotationView
|
|
annotationView.image = pastquake.image
|
|
annotationView.title = pastquake.title
|
|
return annotationView
|
|
case let report as EQNMapAnnotationUserReport:
|
|
let annotationView = mapView.dequeueReusableAnnotationView(
|
|
withIdentifier: EQNCustomAnnotationView.SmallIdentifier
|
|
) as! EQNCustomAnnotationView
|
|
annotationView.image = report.image(with: EQNCustomAnnotationView.SmallViewImageHeight)
|
|
annotationView.title = report.timeDifference
|
|
return annotationView
|
|
default:
|
|
return nil
|
|
}
|
|
}
|
|
|
|
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
|
|
animator?.getOverlayRenderer(for: overlay) ?? MKOverlayRenderer(overlay: overlay)
|
|
}
|
|
}
|