Compare commits
39 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6be5f72360 | |||
| ccd1b9de59 | |||
| 5737eb5b02 | |||
| c549bb6ea5 | |||
| ff80905033 | |||
| dad2bc5648 | |||
| 10c74e278e | |||
| 96dbf960d2 | |||
| 81bfdd02a6 | |||
| 2ab3267981 | |||
| 48b6941ed5 | |||
| 669cb3c4f3 | |||
| 638d819d35 | |||
| a9884d8a8d | |||
| 2ef3560011 | |||
| 05093bb7a4 | |||
| 55f84ab46d | |||
| 03b4d0ddd6 | |||
| 3c5f26bc94 | |||
| 8c79d45b19 | |||
| 931d04c5e1 | |||
| 4d62fbbbd3 | |||
| 1c7065ece7 | |||
| 6dfa51e013 | |||
| b8b21d1458 | |||
| 88317f79e8 | |||
| 4e1147e782 | |||
| 579969d507 | |||
| 4d991d9a10 | |||
| 41491b5ee7 | |||
| 197b375c28 | |||
| f41e6b50ec | |||
| 796e4b5895 | |||
| e43a93979d | |||
| ef1aaa7d71 | |||
| 22d78baa8a | |||
| e4588aa731 | |||
| 07764f91ed | |||
| a0a238e384 |
@@ -1,5 +1,9 @@
|
||||
# Changelog
|
||||
|
||||
## Versione 5.8.1
|
||||
- Corrette traduzioni errate (causavano crash)
|
||||
- Aggiunto ordinamento in sottoscrizioni utente (prima Top10k)
|
||||
|
||||
## Versione 5.8
|
||||
- Modifica algoritmo filtro lista (issue #70)
|
||||
- Modifica impostazioni "Notifiche da reti sismiche" (issue #66)
|
||||
|
||||
@@ -1,32 +1,34 @@
|
||||
{
|
||||
"Simulator Target Bundle": "com.finazzi.distquake",
|
||||
"magnitude_range" : "0",
|
||||
"provider" : "SGC",
|
||||
"google.c.a.e" : "1",
|
||||
"google.c.fid" : "d3PS1dEvrUA-tmLLpl5E5f",
|
||||
"provider" : "INGV",
|
||||
"google.c.fid" : "fFjFx_Em8E-op_zHYXZpSr",
|
||||
"preliminary" : "0",
|
||||
"longitude" : "-75.5157",
|
||||
"gcm.message_id" : "1668682445010677",
|
||||
"latitude" : "4.35306",
|
||||
"type" : "official",
|
||||
"longitude" : "15.2917",
|
||||
"gcm.message_id" : "1719991146578422",
|
||||
"latitude" : "40.7738",
|
||||
"google.c.sender.id" : "899482329945",
|
||||
"difference" : "6",
|
||||
"data" : "2022-11-17 11:48:00",
|
||||
"depth" : "26",
|
||||
"type" : "official",
|
||||
"magnitude" : "1.4",
|
||||
"difference" : "13",
|
||||
"depth" : "14.6",
|
||||
"aps" : {
|
||||
"content-available" : 1,
|
||||
"mutable-content" : 1,
|
||||
"alert" : {
|
||||
"loc-key" : "Sisma rilevato a",
|
||||
"body" : "Sisma rilevato a",
|
||||
"title-loc-key" : "Segnalazione da rete sismica",
|
||||
"title" : "Segnalazione da rete sismica",
|
||||
"loc-key" : "Sisma rilevato a",
|
||||
"action-loc-key" : "",
|
||||
"loc-args" : [
|
||||
"Cajamarca - Tolima, Colombia - M2.2"
|
||||
"2 km SW Laviano (SA) - M1.4"
|
||||
]
|
||||
},
|
||||
"mutable-content" : 1,
|
||||
"content-available" : 1,
|
||||
"sound" : "default"
|
||||
},
|
||||
"magnitude" : "2.2",
|
||||
"magnitude_type" : "M",
|
||||
"place" : "Cajamarca - Tolima, Colombia",
|
||||
"pop100" : "6622"
|
||||
"data" : "2024-07-03 09:05:52",
|
||||
"magnitude_type" : "ML",
|
||||
"place" : "2 km SW Laviano (SA)",
|
||||
"pop100" : "6824"
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
"loc-args": [
|
||||
"2 km da Foligno"
|
||||
],
|
||||
"loc-key": "Rilevato sisma forte a",
|
||||
"loc-key": "Sisma segnalato da utente a",
|
||||
"title-loc-key": "Allerta sismica in tempo reale"
|
||||
},
|
||||
"category": "notifica_con_mappa",
|
||||
|
||||
@@ -97,23 +97,8 @@ class NotificationService: UNNotificationServiceExtension {
|
||||
// use a generic warning icon instead
|
||||
iconName = "warning_yellow.png"
|
||||
case "official":
|
||||
let provider = userInfo.string(forKey: "provider", orDefault: "")
|
||||
let intensity = userInfo.double(forKey: "magnitude", orDefault: 0)
|
||||
|
||||
let color: String
|
||||
if intensity < 2.0 {
|
||||
color = "_white"
|
||||
} else if intensity < 3.5 {
|
||||
color = "_green"
|
||||
} else if intensity < 4.5 {
|
||||
color = "_yellow"
|
||||
} else if intensity < 5.5 {
|
||||
color = "_red"
|
||||
} else {
|
||||
color = "_purple"
|
||||
}
|
||||
|
||||
iconName = manualIconName(for: provider, color: color)
|
||||
// don't show any images
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
@@ -45,8 +45,8 @@
|
||||
658BAB7B25FE67930015C454 /* EQNBaseMapRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 658BAB7A25FE67930015C454 /* EQNBaseMapRepresentable.swift */; };
|
||||
658BC0292859A456009EECAA /* RealtimeAlertViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 658BC0282859A456009EECAA /* RealtimeAlertViewController.swift */; };
|
||||
658BC02B2859A4D3009EECAA /* RealtimeAlertView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 658BC02A2859A4D3009EECAA /* RealtimeAlertView.swift */; };
|
||||
6590EFF82C3004EA00F41420 /* EQNOfficialPushNotification.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6590EFF72C3004EA00F41420 /* EQNOfficialPushNotification.swift */; };
|
||||
65AB4A952C11BED400950DF7 /* SettingsSeismicNetworkNotificationsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65AB4A942C11BED400950DF7 /* SettingsSeismicNetworkNotificationsViewController.swift */; };
|
||||
65AB4A972C11DEB300950DF7 /* SettingsSeismicNetworkNotificationsFilterViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65AB4A962C11DEB300950DF7 /* SettingsSeismicNetworkNotificationsFilterViewController.swift */; };
|
||||
65AB4A992C11DFC200950DF7 /* EQNSettingSeismicNetworkNotification.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65AB4A982C11DFC200950DF7 /* EQNSettingSeismicNetworkNotification.swift */; };
|
||||
65AD23CE261B03D400E3B57C /* SubscriptionsDescriptionTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65AD23CD261B03D400E3B57C /* SubscriptionsDescriptionTableViewCell.swift */; };
|
||||
65B16E1E2BDFA88D0020527E /* Solar in Frameworks */ = {isa = PBXBuildFile; productRef = 65B16E1D2BDFA88D0020527E /* Solar */; };
|
||||
@@ -246,7 +246,6 @@
|
||||
DC99A50324E66E270071BC9F /* EQNCommandProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC99A50224E66E270071BC9F /* EQNCommandProtocol.swift */; };
|
||||
DC99A50524E66E430071BC9F /* EQNAppearanceCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC99A50424E66E430071BC9F /* EQNAppearanceCommand.swift */; };
|
||||
DC99A50724E66E5F0071BC9F /* EQNStartupCommandsBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC99A50624E66E5F0071BC9F /* EQNStartupCommandsBuilder.swift */; };
|
||||
DCA5B6E7252E4BD8002AEC96 /* EQNBaseTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCA5B6E6252E4BD8002AEC96 /* EQNBaseTableViewCell.swift */; };
|
||||
DCAA913F24F68A1D00145A3D /* SettingMultivaluesTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCAA913E24F68A1D00145A3D /* SettingMultivaluesTableViewCell.swift */; };
|
||||
DCB28CEE24FB8400001F557E /* SettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCB28CED24FB8400001F557E /* SettingsViewController.swift */; };
|
||||
DCB528212560161C005288E5 /* AlertSimulatorViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCB528202560161C005288E5 /* AlertSimulatorViewController.swift */; };
|
||||
@@ -345,6 +344,7 @@
|
||||
658BC02A2859A4D3009EECAA /* RealtimeAlertView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RealtimeAlertView.swift; sourceTree = "<group>"; };
|
||||
658F19692A0D1F8F00BECC05 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
658F196A2A0D1F8F00BECC05 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
6590EFF72C3004EA00F41420 /* EQNOfficialPushNotification.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EQNOfficialPushNotification.swift; sourceTree = "<group>"; };
|
||||
65A4D5AA26280A24003918E0 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
65A4D5AB26280A24003918E0 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
65A4D5AC26280A56003918E0 /* el-GR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "el-GR"; path = "el-GR.lproj/InfoPlist.strings"; sourceTree = "<group>"; };
|
||||
@@ -356,7 +356,6 @@
|
||||
65A4D5B526281126003918E0 /* id-ID */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "id-ID"; path = "id-ID.lproj/InfoPlist.strings"; sourceTree = "<group>"; };
|
||||
65A4D5B626281126003918E0 /* id-ID */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "id-ID"; path = "id-ID.lproj/Localizable.strings"; sourceTree = "<group>"; };
|
||||
65AB4A942C11BED400950DF7 /* SettingsSeismicNetworkNotificationsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsSeismicNetworkNotificationsViewController.swift; sourceTree = "<group>"; };
|
||||
65AB4A962C11DEB300950DF7 /* SettingsSeismicNetworkNotificationsFilterViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsSeismicNetworkNotificationsFilterViewController.swift; sourceTree = "<group>"; };
|
||||
65AB4A982C11DFC200950DF7 /* EQNSettingSeismicNetworkNotification.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EQNSettingSeismicNetworkNotification.swift; sourceTree = "<group>"; };
|
||||
65AD23CD261B03D400E3B57C /* SubscriptionsDescriptionTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscriptionsDescriptionTableViewCell.swift; sourceTree = "<group>"; };
|
||||
65BBB22B26064BE6005D6CDF /* SegnalazioniLast24HoursCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SegnalazioniLast24HoursCell.swift; sourceTree = "<group>"; };
|
||||
@@ -574,7 +573,6 @@
|
||||
DC99A50224E66E270071BC9F /* EQNCommandProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EQNCommandProtocol.swift; sourceTree = "<group>"; };
|
||||
DC99A50424E66E430071BC9F /* EQNAppearanceCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EQNAppearanceCommand.swift; sourceTree = "<group>"; };
|
||||
DC99A50624E66E5F0071BC9F /* EQNStartupCommandsBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EQNStartupCommandsBuilder.swift; sourceTree = "<group>"; };
|
||||
DCA5B6E6252E4BD8002AEC96 /* EQNBaseTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EQNBaseTableViewCell.swift; sourceTree = "<group>"; };
|
||||
DCAA913E24F68A1D00145A3D /* SettingMultivaluesTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingMultivaluesTableViewCell.swift; sourceTree = "<group>"; };
|
||||
DCB28CED24FB8400001F557E /* SettingsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewController.swift; sourceTree = "<group>"; };
|
||||
DCB528202560161C005288E5 /* AlertSimulatorViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertSimulatorViewController.swift; sourceTree = "<group>"; };
|
||||
@@ -1114,6 +1112,7 @@
|
||||
8CF4F4DA216D44930057110B /* EQNPastquakes.m */,
|
||||
65EA58812A60360D0038EE9D /* EQNRealtimePushNotification.swift */,
|
||||
6552C1452926DBA1008E723C /* AppPreferences.swift */,
|
||||
6590EFF72C3004EA00F41420 /* EQNOfficialPushNotification.swift */,
|
||||
);
|
||||
path = Models;
|
||||
sourceTree = "<group>";
|
||||
@@ -1141,13 +1140,12 @@
|
||||
DCC23DED24D28F41003A2404 /* UI */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
DC52B8A424FCCD6900ABEBA6 /* AppTheme.swift */,
|
||||
DCC23DEE24D28F58003A2404 /* EQNEdgeInsetLabel.swift */,
|
||||
DC03BEAA250BC0A60084769B /* EQNRoundedButton.swift */,
|
||||
DC52B8A424FCCD6900ABEBA6 /* AppTheme.swift */,
|
||||
DCA5B6E6252E4BD8002AEC96 /* EQNBaseTableViewCell.swift */,
|
||||
6586971025F44C26009C0182 /* EQNBlurredCloseButton.swift */,
|
||||
656E02152C1C4DF2008D0E92 /* EQNBaseContainerTableViewCell.swift */,
|
||||
653C67E125F3CC2E00FE52AC /* EQNCustomAnnotationView.swift */,
|
||||
6586971025F44C26009C0182 /* EQNBlurredCloseButton.swift */,
|
||||
65172F522C25C496006D2A5C /* EQNSeismicAnnotationView.swift */,
|
||||
);
|
||||
path = UI;
|
||||
@@ -1175,7 +1173,6 @@
|
||||
65DB60EF2C16F5B100164366 /* SettingsBaseTableViewController.swift */,
|
||||
65DB60F92C17158D00164366 /* SettingsUserReportNotificationsViewController.swift */,
|
||||
65AB4A942C11BED400950DF7 /* SettingsSeismicNetworkNotificationsViewController.swift */,
|
||||
65AB4A962C11DEB300950DF7 /* SettingsSeismicNetworkNotificationsFilterViewController.swift */,
|
||||
65DB60F12C16FA3600164366 /* SettingsRealTimeAlertsViewController.swift */,
|
||||
);
|
||||
path = Settings;
|
||||
@@ -1574,8 +1571,8 @@
|
||||
6562C80725FFA6B100C85273 /* SeismicNetworkViewModel.swift in Sources */,
|
||||
DCDE0BD924E58CCE00209778 /* EQNMainTabBarController.m in Sources */,
|
||||
8C4E344B2152EE5B008B0D2A /* EQNGeneratoreURLServer.m in Sources */,
|
||||
6590EFF82C3004EA00F41420 /* EQNOfficialPushNotification.swift in Sources */,
|
||||
DC99A50724E66E5F0071BC9F /* EQNStartupCommandsBuilder.swift in Sources */,
|
||||
DCA5B6E7252E4BD8002AEC96 /* EQNBaseTableViewCell.swift in Sources */,
|
||||
8CF66058214C566B009F4314 /* ServerRequest.m in Sources */,
|
||||
DCF9E14D24F6D1AA002B6B1D /* EQNData.swift in Sources */,
|
||||
DC52B8A524FCCD6900ABEBA6 /* AppTheme.swift in Sources */,
|
||||
@@ -1607,7 +1604,6 @@
|
||||
65BBB22C26064BE6005D6CDF /* SegnalazioniLast24HoursCell.swift in Sources */,
|
||||
DC47D1BC252A0C2B004119F6 /* AlertsPastEartquakesTableViewCell.swift in Sources */,
|
||||
654D18C925F93CD700BB6DB0 /* EQNMapAnnotationPastquake.swift in Sources */,
|
||||
65AB4A972C11DEB300950DF7 /* SettingsSeismicNetworkNotificationsFilterViewController.swift in Sources */,
|
||||
DCEFF21724F58569009D3FE1 /* SettingSectionHeaderView.swift in Sources */,
|
||||
65DB60FD2C172C4A00164366 /* EQNSettingRealTimeAlert.swift in Sources */,
|
||||
DCBB267A24D1E7F500F04559 /* SubscriptionsHeaderTableViewCell.swift in Sources */,
|
||||
@@ -1777,7 +1773,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
CURRENT_PROJECT_VERSION = 129;
|
||||
CURRENT_PROJECT_VERSION = 136;
|
||||
DEVELOPMENT_TEAM = "";
|
||||
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = WJA4MR4CPC;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
@@ -1794,7 +1790,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 5.8;
|
||||
MARKETING_VERSION = 5.8.1;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.finazzi.distquake.notificationservice;
|
||||
@@ -1819,7 +1815,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Distribution";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
CURRENT_PROJECT_VERSION = 129;
|
||||
CURRENT_PROJECT_VERSION = 136;
|
||||
DEVELOPMENT_TEAM = "";
|
||||
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = WJA4MR4CPC;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
@@ -1832,7 +1828,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 5.8;
|
||||
MARKETING_VERSION = 5.8.1;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.finazzi.distquake.notificationservice;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
@@ -1974,7 +1970,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = "Earthquake Network/Earthquake Network.entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
CURRENT_PROJECT_VERSION = 129;
|
||||
CURRENT_PROJECT_VERSION = 136;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEFINES_MODULE = YES;
|
||||
DEVELOPMENT_TEAM = WJA4MR4CPC;
|
||||
@@ -1985,7 +1981,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 5.8;
|
||||
MARKETING_VERSION = 5.8.1;
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
"-ObjC",
|
||||
@@ -2061,7 +2057,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = "Earthquake Network/Earthquake Network.entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
CURRENT_PROJECT_VERSION = 129;
|
||||
CURRENT_PROJECT_VERSION = 136;
|
||||
DEFINES_MODULE = YES;
|
||||
DEVELOPMENT_TEAM = WJA4MR4CPC;
|
||||
GCC_PREFIX_HEADER = "Earthquake Network/Earthquake Network-Prefix.pch";
|
||||
@@ -2071,7 +2067,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 5.8;
|
||||
MARKETING_VERSION = 5.8.1;
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
"-ObjC",
|
||||
@@ -2144,7 +2140,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = EQNNotificationContent/EQNNotificationContent.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
CURRENT_PROJECT_VERSION = 129;
|
||||
CURRENT_PROJECT_VERSION = 136;
|
||||
DEVELOPMENT_TEAM = WJA4MR4CPC;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
@@ -2159,7 +2155,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 5.8;
|
||||
MARKETING_VERSION = 5.8.1;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.finazzi.distquake.notificationcontent;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "EQNetwork Extension Content - Development";
|
||||
@@ -2178,7 +2174,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = EQNNotificationContent/EQNNotificationContent.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
CURRENT_PROJECT_VERSION = 129;
|
||||
CURRENT_PROJECT_VERSION = 136;
|
||||
DEVELOPMENT_TEAM = WJA4MR4CPC;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"ADS_ENABLED=0",
|
||||
@@ -2191,7 +2187,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 5.8;
|
||||
MARKETING_VERSION = 5.8.1;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.finazzi.distquake.notificationcontent;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "EQNetwork Extension Content - AppStore";
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"originHash" : "702893df2780e15a380fe3df120a583fefc365501dca7487eaf0c2b967baf71c",
|
||||
"originHash" : "c29b9b16ee6b4d1a6fec2debc59749097860256c8cbb2addc2abc08d3adba59d",
|
||||
"pins" : [
|
||||
{
|
||||
"identity" : "abseil-cpp-binary",
|
||||
@@ -42,8 +42,8 @@
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/firebase/firebase-ios-sdk.git",
|
||||
"state" : {
|
||||
"revision" : "e57841b296d04370ea23580f908881b0ccab17b9",
|
||||
"version" : "10.28.1"
|
||||
"revision" : "eca84fd638116dd6adb633b5a3f31cc7befcbb7d",
|
||||
"version" : "10.29.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -170,20 +170,22 @@
|
||||
{
|
||||
NSString *type = content.userInfo[@"type"];
|
||||
|
||||
// Store both original payload and modified title/body
|
||||
// This will be usefull to avoid to re-evaluate logic for title display.
|
||||
NSDictionary *notification = @{
|
||||
@"title": content.title,
|
||||
@"body": content.body,
|
||||
@"userInfo": content.userInfo
|
||||
};
|
||||
|
||||
EQNTabBarSection section = EQNTabBarSectionAllerte;
|
||||
if ([type isEqualToString:@"eqn"]) {
|
||||
// Store both original payload and modified title/body
|
||||
// This will be usefull to avoid to re-evaluate logic for title display.
|
||||
NSDictionary *notification = @{
|
||||
@"title": content.title,
|
||||
@"body": content.body,
|
||||
@"userInfo": content.userInfo
|
||||
};
|
||||
if ([type isEqualToString:@"eqn"]) {
|
||||
[EQNRealtimePushNotification storeNotificationWithPayload:notification];
|
||||
section = EQNTabBarSectionAllerte;
|
||||
} else if([type isEqualToString:@"manual"]) {
|
||||
section = EQNTabBarSectionSegnalazioni;
|
||||
} else if([type isEqualToString:@"official"]) {
|
||||
[EQNOfficialPushNotification storeNotificationWithPayload:notification];
|
||||
section = EQNTabBarSectionRetiSismiche;
|
||||
}
|
||||
|
||||
|
||||
@@ -69,6 +69,8 @@ extension UserDefaults {
|
||||
// Notifica allerta salvata
|
||||
static let RealTimeAlertPayload = "EQNData.RealtimePushNotificationPayload"
|
||||
static let RealTimeAlertDate = "EQNData.RealtimeAlertDate"
|
||||
// Notifica rete sismica aperta
|
||||
static let OfficialAlertPayload = "EQNData.OfficialPushNotificationPayload"
|
||||
|
||||
// Filtri sezioni reti sismiche
|
||||
static let SeismicFilterOption = "EQN_SISMI_TIPOLOGIA_FILTRO"
|
||||
|
||||
@@ -106,7 +106,8 @@ typedef NS_ENUM(NSInteger, AllerteTableRow) {
|
||||
[self.tableView registerClass:[AlertsPriorityServiceTableViewCell class] forCellReuseIdentifier:@"PriorityCell"];
|
||||
[self.tableView registerClass:[AlertsNoLocationTableViewCell class] forCellReuseIdentifier:@"NoLocationCell"];
|
||||
[self.tableView registerClass:[AlertsPastEartquakesTableViewCell class] forCellReuseIdentifier:@"PastEarthquakesCell"];
|
||||
[self.tableView registerClass:[AlertsSeismicNotificationCompactTableViewCell class] forCellReuseIdentifier:@"SeismicNotificationCell"];
|
||||
[self.tableView registerClass:[AlertsSeismicNotificationCompactTableViewCell class] forCellReuseIdentifier:@"SeismicNotificationCompactCell"];
|
||||
[self.tableView registerClass:[AlertsSeismicNotificationExpandedTableViewCell class] forCellReuseIdentifier:@"SeismicNotificationExpandedCell"];
|
||||
[self.tableView registerClass:[AlertsPositionDataTableViewCell class] forCellReuseIdentifier:@"PositionDataCell"];
|
||||
|
||||
if (EQNBackgroundPositionDebugHelper.shared.isEnabled) {
|
||||
@@ -278,7 +279,7 @@ typedef NS_ENUM(NSInteger, AllerteTableRow) {
|
||||
AlertsSeismicNotificationExpandedTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"SeismicNotificationExpandedCell" forIndexPath:indexPath];
|
||||
cell.selectionStyle = UITableViewCellSelectionStyleNone;
|
||||
EQNRealtimePushNotification *notification = [EQNRealtimePushNotification storedNotification];
|
||||
cell.notification = notification;
|
||||
[cell updateWith:notification];
|
||||
|
||||
__weak AllerteViewController *weakSelf = self;
|
||||
cell.onTapClose = ^{
|
||||
@@ -297,7 +298,7 @@ typedef NS_ENUM(NSInteger, AllerteTableRow) {
|
||||
return cell;
|
||||
}
|
||||
|
||||
AlertsSeismicNotificationCompactTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"SeismicNotificationCell" forIndexPath:indexPath];
|
||||
AlertsSeismicNotificationCompactTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"SeismicNotificationCompactCell" forIndexPath:indexPath];
|
||||
cell.selectionStyle = UITableViewCellSelectionStyleNone;
|
||||
|
||||
__weak AllerteViewController *weakSelf = self;
|
||||
|
||||
+3
-2
@@ -12,6 +12,7 @@ import UIKit
|
||||
class AlertsPriorityServiceTableViewCell: EQNBaseContainerTableViewCell {
|
||||
|
||||
override var headerText: String { NSLocalizedString("inapp_list", comment: "") }
|
||||
override var isRightArrowVisbile: Bool { true }
|
||||
|
||||
// MARK: - UI
|
||||
|
||||
@@ -28,7 +29,7 @@ class AlertsPriorityServiceTableViewCell: EQNBaseContainerTableViewCell {
|
||||
let label = UILabel()
|
||||
label.translatesAutoresizingMaskIntoConstraints = false
|
||||
label.numberOfLines = 0
|
||||
label.textColor = AppTheme.Colors.red
|
||||
label.textColor = AppTheme.Colors.pureRed
|
||||
label.font = .preferredFont(forTextStyle: .body)
|
||||
return label
|
||||
}()
|
||||
@@ -54,7 +55,7 @@ class AlertsPriorityServiceTableViewCell: EQNBaseContainerTableViewCell {
|
||||
override func updateUI() {
|
||||
super.updateUI()
|
||||
|
||||
containerView.backgroundColor = AppTheme.Colors.cardBackgroundRed
|
||||
backgroundColor = AppTheme.Colors.cardBackgroundOrange
|
||||
descriptionLabel.text = NSLocalizedString("inapp_adv", comment: "")
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -92,7 +92,7 @@ class AlertsSeismicNotificationCompactTableViewCell: EQNBaseContainerTableViewCe
|
||||
override func updateUI() {
|
||||
super.updateUI()
|
||||
|
||||
containerView.backgroundColor = AppTheme.Colors.cardBackgroundGreen
|
||||
backgroundColor = AppTheme.Colors.cardBackgroundGreen
|
||||
descriptionLabel.text = NSLocalizedString("main_nodetection", comment: "")
|
||||
testAlertButton.setLocalizedTitle(key: "main_alerttest", uppercased: true, emoji: "🚨")
|
||||
simulatorAlertButton.setLocalizedTitle(key: "main_simulator", uppercased: true, emoji: "⏱")
|
||||
|
||||
+152
-58
@@ -10,78 +10,173 @@ import UIKit
|
||||
import MapKit
|
||||
import Shogun
|
||||
|
||||
class AlertsSeismicNotificationExpandedTableViewCell: EQNBaseTableViewCell, MKMapViewDelegate {
|
||||
|
||||
class AlertsSeismicNotificationExpandedTableViewCell: EQNBaseContainerTableViewCell, MKMapViewDelegate {
|
||||
|
||||
override var isHeaderVisible: Bool { false }
|
||||
|
||||
typealias DefaultCompletion = () -> Void
|
||||
|
||||
@objc var notification: EQNRealtimePushNotification? {
|
||||
didSet {
|
||||
updateUI()
|
||||
}
|
||||
}
|
||||
@objc var onTapOpenTwitter: DefaultCompletion?
|
||||
@objc var onTapRateApp: DefaultCompletion?
|
||||
@objc var onTapClose: DefaultCompletion?
|
||||
@objc var onTapShareApp: DefaultCompletion?
|
||||
|
||||
// MARK: - UI
|
||||
|
||||
private lazy var notificationTitleLabel: UILabel = {
|
||||
let label = UILabel()
|
||||
label.translatesAutoresizingMaskIntoConstraints = false
|
||||
label.numberOfLines = 0
|
||||
label.textColor = AppTheme.shared.cardTextColor
|
||||
label.font = .preferredFont(forTextStyle: .title1)
|
||||
label.textAlignment = .center
|
||||
return label
|
||||
}()
|
||||
|
||||
private lazy var notificationIntensityLabel: UILabel = {
|
||||
let label = UILabel()
|
||||
label.translatesAutoresizingMaskIntoConstraints = false
|
||||
label.numberOfLines = 0
|
||||
label.textColor = AppTheme.shared.cardTextColor
|
||||
label.font = .preferredFont(forTextStyle: .title1)
|
||||
label.textAlignment = .center
|
||||
return label
|
||||
}()
|
||||
|
||||
private lazy var notificationDescriptionLabel: UILabel = {
|
||||
let label = UILabel()
|
||||
label.translatesAutoresizingMaskIntoConstraints = false
|
||||
label.numberOfLines = 0
|
||||
label.textColor = AppTheme.shared.cardTextColor
|
||||
label.font = .preferredFont(forTextStyle: .body)
|
||||
label.textAlignment = .center
|
||||
return label
|
||||
}()
|
||||
|
||||
private lazy var mapView: MKMapView = {
|
||||
let mapView = MKMapView()
|
||||
mapView.translatesAutoresizingMaskIntoConstraints = false
|
||||
mapView.delegate = self
|
||||
mapView.isScrollEnabled = false
|
||||
mapView.isZoomEnabled = false
|
||||
mapView.register(EQNCustomAnnotationView.self, forAnnotationViewWithReuseIdentifier: EQNCustomAnnotationView.SingleLineIdentifier)
|
||||
return mapView
|
||||
}()
|
||||
|
||||
private lazy var shareButton: UIButton = {
|
||||
let button = EQNRoundedButton.make(target: self, action: #selector(shareAppTapped(_:)))
|
||||
return button
|
||||
}()
|
||||
|
||||
private lazy var rateAppButton: UIButton = {
|
||||
let button = EQNRoundedButton.make(target: self, action: #selector(rateAppTapped(_:)))
|
||||
return button
|
||||
}()
|
||||
|
||||
private lazy var viewOnTwitterButton: UIButton = {
|
||||
let button = EQNRoundedButton.make(target: self, action: #selector(viewInTwitterTapped(_:)))
|
||||
return button
|
||||
}()
|
||||
|
||||
private lazy var closeButton: UIButton = {
|
||||
let button = EQNRoundedButton.make(target: self, action: #selector(closeTapped(_:)))
|
||||
return button
|
||||
}()
|
||||
|
||||
private lazy var descriptionLabel: UILabel = {
|
||||
let label = UILabel()
|
||||
label.translatesAutoresizingMaskIntoConstraints = false
|
||||
label.numberOfLines = 0
|
||||
label.textColor = AppTheme.shared.cardTextColor
|
||||
label.font = .preferredFont(forTextStyle: .body)
|
||||
label.textAlignment = .center
|
||||
return label
|
||||
}()
|
||||
|
||||
|
||||
// MARK: - Internal
|
||||
|
||||
@IBOutlet weak var notificationTitleLabel: UILabel!
|
||||
@IBOutlet weak var notificationDescriptionLabel: UILabel!
|
||||
@IBOutlet weak var notificationIntensityLabel: UILabel!
|
||||
@IBOutlet weak var waveTimeLabel: UILabel!
|
||||
@IBOutlet weak var mapView: MKMapView! {
|
||||
didSet {
|
||||
mapView.delegate = self
|
||||
mapView.isScrollEnabled = false
|
||||
mapView.isZoomEnabled = false
|
||||
mapView.register(EQNCustomAnnotationView.self, forAnnotationViewWithReuseIdentifier: EQNCustomAnnotationView.SingleLineIdentifier)
|
||||
}
|
||||
}
|
||||
@IBOutlet private weak var shareButton: UIButton!
|
||||
@IBOutlet private weak var rateAppButton: UIButton!
|
||||
@IBOutlet private weak var viewOnTwitterButton: UIButton!
|
||||
@IBOutlet private weak var closeButton: UIButton!
|
||||
@IBOutlet private weak var descriptionLabel: UILabel!
|
||||
private var impactTimestamp: Date?
|
||||
private var countdownTimer: Timer?
|
||||
|
||||
// MARK: - View Lifecycle
|
||||
|
||||
override func awakeFromNib() {
|
||||
super.awakeFromNib()
|
||||
override func setupUI() {
|
||||
super.setupUI()
|
||||
|
||||
localizeUI()
|
||||
setUI()
|
||||
let stackView = UIStackView(arrangedSubviews: [shareButton, rateAppButton])
|
||||
stackView.translatesAutoresizingMaskIntoConstraints = false
|
||||
stackView.axis = .horizontal
|
||||
stackView.distribution = .fillEqually
|
||||
stackView.spacing = .cardVerticalSpacing
|
||||
|
||||
containerView.addSubview(notificationTitleLabel)
|
||||
containerView.addSubview(notificationIntensityLabel)
|
||||
containerView.addSubview(notificationDescriptionLabel)
|
||||
containerView.addSubview(mapView)
|
||||
containerView.addSubview(stackView)
|
||||
containerView.addSubview(viewOnTwitterButton)
|
||||
containerView.addSubview(descriptionLabel)
|
||||
containerView.addSubview(closeButton)
|
||||
|
||||
notificationTitleLabel.topAnchor.constraint(equalTo: containerView.topAnchor, constant: .cardPadding).isActive = true
|
||||
notificationTitleLabel.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: .cardPadding).isActive = true
|
||||
notificationTitleLabel.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: .cardPadding.negative).isActive = true
|
||||
|
||||
notificationIntensityLabel.topAnchor.constraint(equalTo: notificationTitleLabel.bottomAnchor, constant: .cardVerticalSpacing).isActive = true
|
||||
notificationIntensityLabel.leadingAnchor.constraint(equalTo: notificationTitleLabel.leadingAnchor).isActive = true
|
||||
notificationIntensityLabel.trailingAnchor.constraint(equalTo: notificationTitleLabel.trailingAnchor).isActive = true
|
||||
|
||||
notificationDescriptionLabel.topAnchor.constraint(equalTo: notificationIntensityLabel.bottomAnchor, constant: .cardVerticalSpacing).isActive = true
|
||||
notificationDescriptionLabel.leadingAnchor.constraint(equalTo: notificationTitleLabel.leadingAnchor).isActive = true
|
||||
notificationDescriptionLabel.trailingAnchor.constraint(equalTo: notificationTitleLabel.trailingAnchor).isActive = true
|
||||
|
||||
mapView.topAnchor.constraint(equalTo: notificationDescriptionLabel.bottomAnchor, constant: .cardVerticalSpacing).isActive = true
|
||||
mapView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor).isActive = true
|
||||
mapView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor).isActive = true
|
||||
mapView.heightAnchor.constraint(greaterThanOrEqualToConstant: 240.0).isActive = true
|
||||
|
||||
shareButton.heightAnchor.constraint(greaterThanOrEqualToConstant: 40.0).isActive = true
|
||||
rateAppButton.heightAnchor.constraint(equalTo: shareButton.heightAnchor).isActive = true
|
||||
viewOnTwitterButton.heightAnchor.constraint(equalTo: shareButton.heightAnchor).isActive = true
|
||||
closeButton.heightAnchor.constraint(equalTo: shareButton.heightAnchor).isActive = true
|
||||
stackView.topAnchor.constraint(equalTo: mapView.bottomAnchor, constant: .cardVerticalSpacing).isActive = true
|
||||
stackView.leadingAnchor.constraint(equalTo: notificationDescriptionLabel.leadingAnchor).isActive = true
|
||||
stackView.trailingAnchor.constraint(equalTo: notificationDescriptionLabel.trailingAnchor).isActive = true
|
||||
|
||||
viewOnTwitterButton.topAnchor.constraint(equalTo: stackView.bottomAnchor, constant: .cardVerticalSpacing).isActive = true
|
||||
viewOnTwitterButton.leadingAnchor.constraint(equalTo: stackView.leadingAnchor).isActive = true
|
||||
viewOnTwitterButton.trailingAnchor.constraint(equalTo: stackView.trailingAnchor).isActive = true
|
||||
|
||||
descriptionLabel.topAnchor.constraint(equalTo: viewOnTwitterButton.bottomAnchor, constant: .cardPadding).isActive = true
|
||||
descriptionLabel.leadingAnchor.constraint(equalTo: viewOnTwitterButton.leadingAnchor).isActive = true
|
||||
descriptionLabel.trailingAnchor.constraint(equalTo: viewOnTwitterButton.trailingAnchor).isActive = true
|
||||
|
||||
closeButton.topAnchor.constraint(equalTo: descriptionLabel.bottomAnchor, constant: .cardVerticalSpacing).isActive = true
|
||||
closeButton.leadingAnchor.constraint(equalTo: descriptionLabel.leadingAnchor).isActive = true
|
||||
closeButton.trailingAnchor.constraint(equalTo: descriptionLabel.trailingAnchor).isActive = true
|
||||
closeButton.bottomAnchor.constraint(equalTo: containerView.bottomAnchor, constant: .cardVerticalSpacing.negative).isActive = true
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
private func localizeUI() {
|
||||
override func updateUI() {
|
||||
super.updateUI()
|
||||
|
||||
shareButton.setLocalizedTitle(key: "main_share_app")
|
||||
rateAppButton.setLocalizedTitle(key: "main_vote")
|
||||
viewOnTwitterButton.setLocalizedTitle(key: "main_twitter_see")
|
||||
closeButton.setLocalizedTitle(key: "official_close")
|
||||
descriptionLabel.text = NSLocalizedString("map_smartphone_magnitude", comment: "")
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
|
||||
private func setUI() {
|
||||
shareButton.layer.borderColor = AppTheme.Colors.darkGray.cgColor
|
||||
rateAppButton.layer.borderColor = AppTheme.Colors.darkGray.cgColor
|
||||
viewOnTwitterButton.layer.borderColor = AppTheme.Colors.darkGray.cgColor
|
||||
closeButton.layer.borderColor = AppTheme.Colors.darkGray.cgColor
|
||||
}
|
||||
|
||||
private func updateUI() {
|
||||
@objc
|
||||
func update(with notification: EQNRealtimePushNotification?) {
|
||||
// clearn any other previous notifications
|
||||
notificationTitleLabel.text = ""
|
||||
notificationDescriptionLabel.text = ""
|
||||
notificationTitleLabel.text = "Sisma rilevato a 150km (TEST)"
|
||||
notificationIntensityLabel.text = "Previsto uno scuotimento forte"
|
||||
notificationDescriptionLabel.text = "Distanza 150 km - 13 minuti fa"
|
||||
mapView.removeAnnotations(mapView.annotations)
|
||||
|
||||
guard let notification = notification else { return }
|
||||
|
||||
containerView.backgroundColor = backgroundColor(for: notification.relativeIntensity())
|
||||
|
||||
backgroundColor = backgroundColor(for: notification.relativeIntensity())
|
||||
notificationTitleLabel.text = notification.title
|
||||
notificationIntensityLabel.text = notification.displayBody
|
||||
notificationIntensityLabel.textColor = notification.relativeIntensityColor
|
||||
@@ -95,7 +190,6 @@ class AlertsSeismicNotificationExpandedTableViewCell: EQNBaseTableViewCell, MKMa
|
||||
notificationDescriptionLabel.text = ""
|
||||
+ NSLocalizedString("official_card_distance", comment: "") + " \(distanceRound) km"
|
||||
+ " - " + EQNUtility.formattedString(forTimeDifference: difference)
|
||||
+ "\n" + String(format: NSLocalizedString("map_number", comment: ""), "\(notification.counter)")
|
||||
}
|
||||
|
||||
let span = MKCoordinateSpan(latitudeDelta: 10.5, longitudeDelta: 10.5)
|
||||
@@ -118,37 +212,37 @@ class AlertsSeismicNotificationExpandedTableViewCell: EQNBaseTableViewCell, MKMa
|
||||
annotationView.title = annotation.title
|
||||
return annotationView
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Actions
|
||||
|
||||
@IBAction private func shareAppTapped(_ sender: UIButton) {
|
||||
@objc private func shareAppTapped(_ sender: UIButton) {
|
||||
onTapShareApp?()
|
||||
}
|
||||
|
||||
@IBAction private func rateAppTapped(_ sender: UIButton) {
|
||||
@objc private func rateAppTapped(_ sender: UIButton) {
|
||||
onTapRateApp?()
|
||||
}
|
||||
|
||||
@IBAction private func viewInTwitterTapped(_ sender: UIButton) {
|
||||
@objc private func viewInTwitterTapped(_ sender: UIButton) {
|
||||
onTapOpenTwitter?()
|
||||
}
|
||||
|
||||
@IBAction private func closeTapped(_ sender: UIButton) {
|
||||
@objc private func closeTapped(_ sender: UIButton) {
|
||||
onTapClose?()
|
||||
}
|
||||
|
||||
// MARK: - Helpers
|
||||
// MARK: - Private
|
||||
|
||||
private func backgroundColor(for intensity: Double) -> UIColor {
|
||||
switch intensity {
|
||||
case _ where intensity < 0.004:
|
||||
return UIColor(named: "Gray (card background)")!
|
||||
return AppTheme.Colors.cardBackgroundGray
|
||||
case _ where intensity < 0.30:
|
||||
return UIColor(named: "Green (card background)")!
|
||||
return AppTheme.Colors.cardBackgroundGreen
|
||||
case _ where intensity < 0.70:
|
||||
return UIColor(named: "Yellow (card background)")!
|
||||
return AppTheme.Colors.cardBackgroundYellow
|
||||
default:
|
||||
return UIColor(named: "Red (card background)")!
|
||||
return AppTheme.Colors.cardBackgroundRed
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+25
-2
@@ -14,6 +14,8 @@ class SubscriptionsActiveTableViewCell: EQNBaseContainerTableViewCell {
|
||||
|
||||
override var headerText: String { NSLocalizedString("inapp_active", comment: "") }
|
||||
|
||||
var onTapRestore: () -> Void = { }
|
||||
|
||||
// MARK: - UI
|
||||
|
||||
private lazy var noSubscriptionsLabel: UILabel = {
|
||||
@@ -32,22 +34,36 @@ class SubscriptionsActiveTableViewCell: EQNBaseContainerTableViewCell {
|
||||
imageView.contentMode = .scaleAspectFit
|
||||
return imageView
|
||||
}()
|
||||
|
||||
private lazy var restoreButton: UIButton = {
|
||||
let button = UIButton(type: .system)
|
||||
button.translatesAutoresizingMaskIntoConstraints = false
|
||||
button.addTarget(self, action: #selector(restoreSubscriptionsTapped(_:)), for: .touchUpInside)
|
||||
button.titleLabel?.font = .preferredFont(forTextStyle: .headline)
|
||||
button.backgroundColor = .systemGroupedBackground
|
||||
button.eqn_applyShadowAndRoundedCorners()
|
||||
return button
|
||||
}()
|
||||
|
||||
// MARK: - Internal
|
||||
|
||||
override func setupUI() {
|
||||
super.setupUI()
|
||||
|
||||
let stackView = UIStackView(arrangedSubviews: [ activeSubscriptionImageView, noSubscriptionsLabel ])
|
||||
let stackView = UIStackView(arrangedSubviews: [ activeSubscriptionImageView, noSubscriptionsLabel, restoreButton ])
|
||||
stackView.translatesAutoresizingMaskIntoConstraints = false
|
||||
stackView.alignment = .center
|
||||
stackView.distribution = .equalSpacing
|
||||
stackView.axis = .vertical
|
||||
stackView.spacing = 20.0
|
||||
containerView.addSubview(stackView)
|
||||
|
||||
activeSubscriptionImageView.widthAnchor.constraint(equalToConstant: 150.0).isActive = true
|
||||
activeSubscriptionImageView.heightAnchor.constraint(equalToConstant: 50.0).isActive = true
|
||||
|
||||
restoreButton.heightAnchor.constraint(equalToConstant: 40.0).isActive = true
|
||||
restoreButton.leadingAnchor.constraint(equalTo: stackView.leadingAnchor).isActive = true
|
||||
restoreButton.trailingAnchor.constraint(equalTo: stackView.trailingAnchor).isActive = true
|
||||
|
||||
stackView.topAnchor.constraint(equalTo: topView.bottomAnchor, constant: .cardVerticalSpacing).isActive = true
|
||||
stackView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: .cardPadding).isActive = true
|
||||
stackView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: .cardPadding.negative).isActive = true
|
||||
@@ -58,6 +74,13 @@ class SubscriptionsActiveTableViewCell: EQNBaseContainerTableViewCell {
|
||||
super.updateUI()
|
||||
|
||||
noSubscriptionsLabel.text = NSLocalizedString("inapp_nosub", comment: "")
|
||||
restoreButton.setTitle(NSLocalizedString("purchase_pro_restore", comment: ""), for: .normal)
|
||||
}
|
||||
|
||||
// MARK: - Actions
|
||||
|
||||
@objc private func restoreSubscriptionsTapped(_ sender: UIButton) {
|
||||
onTapRestore()
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
|
||||
@@ -80,12 +80,6 @@ class SubscriptionsViewController: UITableViewController {
|
||||
}
|
||||
|
||||
private func configureUI() {
|
||||
let restoreButton = UIBarButtonItem(title: NSLocalizedString("purchase_pro_restore", comment: ""),
|
||||
style: .plain,
|
||||
target: self,
|
||||
action: #selector(restoreTapped(_:)))
|
||||
navigationItem.rightBarButtonItem = restoreButton
|
||||
|
||||
// if is presented in Simulator, add done button
|
||||
if navigationController?.viewControllers.first == self {
|
||||
let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(closeTapped(_:)))
|
||||
@@ -113,11 +107,22 @@ class SubscriptionsViewController: UITableViewController {
|
||||
|
||||
let products = storeProducts.compactMap { EQNInAppProducts.from(product: $0) }
|
||||
|
||||
let purchased = products.filter { (product) -> Bool in
|
||||
let isPurchased = EQNInAppProducts.store.isProductPurchased(product.productIdentifier)
|
||||
let isSubscription = product.isSubscription
|
||||
return isPurchased && isSubscription
|
||||
}
|
||||
let purchased = products
|
||||
.filter { (product) -> Bool in
|
||||
// filter for subscriptions
|
||||
let isPurchased = EQNInAppProducts.store.isProductPurchased(product.productIdentifier)
|
||||
let isSubscription = product.isSubscription
|
||||
return isPurchased && isSubscription
|
||||
}.sorted { lProduct, rProduct in
|
||||
// if user has more than one subscriptions,
|
||||
// show first the Top10k
|
||||
let lIs10k = lProduct.isTop100k
|
||||
let rIs10k = rProduct.isTop100k
|
||||
if lIs10k {
|
||||
return lIs10k
|
||||
}
|
||||
return rIs10k
|
||||
}
|
||||
self.productSubscribed = purchased.first
|
||||
self.products = products.sorted(by: { $0.productIdentifier > $1.productIdentifier })
|
||||
self.tableView.reloadData()
|
||||
@@ -140,11 +145,6 @@ class SubscriptionsViewController: UITableViewController {
|
||||
|
||||
// MARK: - Actions
|
||||
|
||||
@objc func restoreTapped(_ sender: AnyObject) {
|
||||
isRestorePurchase = true
|
||||
EQNInAppProducts.store.restorePurchases()
|
||||
}
|
||||
|
||||
@objc func closeTapped(_ sender: AnyObject) {
|
||||
dismiss(animated: true, completion: nil)
|
||||
}
|
||||
@@ -220,6 +220,12 @@ class SubscriptionsViewController: UITableViewController {
|
||||
let cell = tableView.dequeueReusableCell(cellIdentifiable: SubscriptionsActiveTableViewCell.self, for: indexPath)
|
||||
cell.selectionStyle = .none
|
||||
cell.update(with: productSubscribed)
|
||||
cell.onTapRestore = { [weak self] in
|
||||
guard let self else { return }
|
||||
|
||||
self.isRestorePurchase = true
|
||||
EQNInAppProducts.store.restorePurchases()
|
||||
}
|
||||
return cell
|
||||
case .description:
|
||||
let cell = tableView.dequeueReusableCell(cellIdentifiable: SubscriptionsDescriptionTableViewCell.self, for: indexPath)
|
||||
|
||||
@@ -15,6 +15,8 @@ class RealtimeAlertContainerView: UIView {
|
||||
lazy var alertView: RealtimeAlertView = {
|
||||
let view = RealtimeAlertView()
|
||||
view.translatesAutoresizingMaskIntoConstraints = false
|
||||
view.eqn_applyRoundedCorners()
|
||||
view.clipsToBounds = true
|
||||
return view
|
||||
}()
|
||||
|
||||
@@ -78,10 +80,11 @@ class RealtimeAlertView: UIView {
|
||||
let waveTimeLabel: UILabel = {
|
||||
let label = UILabel()
|
||||
label.translatesAutoresizingMaskIntoConstraints = false
|
||||
label.font = .preferredFont(forTextStyle: .title2)
|
||||
label.font = .preferredFont(forTextStyle: .largeTitle)
|
||||
label.textColor = AppTheme.Colors.red
|
||||
label.text = String.localizedStringWithFormat(NSLocalizedString("alert_wave", comment: ""), 0)
|
||||
label.textAlignment = .center
|
||||
label.numberOfLines = 2
|
||||
label.isHidden = true
|
||||
return label
|
||||
}()
|
||||
@@ -89,7 +92,7 @@ class RealtimeAlertView: UIView {
|
||||
let intensityLabel: UILabel = {
|
||||
let label = UILabel()
|
||||
label.translatesAutoresizingMaskIntoConstraints = false
|
||||
label.font = .preferredFont(forTextStyle: .title3)
|
||||
label.font = .preferredFont(forTextStyle: .largeTitle)
|
||||
label.textColor = AppTheme.Colors.red
|
||||
label.textAlignment = .center
|
||||
label.numberOfLines = 2
|
||||
|
||||
+25
-12
@@ -57,6 +57,7 @@ class SeismicNetworkTableViewCell: UITableViewCell {
|
||||
private var seismic: EQNSisma?
|
||||
private(set) var displayType = DisplayType.normal
|
||||
private var informationTypes = [InformationType]()
|
||||
private var isPushSelected = false
|
||||
|
||||
private var colors: MagnitudeColors?
|
||||
|
||||
@@ -65,14 +66,8 @@ class SeismicNetworkTableViewCell: UITableViewCell {
|
||||
private lazy var containerView: UIView = {
|
||||
let view = UIView(frame: .zero)
|
||||
view.translatesAutoresizingMaskIntoConstraints = false
|
||||
view.layer.cornerRadius = AppTheme.shared.cardCornerRadius
|
||||
view.layer.masksToBounds = false
|
||||
|
||||
// add shadow
|
||||
view.layer.shadowColor = UIColor.black.cgColor
|
||||
view.layer.shadowOpacity = 0.5
|
||||
view.layer.shadowOffset = CGSize(width: 0, height: 2)
|
||||
view.layer.shadowRadius = 2
|
||||
view.backgroundColor = .white
|
||||
view.clipsToBounds = true
|
||||
return view
|
||||
}()
|
||||
|
||||
@@ -83,7 +78,7 @@ class SeismicNetworkTableViewCell: UITableViewCell {
|
||||
// disegnare la view non abbiamo le misure corrette.
|
||||
let view = UIImageView(frame: .zero)
|
||||
view.translatesAutoresizingMaskIntoConstraints = false
|
||||
view.contentMode = .scaleAspectFill
|
||||
view.contentMode = .scaleToFill
|
||||
return view
|
||||
}()
|
||||
|
||||
@@ -194,6 +189,15 @@ class SeismicNetworkTableViewCell: UITableViewCell {
|
||||
setupUI()
|
||||
}
|
||||
|
||||
// MARK: - View Lifecycle
|
||||
|
||||
override func layoutSubviews() {
|
||||
super.layoutSubviews()
|
||||
|
||||
containerView.eqn_applyShadowAndRoundedCorners()
|
||||
gradientView.eqn_applyRoundedCorners()
|
||||
}
|
||||
|
||||
// MARK: - Setup
|
||||
|
||||
private func setupUI() {
|
||||
@@ -206,7 +210,6 @@ class SeismicNetworkTableViewCell: UITableViewCell {
|
||||
containerView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -8.0).isActive = true
|
||||
containerView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 8.0).isActive = true
|
||||
containerView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -4.0).isActive = true
|
||||
containerView.clipsToBounds = true
|
||||
|
||||
containerView.addSubview(gradientView)
|
||||
gradientView.constraint(to: containerView)
|
||||
@@ -379,6 +382,9 @@ class SeismicNetworkTableViewCell: UITableViewCell {
|
||||
else {
|
||||
previousView.bottomAnchor.constraint(equalTo: containerView.layoutMarginsGuide.bottomAnchor).isActive = true
|
||||
}
|
||||
|
||||
containerView.eqn_applyShadowAndRoundedCorners()
|
||||
gradientView.eqn_applyRoundedCorners()
|
||||
}
|
||||
|
||||
private func recreateUI() {
|
||||
@@ -393,13 +399,14 @@ class SeismicNetworkTableViewCell: UITableViewCell {
|
||||
let viewModel = SeismicNetworkViewModel(seismic: seismic)
|
||||
|
||||
if let colors = colors {
|
||||
gradientView.image = .gradient(from: colors.startColor, to: colors.endColor, with: .init(origin: .zero, size: .init(width: 400, height: 300)))
|
||||
gradientView.image = .gradient(from: colors.startColor, to: colors.endColor, with: .init(origin: .zero, size: .init(width: 500, height: 1)))
|
||||
} else {
|
||||
gradientView.image = nil
|
||||
}
|
||||
|
||||
// update seismic data
|
||||
placeLabel.text = viewModel.place
|
||||
placeLabel.textColor = isPushSelected ? AppTheme.Colors.pureBlue : AppTheme.shared.cardTextColor
|
||||
networkLabel.text = String(format: NSLocalizedString("official_provider", comment: ""), viewModel.network)
|
||||
magnitudeLabel.textColor = colors?.textColor
|
||||
magnitudeLabel.text = viewModel.magnitude
|
||||
@@ -447,11 +454,17 @@ class SeismicNetworkTableViewCell: UITableViewCell {
|
||||
/// - seismic: Seismic to display
|
||||
/// - type: Type of cell
|
||||
/// - informations: Informations to show
|
||||
public func configure(with seismic: EQNSisma, type: DisplayType, informations: [InformationType]) {
|
||||
public func configure(
|
||||
with seismic: EQNSisma,
|
||||
type: DisplayType,
|
||||
informations: [InformationType],
|
||||
isPushSelected: Bool
|
||||
) {
|
||||
self.seismic = seismic
|
||||
self.colors = calculateColors(for: seismic.magnitude.doubleValue)
|
||||
self.displayType = type
|
||||
self.informationTypes = informations
|
||||
self.isPushSelected = isPushSelected
|
||||
|
||||
if !informations.contains(.time) {
|
||||
self.informationTypes += [.time]
|
||||
|
||||
+387
-22
@@ -23,11 +23,6 @@ class SeismicNetworksViewController: UIViewController, UITableViewDelegate, UITa
|
||||
|
||||
// MARK: - Internal
|
||||
|
||||
@IBOutlet private weak var tableView: UITableView?
|
||||
@IBOutlet private weak var expandeCollapseButton: UIBarButtonItem!
|
||||
@IBOutlet private weak var sortButton: UIBarButtonItem!
|
||||
weak var currentMapController: SeismicNetworksMapDetailViewController?
|
||||
|
||||
/// The ad loader
|
||||
private lazy var adLoader: GADAdLoader = {
|
||||
let adLoader = GADAdLoader(
|
||||
@@ -43,15 +38,64 @@ class SeismicNetworksViewController: UIViewController, UITableViewDelegate, UITa
|
||||
private var informations = [SeismicNetworkTableViewCell.InformationType]()
|
||||
/// Index path of row with map expanded
|
||||
private var openMapIndexPath: IndexPath?
|
||||
/// Push notification opened by the user
|
||||
private var openedPushNotification: EQNOfficialPushNotification? {
|
||||
didSet {
|
||||
scrollToOpenedSeismic = true
|
||||
}
|
||||
}
|
||||
private var scrollToOpenedSeismic = false
|
||||
/// Current displayed controller with map
|
||||
private weak var currentMapController: SeismicNetworksMapDetailViewController?
|
||||
|
||||
// MARK: - UI
|
||||
|
||||
@IBOutlet private weak var expandeCollapseButton: UIBarButtonItem!
|
||||
@IBOutlet private weak var sortButton: UIBarButtonItem!
|
||||
private var tableViewTopConstraint: NSLayoutConstraint?
|
||||
|
||||
private lazy var tableView: UITableView = {
|
||||
let tableView = UITableView(frame: .zero, style: .plain)
|
||||
tableView.translatesAutoresizingMaskIntoConstraints = false
|
||||
tableView.delegate = self
|
||||
tableView.dataSource = self
|
||||
return tableView
|
||||
}()
|
||||
|
||||
private lazy var filterChangedView: UIView = {
|
||||
let view = UIView(frame: .zero)
|
||||
view.translatesAutoresizingMaskIntoConstraints = false
|
||||
view.backgroundColor = AppTheme.Colors.pureBlue
|
||||
|
||||
view.addSubview(filterChangedLabel)
|
||||
filterChangedLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 8.0).isActive = true
|
||||
filterChangedLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -8.0).isActive = true
|
||||
filterChangedLabel.topAnchor.constraint(equalTo: view.topAnchor, constant: 8.0).isActive = true
|
||||
filterChangedLabel.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -8.0).isActive = true
|
||||
|
||||
return view
|
||||
}()
|
||||
|
||||
private lazy var filterChangedLabel: UILabel = {
|
||||
let label = UILabel(frame: .zero)
|
||||
label.translatesAutoresizingMaskIntoConstraints = false
|
||||
label.textColor = .white
|
||||
label.font = .preferredFont(forTextStyle: .subheadline)
|
||||
label.numberOfLines = 0
|
||||
label.textAlignment = .center
|
||||
return label
|
||||
}()
|
||||
|
||||
// MARK: - View Lifecycle
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
setupUI()
|
||||
configureUI()
|
||||
checkForLocation()
|
||||
refreshUI()
|
||||
configureFilterView(isVisible: false)
|
||||
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(didReceiveDownloadCompleteNotification(_:)), name: .EQNDownloadDataDidComplete, object: nil)
|
||||
}
|
||||
@@ -60,16 +104,69 @@ class SeismicNetworksViewController: UIViewController, UITableViewDelegate, UITa
|
||||
super.viewWillAppear(animated)
|
||||
|
||||
loadData(forced: false)
|
||||
|
||||
// check for a push to manage
|
||||
if let notification = EQNOfficialPushNotification.stored() {
|
||||
manageFilter(for: notification)
|
||||
self.openedPushNotification = notification
|
||||
EQNOfficialPushNotification.removeStored()
|
||||
} else {
|
||||
configureFilterView(isVisible: false)
|
||||
self.openedPushNotification = nil
|
||||
}
|
||||
|
||||
tableView.reloadData()
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
private func setupUI() {
|
||||
view.addSubview(tableView)
|
||||
|
||||
tableViewTopConstraint = tableView.topAnchor.constraint(equalTo: view.topAnchor)
|
||||
tableViewTopConstraint?.isActive = true
|
||||
tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
|
||||
tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
|
||||
tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
|
||||
}
|
||||
|
||||
private func setupFilterView(isVisible: Bool) {
|
||||
if isVisible && filterChangedView.superview == nil {
|
||||
view.addSubview(filterChangedView)
|
||||
tableViewTopConstraint?.isActive = false
|
||||
filterChangedView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
|
||||
filterChangedView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
|
||||
filterChangedView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
|
||||
tableViewTopConstraint = filterChangedView.bottomAnchor.constraint(equalTo: tableView.topAnchor)
|
||||
tableViewTopConstraint?.isActive = true
|
||||
} else {
|
||||
filterChangedView.removeFromSuperview()
|
||||
tableViewTopConstraint?.isActive = false
|
||||
tableViewTopConstraint = tableView.topAnchor.constraint(equalTo: view.topAnchor)
|
||||
tableViewTopConstraint?.isActive = true
|
||||
}
|
||||
}
|
||||
|
||||
private func configureFilterView(isVisible: Bool) {
|
||||
setupFilterView(isVisible: isVisible)
|
||||
if isVisible {
|
||||
filterChangedLabel.text = NSLocalizedString("official_filter_changed", comment: "")
|
||||
filterChangedView.backgroundColor = AppTheme.Colors.pureBlue
|
||||
} else {
|
||||
filterChangedLabel.text = nil
|
||||
filterChangedView.backgroundColor = .white
|
||||
}
|
||||
}
|
||||
|
||||
private func configureUI() {
|
||||
title = NSLocalizedString("tab_official", comment: "").capitalized
|
||||
|
||||
tableView?.estimatedRowHeight = 300.0
|
||||
tableView?.rowHeight = UITableView.automaticDimension
|
||||
tableView?.registerCell(for: SeismicNetworkTableViewCell.self)
|
||||
tableView?.registerCell(for: SeismicNetworkAdvertiseTableViewCell.self)
|
||||
tableView?.emptyDataSetSource = self
|
||||
tableView.estimatedRowHeight = 300.0
|
||||
tableView.rowHeight = UITableView.automaticDimension
|
||||
tableView.registerCell(for: SeismicNetworkTableViewCell.self)
|
||||
tableView.registerCell(for: SeismicNetworkAdvertiseTableViewCell.self)
|
||||
tableView.emptyDataSetSource = self
|
||||
tableView.separatorStyle = .none
|
||||
|
||||
setupSortMenu()
|
||||
}
|
||||
@@ -92,7 +189,7 @@ class SeismicNetworksViewController: UIViewController, UITableViewDelegate, UITa
|
||||
private func checkForLocation() {
|
||||
// check if a valid location is available,
|
||||
// otherwise change the filter settings
|
||||
if EQNUser.default().lastPosition == nil {
|
||||
if !isLocationAvailable() {
|
||||
EQNSeismic.shared.filterOption = .worldWide
|
||||
EQNSeismic.shared.saveFilters()
|
||||
}
|
||||
@@ -148,7 +245,12 @@ class SeismicNetworksViewController: UIViewController, UITableViewDelegate, UITa
|
||||
expandeCollapseButton.image = UIImage(named: "navbar-icon-arrow-expand")
|
||||
}
|
||||
|
||||
tableView?.reloadData()
|
||||
tableView.reloadData()
|
||||
|
||||
if scrollToOpenedSeismic, let index = getSeismics().firstIndex(where: { isSeismicToHighlight(seismic: $0) }) {
|
||||
tableView.scrollToRow(at: IndexPath(row: index, section: 0), at: .middle, animated: true)
|
||||
scrollToOpenedSeismic = false
|
||||
}
|
||||
}
|
||||
|
||||
private func loadAd() {
|
||||
@@ -196,6 +298,268 @@ class SeismicNetworksViewController: UIViewController, UITableViewDelegate, UITa
|
||||
refreshUI()
|
||||
}
|
||||
|
||||
private func manageFilter(
|
||||
for notification: EQNOfficialPushNotification
|
||||
) {
|
||||
//gestisco i filtri solo se la posizione dell'utente è nota
|
||||
guard let userPosition = EQNUser.default().lastPosition else {
|
||||
return
|
||||
}
|
||||
|
||||
var filter_type = EQNSeismic.shared.filterOption
|
||||
var filter_radius = Double(EQNSeismic.shared.maximumDistance) ?? 0
|
||||
var filter_min_magnitude = Double(EQNSeismic.shared.minimumMagnitude) ?? 0
|
||||
|
||||
var filter_changed = false
|
||||
|
||||
//recupero i dati del sisma notificato
|
||||
let notification_magnitude = notification.magnitude
|
||||
let notification_latitude = notification.coordinate.coordinate.latitude
|
||||
let notification_longitude = notification.coordinate.coordinate.longitude
|
||||
|
||||
//distanza tra smartphone utente e sisma notificato
|
||||
let locationNotification = CLLocation(latitude: notification_latitude, longitude: notification_longitude)
|
||||
let distance = userPosition.distance(from: locationNotification) / 1_000
|
||||
|
||||
//verifico se il sisma è significativo in base alla definizione di significativo
|
||||
var is_significant = true
|
||||
if notification_magnitude < 7.0 && distance > 2000 {
|
||||
is_significant = false
|
||||
} else if notification_magnitude < 6.5 && distance > 1600 {
|
||||
is_significant = false
|
||||
} else if notification_magnitude < 6.0 && distance > 1300 {
|
||||
is_significant = false
|
||||
} else if notification_magnitude < 5.5 && distance > 1000 {
|
||||
is_significant = false
|
||||
} else if notification_magnitude < 5.0 && distance > 700 {
|
||||
is_significant = false
|
||||
} else if notification_magnitude < 4.5 && distance > 500 {
|
||||
is_significant = false
|
||||
} else if notification_magnitude < 4.0 && distance > 350 {
|
||||
is_significant = false
|
||||
} else if notification_magnitude < 3.5 && distance > 200 {
|
||||
is_significant = false
|
||||
} else if notification_magnitude < 3.0 && distance > 125 {
|
||||
is_significant = false
|
||||
} else if notification_magnitude < 2.5 && distance > 70 {
|
||||
is_significant = false
|
||||
} else if notification_magnitude < 2.0 && distance > 35 {
|
||||
is_significant = false
|
||||
} else if notification_magnitude < 1.5 && distance > 20 {
|
||||
is_significant = false
|
||||
}
|
||||
|
||||
//verifico se devo modificare il filtro scelto dall'utente
|
||||
if filter_type == .inRadius { //filter_type=0 è il filtro basato su raggio e magnitudo
|
||||
if distance > 2000 && is_significant {
|
||||
filter_type = .positionRelevant //passo al filtro che mostra i sismi significativi (perché il raggio massimo del filtro basato sul raggio è 2000)
|
||||
updateFilter(type: filter_type)
|
||||
filter_changed = true
|
||||
}
|
||||
else if distance > 2000 && notification_magnitude >= 2.0 {
|
||||
filter_type = .worldWide //passo al filtro che mostra tutti i sismi nel mondo
|
||||
updateFilter(type: filter_type)
|
||||
filter_changed = true
|
||||
}
|
||||
else {
|
||||
//verifico se devo cambiare il raggio del filtro
|
||||
if distance > filter_radius {
|
||||
if distance > 1500 {
|
||||
filter_radius = 2000
|
||||
} else if distance > 1000 {
|
||||
filter_radius = 1500
|
||||
} else if distance > 750 {
|
||||
filter_radius = 1000
|
||||
} else if distance > 500 {
|
||||
filter_radius = 750
|
||||
} else if distance > 250 {
|
||||
filter_radius = 500
|
||||
} else if distance > 100 {
|
||||
filter_radius = 250
|
||||
}
|
||||
updateFilter(radius: filter_radius)
|
||||
|
||||
filter_changed = true
|
||||
}
|
||||
//verifico se devo cambiare la mgnitudo del filtro
|
||||
if notification_magnitude < filter_min_magnitude {
|
||||
if notification_magnitude < 1.0 {
|
||||
filter_min_magnitude = 0.0
|
||||
} else if notification_magnitude < 2.0 {
|
||||
filter_min_magnitude = 1.0
|
||||
} else if notification_magnitude < 3.0 {
|
||||
filter_min_magnitude = 2.0
|
||||
} else if notification_magnitude < 4.0 {
|
||||
filter_min_magnitude = 3.0
|
||||
} else if notification_magnitude < 5.0 {
|
||||
filter_min_magnitude = 4.0
|
||||
} else if notification_magnitude < 6.0 {
|
||||
filter_min_magnitude = 5.0
|
||||
}
|
||||
|
||||
filter_changed = true
|
||||
updateFilter(magnitude: filter_min_magnitude)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if filter_type == .positionRelevant && !is_significant && distance <= 2000 {
|
||||
filter_type = .inRadius //passo a filtro basato su raggio e magnitudo
|
||||
updateFilter(type: filter_type)
|
||||
|
||||
if distance > filter_radius {
|
||||
if distance>1500 {
|
||||
filter_radius = 2000
|
||||
}
|
||||
else if distance > 1000 {
|
||||
filter_radius = 1500
|
||||
}
|
||||
else if distance > 750 {
|
||||
filter_radius = 1000
|
||||
}
|
||||
else if distance > 500 {
|
||||
filter_radius = 750
|
||||
}
|
||||
else if distance > 250 {
|
||||
filter_radius = 500
|
||||
}
|
||||
else if distance > 100 {
|
||||
filter_radius = 250
|
||||
}
|
||||
updateFilter(radius: filter_radius)
|
||||
}
|
||||
if notification_magnitude < filter_min_magnitude {
|
||||
if notification_magnitude < 1.0 {
|
||||
filter_min_magnitude = 0.0
|
||||
}
|
||||
else if notification_magnitude < 2.0 {
|
||||
filter_min_magnitude = 1.0
|
||||
}
|
||||
else if notification_magnitude < 3.0 {
|
||||
filter_min_magnitude = 2.0
|
||||
}
|
||||
else if notification_magnitude < 4.0 {
|
||||
filter_min_magnitude = 3.0
|
||||
}
|
||||
else if notification_magnitude < 5.0 {
|
||||
filter_min_magnitude = 4.0
|
||||
}
|
||||
else if notification_magnitude < 6.0 {
|
||||
filter_min_magnitude = 5.0
|
||||
}
|
||||
updateFilter(magnitude: filter_min_magnitude)
|
||||
}
|
||||
|
||||
filter_changed = true
|
||||
}
|
||||
|
||||
if filter_type == .positionRelevant && !is_significant && distance > 2000 && notification_magnitude >= 2.0 {
|
||||
filter_type = .worldWide //passo a filtro che mostra tutti i sismi nel mondo
|
||||
updateFilter(type: filter_type)
|
||||
filter_changed = true
|
||||
}
|
||||
|
||||
if filter_type == .worldWide && notification_magnitude < 2.0 && is_significant {
|
||||
filter_type = .positionRelevant //passo a filtro sismi significativi
|
||||
updateFilter(type: filter_type)
|
||||
filter_changed = true
|
||||
}
|
||||
|
||||
if filter_type == .worldWide && notification_magnitude < 2.0 && distance <= 2000 && !is_significant {
|
||||
filter_type = .inRadius
|
||||
updateFilter(type: filter_type)
|
||||
|
||||
if distance > filter_radius {
|
||||
if distance > 1500 {
|
||||
filter_radius = 2000
|
||||
}
|
||||
else if distance > 1000 {
|
||||
filter_radius = 1500
|
||||
}
|
||||
else if distance > 750 {
|
||||
filter_radius = 1000
|
||||
}
|
||||
else if distance > 500 {
|
||||
filter_radius = 750
|
||||
}
|
||||
else if distance > 250 {
|
||||
filter_radius = 500
|
||||
}
|
||||
else if distance > 100 {
|
||||
filter_radius = 250
|
||||
}
|
||||
updateFilter(radius: filter_radius)
|
||||
}
|
||||
if notification_magnitude < filter_min_magnitude {
|
||||
if notification_magnitude < 1.0 {
|
||||
filter_min_magnitude = 0.0
|
||||
}
|
||||
else if notification_magnitude < 2.0 {
|
||||
filter_min_magnitude = 1.0
|
||||
}
|
||||
else if notification_magnitude < 3.0 {
|
||||
filter_min_magnitude = 2.0
|
||||
}
|
||||
else if notification_magnitude < 4.0 {
|
||||
filter_min_magnitude = 3.0
|
||||
}
|
||||
else if notification_magnitude < 5.0 {
|
||||
filter_min_magnitude = 4.0
|
||||
}
|
||||
else if notification_magnitude < 6.0 {
|
||||
filter_min_magnitude = 5.0
|
||||
}
|
||||
updateFilter(magnitude: filter_min_magnitude)
|
||||
}
|
||||
|
||||
filter_changed = true
|
||||
}
|
||||
|
||||
//mostro all'utente un messaggio per avvisarlo che i filtri sono stati modificati
|
||||
configureFilterView(isVisible: filter_changed)
|
||||
if filter_changed {
|
||||
loadData(forced: true)
|
||||
}
|
||||
}
|
||||
|
||||
private func updateFilter(
|
||||
type: EQNSeismic.FilterType? = nil,
|
||||
radius: Double? = nil,
|
||||
magnitude: Double? = nil
|
||||
) {
|
||||
if let type {
|
||||
EQNSeismic.shared.filterOption = type
|
||||
}
|
||||
if let radius {
|
||||
EQNSeismic.shared.maximumDistance = String(format: "%.0f", radius)
|
||||
}
|
||||
if let magnitude {
|
||||
EQNSeismic.shared.minimumMagnitude = String(format: "%.1f", magnitude)
|
||||
}
|
||||
EQNSeismic.shared.saveFilters()
|
||||
}
|
||||
|
||||
private func isLocationAvailable() -> Bool {
|
||||
EQNUser.default().lastPosition != nil
|
||||
}
|
||||
|
||||
private func isSeismicToHighlight(seismic: EQNSisma) -> Bool {
|
||||
guard let notification = openedPushNotification else {
|
||||
return false
|
||||
}
|
||||
|
||||
guard let seismicDate = seismic.date, let notificationDate = notification.date else { return false }
|
||||
|
||||
let deltaTime = abs(seismicDate.timeIntervalSince(notificationDate))
|
||||
let magnitudeRatio = seismic.magnitude.doubleValue / notification.magnitude
|
||||
let latitudeDiff = abs(seismic.coordinate.coordinate.latitude - notification.coordinate.coordinate.latitude)
|
||||
let longitudeDiff = abs(seismic.coordinate.coordinate.longitude - notification.coordinate.coordinate.longitude)
|
||||
if deltaTime <= 120 && magnitudeRatio > 0.8 && magnitudeRatio < 1.2 && latitudeDiff < 1 && longitudeDiff < 1 { // secondi?
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// MARK: - Actions
|
||||
|
||||
@IBAction func refreshDataTapped(_ sender: Any) {
|
||||
@@ -233,8 +597,9 @@ class SeismicNetworksViewController: UIViewController, UITableViewDelegate, UITa
|
||||
if openMapIndexPath == indexPath {
|
||||
type = .mapExpanded
|
||||
}
|
||||
|
||||
cell.configure(with: seismic, type: type, informations: informations)
|
||||
|
||||
let isPushSelected = isSeismicToHighlight(seismic: seismic)
|
||||
cell.configure(with: seismic, type: type, informations: informations, isPushSelected: isPushSelected)
|
||||
cell.delegate = self
|
||||
return cell
|
||||
case .advertise(let nativeAd):
|
||||
@@ -314,7 +679,7 @@ extension SeismicNetworksViewController: GADNativeAdLoaderDelegate {
|
||||
|
||||
let adPosition = min(3, rows.count)
|
||||
rows.insert(.advertise(nativeAd), at: adPosition)
|
||||
tableView?.reloadData()
|
||||
tableView.reloadData()
|
||||
}
|
||||
|
||||
func adLoader(_ adLoader: GADAdLoader, didFailToReceiveAdWithError error: Error) {
|
||||
@@ -326,7 +691,7 @@ extension SeismicNetworksViewController: GADNativeAdLoaderDelegate {
|
||||
extension SeismicNetworksViewController: SeismicNetworkTableViewCellDelegate {
|
||||
|
||||
func seismicNetworkCellDidTapShare(_ cell: SeismicNetworkTableViewCell) {
|
||||
guard let index = tableView?.indexPath(for: cell), case let .seismic(seismic) = rows[index.row] else { return }
|
||||
guard let index = tableView.indexPath(for: cell), case let .seismic(seismic) = rows[index.row] else { return }
|
||||
|
||||
// create a snapshot of the cell and share with default share sheet
|
||||
let snapshot = cell.contentView.createSnapshot()
|
||||
@@ -343,22 +708,22 @@ extension SeismicNetworksViewController: SeismicNetworkTableViewCellDelegate {
|
||||
}
|
||||
|
||||
func seismicNetworkCellDidTapMap(_ cell: SeismicNetworkTableViewCell) {
|
||||
guard let index = tableView?.indexPath(for: cell) else { return }
|
||||
guard let index = tableView.indexPath(for: cell) else { return }
|
||||
|
||||
let indexToReloads = [openMapIndexPath, index].compactMap { $0 }
|
||||
|
||||
openMapIndexPath = index
|
||||
tableView?.reloadRows(at: indexToReloads, with: .automatic)
|
||||
tableView.reloadRows(at: indexToReloads, with: .automatic)
|
||||
}
|
||||
|
||||
func seismicNetworkCellDidTapMapDetail(_ cell: SeismicNetworkTableViewCell) {
|
||||
guard let index = tableView?.indexPath(for: cell), case let .seismic(seismic) = rows[index.row] else { return }
|
||||
guard let index = tableView.indexPath(for: cell), case let .seismic(seismic) = rows[index.row] else { return }
|
||||
|
||||
showMapDetail(for: seismic)
|
||||
}
|
||||
|
||||
func seismicNetworkCellDidTapCalendar(_ cell: SeismicNetworkTableViewCell) {
|
||||
guard let index = tableView?.indexPath(for: cell), case let .seismic(seismic) = rows[index.row] else { return }
|
||||
guard let index = tableView.indexPath(for: cell), case let .seismic(seismic) = rows[index.row] else { return }
|
||||
|
||||
openCalendar(for: seismic)
|
||||
}
|
||||
@@ -368,12 +733,12 @@ extension SeismicNetworksViewController: SeismicNetworkTableViewCellDelegate {
|
||||
}
|
||||
|
||||
func seismicNetworkCellDidTapClose(_ cell: SeismicNetworkTableViewCell) {
|
||||
guard let index = tableView?.indexPath(for: cell) else { return }
|
||||
guard let index = tableView.indexPath(for: cell) else { return }
|
||||
|
||||
let indexToReloads = [openMapIndexPath, index].compactMap { $0 }
|
||||
|
||||
openMapIndexPath = nil
|
||||
tableView?.reloadRows(at: indexToReloads, with: .automatic)
|
||||
tableView.reloadRows(at: indexToReloads, with: .automatic)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-73
@@ -1,73 +0,0 @@
|
||||
//
|
||||
// SettingsSeismicNetworkNotificationsFilterViewController.swift
|
||||
// Earthquake Network
|
||||
//
|
||||
// Created by Andrea Busi on 06/06/24.
|
||||
// Copyright © 2024 Earthquake Network. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import Shogun
|
||||
|
||||
class SettingsSeismicNetworkNotificationsFilterViewController: UITableViewController {
|
||||
|
||||
private let filters: [EQNSettingSeismicNetworkNotification.FilterType] = [.soloRilevanti, .condizionati]
|
||||
private var currentFilter = EQNSettingSeismicNetworkNotification.shared.filtro
|
||||
|
||||
// MARK: - Init
|
||||
|
||||
convenience init() {
|
||||
self.init(style: .insetGrouped)
|
||||
}
|
||||
|
||||
// MARK: - View Lifecycle
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
setupUI()
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
private func setupUI() {
|
||||
tableView.estimatedRowHeight = 200.0
|
||||
tableView.rowHeight = UITableView.automaticDimension
|
||||
tableView.registerHeaderFooterView(for: SettingSectionHeaderView.self)
|
||||
tableView.registerCell(for: SettingDetailTableViewCell.self)
|
||||
}
|
||||
|
||||
// MARK: - Table view data source
|
||||
|
||||
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
|
||||
let view = tableView.dequeueHeaderFooterView(cellIdentifiable: SettingSectionHeaderView.self)
|
||||
view.titleLabel.text = NSLocalizedString("options_official_type", comment: "")
|
||||
return view
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
|
||||
SettingSectionHeaderView.Height
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||
return filters.count
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
let filter = filters[indexPath.row]
|
||||
let cell = tableView.dequeueReusableCell(cellIdentifiable: SettingDetailTableViewCell.self, for: indexPath)
|
||||
cell.textLabel?.text = filter.displayName
|
||||
cell.textLabel?.numberOfLines = 0
|
||||
cell.accessoryType = currentFilter == filter ? .checkmark : .none
|
||||
return cell
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||
let filter = filters[indexPath.row]
|
||||
|
||||
EQNSettingSeismicNetworkNotification.shared.filtro = filter
|
||||
EQNSettingSeismicNetworkNotification.shared.saveUserInfo()
|
||||
|
||||
navigationController?.popViewController(animated: true)
|
||||
}
|
||||
}
|
||||
+2
-36
@@ -13,15 +13,11 @@ class SettingsSeismicNetworkNotificationsViewController: SettingsBaseTableViewCo
|
||||
|
||||
private enum RowIdentifier: Int {
|
||||
case abilitaNotifiche
|
||||
case filtroNotifiche
|
||||
case magnitudoMinima
|
||||
case distanzaMassima
|
||||
}
|
||||
|
||||
private static let SegueFilters = "ShowFilters"
|
||||
|
||||
|
||||
private var isNotificationEnabled = false
|
||||
private var currentFilter: EQNSettingSeismicNetworkNotification.FilterType = .soloRilevanti
|
||||
private var currentMinimumMagnitude = EQNData.DefaultSettingSeismicNetworkNotificationMagitude
|
||||
private var currentMaximumDistance = EQNData.DefaultSettingSeismicNetworkNotificationRadius
|
||||
private let dataSourceMinimumMagnitude = EQNData.settingSeismicNetworkNotificationMagnitudes
|
||||
@@ -29,7 +25,6 @@ class SettingsSeismicNetworkNotificationsViewController: SettingsBaseTableViewCo
|
||||
|
||||
private let settings: [SettingItem] = [
|
||||
.init(type: .enable, title: NSLocalizedString("options_notification_enable_official", comment: "")),
|
||||
.init(type: .multiValues, title: NSLocalizedString("options_official_type", comment: ""), segue: SegueFilters),
|
||||
.init(type: .slider, title: NSLocalizedString("options_official_minmag", comment: "")),
|
||||
.init(type: .slider, title: NSLocalizedString("options_official_maxdist", comment: ""))
|
||||
]
|
||||
@@ -69,9 +64,6 @@ class SettingsSeismicNetworkNotificationsViewController: SettingsBaseTableViewCo
|
||||
|
||||
isNotificationEnabled = saved.isAbilitato
|
||||
|
||||
// filtro notifiche
|
||||
currentFilter = saved.filtro
|
||||
|
||||
// magnitudo minima
|
||||
let magnitudoMinima = EQNData.getSettingSeismicNetworkNotificationMagnitudes(for: saved.magnitudoMinima)
|
||||
currentMinimumMagnitude = magnitudoMinima
|
||||
@@ -119,28 +111,13 @@ class SettingsSeismicNetworkNotificationsViewController: SettingsBaseTableViewCo
|
||||
break
|
||||
}
|
||||
|
||||
return cell
|
||||
case .multiValues:
|
||||
let cell = tableView.dequeueReusableCell(cellIdentifiable: SettingMultivaluesTableViewCell.self, for: indexPath)
|
||||
cell.accessoryType = .disclosureIndicator
|
||||
cell.titleLabel.text = setting.title
|
||||
|
||||
switch identifier {
|
||||
case .filtroNotifiche:
|
||||
cell.isDisabled = !isNotificationEnabled
|
||||
cell.isUserInteractionEnabled = isNotificationEnabled
|
||||
cell.valuesLabel.text = currentFilter.displayName
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
return cell
|
||||
|
||||
case .slider:
|
||||
let cell = tableView.dequeueReusableCell(cellIdentifiable: SettingSliderTableViewCell.self, for: indexPath)
|
||||
cell.titleLabel.text = setting.displayTitle
|
||||
|
||||
let filtersEnabled = isNotificationEnabled && currentFilter == .condizionati
|
||||
let filtersEnabled = isNotificationEnabled
|
||||
switch identifier {
|
||||
case .magnitudoMinima:
|
||||
cell.isDisabled = !filtersEnabled
|
||||
@@ -165,17 +142,6 @@ class SettingsSeismicNetworkNotificationsViewController: SettingsBaseTableViewCo
|
||||
}
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||
let setting = settings[indexPath.row]
|
||||
switch setting.segue {
|
||||
case Self.SegueFilters:
|
||||
let controller = SettingsSeismicNetworkNotificationsFilterViewController()
|
||||
navigationController?.pushViewController(controller, animated: true)
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
private func onChangeNotificationEnabled(_ enabled: Bool) {
|
||||
isNotificationEnabled = enabled
|
||||
EQNSettingSeismicNetworkNotification.shared.isAbilitato = isNotificationEnabled
|
||||
|
||||
@@ -12,9 +12,7 @@ import UIKit
|
||||
extension UIView {
|
||||
|
||||
func eqn_applyShadowAndRoundedCorners() {
|
||||
// rounded corners
|
||||
layer.cornerRadius = AppTheme.shared.cardCornerRadius
|
||||
layer.masksToBounds = false
|
||||
eqn_applyRoundedCorners()
|
||||
|
||||
// apply a shadow to the current view
|
||||
layer.shadowColor = UIColor.black.cgColor
|
||||
@@ -22,4 +20,10 @@ extension UIView {
|
||||
layer.shadowOffset = CGSize(width: 0, height: 2)
|
||||
layer.shadowRadius = 2
|
||||
}
|
||||
|
||||
func eqn_applyRoundedCorners() {
|
||||
// rounded corners
|
||||
layer.cornerRadius = AppTheme.shared.cardCornerRadius
|
||||
layer.masksToBounds = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ public class EQNAppearanceCommand: EQNCommandProtocol {
|
||||
// MARK: - Public
|
||||
|
||||
func execute() {
|
||||
print("EQNAppearanceCommand: start execute")
|
||||
print("[EQNAppearanceCommand] Start execute")
|
||||
|
||||
applyAppearance()
|
||||
}
|
||||
@@ -32,7 +32,7 @@ public class EQNAppearanceCommand: EQNCommandProtocol {
|
||||
navAppearance.largeTitleTextAttributes = [
|
||||
NSAttributedString.Key.foregroundColor: AppTheme.Colors.darkGray
|
||||
]
|
||||
navAppearance.backgroundColor = AppTheme.Colors.primary
|
||||
navAppearance.backgroundColor = AppTheme.Colors.navBar
|
||||
navAppearance.shadowColor = UIColor.clear
|
||||
|
||||
proxyNavBar.isTranslucent = false
|
||||
|
||||
@@ -15,7 +15,7 @@ public class EQNUserDefaultsCommand: EQNCommandProtocol {
|
||||
// MARK: - Public
|
||||
|
||||
func execute() {
|
||||
print("EQNUserDefaultsCommand: start execute")
|
||||
print("[EQNUserDefaultsCommand] Start execute")
|
||||
|
||||
applyDefaultSettings()
|
||||
saveMissingValues()
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
//
|
||||
// EQNOfficialPushNotification.swift
|
||||
// Earthquake Network
|
||||
//
|
||||
// Created by Andrea Busi on 29/06/24.
|
||||
// Copyright © 2024 Earthquake Network. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Shogun
|
||||
|
||||
|
||||
@objc
|
||||
class EQNOfficialPushNotification: NSObject, Codable {
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case latitude
|
||||
case longitude
|
||||
case magnitude
|
||||
case date
|
||||
}
|
||||
|
||||
private let latitude: Double
|
||||
private let longitude: Double
|
||||
let magnitude: Double
|
||||
let date: Date?
|
||||
|
||||
var coordinate: CLLocation {
|
||||
.init(latitude: latitude, longitude: longitude)
|
||||
}
|
||||
|
||||
// MARK: - Init
|
||||
|
||||
init(
|
||||
latitude: Double,
|
||||
longitude: Double,
|
||||
magnitude: Double,
|
||||
date: Date?
|
||||
) {
|
||||
self.latitude = latitude
|
||||
self.longitude = longitude
|
||||
self.magnitude = magnitude
|
||||
self.date = date
|
||||
}
|
||||
|
||||
// MARK: - Class
|
||||
|
||||
/// Remove any saved notification
|
||||
static func removeStored() {
|
||||
UserDefaults.standard.removeObject(forKey: UserDefaults.OfficialAlertPayload)
|
||||
}
|
||||
|
||||
/// Retrieve stored notification (if any)
|
||||
static func stored() -> EQNOfficialPushNotification? {
|
||||
guard let data = UserDefaults.standard.object(forKey: UserDefaults.OfficialAlertPayload) as? Data else {
|
||||
print("[EQNOfficialPushNotification] No notification saved for key '\(UserDefaults.OfficialAlertPayload)'")
|
||||
return nil
|
||||
}
|
||||
|
||||
guard let notification = try? JSONDecoder().decode(EQNOfficialPushNotification.self, from: data) else {
|
||||
print("[EQNOfficialPushNotification] Unable to decode given notification")
|
||||
return nil
|
||||
}
|
||||
|
||||
return notification
|
||||
}
|
||||
|
||||
/// Convert and store a push notification payload.
|
||||
/// Expected payload has the following structure:
|
||||
/// ```
|
||||
/// {
|
||||
/// "title": "Segnalazione da rete sismica",
|
||||
/// "body": "Sisma rilevato a 4km S Valfabbrica (PG)",
|
||||
/// "userInfo": {
|
||||
/// "data" : "2024-06-29 11:21:30",
|
||||
/// ...
|
||||
/// "aps": {
|
||||
/// "alert" : {
|
||||
/// "loc-key" : "Sisma rilevato a",
|
||||
/// "title-loc-key" : "Segnalazione da rete sismica",
|
||||
/// "title" : "Segnalazione da rete sismica",
|
||||
/// "action-loc-key" : "",
|
||||
/// "loc-args" : [
|
||||
/// "6 km S Acate (RG) - M1.9"
|
||||
/// ]
|
||||
/// },
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
/// - Parameter payload: Notification payload
|
||||
/// - Returns: `true` if save succeed, `false` otherwise
|
||||
@objc(storeNotificationWithPayload:)
|
||||
@discardableResult
|
||||
static func store(payload: [String: Any]) -> Bool {
|
||||
guard let notification = from(payload: payload) else {
|
||||
print("[EQNOfficialPushNotification] Unable to convert received notification")
|
||||
return false
|
||||
}
|
||||
|
||||
guard let data = try? JSONEncoder().encode(notification) else {
|
||||
print("[EQNOfficialPushNotification] Unable to encode given notification")
|
||||
return false
|
||||
}
|
||||
|
||||
UserDefaults.standard.set(data, forKey: UserDefaults.OfficialAlertPayload)
|
||||
return true
|
||||
}
|
||||
|
||||
@objc
|
||||
private static func from(payload: [String: Any]) -> EQNOfficialPushNotification? {
|
||||
guard let userInfo = payload["userInfo"] as? [String: Any] else {
|
||||
print("[EQNOfficialPushNotification] Missing required info to parse push notification")
|
||||
return nil
|
||||
}
|
||||
|
||||
let latitude = userInfo.double(forKey: "latitude") ?? 0
|
||||
let longitude = userInfo.double(forKey: "longitude") ?? 0
|
||||
let magnitude = userInfo.double(forKey: "magnitude") ?? 0
|
||||
let dateString = userInfo.string(forKey: "data") ?? ""
|
||||
let date = EQNUtility.getDateFrom(dateString)
|
||||
|
||||
return .init(
|
||||
latitude: latitude,
|
||||
longitude: longitude,
|
||||
magnitude: magnitude,
|
||||
date: date
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -11,29 +11,15 @@ import Foundation
|
||||
@objc
|
||||
class EQNSettingSeismicNetworkNotification: NSObject {
|
||||
|
||||
enum FilterType: Int {
|
||||
case soloRilevanti
|
||||
case condizionati
|
||||
|
||||
var displayName: String {
|
||||
switch self {
|
||||
case .soloRilevanti: NSLocalizedString("options_official_type_relevant", comment: "")
|
||||
case .condizionati: NSLocalizedString("options_official_type_area", comment: "")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@objc(sharedInstance)
|
||||
static let shared = EQNSettingSeismicNetworkNotification()
|
||||
|
||||
@objc var isAbilitato: Bool
|
||||
@objc var magnitudoMinima: String
|
||||
@objc var distanzaMassima: String
|
||||
var filtro: FilterType
|
||||
|
||||
private static let DefaultMagnitudoMinima = EQNData.DefaultFilterMagnitude.value
|
||||
private static let DefaultDistanzaMassima = EQNData.DefaultFilterRadius.value
|
||||
private static let DefaultFiltro = FilterType.soloRilevanti
|
||||
|
||||
// MARK: - Init
|
||||
|
||||
@@ -44,7 +30,6 @@ class EQNSettingSeismicNetworkNotification: NSObject {
|
||||
self.isAbilitato = defaults.bool(forKey: UserDefaults.NotificheRetiSismicheAbilitato)
|
||||
self.magnitudoMinima = defaults.object(forKey: UserDefaults.NotificheRetiSismicheMagnitudoMinima, or: Self.DefaultMagnitudoMinima)
|
||||
self.distanzaMassima = defaults.object(forKey: UserDefaults.NotificheRetiSismicheDistanzaMassima, or: Self.DefaultDistanzaMassima)
|
||||
self.filtro = defaults.enumObject(forKey: UserDefaults.NotificheRetiSismicheFiltroNotifiche, or: Self.DefaultFiltro)
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
@@ -54,14 +39,12 @@ class EQNSettingSeismicNetworkNotification: NSObject {
|
||||
defaults.set(isAbilitato, forKey: UserDefaults.NotificheRetiSismicheAbilitato)
|
||||
defaults.set(magnitudoMinima, forKey: UserDefaults.NotificheRetiSismicheMagnitudoMinima)
|
||||
defaults.set(distanzaMassima, forKey: UserDefaults.NotificheRetiSismicheDistanzaMassima)
|
||||
defaults.set(filtro.rawValue, forKey: UserDefaults.NotificheRetiSismicheFiltroNotifiche)
|
||||
}
|
||||
|
||||
@objc class func saveDefaultValues() {
|
||||
shared.isAbilitato = true
|
||||
shared.magnitudoMinima = DefaultMagnitudoMinima
|
||||
shared.distanzaMassima = DefaultDistanzaMassima
|
||||
shared.filtro = DefaultFiltro
|
||||
shared.saveUserInfo()
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -5,9 +5,9 @@
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "130",
|
||||
"green" : "212",
|
||||
"red" : "148"
|
||||
"blue" : "196",
|
||||
"green" : "226",
|
||||
"red" : "200"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"colors" : [
|
||||
{
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "167",
|
||||
"green" : "231",
|
||||
"red" : "255"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -5,9 +5,9 @@
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0.318",
|
||||
"green" : "0.565",
|
||||
"red" : "0.000"
|
||||
"blue" : "35",
|
||||
"green" : "160",
|
||||
"red" : "12"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
|
||||
@@ -134,6 +134,7 @@
|
||||
case EQNTipoChiamataCalibrazione:
|
||||
case EQNTipoChiamataImpostazioniNotifiche:
|
||||
case EQNTipoChiamataAlertSimulator:
|
||||
case EQNTipoChiamataAlertPushTest:
|
||||
case EQNTipoChiamataRegisterSubscription:
|
||||
onSuccess(newStr);
|
||||
default:
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22685"/>
|
||||
<capability name="Named colors" minToolsVersion="9.0"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="System colors in document resources" minToolsVersion="11.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
@@ -17,23 +16,8 @@
|
||||
<view key="view" contentMode="scaleToFill" id="yYN-HE-bpD">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="none" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="q4o-YO-KLX">
|
||||
<rect key="frame" x="0.0" y="144" width="414" height="669"/>
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="tVM-DH-fmv" id="XVf-fb-5Kl"/>
|
||||
<outlet property="delegate" destination="tVM-DH-fmv" id="dWO-2A-Ukg"/>
|
||||
</connections>
|
||||
</tableView>
|
||||
</subviews>
|
||||
<viewLayoutGuide key="safeArea" id="VUD-fs-xgm"/>
|
||||
<color key="backgroundColor" systemColor="groupTableViewBackgroundColor"/>
|
||||
<constraints>
|
||||
<constraint firstItem="VUD-fs-xgm" firstAttribute="bottom" secondItem="q4o-YO-KLX" secondAttribute="bottom" id="3P1-fP-chi"/>
|
||||
<constraint firstItem="q4o-YO-KLX" firstAttribute="top" secondItem="VUD-fs-xgm" secondAttribute="top" id="IeK-TW-jL5"/>
|
||||
<constraint firstItem="q4o-YO-KLX" firstAttribute="leading" secondItem="VUD-fs-xgm" secondAttribute="leading" id="Yyx-Tc-hnn"/>
|
||||
<constraint firstItem="VUD-fs-xgm" firstAttribute="trailing" secondItem="q4o-YO-KLX" secondAttribute="trailing" id="yd6-Pa-c2s"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<navigationItem key="navigationItem" id="6kD-jk-5Aw">
|
||||
<rightBarButtonItems>
|
||||
@@ -58,14 +42,13 @@
|
||||
<connections>
|
||||
<outlet property="expandeCollapseButton" destination="HTN-07-s5p" id="lxP-Im-NME"/>
|
||||
<outlet property="sortButton" destination="LyU-KI-3Mb" id="969-Zg-YBB"/>
|
||||
<outlet property="tableView" destination="q4o-YO-KLX" id="tee-h5-dZi"/>
|
||||
<segue destination="6LP-zk-O1z" kind="presentation" identifier="ShowFilters" modalPresentationStyle="overCurrentContext" modalTransitionStyle="crossDissolve" id="Nzu-iH-UgB"/>
|
||||
<segue destination="Rfp-kt-2Kx" kind="presentation" identifier="ShowCardSettings" modalPresentationStyle="overCurrentContext" modalTransitionStyle="crossDissolve" id="VWw-16-xGw"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="34i-9D-p3O" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="-8709" y="-5464"/>
|
||||
<point key="canvasLocation" x="-8710.144927536232" y="-5464.2857142857138"/>
|
||||
</scene>
|
||||
<!--Segnalazioni View Controller-->
|
||||
<scene sceneID="2v7-dY-aHc">
|
||||
@@ -582,154 +565,8 @@
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="none" rowHeight="-1" estimatedRowHeight="200" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="a35-sg-TCr">
|
||||
<rect key="frame" x="0.0" y="92" width="414" height="666"/>
|
||||
<rect key="frame" x="0.0" y="144" width="414" height="614"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<prototypes>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" reuseIdentifier="SeismicNotificationExpandedCell" rowHeight="700" id="C7v-rs-1fb" customClass="AlertsSeismicNotificationExpandedTableViewCell" customModule="Earthquake_Network" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="50" width="414" height="700"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="C7v-rs-1fb" id="aEH-vE-u7m">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="700"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="TfA-6E-CQc">
|
||||
<rect key="frame" x="8" y="8" width="398" height="684"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Rilevato un sisma debole a 150 km (Test)" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="M7i-e5-N6v">
|
||||
<rect key="frame" x="8" y="8" width="382" height="67.5"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleTitle1"/>
|
||||
<color key="textColor" name="Gray (dark)"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="DyB-fs-sPo">
|
||||
<rect key="frame" x="8" y="87.5" width="382" height="42.5"/>
|
||||
<string key="text">Distanza 149 km - 0 minuti fa
|
||||
Sisma rilevato da 10 smartphone</string>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
<color key="textColor" name="Gray (dark)"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<mapView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" mapType="standard" translatesAutoresizingMaskIntoConstraints="NO" id="tqM-QH-LJ3">
|
||||
<rect key="frame" x="0.0" y="172.5" width="398" height="287"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="240" id="w6M-Ao-KHo"/>
|
||||
</constraints>
|
||||
</mapView>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="Q2V-3p-DUh">
|
||||
<rect key="frame" x="8" y="467.5" width="382" height="40"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="V2G-UH-Ibe" customClass="EQNRoundedButton" customModule="Earthquake_Network" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="0.0" width="187" height="40"/>
|
||||
<color key="backgroundColor" white="1" alpha="0.5" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<state key="normal" title="SHARE APP">
|
||||
<color key="titleColor" name="Gray (dark)"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="shareAppTapped:" destination="C7v-rs-1fb" eventType="touchUpInside" id="Igp-0D-llw"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="n9y-jx-2xG" customClass="EQNRoundedButton" customModule="Earthquake_Network" customModuleProvider="target">
|
||||
<rect key="frame" x="195" y="0.0" width="187" height="40"/>
|
||||
<color key="backgroundColor" white="1" alpha="0.5" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<state key="normal" title="RATE THE APP">
|
||||
<color key="titleColor" name="Gray (dark)"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="rateAppTapped:" destination="C7v-rs-1fb" eventType="touchUpInside" id="xgm-dy-Uy3"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="40" id="Qe8-J8-tY6"/>
|
||||
</constraints>
|
||||
</stackView>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Jwx-kf-che" customClass="EQNRoundedButton" customModule="Earthquake_Network" customModuleProvider="target">
|
||||
<rect key="frame" x="8" y="515.5" width="382" height="40"/>
|
||||
<color key="backgroundColor" white="1" alpha="0.5" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<state key="normal" title="VIEW ON TWITTER">
|
||||
<color key="titleColor" name="Gray (dark)"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="viewInTwitterTapped:" destination="C7v-rs-1fb" eventType="touchUpInside" id="djx-1X-bbD"/>
|
||||
</connections>
|
||||
</button>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="The magnitude will be estimated by the national seismic network and it will appear in the Seismic Networks tab of the app" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="GIh-sK-KX1">
|
||||
<rect key="frame" x="8" y="563.5" width="382" height="64.5"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
<color key="textColor" name="Gray (dark)"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="3Ga-UF-Cr7" customClass="EQNRoundedButton" customModule="Earthquake_Network" customModuleProvider="target">
|
||||
<rect key="frame" x="8" y="636" width="382" height="40"/>
|
||||
<color key="backgroundColor" white="1" alpha="0.5" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<state key="normal" title="CLOSE">
|
||||
<color key="titleColor" name="Gray (dark)"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="closeTapped:" destination="C7v-rs-1fb" eventType="touchUpInside" id="y39-44-3gS"/>
|
||||
</connections>
|
||||
</button>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Rilevato scuotimento forte" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Xb4-4c-oEd">
|
||||
<rect key="frame" x="8" y="138" width="382" height="26.5"/>
|
||||
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="22"/>
|
||||
<color key="textColor" name="Gray (dark)"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstItem="3Ga-UF-Cr7" firstAttribute="trailing" secondItem="GIh-sK-KX1" secondAttribute="trailing" id="1qg-dS-vGZ"/>
|
||||
<constraint firstItem="DyB-fs-sPo" firstAttribute="top" secondItem="M7i-e5-N6v" secondAttribute="bottom" constant="12" id="7gG-Y2-tda"/>
|
||||
<constraint firstAttribute="trailing" secondItem="GIh-sK-KX1" secondAttribute="trailing" constant="8" id="8TC-4t-7fC"/>
|
||||
<constraint firstItem="tqM-QH-LJ3" firstAttribute="top" secondItem="Xb4-4c-oEd" secondAttribute="bottom" constant="8" id="9Nv-Zb-mlE"/>
|
||||
<constraint firstItem="Xb4-4c-oEd" firstAttribute="trailing" secondItem="DyB-fs-sPo" secondAttribute="trailing" id="F4e-yh-mKB"/>
|
||||
<constraint firstAttribute="trailing" secondItem="tqM-QH-LJ3" secondAttribute="trailing" id="Gf0-a2-jaj"/>
|
||||
<constraint firstItem="3Ga-UF-Cr7" firstAttribute="height" secondItem="Q2V-3p-DUh" secondAttribute="height" id="N2x-vd-6D6"/>
|
||||
<constraint firstItem="Xb4-4c-oEd" firstAttribute="leading" secondItem="DyB-fs-sPo" secondAttribute="leading" id="QAk-d3-ZOG"/>
|
||||
<constraint firstItem="Jwx-kf-che" firstAttribute="trailing" secondItem="Q2V-3p-DUh" secondAttribute="trailing" id="Qie-q3-No5"/>
|
||||
<constraint firstItem="Q2V-3p-DUh" firstAttribute="top" secondItem="tqM-QH-LJ3" secondAttribute="bottom" constant="8" id="TM2-ig-acw"/>
|
||||
<constraint firstItem="Jwx-kf-che" firstAttribute="top" secondItem="Q2V-3p-DUh" secondAttribute="bottom" constant="8" id="Wjc-dF-bMj"/>
|
||||
<constraint firstAttribute="trailing" secondItem="M7i-e5-N6v" secondAttribute="trailing" constant="8" id="XHM-kN-PXl"/>
|
||||
<constraint firstItem="3Ga-UF-Cr7" firstAttribute="leading" secondItem="GIh-sK-KX1" secondAttribute="leading" id="YhB-av-ejA"/>
|
||||
<constraint firstItem="DyB-fs-sPo" firstAttribute="leading" secondItem="M7i-e5-N6v" secondAttribute="leading" id="ZHJ-oa-DjC"/>
|
||||
<constraint firstItem="Jwx-kf-che" firstAttribute="height" secondItem="Q2V-3p-DUh" secondAttribute="height" id="Zp0-Q0-p0q"/>
|
||||
<constraint firstItem="Q2V-3p-DUh" firstAttribute="leading" secondItem="TfA-6E-CQc" secondAttribute="leading" constant="8" id="ZsU-Ec-9Bc"/>
|
||||
<constraint firstAttribute="trailing" secondItem="Q2V-3p-DUh" secondAttribute="trailing" constant="8" id="bmi-oa-9ss"/>
|
||||
<constraint firstItem="tqM-QH-LJ3" firstAttribute="leading" secondItem="TfA-6E-CQc" secondAttribute="leading" id="gUO-ka-XvB"/>
|
||||
<constraint firstAttribute="bottom" secondItem="3Ga-UF-Cr7" secondAttribute="bottom" constant="8" id="gWA-6h-HmJ"/>
|
||||
<constraint firstItem="DyB-fs-sPo" firstAttribute="trailing" secondItem="M7i-e5-N6v" secondAttribute="trailing" id="jD7-QV-p8s"/>
|
||||
<constraint firstItem="GIh-sK-KX1" firstAttribute="top" secondItem="Jwx-kf-che" secondAttribute="bottom" constant="8" id="nJj-g4-TSs"/>
|
||||
<constraint firstItem="Xb4-4c-oEd" firstAttribute="top" secondItem="DyB-fs-sPo" secondAttribute="bottom" constant="8" symbolic="YES" id="pct-jg-eJW"/>
|
||||
<constraint firstItem="3Ga-UF-Cr7" firstAttribute="top" secondItem="GIh-sK-KX1" secondAttribute="bottom" constant="8" id="qaQ-zK-ael"/>
|
||||
<constraint firstItem="M7i-e5-N6v" firstAttribute="leading" secondItem="TfA-6E-CQc" secondAttribute="leading" constant="8" id="rsV-dp-eqa"/>
|
||||
<constraint firstItem="M7i-e5-N6v" firstAttribute="top" secondItem="TfA-6E-CQc" secondAttribute="top" constant="8" id="seX-2q-JVM"/>
|
||||
<constraint firstItem="Jwx-kf-che" firstAttribute="leading" secondItem="Q2V-3p-DUh" secondAttribute="leading" id="tND-n7-uEb"/>
|
||||
<constraint firstItem="GIh-sK-KX1" firstAttribute="leading" secondItem="TfA-6E-CQc" secondAttribute="leading" constant="8" id="tsI-iu-M9g"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="TfA-6E-CQc" firstAttribute="top" secondItem="aEH-vE-u7m" secondAttribute="top" constant="8" id="9GR-hr-g5x"/>
|
||||
<constraint firstAttribute="trailing" secondItem="TfA-6E-CQc" secondAttribute="trailing" constant="8" id="FWZ-RC-8Ed"/>
|
||||
<constraint firstAttribute="bottom" secondItem="TfA-6E-CQc" secondAttribute="bottom" constant="8" id="fld-qW-XMS"/>
|
||||
<constraint firstItem="TfA-6E-CQc" firstAttribute="leading" secondItem="aEH-vE-u7m" secondAttribute="leading" constant="8" id="r0r-m9-EiO"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<connections>
|
||||
<outlet property="closeButton" destination="3Ga-UF-Cr7" id="yNt-rU-bZX"/>
|
||||
<outlet property="containerView" destination="TfA-6E-CQc" id="twS-Jx-IAd"/>
|
||||
<outlet property="descriptionLabel" destination="GIh-sK-KX1" id="L4X-lK-CVb"/>
|
||||
<outlet property="mapView" destination="tqM-QH-LJ3" id="Gp4-gu-q8r"/>
|
||||
<outlet property="notificationDescriptionLabel" destination="DyB-fs-sPo" id="aLr-34-WND"/>
|
||||
<outlet property="notificationIntensityLabel" destination="Xb4-4c-oEd" id="QFh-Jd-pLP"/>
|
||||
<outlet property="notificationTitleLabel" destination="M7i-e5-N6v" id="RqD-wo-sXl"/>
|
||||
<outlet property="rateAppButton" destination="n9y-jx-2xG" id="mvX-2K-I6i"/>
|
||||
<outlet property="shareButton" destination="V2G-UH-Ibe" id="JT4-jR-d45"/>
|
||||
<outlet property="viewOnTwitterButton" destination="Jwx-kf-che" id="xNf-ps-fWL"/>
|
||||
</connections>
|
||||
</tableViewCell>
|
||||
</prototypes>
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="syj-UE-OWc" id="Vah-TU-YfT"/>
|
||||
<outlet property="delegate" destination="syj-UE-OWc" id="Iqp-Mp-8lG"/>
|
||||
@@ -792,9 +629,6 @@ Sisma rilevato da 10 smartphone</string>
|
||||
<image name="tabbar-icon-networks" width="25" height="25"/>
|
||||
<image name="tabbar-icon-reports" width="25" height="25"/>
|
||||
<image name="tabbar-icon-settings" width="25" height="25"/>
|
||||
<namedColor name="Gray (dark)">
|
||||
<color red="0.10999999940395355" green="0.13300000131130219" blue="0.14900000393390656" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</namedColor>
|
||||
<systemColor name="groupTableViewBackgroundColor">
|
||||
<color red="0.94901960784313721" green="0.94901960784313721" blue="0.96862745098039216" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</systemColor>
|
||||
|
||||
@@ -21,7 +21,15 @@ class AppTheme: NSObject {
|
||||
static let lightGray = UIColor(named: "Gray (light)")!
|
||||
|
||||
static let cardBackgroundRed = UIColor(named: "Red (card background)")!
|
||||
static let cardBackgroundOrange = UIColor(named: "Orange (card background)")!
|
||||
static let cardBackgroundGreen = UIColor(named: "Green (card background)")!
|
||||
static let cardBackgroundYellow = UIColor(named: "Yellow (card background)")!
|
||||
static let cardBackgroundGray = UIColor(named: "Gray (card background)")!
|
||||
|
||||
static let pureBlue = UIColor(red: 0.0, green: 0.0, blue: 1.0, alpha: 1.0)
|
||||
static let pureRed = UIColor(red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0)
|
||||
|
||||
static let navBar = UIColor(red: 155.0/255.0, green: 225.0/255.0, blue: 255.0/255.0, alpha: 1.0)
|
||||
}
|
||||
|
||||
static let shared = AppTheme()
|
||||
|
||||
@@ -28,14 +28,6 @@ class EQNBaseContainerTableViewCell: UITableViewCell {
|
||||
let view = UIView(frame: .zero)
|
||||
view.translatesAutoresizingMaskIntoConstraints = false
|
||||
view.backgroundColor = .white
|
||||
view.layer.cornerRadius = AppTheme.shared.cardCornerRadius
|
||||
view.layer.masksToBounds = false
|
||||
|
||||
// add shadow
|
||||
view.layer.shadowColor = UIColor.black.cgColor
|
||||
view.layer.shadowOpacity = 0.5
|
||||
view.layer.shadowOffset = CGSize(width: 0, height: 2)
|
||||
view.layer.shadowRadius = 2
|
||||
return view
|
||||
}()
|
||||
|
||||
@@ -80,6 +72,15 @@ class EQNBaseContainerTableViewCell: UITableViewCell {
|
||||
/// Text to display inside the header
|
||||
var headerText: String { "" }
|
||||
|
||||
override var backgroundColor: UIColor? {
|
||||
set {
|
||||
internalContainerView.backgroundColor = newValue
|
||||
}
|
||||
get {
|
||||
internalContainerView.backgroundColor
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Init
|
||||
|
||||
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||
@@ -93,12 +94,20 @@ class EQNBaseContainerTableViewCell: UITableViewCell {
|
||||
setupUI()
|
||||
updateUI()
|
||||
}
|
||||
|
||||
// MARK: - View Lifecycle
|
||||
|
||||
override func layoutSubviews() {
|
||||
super.layoutSubviews()
|
||||
containerView.eqn_applyRoundedCorners()
|
||||
internalContainerView.eqn_applyShadowAndRoundedCorners()
|
||||
}
|
||||
|
||||
// MARK: - Internal
|
||||
|
||||
func setupUI() {
|
||||
selectionStyle = .default
|
||||
backgroundColor = .clear
|
||||
super.backgroundColor = .clear
|
||||
|
||||
contentView.addSubview(internalContainerView)
|
||||
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
//
|
||||
// EQNBaseTableViewCell.swift
|
||||
// Earthquake Network
|
||||
//
|
||||
// Created by Busi Andrea on 07/10/2020.
|
||||
// Copyright © 2020 Earthquake Network. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
|
||||
class EQNBaseTableViewCell: UITableViewCell {
|
||||
|
||||
@IBOutlet weak var containerView: UIView!
|
||||
|
||||
// MARK: - View Lifecycle
|
||||
|
||||
override func awakeFromNib() {
|
||||
super.awakeFromNib()
|
||||
|
||||
clipsToBounds = true
|
||||
|
||||
// rounded corners and shadow
|
||||
containerView.eqn_applyShadowAndRoundedCorners()
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
"Rilevato sisma debole a" = "رصد زلزال خفيف في ميلانو %@";
|
||||
"Rilevato sisma forte a" = "رصد زلزال قوي في ميلانو %@";
|
||||
"Rilevato sisma a" = "رصد زلزال في ميلانو %@";
|
||||
"Sisma segnalato da utente a" = "أبلغ المستخدم عن الزلزال في %@";
|
||||
"Sisma segnalato da utente a" = "تم الإبلاغ عن الزلزال من قبل مستخدمي التطبيق في %@";
|
||||
"Sisma lieve segnalato da utente a" = "Mild quake reported by user at %@"; // replaced by alert_intensity_mild
|
||||
"Sisma forte segnalato da utente a" = "Strong quake reported by user at %@"; // replaced by alert_intensity_moderate
|
||||
"Sisma molto forte segnalato da utente a" = "Very strong quake reported by user at %@"; // replaced by alert_intensity_strong
|
||||
@@ -26,7 +26,7 @@
|
||||
"drawer_privacy" = "الخصوصيات";
|
||||
"tab_network" = "تنبيهات";
|
||||
"tab_manual" = "تقارير";
|
||||
"tab_official" = "الشبكات الزلزالية";
|
||||
"tab_official" = "قائمة الزلزال";
|
||||
"inapp_available_10k" = "\U200FTop 10K %lu اشتراكات لا تزال متوفرة ليتم تنبيهها في أقل من ثانية واحدة منذ اكتشاف الزلزال";
|
||||
"inapp_available_100k" = "\U200FTop 100K %lu اشتراكات لا تزال متوفرة ليتم تنبيهها في أقل من 5 ثوان منذ اكتشاف الزلزال";
|
||||
"filter_filter" = "اختر الزلازل التي تريد عرضها";
|
||||
@@ -44,6 +44,7 @@
|
||||
"filter_empty_area" = "لا توجد زلازل خلال الـ 24 ساعة الماضية وفقًا للمرشحات";
|
||||
"filter_empty_relevant" = "لم تكن هناك زلازل ذات صلة بموقعك خلال الـ 24 ساعة الماضية";
|
||||
"filter_nolocation" = "هذا الخيار غير متاح لأن موقعك غير معروف";
|
||||
"official_filter_changed" = "تم تغيير مرشحات القائمة لإظهار الزلزال الذي تم الإبلاغ عنه";
|
||||
"official_provider" = "المصدر: %@";
|
||||
"share_hashtag" = "#زلزال أرضي";
|
||||
"share_notified" = "قررت من خلال التطبيق منبه الزلازل. قم بتنزيل التطبيق من https://sismo.app/download/ لاستلام تنبيهات في الوقت الفعلي حول #earthquake @SismoDetector";
|
||||
@@ -84,7 +85,7 @@
|
||||
"options_official_maxdist" = "المسافة القصو";
|
||||
"options_notification_manual" = "إشعارات تقرير المستخدم";
|
||||
"options_notification_enable_manual" = "استلم الإخطارات للزلازل التي أبلغ عنها يدويا من قبل المستخدمين";
|
||||
"main_areacheck_message" = "في الوقت الحالي ، يوجد في منطقتك %s هواتف ذكية تراقب الزلازل في الوقت الفعلي. قدرة شبكة الهاتف الذكي على اكتشاف الزلازل في الوقت الفعلي هي%@. لتحسين اكتشاف الزلازل في منطقتك ، شارك التطبيق مع عائلتك وأصدقائك ، شكرًا!";
|
||||
"main_areacheck_message" = "في الوقت الحالي ، يوجد في منطقتك %@ هواتف ذكية تراقب الزلازل في الوقت الفعلي. لتحسين اكتشاف الزلازل في منطقتك ، شارك التطبيق مع عائلتك وأصدقائك ، شكرًا!";
|
||||
"main_version" = "نموذج";
|
||||
"app_name" = "منبه الزلازل";
|
||||
"official_depth" = "العمق:";
|
||||
@@ -215,7 +216,7 @@
|
||||
"attention" = "انتباه";
|
||||
"official_no_country_selected" = "لم تقم بتحديد أي بلد";
|
||||
"report" = "التقارير";
|
||||
"purchase_pro_restore" = "يعيد";
|
||||
"purchase_pro_restore" = "استعادة الاشتراكات";
|
||||
"purchase_pro_restore_alert_title" = "اكتملت الاستعادة";
|
||||
"purchase_pro_restore_alert_message" = "لقد استعدت المنتج الذي اشتريته";
|
||||
"purchase_pro_no_subscriptions_alert_message" = "لم يتم العثور على شراء للاستعادة. تأكد من تسجيل الدخول إلى الحساب الذي تم الشراء به.";
|
||||
|
||||
@@ -5,9 +5,10 @@
|
||||
"Rilevato sisma debole a" = "Ήπιο σεισμό που ανιχνεύεται στο %@";
|
||||
"Rilevato sisma forte a" = "Ισχυρός σεισμός που ανιχνεύεται στο %@";
|
||||
"Rilevato sisma a" = "Ο σεισμός ανιχνεύθηκε στο %@";
|
||||
"Sisma lieve segnalato da utente a" = "Ήπιο σεισμό που αναφέρθηκε από έναν χρήστη στο %@";
|
||||
"Sisma forte segnalato da utente a" = "Ισχυρός σεισμός που αναφέρθηκε από έναν χρήστη στο %@";
|
||||
"Sisma molto forte segnalato da utente a" = "Πολύ ισχυρός σεισμός που αναφέρθηκε από έναν χρήστη στο %@";
|
||||
"Sisma segnalato da utente a" = "Σεισμός που αναφέρθηκε από χρήστες της εφαρμογής στο %@";
|
||||
"Sisma lieve segnalato da utente a" = "Ήπιο σεισμό που αναφέρθηκε από έναν χρήστη στο %@"; // not used, to be removed
|
||||
"Sisma forte segnalato da utente a" = "Ισχυρός σεισμός που αναφέρθηκε από έναν χρήστη στο %@"; // not used, to be removed
|
||||
"Sisma molto forte segnalato da utente a" = "Πολύ ισχυρός σεισμός που αναφέρθηκε από έναν χρήστη στο %@"; // not used, to be removed
|
||||
"Sisma rilevato a" = "Ο σεισμός ανιχνεύθηκε στο %@";
|
||||
"alert_intensity_no_shaking" = "Δεν γίνεται αισθητό στην τοποθεσία σας";
|
||||
"alert_intensity_mild" = "Να περιμένετε ήπιο ή καθόλου κούνημα";
|
||||
@@ -25,7 +26,7 @@
|
||||
"drawer_privacy" = "Ιδιωτικό απόρρητο";
|
||||
"tab_network" = "ΕΙΔΟΠΟΙΗΣΕΙΣ";
|
||||
"tab_manual" = "ΑΝΑΦΟΡΕΣ";
|
||||
"tab_official" = "ΣΕΙΣΜΙΚΑ ΔΙΚΤΥΑ";
|
||||
"tab_official" = "Λιστα σεισμων";
|
||||
"inapp_available_10k" = "Top 10K: %lu εγγραφές είναι ακόμη διαθέσιμες για ειδοποίηση σε λιγότερο από 1 δευτερόλεπτο από την ανίχνευση του σεισμού";
|
||||
"inapp_available_100k" = "Top 100K: %lu εγγραφή είναι ακόμη διαθέσιμη για ειδοποίηση σε λιγότερο από 5 δευτερόλεπτα από την ανίχνευση του σεισμού";
|
||||
"filter_filter" = "Επιλέξτε ποιους σεισμούς θέλετε να δείτε";
|
||||
@@ -43,6 +44,7 @@
|
||||
"filter_empty_area" = "Δεν υπάρχουν σεισμοί τις τελευταίες 24 ώρες σύμφωνα με τα φίλτρα";
|
||||
"filter_empty_relevant" = "Δεν υπάρχουν σχετικοί σεισμοί τις τελευταίες 24 ώρες σε σχέση με την τοποθεσία σας";
|
||||
"filter_nolocation" = "Αυτή η επιλογή δεν είναι διαθέσιμη επειδή η τοποθεσία σας είναι άγνωστη";
|
||||
"official_filter_changed" = "Τα φίλτρα της λίστας έχουν αλλάξει για να εμφανιστεί ο ειδοποιημένος σεισμός";
|
||||
"official_provider" = "Πηγή: %@";
|
||||
"share_hashtag" = "#σεισμός";
|
||||
"share_notified" = "Έχει αναφερθεί μέσω της εφαρμογής Ανιχνευτής Σεισμών. Κατέβασε την εφαρμογή από το https://sismo.app/download/ για να λαμβάνεις σε πραγματικό χρόνο ειδοποιήσεις #σεισμού @SismoDetector";
|
||||
@@ -214,7 +216,7 @@
|
||||
"attention" = "Προσοχή";
|
||||
"official_no_country_selected" = "Δεν έχετε επιλέξει καμία χώρα";
|
||||
"report" = "Αναφορά";
|
||||
"purchase_pro_restore" = "Επαναφέρω";
|
||||
"purchase_pro_restore" = "Επαναφορά συνδρομών";
|
||||
"purchase_pro_restore_alert_title" = "Επαναφέρω ολοκληρώθηκε";
|
||||
"purchase_pro_restore_alert_message" = "Έχετε αποκαταστήσει το προϊόν που αγοράσατε";
|
||||
"purchase_pro_no_subscriptions_alert_message" = "Δεν βρέθηκε αγορά αγοράς. Βεβαιωθείτε ότι έχετε συνδεθεί στο λογαριασμό, η αγορά έγινε με.";
|
||||
|
||||
@@ -5,9 +5,10 @@
|
||||
"Rilevato sisma debole a" = "Mild quake detected at %@";
|
||||
"Rilevato sisma forte a" = "Strong quake detected at %@";
|
||||
"Rilevato sisma a" = "Quake detected at %@";
|
||||
"Sisma lieve segnalato da utente a" = "Mild quake reported by user at %@";
|
||||
"Sisma forte segnalato da utente a" = "Strong quake reported by user at %@";
|
||||
"Sisma molto forte segnalato da utente a" = "Very strong quake reported by user at %@";
|
||||
"Sisma segnalato da utente a" = "Earthquake reported by the app users at %@";
|
||||
"Sisma lieve segnalato da utente a" = "Mild quake reported by user at %@"; // not used, to be removed
|
||||
"Sisma forte segnalato da utente a" = "Strong quake reported by user at %@"; // not used, to be removed
|
||||
"Sisma molto forte segnalato da utente a" = "Very strong quake reported by user at %@"; // not used, to be removed
|
||||
"Sisma rilevato a" = "Quake detected at %@";
|
||||
"alert_intensity_no_shaking" = "Not felt at your location";
|
||||
"alert_intensity_mild" = "Expect mild or no shaking";
|
||||
@@ -25,7 +26,7 @@
|
||||
"drawer_privacy" = "Privacy";
|
||||
"tab_network" = "ALERTS";
|
||||
"tab_manual" = "REPORTS";
|
||||
"tab_official" = "SEISMIC NETWORKS";
|
||||
"tab_official" = "Quake list";
|
||||
"inapp_available_10k" = "Top 10K: %lu subscriptions still available to be alerted in less than 1 second since the detection of the quake";
|
||||
"inapp_available_100k" = "Top 100K: %lu subscriptions still available to be alerted in less than 5 seconds since the detection of the quake";
|
||||
"filter_filter" = "Choose which earthquakes you want to view";
|
||||
@@ -43,10 +44,11 @@
|
||||
"filter_empty_area" = "Nessun sisma nelle ultime 24 ore in base ai filtri impostati";
|
||||
"filter_empty_relevant" = "No relevant earthquakes in the last 24 hours with respect to your location";
|
||||
"filter_nolocation" = "This option is not available because your location is unknown";
|
||||
"official_filter_changed" = "List filters have been changed in order to show the notified earthquake";
|
||||
"official_provider" = "Source: %@";
|
||||
"share_hashtag" = "#earthquake";
|
||||
"share_notified" = "Reported through the app Earthquake Network. Download the app from https://sismo.app/download/ to receive real time alerts of #earthquake @SismoDetector";
|
||||
"manual_sure" = "Do you really want to notify an earthquake?";
|
||||
"manual_sure" = "Do you really want to report an earthquake?";
|
||||
"manual_yes" = "Yes";
|
||||
"filter_area" = "Quakes shown: in the radius";
|
||||
"filter_relevant" = "Quakes shown: relevant";
|
||||
@@ -214,7 +216,7 @@
|
||||
"attention" = "Attention";
|
||||
"official_no_country_selected" = "You have not selected any country";
|
||||
"report" = "Report";
|
||||
"purchase_pro_restore" = "Restore";
|
||||
"purchase_pro_restore" = "Restore subscriptions";
|
||||
"purchase_pro_restore_alert_title" = "Restore completed";
|
||||
"purchase_pro_restore_alert_message" = "You have restored the product you purchased";
|
||||
"purchase_pro_no_subscriptions_alert_message" = "No purchase was found to restore. Make sure you are logged into the account the purchase was made with.";
|
||||
|
||||
@@ -5,9 +5,10 @@
|
||||
"Rilevato sisma debole a" = "Leve sismo detectado en %@";
|
||||
"Rilevato sisma forte a" = "Fuerte sismo detectado en %@";
|
||||
"Rilevato sisma a" = "Sismo detectado e %@";
|
||||
"Sisma lieve segnalato da utente a" = "Sismo leve informado por un usuario en %@";
|
||||
"Sisma forte segnalato da utente a" = "Fuerte sismo reportado por un usuario en %@";
|
||||
"Sisma molto forte segnalato da utente a" = "Sismo muy fuerte reportado por un usuario en %@";
|
||||
"Sisma segnalato da utente a" = "Sismo reportado por los usuarios de la aplicación en %@";
|
||||
"Sisma lieve segnalato da utente a" = "Sismo leve informado por un usuario en %@"; // not used, to be removed
|
||||
"Sisma forte segnalato da utente a" = "Fuerte sismo reportado por un usuario en %@"; // not used, to be removed
|
||||
"Sisma molto forte segnalato da utente a" = "Sismo muy fuerte reportado por un usuario en %@"; // not used, to be removed
|
||||
"Sisma rilevato a" = "Sismo detectado en %@";
|
||||
"alert_intensity_no_shaking" = "No se siente en tu ubicación";
|
||||
"alert_intensity_mild" = "Espera movimiento leve o nulo";
|
||||
@@ -25,7 +26,7 @@
|
||||
"drawer_privacy" = "Privacy";
|
||||
"tab_network" = "ALERTAS";
|
||||
"tab_manual" = "REPORTES";
|
||||
"tab_official" = "REDES SÍSMICAS";
|
||||
"tab_official" = "Lista sismos";
|
||||
"inapp_available_10k" = "Top 10K: %lu suscripciones aún disponibles para recibir la alerta en menos de 1 segundo a partir de la detección del sismo";
|
||||
"inapp_available_100k" = "Top 100K: %lu suscripciones aún disponibles para recibir la alerta en menos de 5 segundos a partir de la detección del sismo";
|
||||
"filter_filter" = "Elige qué sismos quieres ver";
|
||||
@@ -43,6 +44,7 @@
|
||||
"filter_empty_area" = "No hay sismos en las últimas 24 horas según los filtros";
|
||||
"filter_empty_relevant" = "No hay sismos relevantes en las últimas 24 horas con respecto a tu ubicación";
|
||||
"filter_nolocation" = "Esta opción no está disponible porque tu ubicación es desconocida";
|
||||
"official_filter_changed" = "Los filtros de lista se han cambiado para mostrar el sismo notificado";
|
||||
"official_provider" = "Fuente: %@";
|
||||
"share_hashtag" = "#sismo";
|
||||
"share_notified" = "Reportado a través de la app Sismo Detector. Descarga la app desde https://sismo.app/download/ para recibir alertas de #sismo en tiempo real @SismoDetector";
|
||||
@@ -66,7 +68,7 @@
|
||||
"globe_simulation_message1" = "Con este epicentro, deberías recibir la alerta %.0f segundos antes. Sin embargo, %.0f personas serán alertadas antes que tú. El tiempo de aviso será de %.0f segundos. Al suscribirse hoy al servicio de prioridad TOP 10K, solo %.0f personas recibirán la alerta antes que usted (en orden de distancia del epicentro)";
|
||||
"globe_simulation_message2" = "Con este epicentro, deberías recibir la alerta %.0f segundos antes. Sin embargo, %.0f personas serán alertadas antes que tú. Recibirá la alerta %.0f segundos después de las ondas sísmicas. Al suscribirse hoy al servicio de prioridad TOP 10K, solo %.0f personas recibirán la alerta antes que usted (en orden de distancia del epicentro)";
|
||||
"globe_simulation_message3" = "Con este epicentro, deberías recibir la alerta %.0f segundos antes. Sin embargo, %.0f personas serán alertadas antes que tú. Al suscribirse hoy al servicio de prioridad TOP 10K, solo %.0f personas recibirán la alerta antes que usted (en orden de distancia del epicentro)";
|
||||
"globe_simulation_message4" = "Con este epicentro, gracias al servicio de prioridad %@, deberías recibir la alerta %.0f segundos antes. Solo %@ personas serán alertadas antes que tú";
|
||||
"globe_simulation_message4" = "Con este epicentro, gracias al servicio de prioridad %@, deberías recibir la alerta %.0f segundos antes. Solo %.0f personas serán alertadas antes que tú";
|
||||
"globe_simulation_message5" = "Con este epicentro, gracias al servicio de prioridad %@, deberías recibir la alerta %.0f segundos antes. %.0f personas serán alertadas antes que tú. Para aumentar el tiempo de advertencia, puede suscribirse al servicio de prioridad %@";
|
||||
"globe_simulation_message6" = "Con este epicentro, gracias al servicio de prioridad %@, deberías recibir la alerta %.0f segundos antes. ¡Serás la primera persona en ser alertada!";
|
||||
"globe_simulation_priority" = "Servicio prioritario";
|
||||
@@ -214,7 +216,7 @@
|
||||
"attention" = "Atención";
|
||||
"official_no_country_selected" = "No has seleccionado ningún país";
|
||||
"report" = "Informe";
|
||||
"purchase_pro_restore" = "Restaurar";
|
||||
"purchase_pro_restore" = "Restablecer suscripciones";
|
||||
"purchase_pro_restore_alert_title" = "Restauración completada";
|
||||
"purchase_pro_restore_alert_message" = "Has restaurado el producto que compraste.";
|
||||
"purchase_pro_no_subscriptions_alert_message" = "No se encontró ninguna compra para restaurar. Asegúrese de haber iniciado sesión en la cuenta con la que se realizó la compra.";
|
||||
|
||||
@@ -5,9 +5,10 @@
|
||||
"Rilevato sisma debole a" = "Séisme léger détecté à %@";
|
||||
"Rilevato sisma forte a" = "Fort séisme détecté à %@";
|
||||
"Rilevato sisma a" = "Séisme détecté à %@";
|
||||
"Sisma lieve segnalato da utente a" = "Séisme léger signalé par un utilisateur à %@";
|
||||
"Sisma forte segnalato da utente a" = "Fort séisme signalé par un utilisateur à %@";
|
||||
"Sisma molto forte segnalato da utente a" = "Très fort séisme signalé par un utilisateur à %@";
|
||||
"Sisma segnalato da utente a" = "Séisme signalé par les utilisateurs de l'application à %@";
|
||||
"Sisma lieve segnalato da utente a" = "Séisme léger signalé par un utilisateur à %@"; // not used, to be removed
|
||||
"Sisma forte segnalato da utente a" = "Fort séisme signalé par un utilisateur à %@"; // not used, to be removed
|
||||
"Sisma molto forte segnalato da utente a" = "Très fort séisme signalé par un utilisateur à %@"; // not used, to be removed
|
||||
"Sisma rilevato a" = "Séisme détecté à %@";
|
||||
"alert_intensity_no_shaking" = "Pas ressenti à votre emplacement";
|
||||
"alert_intensity_mild" = "Attendez-vous à des secousses légères ou nulles";
|
||||
@@ -25,7 +26,7 @@
|
||||
"drawer_privacy" = "Confidentialité";
|
||||
"tab_network" = "ALERTES";
|
||||
"tab_manual" = "SIGNALEMENTS";
|
||||
"tab_official" = "RÉSEAUX SISMIQUES";
|
||||
"tab_official" = "Liste des séisme";
|
||||
"inapp_available_10k" = "Top 10K : %lu abonnements encore disponibles pour être alerté en moins de 1 seconde à partir de la détection du séisme";
|
||||
"inapp_available_100k" = "Top 100K : %lu abonnements encore disponibles pour être alerté en moins de 5 secondes à partir de la détection du séisme";
|
||||
"filter_filter" = "Choisissez les tremblements de terre que vous souhaitez visualiser";
|
||||
@@ -43,6 +44,7 @@
|
||||
"filter_empty_area" = "Aucun tremblement de terre au cours des dernières 24 heures selon les filtres";
|
||||
"filter_empty_relevant" = "Aucun tremblement de terre pertinent au cours des dernières 24 heures par rapport à votre emplacement";
|
||||
"filter_nolocation" = "EsCette option n'est pas disponible car votre emplacement est inconnu";
|
||||
"official_filter_changed" = "Les filtres de liste ont été modifiés afin d\'afficher le séisme signalé";
|
||||
"official_provider" = "Source : %@";
|
||||
"share_hashtag" = "#séisme";
|
||||
"share_notified" = "Signalé via l'app Détecteur de Séisme. Téléchargez l'app depuis https://sismo.app/download/ pour recevoir des alertes de #séisme en temps réel @SismoDetector";
|
||||
@@ -214,7 +216,7 @@
|
||||
"attention" = "Attention";
|
||||
"official_no_country_selected" = "Vous n'avez sélectionné aucun pays";
|
||||
"report" = "Signaler";
|
||||
"purchase_pro_restore" = "Restaurer";
|
||||
"purchase_pro_restore" = "Restaurer les abonnements";
|
||||
"purchase_pro_restore_alert_title" = "Restauration terminée";
|
||||
"purchase_pro_restore_alert_message" = "Vous avez restauré le produit que vous avez acheté";
|
||||
"purchase_pro_no_subscriptions_alert_message" = "Aucun achat à restaurer n'a été trouvé. Assurez-vous que vous êtes connecté au compte avec lequel l'achat a été effectué.";
|
||||
|
||||
@@ -5,9 +5,10 @@
|
||||
"Rilevato sisma debole a" = "Blagi potres otkriven u %@";
|
||||
"Rilevato sisma forte a" = "Snažan potres otkriven u %@";
|
||||
"Rilevato sisma a" = "Potres otkriven u %@";
|
||||
"Sisma lieve segnalato da utente a" = "Blagi potres prijavio korisnik u %@";
|
||||
"Sisma forte segnalato da utente a" = "Snažan potres prijavio korisnik u %@";
|
||||
"Sisma molto forte segnalato da utente a" = "Vrlo jak potres prijavio korisnik u %@";
|
||||
"Sisma segnalato da utente a" = "Korisnici aplikacije prijavili potres u %@";
|
||||
"Sisma lieve segnalato da utente a" = "Blagi potres prijavio korisnik u %@"; // not used, to be removed
|
||||
"Sisma forte segnalato da utente a" = "Snažan potres prijavio korisnik u %@"; // not used, to be removed
|
||||
"Sisma molto forte segnalato da utente a" = "Vrlo jak potres prijavio korisnik u %@"; // not used, to be removed
|
||||
"Sisma rilevato a" = "Potres otkriven u %@";
|
||||
"alert_intensity_no_shaking" = "Ne osjeća se na vašoj lokaciji";
|
||||
"alert_intensity_mild" = "Očekujte blago podrhtavanje ili ga nema";
|
||||
@@ -25,7 +26,7 @@
|
||||
"drawer_privacy" = "Privatnost";
|
||||
"tab_network" = "UPOZORENJA";
|
||||
"tab_manual" = "PRIJAVE";
|
||||
"tab_official" = "SEIZMOLOŠKE MREŽE";
|
||||
"tab_official" = "Popis potresa";
|
||||
"inapp_available_10k" = "Top 10K: Dostupan je sljedeći broj pretplata za primanje upozorenja za manje od 1 sekunde od otkrivanja potresa: %lu";
|
||||
"inapp_available_100k" = "Top 100K: Dostupan je sljedeći broj pretplata za primanje upozorenja za manje od 1 sekunde od otkrivanja potresa: %lu";
|
||||
"filter_filter" = "Odaberite koje potrese želite vidjeti";
|
||||
@@ -43,10 +44,11 @@
|
||||
"filter_empty_area" = "Nema potresa u posljednja 24 sata prema filtrima";
|
||||
"filter_empty_relevant" = "Nema relevantnih potresa u posljednja 24 sata u odnosu na vašu lokaciju";
|
||||
"filter_nolocation" = "Ova opcija nije dostupna jer je vaša lokacija nepoznata";
|
||||
"official_filter_changed" = "Filtri popisa su promijenjeni kako bi se prikazao prijavljeni potres";
|
||||
"official_provider" = "Izvor: %@";
|
||||
"share_hashtag" = "#potres";
|
||||
"share_notified" = "Prijavljen putem aplikacije Detektor Potresa. Preuzmite aplikaciju na https://sismo.app/download/ da biste u stvarnom vremenu primali upozorenja kada se dogodi #potres @DetektorPotresa";
|
||||
"manual_sure" = "Želite li zaista poslati obavijest o potresu?";
|
||||
"manual_sure" = "Želite li stvarno poslati izvješće o potresu?";
|
||||
"manual_yes" = "Da";
|
||||
"filter_area" = "Prikazani potresi: u polumjeru";
|
||||
"filter_relevant" = "Prikazani potresi: relevantni";
|
||||
@@ -214,7 +216,7 @@
|
||||
"attention" = "Pažnja";
|
||||
"official_no_country_selected" = "Niste odabrali nijednu zemlju";
|
||||
"report" = "Izvješće";
|
||||
"purchase_pro_restore" = "Vratiti";
|
||||
"purchase_pro_restore" = "Obnovi pretplate";
|
||||
"purchase_pro_restore_alert_title" = "Vraćanje dovršeno";
|
||||
"purchase_pro_restore_alert_message" = "Obnovili ste proizvod koji ste kupili";
|
||||
"purchase_pro_no_subscriptions_alert_message" = "Nije pronađena nijedna kupnja za vraćanje. Obavezno se prijavite na račun s kojim je obavljena kupnja.";
|
||||
|
||||
@@ -5,9 +5,10 @@
|
||||
"Rilevato sisma debole a" = "Gempa ringan terdeteksi di %@";
|
||||
"Rilevato sisma forte a" = "Gempa kuat terdeteksi di %@";
|
||||
"Rilevato sisma a" = "Gempa terdeteksi di %@";
|
||||
"Sisma lieve segnalato da utente a" = "Gempa ringan dilaporkan oleh pengguna di %@";
|
||||
"Sisma forte segnalato da utente a" = "Gempa kuat dilaporkan oleh pengguna di %@";
|
||||
"Sisma molto forte segnalato da utente a" = "Gempa sangat kuat dilaporkan oleh pengguna di %@";
|
||||
"Sisma segnalato da utente a" = "Gempa bumi yang dilaporkan oleh pengguna aplikasi di %@";
|
||||
"Sisma lieve segnalato da utente a" = "Gempa ringan dilaporkan oleh pengguna di %@"; // not used, to be removed
|
||||
"Sisma forte segnalato da utente a" = "Gempa kuat dilaporkan oleh pengguna di %@"; // not used, to be removed
|
||||
"Sisma molto forte segnalato da utente a" = "Gempa sangat kuat dilaporkan oleh pengguna di %@"; // not used, to be removed
|
||||
"Sisma rilevato a" = "Gempa terdeteksi di %@";
|
||||
"alert_intensity_no_shaking" = "Tidak terasa di lokasi Anda";
|
||||
"alert_intensity_mild" = "Harapkan ringan atau tidak ada guncangan";
|
||||
@@ -25,7 +26,7 @@
|
||||
"drawer_privacy" = "Privasi";
|
||||
"tab_network" = "PERINGATAN";
|
||||
"tab_manual" = "LAPORAN";
|
||||
"tab_official" = "JARINGAN SEISMIK";
|
||||
"tab_official" = "Daftar gempa";
|
||||
"inapp_available_10k" = "Top 10K: %lu langganan masih tersedia untuk mendapat peringatan dalam waktu kurang dari 1 detik sejak deteksi gempa";
|
||||
"inapp_available_100k" = "Top 100K: %lu langganan masih tersedia untuk mendapat peringatan dalam waktu kurang dari 5 detik sejak deteksi gempa";
|
||||
"filter_filter" = "Pilih gempa mana yang ingin Anda lihat";
|
||||
@@ -43,6 +44,7 @@
|
||||
"filter_empty_area" = "Tidak ada gempa bumi dalam 24 jam terakhir menurut filter";
|
||||
"filter_empty_relevant" = "Tidak ada gempa bumi yang relevan dalam 24 jam terakhir sehubungan dengan lokasi Anda";
|
||||
"filter_nolocation" = "Opsi ini tidak tersedia karena lokasi Anda tidak diketahui";
|
||||
"official_filter_changed" = "Filter daftar telah diubah untuk menampilkan pemberitahuan gempa";
|
||||
"official_provider" = "Sumber: %@";
|
||||
"share_hashtag" = "#gempa";
|
||||
"share_notified" = "Dilaporkan melalui aplikasi Detektor Gempa. Unduh aplikasi dari https://sismo.app/download/ untuk menerima peringatan real time #gempa @SismoDetector";
|
||||
@@ -214,7 +216,7 @@
|
||||
"attention" = "Perhatian";
|
||||
"official_no_country_selected" = "Anda belum memilih negara mana pun";
|
||||
"report" = "Melaporkan";
|
||||
"purchase_pro_restore" = "Mengembalikan";
|
||||
"purchase_pro_restore" = "Pulihkan langganan";
|
||||
"purchase_pro_restore_alert_title" = "Kembalikan selesai";
|
||||
"purchase_pro_restore_alert_message" = "Anda telah memulihkan produk yang Anda belid";
|
||||
"purchase_pro_no_subscriptions_alert_message" = "Tidak ada pembelian yang ditemukan untuk dipulihkan. Pastikan Anda masuk ke akun tempat pembelian dilakukan.";
|
||||
|
||||
@@ -5,9 +5,10 @@
|
||||
"Rilevato sisma debole a" = "Sisma leggero rilevato a %@";
|
||||
"Rilevato sisma forte a" = "Sisma forte rilevato a %@";
|
||||
"Rilevato sisma a" = "Sisma rilevato a %@";
|
||||
"Sisma lieve segnalato da utente a" = "Sisma lieve segnalato da un utente a %@";
|
||||
"Sisma forte segnalato da utente a" = "Sisma forte segnalato da un utente a %@";
|
||||
"Sisma molto forte segnalato da utente a" = "Sisma molto forte segnalato da un utente at %@";
|
||||
"Sisma segnalato da utente a" = "Sisma segnalato dagli utenti dell'app a %@";
|
||||
"Sisma lieve segnalato da utente a" = "Sisma lieve segnalato da un utente a %@"; // not used, to be removed
|
||||
"Sisma forte segnalato da utente a" = "Sisma forte segnalato da un utente a %@"; // not used, to be removed
|
||||
"Sisma molto forte segnalato da utente a" = "Sisma molto forte segnalato da un utente at %@"; // not used, to be removed
|
||||
"Sisma rilevato a" = "Sisma rilevato a %@";
|
||||
"alert_intensity_no_shaking" = "Non percepito dove ti trovi";
|
||||
"alert_intensity_mild" = "Previsto uno scuotimento leggero o nullo";
|
||||
@@ -25,7 +26,7 @@
|
||||
"drawer_privacy" = "Privacy";
|
||||
"tab_network" = "ALLERTE";
|
||||
"tab_manual" = "SEGNALAZIONI";
|
||||
"tab_official" = "RETI SISMICHE";
|
||||
"tab_official" = "Lista sismi";
|
||||
"inapp_available_10k" = "Top 10K: %lu sottoscrizioni ancora disponibili per essere allertato in meno di 1 secondo dal rilevamento del sisma";
|
||||
"inapp_available_100k" = "Top 100K: %lu sottoscrizioni ancora disponibili per essere allertato in meno di 5 secondi dal rilevamento del sisma";
|
||||
"filter_filter" = "Scegli quali sismi vuoi visualizzare";
|
||||
@@ -43,6 +44,7 @@
|
||||
"filter_empty_area" = "Nessun sisma nelle ultime 24 ore in base ai filtri impostati";
|
||||
"filter_empty_relevant" = "Nessun sisma rilevante nelle ultime 24 ore rispetto alla tua posizione";
|
||||
"filter_nolocation" = "Questa opzione non è disponibile perché la tua posizione è sconosciuta";
|
||||
"official_filter_changed" = "I filtri della lista sono stati modificati per mostrare il sisma notificato";
|
||||
"official_provider" = "Fonte: %@";
|
||||
"share_hashtag" = "#terremoto";
|
||||
"share_notified" = "Segnalato tramite la app Rilevatore Terremoto. Scarica la app da https://sismo.app/download/ per ricevere allerte #terremoto in tempo reale @SismoDetector";
|
||||
@@ -214,7 +216,7 @@
|
||||
"attention" = "Attenzione";
|
||||
"official_no_country_selected" = "Non hai selezionato alcuna nazione";
|
||||
"report" = "Report";
|
||||
"purchase_pro_restore" = "Ripristina";
|
||||
"purchase_pro_restore" = "Ripristina abbonamenti";
|
||||
"purchase_pro_restore_alert_title" = "Ripristino completato";
|
||||
"purchase_pro_restore_alert_message" = "Hai ripristinato il prodotto che avevi acquistato";
|
||||
"purchase_pro_no_subscriptions_alert_message" = "Non è stato trovato alcun prodotto da ripristinare. Assicurati di essere registrato con l'account dal quale avevi fatto l'acquisto.";
|
||||
|
||||
@@ -5,9 +5,10 @@
|
||||
"Rilevato sisma debole a" = "%@'da hafif deprem tespit edildi";
|
||||
"Rilevato sisma forte a" = "%@'da şiddetli deprem tespit edildi";
|
||||
"Rilevato sisma a" = "%@'da deprem tespit edildi";
|
||||
"Sisma lieve segnalato da utente a" = "%@da kullanıcı tarafından bildirilen hafif deprem";
|
||||
"Sisma forte segnalato da utente a" = "%@'da kullanıcı tarafından bildirilen şiddetli deprem";
|
||||
"Sisma molto forte segnalato da utente a" = "@'da kullanıcı tarafından bildirilen çok şiddetli deprem";
|
||||
"Sisma segnalato da utente a" = "Uygulama kullanıcıları tarafından %@'de bildirilen deprem";
|
||||
"Sisma lieve segnalato da utente a" = "%@da kullanıcı tarafından bildirilen hafif deprem"; // not used, to be removed
|
||||
"Sisma forte segnalato da utente a" = "%@'da kullanıcı tarafından bildirilen şiddetli deprem"; // not used, to be removed
|
||||
"Sisma molto forte segnalato da utente a" = "@'da kullanıcı tarafından bildirilen çok şiddetli deprem"; // not used, to be removed
|
||||
"Sisma rilevato a" = "%@'da deprem tespit edildi";
|
||||
"alert_intensity_no_shaking" = "Bulunduğunuz yerde hissedilmiyor";
|
||||
"alert_intensity_mild" = "Hafif veya hiç titreme beklemeyin";
|
||||
@@ -25,7 +26,7 @@
|
||||
"drawer_privacy" = "Gizlilik";
|
||||
"tab_network" = "UYARILAR";
|
||||
"tab_manual" = "RAPORLAR";
|
||||
"tab_official" = "SİSMİK AĞLAR";
|
||||
"tab_official" = "Deprem listesi";
|
||||
"inapp_available_10k" = "Top 10K: Hala depremin tespitinden itibaren 1 saniyeden daha kısa süre içinde uyarı alacak %lu abonelik mevcut";
|
||||
"inapp_available_100k" = "Top 100K: Hala depremin tespitinden itibaren 5 saniyeden daha kısa süre içinde uyarı alacak %lu abonelik mevcut";
|
||||
"filter_filter" = "Görüntülemek istediğiniz depremleri seçin";
|
||||
@@ -43,6 +44,7 @@
|
||||
"filter_empty_area" = "Filtrelere göre son 24 saatte deprem yok";
|
||||
"filter_empty_relevant" = "Son 24 saat içinde konumunuza göre alakalı deprem yok";
|
||||
"filter_nolocation" = "Konumunuz bilinmediğinden bu seçenek kullanılamıyor";
|
||||
"official_filter_changed" = "Bildirilen depremin gösterilmesi için liste filtreleri değiştirildi";
|
||||
"official_provider" = "Kaynak: %@";
|
||||
"share_hashtag" = "#deprem";
|
||||
"share_notified" = "Deprem Ağı uygulaması aracılığıyla bildirildi. @SismoDetector gerçek zamanlı #deprem uyarılarını almak için uygulamayı https://sismo.app/download/ adresinden indirin.";
|
||||
@@ -214,7 +216,7 @@
|
||||
"attention" = "Dikkat";
|
||||
"official_no_country_selected" = "Herhangi bir ülke seçmediniz";
|
||||
"report" = "Bildiri";
|
||||
"purchase_pro_restore" = "Geri yükle";
|
||||
"purchase_pro_restore" = "Abonelikleri geri yükle";
|
||||
"purchase_pro_restore_alert_title" = "Geri yükleme tamamlandı";
|
||||
"purchase_pro_restore_alert_message" = "Satın aldığınız ürünü geri yüklediniz";
|
||||
"purchase_pro_no_subscriptions_alert_message" = "Geri yüklenecek satın alma bulunamadı. Satın alma işleminin yapıldığı hesapta oturum açtığınızdan emin olun.";
|
||||
|
||||
Reference in New Issue
Block a user