diff --git a/Sources/EQNNotificationService/NotificationService.swift b/Sources/EQNNotificationService/NotificationService.swift index 7976649..066e4f1 100644 --- a/Sources/EQNNotificationService/NotificationService.swift +++ b/Sources/EQNNotificationService/NotificationService.swift @@ -59,13 +59,23 @@ class NotificationService: UNNotificationServiceExtension { return } + let magnitude = userInfo.double(forKey: "mag") ?? 0 let location = CLLocation(latitude: latitude, longitude: longitude) guard let distance = EQNUserData.shared.lastLocation?.distance(from: location) else { print("[NotificationService] Unable to calculate distance or get last location") return } - + let distanceKm = distance / 1_000 + + // If the shake is mild, user can disale sound and use default notification sound + // This logic is done here and not with the rest because distance and other informations are needed + let mildQuakeSoundDisabled = UserDefaults.appGroup?.bool(forKey: UserDefaults.AllertaSismicaSuonoDisabilitatoSismaDebole) ?? true + let isMildQuake = isMildQuake(magnitude: magnitude, distance: distanceKm) + if isMildQuake && mildQuakeSoundDisabled { + bestAttemptContent.sound = UNNotificationSound.default + } + let intensita = peak * exp(-distanceKm/peak/250) let stringSuffix = if intensita < 0.004 { "no_shaking" @@ -165,6 +175,20 @@ class NotificationService: UNNotificationServiceExtension { } } + private func isMildQuake( + magnitude: Double, + distance: Double + ) -> Bool { + var intensity_at_location: Double = 0 + if distance > 0 { + let R: Double = 6371 + let eq_depth: Double = 10.0 + let hyp_distance = sqrt(pow(eq_depth, 2) + 4 * R * (R - eq_depth) * pow(sin(distance / (2 * R)), 2)) + intensity_at_location = -2.15 * log10(hyp_distance) + 1.0 * magnitude + 2.31 + } + return intensity_at_location < 3 + } + // MARK: - Helpers private func manualIconName(for provider: String, color: String) -> String { diff --git a/Sources/Earthquake Network/Constants.swift b/Sources/Earthquake Network/Constants.swift index 1d022bc..ab37066 100644 --- a/Sources/Earthquake Network/Constants.swift +++ b/Sources/Earthquake Network/Constants.swift @@ -17,6 +17,7 @@ extension UserDefaults { // Impostazioni della sezione `Allerta in tempo reale` static let AllertaSismicaAbilitato = "NOTIFICHE_ALLERA_SISMICA_ABILITATO" + static let AllertaSismicaSuonoDisabilitatoSismaDebole = "NOTIFICHE_ALLERA_SISMICA_SUONO_DISABILITATO_SISMA_DEBOLE" static let AllertaSismicaCriticalAlerts = "NOTIFICHE_ALLERA_SISMICA_CRITICAL_ALERTS" static let AllertaSismicaSismiDaNotificare = "NOTIFICHE_ALLERA_SISMICA_SISMI_DA_NOTIFICARE" static let AllertaSismicaRaggioSismiLievi = "NOTIFICHE_ALLERA_SISMICA_RAGGIO_SISMI_LIEVI" @@ -69,6 +70,7 @@ extension UserDefaults { static let AppMigrationV5_8 = "EQNUserDefaultMigrationV5_8" static let AppMigrationV5_8_2 = "EQNUserDefaultMigrationV5_8_2" static let AppMigrationV5_9 = "EQNUserDefaultMigrationV5_9" + static let AppMigrationV5_10 = "EQNUserDefaultMigrationV5_10" static let SettingsSeismicNetworkNotificationMigrationV5_8 = "EQNUserDefaultSettingsSeismicNetworkNotificationMigrationV5_8" static let SettingsUserReportNotificationMigrationV5_8 = "EQNUserDefaultSettingsUserReportNotificationMigrationV5_8" diff --git a/Sources/Earthquake Network/Controllers/Settings/SettingsRealTimeAlertsViewController.swift b/Sources/Earthquake Network/Controllers/Settings/SettingsRealTimeAlertsViewController.swift index 0d0e594..8fd2d13 100644 --- a/Sources/Earthquake Network/Controllers/Settings/SettingsRealTimeAlertsViewController.swift +++ b/Sources/Earthquake Network/Controllers/Settings/SettingsRealTimeAlertsViewController.swift @@ -13,14 +13,17 @@ class SettingsRealTimeAlertsViewController: SettingsBaseTableViewController { private enum RowIdentifier: Int { case abilitaNotifiche + case disabilitaSuonoAllerta case abilitaCriticalAlerts } private var isNotificationEnabled = false + private var isMildQuakeSoundDisabled = false private var isCriticalAlertsEnabled = false private let settings: [SettingItem] = [ .init(type: .enable, title: NSLocalizedString("options_notification_enable_alarm", comment: "")), + .init(type: .enable, title: NSLocalizedString("options_notification_disable_sound", comment: "")), .init(type: .enable, title: NSLocalizedString("critical_alerts_setting", comment: "")) ] @@ -56,6 +59,7 @@ class SettingsRealTimeAlertsViewController: SettingsBaseTableViewController { let saved = EQNSettingRealTimeAlert.shared isNotificationEnabled = saved.isAbilitato + isMildQuakeSoundDisabled = saved.isMildQuakeSoundDisabled isCriticalAlertsEnabled = saved.isCriticalAlertsEnabled } @@ -93,6 +97,11 @@ class SettingsRealTimeAlertsViewController: SettingsBaseTableViewController { cell.valueChanged = { [weak self] enabled in self?.onChangeNotificationEnabled(enabled) } + case .disabilitaSuonoAllerta: + cell.toggleSwitch.isOn = isMildQuakeSoundDisabled + cell.valueChanged = { [weak self] enabled in + self?.onChangeDisableSoundEnabled(enabled) + } case .abilitaCriticalAlerts: cell.toggleSwitch.isOn = isCriticalAlertsEnabled cell.valueChanged = { [weak self] enabled in @@ -116,6 +125,14 @@ class SettingsRealTimeAlertsViewController: SettingsBaseTableViewController { tableView.reloadData() } + private func onChangeDisableSoundEnabled(_ enabled: Bool) { + isMildQuakeSoundDisabled = enabled + EQNSettingRealTimeAlert.shared.isMildQuakeSoundDisabled = isMildQuakeSoundDisabled + EQNSettingRealTimeAlert.shared.saveUserInfo() + + tableView.reloadData() + } + private func onChangeCriticalAlertsEnabled(_ enabled: Bool) { if enabled { askForCriticalAlertsPermission() diff --git a/Sources/Earthquake Network/Models/Commands/EQNUserDefaultsCommand.swift b/Sources/Earthquake Network/Models/Commands/EQNUserDefaultsCommand.swift index 8342d42..7beb8fa 100644 --- a/Sources/Earthquake Network/Models/Commands/EQNUserDefaultsCommand.swift +++ b/Sources/Earthquake Network/Models/Commands/EQNUserDefaultsCommand.swift @@ -21,6 +21,7 @@ public class EQNUserDefaultsCommand: EQNCommandProtocol { migrationFirstAppStat() migrationCriticalAlerts() migrationV5_9() + migrationV5_10() } // MARK: - Private @@ -119,4 +120,19 @@ public class EQNUserDefaultsCommand: EQNCommandProtocol { userDefaults.set(true, forKey: UserDefaults.AppMigrationV5_9) } + + private func migrationV5_10() { + let userDefaults = UserDefaults.standard + let migrationPerformed = userDefaults.bool(forKey: UserDefaults.AppMigrationV5_10) + if migrationPerformed { + print("[EQNUserDefaultsCommand] Migration v5.10 already performed") + return + } + + print("[EQNUserDefaultsCommand] Save default value for mildQuakeSoundDisabled") + EQNSettingRealTimeAlert.shared.isMildQuakeSoundDisabled = true + EQNSettingRealTimeAlert.shared.saveUserInfo() + + userDefaults.set(true, forKey: UserDefaults.AppMigrationV5_10) + } } diff --git a/Sources/Earthquake Network/Models/Settings/EQNSettingRealTimeAlert.swift b/Sources/Earthquake Network/Models/Settings/EQNSettingRealTimeAlert.swift index 58917ee..c45b8a8 100644 --- a/Sources/Earthquake Network/Models/Settings/EQNSettingRealTimeAlert.swift +++ b/Sources/Earthquake Network/Models/Settings/EQNSettingRealTimeAlert.swift @@ -16,6 +16,7 @@ class EQNSettingRealTimeAlert: NSObject { static let shared = EQNSettingRealTimeAlert() @objc var isAbilitato: Bool + var isMildQuakeSoundDisabled: Bool var isCriticalAlertsEnabled: Bool var sismiDaNotificare: String @@ -38,6 +39,7 @@ class EQNSettingRealTimeAlert: NSObject { let sharedDefaults = UserDefaults.appGroup isCriticalAlertsEnabled = sharedDefaults?.bool(forKey: UserDefaults.AllertaSismicaCriticalAlerts) ?? false + isMildQuakeSoundDisabled = sharedDefaults?.bool(forKey: UserDefaults.AllertaSismicaSuonoDisabilitatoSismaDebole) ?? true } // MARK: - Public @@ -50,12 +52,14 @@ class EQNSettingRealTimeAlert: NSObject { defaults.set(raggioSismiForti, forKey: UserDefaults.AllertaSismicaRaggioSismiForti) if let sharedDefaults = UserDefaults.appGroup { sharedDefaults.set(isCriticalAlertsEnabled, forKey: UserDefaults.AllertaSismicaCriticalAlerts) + sharedDefaults.set(isMildQuakeSoundDisabled, forKey: UserDefaults.AllertaSismicaSuonoDisabilitatoSismaDebole) } } @objc class func saveDefaultValues() { shared.isAbilitato = true shared.isCriticalAlertsEnabled = false + shared.isMildQuakeSoundDisabled = true shared.sismiDaNotificare = Self.DefaultSismiDaNotificare shared.raggioSismiLievi = Self.DefaultRaggioSismiLievi shared.raggioSismiForti = Self.DefaultRaggioSismiForti diff --git a/Sources/Earthquake Network/ar.lproj/Localizable.strings b/Sources/Earthquake Network/ar.lproj/Localizable.strings index da280fa..f335888 100644 --- a/Sources/Earthquake Network/ar.lproj/Localizable.strings +++ b/Sources/Earthquake Network/ar.lproj/Localizable.strings @@ -77,6 +77,7 @@ "status_cancel" = "ألغي"; "options_alarms" = "تنبيه بوقت فعلي"; "options_notification_enable_alarm" = "قم بتفعيل الإنذار عند اكتشاف زلزال في الوقت الفعلي بواسطة شبكة الهواتف الذكية"; +"options_notification_disable_sound" = "قم بتعطيل صوت المنبه إذا كان الاهتزاز في موقعك خفيفًا"; "options_notification_official" = "إخطارات الشبكة الزلزالية"; "options_notification_enable_official" = "تلقي إشعارات بشأن الزلازل التي اكتشفتها شبكات الزلازل الوطنية والدولية"; "options_official_type" = "مرشح الإشعارات"; diff --git a/Sources/Earthquake Network/el-GR.lproj/Localizable.strings b/Sources/Earthquake Network/el-GR.lproj/Localizable.strings index 0b3c2dc..30b1639 100644 --- a/Sources/Earthquake Network/el-GR.lproj/Localizable.strings +++ b/Sources/Earthquake Network/el-GR.lproj/Localizable.strings @@ -77,6 +77,7 @@ "status_cancel" = "Διαγραφή"; "options_alarms" = "Ειδοποίηση σε πραγματικό χρόνο"; "options_notification_enable_alarm" = "Να ακούγεται συναγερμός όταν ανιχνεύεται σεισμός σε πραγματικό χρόνο από το δίκτυο smartphone"; +"options_notification_disable_sound" = "Απενεργοποιήστε τον ήχο συναγερμού εάν το κούνημα στην τοποθεσία σας είναι ήπιο"; "options_notification_official" = "Κοινοποιήσεις σεισμικών δικτύων"; "options_notification_enable_official" = "Λήψη ειδοποιήσεων για τους σεισμούς που εντοπίζονται από τα εθνικά και διεθνή σεισμικά δίκτυα"; "options_official_type" = "Φίλτρο ειδοποιήσεων"; diff --git a/Sources/Earthquake Network/en.lproj/Localizable.strings b/Sources/Earthquake Network/en.lproj/Localizable.strings index 8b9dd2a..22e092f 100644 --- a/Sources/Earthquake Network/en.lproj/Localizable.strings +++ b/Sources/Earthquake Network/en.lproj/Localizable.strings @@ -77,6 +77,7 @@ "status_cancel" = "Cancel"; "options_alarms" = "Real time alert"; "options_notification_enable_alarm" = "Activate an alarm when a quake is detected in real time by the network of smartphones"; +"options_notification_disable_sound" = "Disable the alarm sound if the shaking at your location is mild"; "options_notification_official" = "Seismic network notifications"; "options_notification_enable_official" = "Receive notifications for the earthquakes detected by the national and international seismic networks"; "options_official_type" = "Notification filter"; diff --git a/Sources/Earthquake Network/es.lproj/Localizable.strings b/Sources/Earthquake Network/es.lproj/Localizable.strings index e8fbba0..e8d21aa 100644 --- a/Sources/Earthquake Network/es.lproj/Localizable.strings +++ b/Sources/Earthquake Network/es.lproj/Localizable.strings @@ -77,6 +77,7 @@ "status_cancel" = "Clara"; "options_alarms" = "Alerta en tiempo real"; "options_notification_enable_alarm" = "Suena una alarma cuando se detecta un sismo en tiempo real por la red de los teléfonos inteligentes"; +"options_notification_disable_sound" = "Desactive el sonido de la alarma si el sismo en tu ubicación es leve"; "options_notification_official" = "Notificaciones redes sísmicas"; "options_notification_enable_official" = "Recibe las notificaciones de los sismos detectados por las redes sísmicas nacionales e internacionales"; "options_official_type" = "Filtro de notificaciones"; diff --git a/Sources/Earthquake Network/fr.lproj/Localizable.strings b/Sources/Earthquake Network/fr.lproj/Localizable.strings index 3713ac5..95129f2 100644 --- a/Sources/Earthquake Network/fr.lproj/Localizable.strings +++ b/Sources/Earthquake Network/fr.lproj/Localizable.strings @@ -77,6 +77,7 @@ "status_cancel" = "Supprimer"; "options_alarms" = "Alerte en temps réel"; "options_notification_enable_alarm" = "Une alarme retentit lorsqu'un séisme est détecté par le réseau des smartphones"; +"options_notification_disable_sound" = "Désactivez le son de l'alarme si les secousses à votre emplacement sont légères"; "options_notification_official" = "Notifications de réseaux sismiquex"; "options_notification_enable_official" = "Recevez les notifications des séismes détectés par les réseaux sismiques nationaux et internationaux"; "options_official_type" = "Filtre de notificatio"; diff --git a/Sources/Earthquake Network/hr-HR.lproj/Localizable.strings b/Sources/Earthquake Network/hr-HR.lproj/Localizable.strings index 954079c..fb1ba0a 100644 --- a/Sources/Earthquake Network/hr-HR.lproj/Localizable.strings +++ b/Sources/Earthquake Network/hr-HR.lproj/Localizable.strings @@ -77,6 +77,7 @@ "status_cancel" = "Poništi"; "options_alarms" = "Upozorenje u stvarnom vremenu"; "options_notification_enable_alarm" = "Aktiviraj alarm kada mreža pametnih telefona u stvarnom vremenu otkrije potres"; +"options_notification_disable_sound" = "Onemogućite zvuk alarma ako je podrhtavanje na vašoj lokaciji blago"; "options_notification_official" = "Obavijesti o seizmološkim mrežama"; "options_notification_enable_official" = "Primajte obavijesti o potresima koje su otkrile nacionalne i međunarodne seizmičke mreže"; "options_official_type" = "Filter obavijesti"; diff --git a/Sources/Earthquake Network/id-ID.lproj/Localizable.strings b/Sources/Earthquake Network/id-ID.lproj/Localizable.strings index 1431336..0fc758c 100644 --- a/Sources/Earthquake Network/id-ID.lproj/Localizable.strings +++ b/Sources/Earthquake Network/id-ID.lproj/Localizable.strings @@ -77,6 +77,7 @@ "status_cancel" = "Batal"; "options_alarms" = "Peringatan real time"; "options_notification_enable_alarm" = "Nyalakan alarm saat gempa terdeteksi secara real time oleh jaringan smartphone"; +"options_notification_disable_sound" = "Nonaktifkan suara alarm jika guncangan di lokasi Anda ringan"; "options_notification_official" = "Pemberitahuan jaringan seismik"; "options_notification_enable_official" = "Terima pemberitahuan untuk gempa bumi yang terdeteksi oleh jaringan seismik nasional dan internasional"; "options_official_type" = "Filter notifikasi"; diff --git a/Sources/Earthquake Network/it.lproj/Localizable.strings b/Sources/Earthquake Network/it.lproj/Localizable.strings index 6061245..584e7ce 100644 --- a/Sources/Earthquake Network/it.lproj/Localizable.strings +++ b/Sources/Earthquake Network/it.lproj/Localizable.strings @@ -77,6 +77,7 @@ "status_cancel" = "Cancella"; "options_alarms" = "Allerta in tempo reale"; "options_notification_enable_alarm" = "Attiva un allarme quando un sisma è rilevato dalla rete smartphone"; +"options_notification_disable_sound" = "Disabilita il suono di allerta se l'intensità del sisma nella tua zona è debole"; "options_notification_official" = "Notifiche da reti sismiche"; "options_notification_enable_official" = "Ricevi notifiche per i sismi rilevati dalle reti sismiche nazionali e internazionali"; "options_official_type" = "Filtro notifiche"; diff --git a/Sources/Earthquake Network/tr-TR.lproj/Localizable.strings b/Sources/Earthquake Network/tr-TR.lproj/Localizable.strings index e0af1c4..e38847d 100644 --- a/Sources/Earthquake Network/tr-TR.lproj/Localizable.strings +++ b/Sources/Earthquake Network/tr-TR.lproj/Localizable.strings @@ -77,6 +77,7 @@ "status_cancel" = "İptal et"; "options_alarms" = "Gerçek zamanlı uyarı"; "options_notification_enable_alarm" = "Bir deprem akıllı telefon ağı tarafından gerçek zamanlı olarak tespit edildiğinde bir alarm çal"; +"options_notification_disable_sound" = "Bulunduğunuz yerdeki sarsıntı hafifse alarm sesini devre dışı bırakın"; "options_notification_official" = "Sismik ağ bildirimleri"; "options_notification_enable_official" = "Ulusal ve uluslararası sismik ağlar tarafından tespit edilen depremler için bildirim alın"; "options_official_type" = "Bildirim filtresi";