feat: Add simulator function
This commit is contained in:
@@ -209,6 +209,7 @@
|
||||
DCAA913F24F68A1D00145A3D /* SettingMultivaluesTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCAA913E24F68A1D00145A3D /* SettingMultivaluesTableViewCell.swift */; };
|
||||
DCB28CEE24FB8400001F557E /* SettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCB28CED24FB8400001F557E /* SettingsViewController.swift */; };
|
||||
DCB45BC8250E86E100DB2D0C /* SeismicSettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCB45BC7250E86E100DB2D0C /* SeismicSettingsViewController.swift */; };
|
||||
DCB528212560161C005288E5 /* AlertSimulatorViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCB528202560161C005288E5 /* AlertSimulatorViewController.swift */; };
|
||||
DCB6FBEC24D0B40600ED23B8 /* Colors.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DCB6FBEB24D0B40600ED23B8 /* Colors.xcassets */; };
|
||||
DCBB267A24D1E7F500F04559 /* SubscriptionsHeaderTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCBB267924D1E7F500F04559 /* SubscriptionsHeaderTableViewCell.swift */; };
|
||||
DCBB267C24D1E98300F04559 /* EQNInsetTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCBB267B24D1E98300F04559 /* EQNInsetTableViewCell.swift */; };
|
||||
@@ -517,6 +518,7 @@
|
||||
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>"; };
|
||||
DCB45BC7250E86E100DB2D0C /* SeismicSettingsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeismicSettingsViewController.swift; sourceTree = "<group>"; };
|
||||
DCB528202560161C005288E5 /* AlertSimulatorViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertSimulatorViewController.swift; sourceTree = "<group>"; };
|
||||
DCB6FBEB24D0B40600ED23B8 /* Colors.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Colors.xcassets; sourceTree = "<group>"; };
|
||||
DCBB267924D1E7F500F04559 /* SubscriptionsHeaderTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscriptionsHeaderTableViewCell.swift; sourceTree = "<group>"; };
|
||||
DCBB267B24D1E98300F04559 /* EQNInsetTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EQNInsetTableViewCell.swift; sourceTree = "<group>"; };
|
||||
@@ -993,6 +995,14 @@
|
||||
path = Commands;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
DCB5281F256015EB005288E5 /* Simulator */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
DCB528202560161C005288E5 /* AlertSimulatorViewController.swift */,
|
||||
);
|
||||
path = Simulator;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
DCB528252560171A005288E5 /* Reports */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -1039,6 +1049,7 @@
|
||||
DCD3E3BE24D1555F007C78D4 /* InApp */,
|
||||
DCEFF21024F57163009D3FE1 /* Settings */,
|
||||
DC141968250E769B0059E060 /* Seismic Networks */,
|
||||
DCB5281F256015EB005288E5 /* Simulator */,
|
||||
);
|
||||
path = Controllers;
|
||||
sourceTree = "<group>";
|
||||
@@ -1560,6 +1571,7 @@
|
||||
DC105641251E7ECE002579BB /* UIFont+Extensions.swift in Sources */,
|
||||
8CA46BA12194532E00C63C16 /* SismaAnnotation.m in Sources */,
|
||||
DCB28CEE24FB8400001F557E /* SettingsViewController.swift in Sources */,
|
||||
DCB528212560161C005288E5 /* AlertSimulatorViewController.swift in Sources */,
|
||||
DCC76BD8251F56050005C4DC /* SeismicCardSettingsViewController.swift in Sources */,
|
||||
DC3CE50A250EB7A8005A7DD5 /* EQNGenericPickerViewController.swift in Sources */,
|
||||
8C602246218D9DB200C799C2 /* PastquakesDettagliMappa.m in Sources */,
|
||||
|
||||
@@ -195,11 +195,11 @@ typedef NS_ENUM(NSInteger, AllerteTableRow) {
|
||||
[self presentViewController:controller animated:YES completion:nil];
|
||||
}
|
||||
|
||||
- (void)actionComingSoon
|
||||
- (void)actionOpenSimulator
|
||||
{
|
||||
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Coming soon..." message:@"🚀" preferredStyle:UIAlertControllerStyleAlert];
|
||||
[alert addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"OK", nil) style:UIAlertActionStyleDefault handler:nil]];
|
||||
[self presentViewController:alert animated:YES completion:nil];
|
||||
AlertSimulatorViewController *controller = [[AlertSimulatorViewController alloc] init];
|
||||
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:controller];
|
||||
[self presentViewController:navController animated:YES completion:nil];
|
||||
}
|
||||
|
||||
- (void)actionHowItWorks
|
||||
@@ -281,7 +281,7 @@ typedef NS_ENUM(NSInteger, AllerteTableRow) {
|
||||
[weakSelf actionTestPush];
|
||||
};
|
||||
cell.onTapSimulator = ^{
|
||||
[weakSelf actionComingSoon];
|
||||
[weakSelf actionOpenSimulator];
|
||||
};
|
||||
cell.onTapHowItWorks = ^{
|
||||
[weakSelf actionHowItWorks];
|
||||
|
||||
@@ -0,0 +1,244 @@
|
||||
//
|
||||
// AlertSimulatorViewController.swift
|
||||
// Earthquake Network
|
||||
//
|
||||
// Created by Busi Andrea on 14/11/2020.
|
||||
// Copyright © 2020 Earthquake Network. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import MapKit
|
||||
|
||||
class AlertSimulatorViewController: UIViewController, MKMapViewDelegate {
|
||||
|
||||
struct MapCircle {
|
||||
let identifier: String
|
||||
let distance: CLLocationDistance
|
||||
let color: UIColor
|
||||
}
|
||||
|
||||
// MARK: - Internal
|
||||
|
||||
private let mapCircles = [
|
||||
MapCircle(identifier: "circle_internal", distance: 50_000, color: AppTheme.Colors.red),
|
||||
MapCircle(identifier: "circle_external", distance: 750_000, color: AppTheme.Colors.green)
|
||||
]
|
||||
|
||||
private lazy var viewfinderView: UIView = {
|
||||
let view = UIView()
|
||||
view.translatesAutoresizingMaskIntoConstraints = false
|
||||
view.backgroundColor = .clear
|
||||
view.isUserInteractionEnabled = false
|
||||
|
||||
// add central vertiacl and horizontal lines
|
||||
let viewfinderVertical = UIView()
|
||||
view.addSubview(viewfinderVertical)
|
||||
viewfinderVertical.translatesAutoresizingMaskIntoConstraints = false
|
||||
viewfinderVertical.backgroundColor = AppTheme.Colors.lightBlue
|
||||
viewfinderVertical.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
|
||||
viewfinderVertical.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
|
||||
viewfinderVertical.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
|
||||
viewfinderVertical.widthAnchor.constraint(equalToConstant: 2.0).isActive = true
|
||||
|
||||
let viewfinderHorizontal = UIView()
|
||||
view.addSubview(viewfinderHorizontal)
|
||||
viewfinderHorizontal.translatesAutoresizingMaskIntoConstraints = false
|
||||
viewfinderHorizontal.backgroundColor = AppTheme.Colors.lightBlue
|
||||
viewfinderHorizontal.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
|
||||
viewfinderHorizontal.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
|
||||
viewfinderHorizontal.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
|
||||
viewfinderHorizontal.heightAnchor.constraint(equalToConstant: 2.0).isActive = true
|
||||
|
||||
return view
|
||||
}()
|
||||
|
||||
private lazy var mapView: MKMapView = {
|
||||
let map = MKMapView()
|
||||
map.translatesAutoresizingMaskIntoConstraints = false
|
||||
map.showsUserLocation = true
|
||||
map.delegate = self
|
||||
return map
|
||||
}()
|
||||
|
||||
private lazy var calculateButton: UIButton = {
|
||||
let button = EQNRoundedButton(type: .custom)
|
||||
button.backgroundColor = .lightGray
|
||||
button.setTitleColor(AppTheme.Colors.darkGray, for: .normal)
|
||||
button.translatesAutoresizingMaskIntoConstraints = false
|
||||
button.setTitle(NSLocalizedString("globe_simulation_button", comment: "").uppercased(), for: .normal)
|
||||
button.addTarget(self, action: #selector(calculateTapped(_:)), for: .touchUpInside)
|
||||
return button
|
||||
}()
|
||||
|
||||
// MARK: - View Lifecycle
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
let closeButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(closeTapped(_:)))
|
||||
navigationItem.rightBarButtonItem = closeButton
|
||||
|
||||
setupUI()
|
||||
configureMap()
|
||||
}
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
super.viewWillAppear(animated)
|
||||
|
||||
// show an alert view functionality details
|
||||
let alert = UIAlertController(title: NSLocalizedString("main_simulator", comment: ""), message: NSLocalizedString("globe_simulation", comment: ""), preferredStyle: .alert)
|
||||
alert.addAction(UIAlertAction(title: NSLocalizedString("main_understood", comment: ""), style: .default))
|
||||
present(alert, animated: true)
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
private func setupUI() {
|
||||
view.addSubview(mapView)
|
||||
view.addSubview(viewfinderView)
|
||||
view.addSubview(calculateButton)
|
||||
|
||||
mapView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
|
||||
mapView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
|
||||
mapView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
|
||||
mapView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
|
||||
|
||||
viewfinderView.topAnchor.constraint(equalTo: mapView.topAnchor).isActive = true
|
||||
viewfinderView.bottomAnchor.constraint(equalTo: mapView.bottomAnchor).isActive = true
|
||||
viewfinderView.leftAnchor.constraint(equalTo: mapView.leftAnchor).isActive = true
|
||||
viewfinderView.rightAnchor.constraint(equalTo: mapView.rightAnchor).isActive = true
|
||||
|
||||
calculateButton.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20.0).isActive = true
|
||||
calculateButton.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20.0).isActive = true
|
||||
calculateButton.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -10.0).isActive = true
|
||||
calculateButton.heightAnchor.constraint(equalToConstant: 40.0).isActive = true
|
||||
}
|
||||
|
||||
private func configureMap() {
|
||||
guard let lastPosition = EQNUser.default().lastPosition else { return }
|
||||
|
||||
let span = MKCoordinateSpan(latitudeDelta: 2.0, longitudeDelta: 2.0)
|
||||
let region = MKCoordinateRegion(center: lastPosition.coordinate, span: span)
|
||||
mapView.setCenter(lastPosition.coordinate, animated: false)
|
||||
mapView.setRegion(region, animated: true)
|
||||
|
||||
mapCircles.forEach { (mapCircle) in
|
||||
addCircle(location: lastPosition, radius: mapCircle.distance, id: mapCircle.identifier)
|
||||
}
|
||||
}
|
||||
|
||||
private func addCircle(location: CLLocation, radius: CLLocationDistance, id: String) {
|
||||
let circle = MKCircle(center: location.coordinate, radius: radius)
|
||||
circle.title = id
|
||||
mapView.addOverlay(circle)
|
||||
}
|
||||
|
||||
// MARK: - Actions
|
||||
|
||||
@objc func closeTapped(_ sender: Any) {
|
||||
dismiss(animated: true)
|
||||
}
|
||||
|
||||
@objc func calculateTapped(_ sender: Any) {
|
||||
guard let lastPosition = EQNUser.default().lastPosition,
|
||||
let circleMin = mapCircles.sorted(by: { $0.distance < $1.distance }).first,
|
||||
let circleMax = mapCircles.sorted(by: { $0.distance > $1.distance }).first else { return }
|
||||
|
||||
let location = CLLocation(latitude: mapView.centerCoordinate.latitude, longitude: mapView.centerCoordinate.longitude)
|
||||
let distance = lastPosition.distance(from: location)
|
||||
|
||||
// check for a valid point selected by the user
|
||||
if distance < circleMin.distance || distance > circleMax.distance {
|
||||
let message = distance < circleMin.distance ? "globe_simulation_outside" : "globe_simulation_inside"
|
||||
|
||||
let alert = UIAlertController(title: NSLocalizedString("Attenzione", comment: ""), message: NSLocalizedString(message, comment: ""), preferredStyle: .alert)
|
||||
alert.addAction(UIAlertAction(title: NSLocalizedString("Ok", comment: ""), style: .cancel, handler: nil))
|
||||
present(alert, animated: true)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
let url = EQNGeneratoreURLServer.urlAlertSimulator()
|
||||
ServerRequest.default().inviaInformazioniAlServer(with: url, richiesta: .alertSimulator) { (result) in
|
||||
if let result = result as? String {
|
||||
DispatchQueue.main.async {
|
||||
self.elaborateServerResponse(result, distance: distance)
|
||||
}
|
||||
}
|
||||
} failure: { (error) in
|
||||
DispatchQueue.main.async {
|
||||
let alert = UIAlertController(title: NSLocalizedString("Attenzione", comment: ""), message: error?.localizedDescription, preferredStyle: .alert)
|
||||
alert.addAction(UIAlertAction(title: NSLocalizedString("Ok", comment: ""), style: .cancel, handler: nil))
|
||||
self.present(alert, animated: true)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func elaborateServerResponse(_ response: String, distance: CLLocationDistance) {
|
||||
let isTop10k = EQNPurchaseUtility.isTop10kEnabled()
|
||||
let isTop100k = EQNPurchaseUtility.isTop100kEnabled()
|
||||
|
||||
// server response (like '3411#12')
|
||||
let split = response.split(separator: "#")
|
||||
|
||||
let people: Int
|
||||
let popleTop10k: Int
|
||||
if split.count > 1 {
|
||||
//caso top10k=0 e top100k=0
|
||||
people = Int(split[0]) ?? 0
|
||||
popleTop10k = Int(split[1]) ?? 0
|
||||
} else {
|
||||
//caso top10k=1 oppure top100k=1
|
||||
people = Int(split[0]) ?? 0
|
||||
popleTop10k = 0
|
||||
}
|
||||
|
||||
let distanceKm = distance / 1000
|
||||
let delay = round(Double(people) / 1000.0 * 0.15) //calcolo il ritardo di allerta dovuto alla coda di utenti
|
||||
let leadTime = round(Double(distanceKm) / 8.0 - 3.0) //calcolo il tempo di allerta teorico nel caso di 0 utenti in coda
|
||||
let actualTime = leadTime - delay //calcolo il tempo di allerta per l'utente
|
||||
|
||||
//il messaggio mostrato all'utente cambia in base al fatto di possedere un abbonamento ed al tempo di allerta calcolato
|
||||
//il messaggio include tag html perché cambio il colore di parte delle stringa, non so se si fa così anche in iOS
|
||||
var message = ""
|
||||
if (isTop10k) {
|
||||
if (people == 0) {
|
||||
message = String(format: NSLocalizedString("globe_simulation_message6", comment: ""), "TOP 10K", leadTime)
|
||||
} else {
|
||||
message = String(format: NSLocalizedString("globe_simulation_message4", comment: ""), "TOP 10K", leadTime, Double(people))
|
||||
}
|
||||
} else if (isTop100k) {
|
||||
message = String(format: NSLocalizedString("globe_simulation_message5", comment: ""), "TOP 100K", leadTime, Double(people), "TOP 10K")
|
||||
} else {
|
||||
if (leadTime / actualTime < 1.4) {
|
||||
message = String(format: NSLocalizedString("globe_simulation_message3", comment: ""), leadTime, Double(people), Double(popleTop10k))
|
||||
} else {
|
||||
if (actualTime > 0) {
|
||||
message = String(format: NSLocalizedString("globe_simulation_message1", comment: ""), leadTime, Double(people), actualTime, Double(popleTop10k))
|
||||
} else {
|
||||
let updatedActualTime = actualTime * -1;
|
||||
message = String(format: NSLocalizedString("globe_simulation_message2", comment: ""), leadTime, Double(people), updatedActualTime, Double(popleTop10k))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let alert = UIAlertController(title: NSLocalizedString("main_simulator", comment: ""), message: message, preferredStyle: .alert)
|
||||
alert.addAction(UIAlertAction(title: NSLocalizedString("Ok", comment: ""), style: .cancel, handler: nil))
|
||||
present(alert, animated: true)
|
||||
}
|
||||
|
||||
// MARK: MKMapViewDelegate
|
||||
|
||||
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
|
||||
if let overlay = overlay as? MKCircle, let mapCircle = mapCircles.first(where: { $0.identifier == overlay.title }) {
|
||||
let circle = MKCircleRenderer(overlay: overlay)
|
||||
circle.strokeColor = mapCircle.color
|
||||
circle.fillColor = AppTheme.Colors.green.withAlphaComponent(0.1)
|
||||
circle.lineWidth = 2.0
|
||||
return circle
|
||||
}
|
||||
|
||||
return MKOverlayRenderer(overlay: overlay)
|
||||
}
|
||||
}
|
||||
@@ -37,7 +37,7 @@ static NSString * const EQNServerUrlOfferTimeRemaining = @"https://srv.earthquak
|
||||
static NSString * const EQNServerUrlAvailableSubscriptionsCounter = @"https://srv.earthquakenetwork.it/distquake_count_top_redis.php";
|
||||
/// Carica le impostazioni delle notifiche definite dall'utente
|
||||
static NSString * const EQNServerUrlUploadSettings = @"https://srv.earthquakenetwork.it/distquake_upload_settings_ios.php";
|
||||
// URL registrazione server
|
||||
// URL EQNTipoChiamataRegistrazione server
|
||||
static NSString * const EQNServerUrlRegistration = @"https://srv.earthquakenetwork.it/distquake_upload_gcm_regid2.php";
|
||||
// URL posizione server
|
||||
static NSString * const EQNServerUrlUserLocation = @"https://srv.earthquakenetwork.it/distquake_upload_gcm_latlon.php";
|
||||
@@ -56,6 +56,8 @@ static NSString * const EQNServerUrlSendUserReport = @"https://srv.earthquakenet
|
||||
static NSString * const EQNServerUrlSendUserReportMessage = @"https://srv.earthquakenetwork.it/distquake_upload_manual_message.php";
|
||||
/// Effettua un test delle notifiche push
|
||||
static NSString * const EQNServerUrlTestAlarm = @"https://srv.earthquakenetwork.it/distquake_upload_testalarm.php";
|
||||
/// Simulatore per calcolo pre-allerta
|
||||
static NSString * const EQNServerUrlAlertSimulator = @"https://srv.earthquakenetwork.it/distquake_download_alertposition.php";
|
||||
|
||||
#pragma mark - UserDefaults Keys
|
||||
|
||||
@@ -142,7 +144,8 @@ typedef NS_ENUM(NSInteger, EQNTipoChiamata) {
|
||||
EQNTipoChiamataCommentoTerremoto,
|
||||
EQNTipoChiamataImpostazioniNotifiche,
|
||||
EQNTipoChiamataOfferTimeRemaining,
|
||||
EQNTipoChiamataAlertPushTest
|
||||
EQNTipoChiamataAlertPushTest,
|
||||
EQNTipoChiamataAlertSimulator
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -12,3 +12,5 @@
|
||||
#import "ReteSismiDettagliMappa.h"
|
||||
#import "SettingsBaseViewController.h"
|
||||
#import "PastquakesAnnotation.h"
|
||||
#import "EQNGeneratoreURLServer.h"
|
||||
#import "ServerRequest.h"
|
||||
|
||||
@@ -20,7 +20,7 @@ typedef void (^errorCompletionHandler)(NSError * _Nullable error);
|
||||
@property (nonatomic) BOOL isConnect;
|
||||
|
||||
|
||||
+ (instancetype)defaultServerConnectionSingleton;
|
||||
+ (instancetype)defaultServerConnectionSingleton NS_SWIFT_NAME(default());
|
||||
|
||||
- (void)inviaInformazioniAlServerWithURL:(NSURL *)url richiesta:(EQNTipoChiamata)chiamata success:(successCompletionHandler)onSuccess failure:(errorCompletionHandler)onFailure;
|
||||
|
||||
|
||||
@@ -112,6 +112,9 @@
|
||||
case EQNTipoChiamataPosizione:
|
||||
onSuccess(@"success");
|
||||
break;
|
||||
case EQNTipoChiamataAlertSimulator:
|
||||
onSuccess([NSString stringWithFormat:@"%@", JSON]);
|
||||
break;
|
||||
default:
|
||||
onSuccess(JSON);
|
||||
break;
|
||||
@@ -135,9 +138,8 @@
|
||||
onSuccess([EQNUtility clearStringMessaggi:newStr]);
|
||||
break;
|
||||
case EQNTipoChiamataCalibrazione:
|
||||
onSuccess(newStr);
|
||||
break;
|
||||
case EQNTipoChiamataImpostazioniNotifiche:
|
||||
case EQNTipoChiamataAlertSimulator:
|
||||
onSuccess(newStr);
|
||||
default:
|
||||
// don't call the callback
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<device id="retina6_1" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17125"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17126"/>
|
||||
<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"/>
|
||||
@@ -2001,7 +2001,7 @@ Sisma rilevato da 10 smartphone</string>
|
||||
<rect key="frame" x="8" y="68" width="382" height="40"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="BjK-4E-Vhw" customClass="EQNRoundedButton" customModule="Earthquake_Network" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="0.0" width="382" height="40"/>
|
||||
<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="TEST ALERT 🚨">
|
||||
<color key="titleColor" name="Gray (dark)"/>
|
||||
@@ -2010,8 +2010,8 @@ Sisma rilevato da 10 smartphone</string>
|
||||
<action selector="testAlertTapped" destination="vSa-gk-t22" eventType="touchUpInside" id="HNp-eo-vpW"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button hidden="YES" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="qkR-Lg-s4B" customClass="EQNRoundedButton" customModule="Earthquake_Network" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="0.0" width="0.0" height="40"/>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="qkR-Lg-s4B" 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="SIMULATOR ⏱">
|
||||
<color key="titleColor" name="Gray (dark)"/>
|
||||
@@ -2107,13 +2107,13 @@ Sisma rilevato da 10 smartphone</string>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" distribution="equalSpacing" alignment="center" spacing="4" translatesAutoresizingMaskIntoConstraints="NO" id="0lY-aw-fec">
|
||||
<rect key="frame" x="11.5" y="0.0" width="106.5" height="25"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Last 24h:" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="hbH-vC-Yma">
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="Last 24h:" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="hbH-vC-Yma">
|
||||
<rect key="frame" x="0.0" y="0.0" width="89" height="25"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="22"/>
|
||||
<color key="textColor" name="Gray (dark)"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="0" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="BRv-IS-2fA">
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="0" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="BRv-IS-2fA">
|
||||
<rect key="frame" x="93" y="0.0" width="13.5" height="25"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="22"/>
|
||||
<color key="textColor" name="Gray (dark)"/>
|
||||
|
||||
@@ -642,3 +642,17 @@
|
||||
"hours_other" = "%lu hours ago";
|
||||
"days_one" = "%lu day ago";
|
||||
"days_other" = "%lu days ago";
|
||||
|
||||
// Simulatore
|
||||
"main_simulator" = "Simulator";
|
||||
"globe_simulation_button" = "Compute warning time";
|
||||
"globe_simulation" = "If the earthquake epicentre is outside the red disk and the quake is immediately detected by the smartphones, you will receive the alert more than 5 seconds in advance. Select on map the possible epicentre in order to compute the warning time.";
|
||||
"globe_simulation_inside" = "Select a location inside the green disk";
|
||||
"globe_simulation_outside" = "Select a location outside the red disk";
|
||||
"globe_simulation_message1" = "With this epicentre, you should receive the alert %.0f seconds in advance. However, %.0f people will be alerted before you. The warning time will be of %.0f seconds. By subscribing now to the TOP 10K priority service, only %.0f people will be alerted before you (in order of distance from the epicenter)";
|
||||
"globe_simulation_message2" = "With this epicentre, you should receive the alert %.0f seconds in advance. However, %.0f people will be alerted before you. You will receive the alert %.0f seconds after the seismic waves. By subscribing now to the TOP 10K priority service, only %.0f people will be alerted before you (in order of distance from the epicenter)";
|
||||
"globe_simulation_message3" = "With this epicentre, you should receive the alert %.0f seconds in advance. However, %.0f people will be alerted before you. By subscribing now to the TOP 10K priority service, only %.0f people will be alerted before you (in order of distance from the epicenter)";
|
||||
"globe_simulation_message4" = "With this epicentre, thanks to the %@ priority service you should receive the alert %.0f seconds in advance. Only %.0f people will be alerted before you.";
|
||||
"globe_simulation_message5" = "With this epicentre, thanks to the %@ priority service you should receive the alert %.0f seconds in advance. %.0f people will be alerted before you. To increase the warning time you can subscribe to the %@ priority service";
|
||||
"globe_simulation_message6" = "With this epicentre, thanks to the %@ priority service you should receive the alert %.0f seconds in advance. You will be the first to be alerted!";
|
||||
"globe_simulation_priority" = "Priority service";
|
||||
|
||||
@@ -638,3 +638,17 @@
|
||||
"hours_other" = "%lu horas";
|
||||
"days_one" = "%lu día";
|
||||
"days_other" = "%lu días";
|
||||
|
||||
// Simulatore
|
||||
"main_simulator" = "Simulador";
|
||||
"globe_simulation_button" = "Calcular el tiempo de alerta";
|
||||
"globe_simulation" = "Si el epicentro del sismo está fuera del disco rojo y los smartphones lo detectan de inmediato, recibirá la alerta con más de 5 segundos de anticipación. Seleccionas en el mapa el posible epicentro para calcular el tiempo de alerta.";
|
||||
"globe_simulation_inside" = "Seleccionas una ubicación dentro del disco verde";
|
||||
"globe_simulation_outside" = "Seleccionas una ubicación fuera del disco rojo";
|
||||
"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 %.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";
|
||||
|
||||
@@ -630,3 +630,18 @@
|
||||
"hours_other" = "%lu ore fa";
|
||||
"days_one" = "%lu giorno fa";
|
||||
"days_other" = "%lu giorni fa";
|
||||
|
||||
// Simulatore
|
||||
"main_simulator" = "Simulatore";
|
||||
"globe_simulation_button" = "Calcola pre-allerta";
|
||||
"globe_simulation" = "Se l'epicentro del sisma è al di fuori del cerchio rosso ed è rilevato immediatamente dagli smartphone, potrai ricevere l'allerta con più di 5 secondi di anticipo. Seleziona su mappa il possibile epicentro del sisma per calcolare il tempo di pre-allerta.";
|
||||
"globe_simulation_inside" = "Seleziona un punto dentro il cerchio verde";
|
||||
"globe_simulation_outside" = "Seleziona un punto fuori dal cerchio rosso";
|
||||
"globe_simulation_message1" = "Con epicentro nella posizione scelta, dovresti ricevere l'allerta con %.0f secondi di anticipo. Tuttavia, prima di te devono essere allertate %.0f persone. Il tempo di preavviso sarà di %.0f secondi. Iscrivendoti oggi al servizio di priorità TOP 10K, solamente %.0f persone saranno allertate prima di te (in ordine di distanza dall'epicentro)";
|
||||
"globe_simulation_message2" = "Con epicentro nella posizione scelta, dovresti ricevere l'allerta con %.0f secondi di anticipo. Tuttavia, prima di te devono essere allertate %.0f persone. L'allerta sarà ricevuta con %.0f secondi di ritardo. Iscrivendoti oggi al servizio di priorità TOP 10K, solamente %.0f persone saranno allertate prima di te (in ordine di distanza dall'epicentro)";
|
||||
"globe_simulation_message3" = "Con epicentro nella posizione scelta, dovresti ricevere l'allerta con %.0f secondi di anticipo. Tuttavia, prima di te devono essere allertate %.0f persone. Iscrivendoti oggi al servizio di priorità TOP 10K, solamente %.0f persone saranno allertate prima di te (in ordine di distanza dall'epicentro)";
|
||||
"globe_simulation_message4" = "Con epicentro nella posizione scelta, grazie al servizio prioritario %@ dovresti ricevere l'allerta con %.0f secondi di anticipo. Prima di te devono essere allertate solo %.0f persone.";
|
||||
"globe_simulation_message5" = "Con epicentro nella posizione scelta, grazie al servizio prioritario %@ dovresti ricevere l'allerta con %.0f secondi di anticipo. Prima di te devono essere allertate %.0f persone. Puoi aumentare il tempo di pre-allerta iscrivendoti al servizio di priorità %@";
|
||||
"globe_simulation_message6" = "Con epicentro nella posizione scelta, grazie al servizio prioritario %@ dovresti ricevere l'allerta con %.0f secondi di anticipo. Sarai il primo ad essere allertato!";
|
||||
"globe_simulation_priority" = "Servizio priorità";
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
+ (NSURL *)urlInvioImpostazioniNotifiche;
|
||||
+ (NSURL *)urlDownloadOfferTimeRemaining;
|
||||
+ (NSURL *)urlAlertPushTest;
|
||||
+ (NSURL *)urlAlertSimulator;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -251,6 +251,16 @@
|
||||
return [NSURL URLWithString:stringUrl];
|
||||
}
|
||||
|
||||
+ (NSURL *)urlAlertSimulator
|
||||
{
|
||||
CLLocationCoordinate2D userLastPosition = [EQNUser defaultUser].lastPosition.coordinate;
|
||||
CLLocationDistance distance = 100;
|
||||
NSInteger top10k = EQNPurchaseUtility.isTop10kEnabled ? 1 : 0;
|
||||
NSInteger top100k = EQNPurchaseUtility.isTop100kEnabled ? 1 : 0;
|
||||
NSString *stringUrl = [NSString stringWithFormat:@"%@?lat=%f&lon=%f&dis=%f&top10k=%lu&top100k=%lu", EQNServerUrlAlertSimulator, userLastPosition.latitude, userLastPosition.longitude, distance, (long)top10k, (long)top100k];
|
||||
return [NSURL URLWithString:stringUrl];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user