diff options
author | Ilya Grechuhin <i.grechuhin@gmail.com> | 2016-12-15 11:15:41 +0300 |
---|---|---|
committer | Ilya Grechuhin <i.grechuhin@gmail.com> | 2016-12-15 18:08:43 +0300 |
commit | 8651506dc68d6643c16f20fa5c0a382ac499cd7f (patch) | |
tree | 4e6fe35074f9c04592d8c80b02808bd5b28f4ca5 /iphone/Maps/Settings | |
parent | ec9c0cd876b66d37b31116f3483ed7fc5241f62c (diff) |
[swift] [ios] Moved settings files to designated folders.
Diffstat (limited to 'iphone/Maps/Settings')
25 files changed, 1295 insertions, 0 deletions
diff --git a/iphone/Maps/Settings/LinkCell.h b/iphone/Maps/Settings/Cells/LinkCell.h index abbfce412d..abbfce412d 100644 --- a/iphone/Maps/Settings/LinkCell.h +++ b/iphone/Maps/Settings/Cells/LinkCell.h diff --git a/iphone/Maps/Settings/LinkCell.mm b/iphone/Maps/Settings/Cells/LinkCell.mm index 1ca486d125..1ca486d125 100644 --- a/iphone/Maps/Settings/LinkCell.mm +++ b/iphone/Maps/Settings/Cells/LinkCell.mm diff --git a/iphone/Maps/Settings/SelectableCell.h b/iphone/Maps/Settings/Cells/SelectableCell.h index d86d8819d1..d86d8819d1 100644 --- a/iphone/Maps/Settings/SelectableCell.h +++ b/iphone/Maps/Settings/Cells/SelectableCell.h diff --git a/iphone/Maps/Settings/SelectableCell.mm b/iphone/Maps/Settings/Cells/SelectableCell.mm index 289e5c7b23..289e5c7b23 100644 --- a/iphone/Maps/Settings/SelectableCell.mm +++ b/iphone/Maps/Settings/Cells/SelectableCell.mm diff --git a/iphone/Maps/Settings/SwitchCell.h b/iphone/Maps/Settings/Cells/SwitchCell.h index 8dfb1ad1c4..8dfb1ad1c4 100644 --- a/iphone/Maps/Settings/SwitchCell.h +++ b/iphone/Maps/Settings/Cells/SwitchCell.h diff --git a/iphone/Maps/Settings/SwitchCell.mm b/iphone/Maps/Settings/Cells/SwitchCell.mm index 292ec81b43..292ec81b43 100644 --- a/iphone/Maps/Settings/SwitchCell.mm +++ b/iphone/Maps/Settings/Cells/SwitchCell.mm diff --git a/iphone/Maps/Settings/MWMAboutController.h b/iphone/Maps/Settings/MWMAboutController.h new file mode 100644 index 0000000000..bf44d902da --- /dev/null +++ b/iphone/Maps/Settings/MWMAboutController.h @@ -0,0 +1,5 @@ +#import "MWMTableViewController.h" + +@interface MWMAboutController : MWMTableViewController + +@end diff --git a/iphone/Maps/Settings/MWMAboutController.mm b/iphone/Maps/Settings/MWMAboutController.mm new file mode 100644 index 0000000000..6df96a4dc4 --- /dev/null +++ b/iphone/Maps/Settings/MWMAboutController.mm @@ -0,0 +1,136 @@ +#import "MWMAboutController.h" +#import "AppInfo.h" +#import "LinkCell.h" +#import "MWMMailViewController.h" +#import "Statistics.h" +#import "WebViewController.h" + +#import "3party/Alohalytics/src/alohalytics_objc.h" + +#include "Framework.h" + +#include "platform/platform.hpp" + +extern NSString * const kAlohalyticsTapEventKey; + +@interface MWMAboutController ()<MFMailComposeViewControllerDelegate> + +@property(weak, nonatomic) IBOutlet UILabel * versionLabel; +@property(weak, nonatomic) IBOutlet UILabel * dateLabel; + +@property(weak, nonatomic) IBOutlet LinkCell * websiteCell; +@property(weak, nonatomic) IBOutlet LinkCell * blogCell; +@property(weak, nonatomic) IBOutlet LinkCell * facebookCell; +@property(weak, nonatomic) IBOutlet LinkCell * twitterCell; +@property(weak, nonatomic) IBOutlet LinkCell * subscribeCell; +@property(weak, nonatomic) IBOutlet LinkCell * rateCell; +@property(weak, nonatomic) IBOutlet LinkCell * copyrightCell; + +@property(nonatomic) IBOutlet UIView * headerView; + +@end + +@implementation MWMAboutController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + self.title = L(@"about_menu_title"); + + [[NSBundle mainBundle] loadNibNamed:@"MWMAboutControllerHeader" owner:self options:nil]; + self.tableView.tableHeaderView = self.headerView; + + AppInfo * appInfo = [AppInfo sharedInfo]; + NSString * version = appInfo.bundleVersion; + if (appInfo.buildNumber) + version = [NSString stringWithFormat:@"%@.%@", version, appInfo.buildNumber]; + self.versionLabel.text = [NSString stringWithFormat:L(@"version"), version]; + + NSDateFormatter * dateFormatter = [[NSDateFormatter alloc] init]; + dateFormatter.dateStyle = NSDateFormatterShortStyle; + dateFormatter.timeStyle = NSDateFormatterNoStyle; + auto const dataVersion = GetFramework().GetCurrentDataVersion(); + self.dateLabel.text = [NSString stringWithFormat:L(@"date"), dataVersion]; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + LinkCell * cell = static_cast<LinkCell *>([tableView cellForRowAtIndexPath:indexPath]); + if (cell == self.websiteCell) + { + [Alohalytics logEvent:kAlohalyticsTapEventKey withValue:@"website"]; + [self openUrl:[NSURL URLWithString:@"https://maps.me"]]; + } + else if (cell == self.blogCell) + { + [Alohalytics logEvent:kAlohalyticsTapEventKey withValue:@"blog"]; + [self openUrl:[NSURL URLWithString:@"http://blog.maps.me"]]; + } + else if (cell == self.facebookCell) + { + [Alohalytics logEvent:kAlohalyticsTapEventKey withValue:@"likeOnFb"]; + [self openUrl:[NSURL URLWithString:@"https://facebook.com/MapsWithMe"]]; + } + else if (cell == self.twitterCell) + { + [Alohalytics logEvent:kAlohalyticsTapEventKey withValue:@"followOnTwitter"]; + [self openUrl:[NSURL URLWithString:@"https://twitter.com/MAPS_ME"]]; + } + else if (cell == self.subscribeCell) + { + [Alohalytics logEvent:kAlohalyticsTapEventKey withValue:@"subscribeToNews"]; + [self sendEmailWithText:L(@"subscribe_me_body") + subject:L(@"subscribe_me_subject") + toRecipient:@"subscribe@maps.me"]; + } + else if (cell == self.rateCell) + { + [Statistics logEvent:kStatSettingsOpenSection withParameters:@{kStatName : kStatRate}]; + [Alohalytics logEvent:kAlohalyticsTapEventKey withValue:@"rate"]; + [[UIApplication sharedApplication] rateVersionFrom:@"rate_menu_item"]; + } + else if (cell == self.copyrightCell) + { + [Statistics logEvent:kStatSettingsOpenSection withParameters:@{kStatName : kStatCopyright}]; + [Alohalytics logEvent:kAlohalyticsTapEventKey withValue:@"copyright"]; + string s; + GetPlatform().GetReader("copyright.html")->ReadAsString(s); + NSString * text = [NSString stringWithFormat:@"%@\n%@", self.versionLabel.text, @(s.c_str())]; + WebViewController * aboutViewController = + [[WebViewController alloc] initWithHtml:text baseUrl:nil andTitleOrNil:L(@"copyright")]; + aboutViewController.openInSafari = YES; + [self.navigationController pushViewController:aboutViewController animated:YES]; + } +} + +- (void)sendEmailWithText:(NSString *)text subject:(NSString *)subject toRecipient:(NSString *)email +{ + if ([MWMMailViewController canSendMail]) + { + MWMMailViewController * vc = [[MWMMailViewController alloc] init]; + vc.mailComposeDelegate = self; + [vc setSubject:subject]; + [vc setMessageBody:text isHTML:NO]; + [vc setToRecipients:@[ email ]]; + [self presentViewController:vc animated:YES completion:nil]; + } + else + { + NSString * text = [NSString stringWithFormat:L(@"email_error_body"), email]; + [[[UIAlertView alloc] initWithTitle:L(@"email_error_title") + message:text + delegate:nil + cancelButtonTitle:L(@"ok") + otherButtonTitles:nil] show]; + } +} + +- (void)mailComposeController:(MFMailComposeViewController *)controller + didFinishWithResult:(MFMailComposeResult)result + error:(NSError *)error +{ + [self dismissViewControllerAnimated:YES completion:nil]; +} + +@end diff --git a/iphone/Maps/Settings/MWMAboutControllerHeader.xib b/iphone/Maps/Settings/MWMAboutControllerHeader.xib new file mode 100644 index 0000000000..8adc47bd07 --- /dev/null +++ b/iphone/Maps/Settings/MWMAboutControllerHeader.xib @@ -0,0 +1,88 @@ +<?xml version="1.0" encoding="UTF-8"?> +<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="11542" systemVersion="16B2555" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES"> + <device id="retina4_7" orientation="portrait"> + <adaptation id="fullscreen"/> + </device> + <dependencies> + <deployment identifier="iOS"/> + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11524"/> + <capability name="Aspect ratio constraints" minToolsVersion="5.1"/> + <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> + </dependencies> + <objects> + <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="MWMAboutController"> + <connections> + <outlet property="dateLabel" destination="2UY-CN-bbR" id="0ad-Y1-yZq"/> + <outlet property="headerView" destination="nNn-As-qvg" id="kwi-x5-YnF"/> + <outlet property="versionLabel" destination="eX4-Y6-p2e" id="4Kf-ae-nY1"/> + </connections> + </placeholder> + <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/> + <view contentMode="scaleToFill" id="nNn-As-qvg"> + <rect key="frame" x="0.0" y="0.0" width="375" height="276"/> + <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> + <subviews> + <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="imgLogo" translatesAutoresizingMaskIntoConstraints="NO" id="MNH-d1-GMj"> + <rect key="frame" x="128" y="24" width="120" height="120"/> + <constraints> + <constraint firstAttribute="width" secondItem="MNH-d1-GMj" secondAttribute="height" multiplier="1:1" id="1UQ-pV-hI7"/> + <constraint firstAttribute="height" priority="750" constant="120" id="9ug-0X-yk5"/> + </constraints> + </imageView> + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" verticalCompressionResistancePriority="1000" text="Версия 6.3.0.318" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="eX4-Y6-p2e"> + <rect key="frame" x="119" y="156" width="137" height="21"/> + <fontDescription key="fontDescription" type="system" weight="medium" pointSize="17"/> + <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> + <nil key="highlightedColor"/> + <userDefinedRuntimeAttributes> + <userDefinedRuntimeAttribute type="string" keyPath="colorName" value="blackPrimaryText"/> + <userDefinedRuntimeAttribute type="string" keyPath="fontName" value="medium17"/> + </userDefinedRuntimeAttributes> + </label> + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" verticalCompressionResistancePriority="1000" text="Дата 16.08.2016" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="2UY-CN-bbR"> + <rect key="frame" x="137" y="181" width="101" height="16"/> + <fontDescription key="fontDescription" type="system" pointSize="13"/> + <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> + <nil key="highlightedColor"/> + <userDefinedRuntimeAttributes> + <userDefinedRuntimeAttribute type="string" keyPath="colorName" value="blackSecondaryText"/> + <userDefinedRuntimeAttribute type="string" keyPath="fontName" value="regular13"/> + </userDefinedRuntimeAttributes> + </label> + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" verticalCompressionResistancePriority="1000" text="Объединив усилия Mail.Ru Group и данные OpenStreetMap, мы создаем незаменимое приложение для путешествий." textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="GEL-Bz-rHg"> + <rect key="frame" x="8" y="205" width="359" height="47"/> + <fontDescription key="fontDescription" type="system" pointSize="13"/> + <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> + <nil key="highlightedColor"/> + <userDefinedRuntimeAttributes> + <userDefinedRuntimeAttribute type="string" keyPath="colorName" value="blackPrimaryText"/> + <userDefinedRuntimeAttribute type="string" keyPath="fontName" value="regular13"/> + <userDefinedRuntimeAttribute type="string" keyPath="localizedText" value="about_description"/> + </userDefinedRuntimeAttributes> + </label> + </subviews> + <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/> + <constraints> + <constraint firstItem="MNH-d1-GMj" firstAttribute="top" secondItem="nNn-As-qvg" secondAttribute="top" constant="24" id="4Yk-N8-0X2"/> + <constraint firstItem="GEL-Bz-rHg" firstAttribute="centerX" secondItem="nNn-As-qvg" secondAttribute="centerX" id="6vn-WQ-qNy"/> + <constraint firstAttribute="trailing" secondItem="GEL-Bz-rHg" secondAttribute="trailing" constant="8" id="8IJ-ww-y0j"/> + <constraint firstItem="GEL-Bz-rHg" firstAttribute="top" secondItem="2UY-CN-bbR" secondAttribute="bottom" constant="8" id="AXP-EC-LMU"/> + <constraint firstItem="GEL-Bz-rHg" firstAttribute="leading" secondItem="nNn-As-qvg" secondAttribute="leading" constant="8" id="Fho-8h-fz5"/> + <constraint firstItem="MNH-d1-GMj" firstAttribute="centerX" secondItem="nNn-As-qvg" secondAttribute="centerX" id="ORf-Qo-mSu"/> + <constraint firstAttribute="bottom" secondItem="GEL-Bz-rHg" secondAttribute="bottom" constant="24" id="OgM-Is-GbO"/> + <constraint firstItem="2UY-CN-bbR" firstAttribute="top" secondItem="eX4-Y6-p2e" secondAttribute="bottom" constant="4" id="XUm-iH-rab"/> + <constraint firstItem="eX4-Y6-p2e" firstAttribute="centerX" secondItem="nNn-As-qvg" secondAttribute="centerX" id="jgK-Ga-gbr"/> + <constraint firstItem="eX4-Y6-p2e" firstAttribute="top" secondItem="MNH-d1-GMj" secondAttribute="bottom" constant="12" id="tbq-yy-OGh"/> + <constraint firstItem="2UY-CN-bbR" firstAttribute="centerX" secondItem="nNn-As-qvg" secondAttribute="centerX" id="zBm-aI-8kB"/> + </constraints> + <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/> + <userDefinedRuntimeAttributes> + <userDefinedRuntimeAttribute type="string" keyPath="backgroundColorName" value="pressBackground"/> + </userDefinedRuntimeAttributes> + <point key="canvasLocation" x="131" y="-39"/> + </view> + </objects> + <resources> + <image name="imgLogo" width="120" height="120"/> + </resources> +</document> diff --git a/iphone/Maps/Settings/MWMHelpController.h b/iphone/Maps/Settings/MWMHelpController.h new file mode 100644 index 0000000000..8906ecbabb --- /dev/null +++ b/iphone/Maps/Settings/MWMHelpController.h @@ -0,0 +1,5 @@ +#import "MWMViewController.h" + +@interface MWMHelpController : MWMViewController + +@end diff --git a/iphone/Maps/Settings/MWMHelpController.mm b/iphone/Maps/Settings/MWMHelpController.mm new file mode 100644 index 0000000000..5ba66f4395 --- /dev/null +++ b/iphone/Maps/Settings/MWMHelpController.mm @@ -0,0 +1,254 @@ +#import "MWMHelpController.h" +#import <sys/utsname.h> +#import "AppInfo.h" +#import "Common.h" +#import "MWMMailViewController.h" +#import "Statistics.h" +#import "UIColor+MapsMeColor.h" +#import "WebViewController.h" + +#import "3party/Alohalytics/src/alohalytics_objc.h" + +#include "platform/platform.hpp" + +extern NSString * const kAlohalyticsTapEventKey; +extern NSString * const kLocaleUsedInSupportEmails = @"en_gb"; +extern NSDictionary * const kDeviceNames = @{ + @"i386" : @"Simulator", + @"iPad1,1" : @"iPad WiFi", + @"iPad1,2" : @"iPad GSM", + @"iPad2,1" : @"iPad 2 WiFi", + @"iPad2,2" : @"iPad 2 CDMA", + @"iPad2,2" : @"iPad 2 GSM", + @"iPad2,3" : @"iPad 2 GSM EV-DO", + @"iPad2,4" : @"iPad 2", + @"iPad2,5" : @"iPad Mini WiFi", + @"iPad2,6" : @"iPad Mini GSM", + @"iPad2,7" : @"iPad Mini CDMA", + @"iPad3,1" : @"iPad 3rd gen. WiFi", + @"iPad3,2" : @"iPad 3rd gen. GSM", + @"iPad3,3" : @"iPad 3rd gen. CDMA", + @"iPad3,4" : @"iPad 4th gen. WiFi", + @"iPad3,5" : @"iPad 4th gen. GSM", + @"iPad3,6" : @"iPad 4th gen. CDMA", + @"iPad4,1" : @"iPad Air WiFi", + @"iPad4,2" : @"iPad Air GSM", + @"iPad4,3" : @"iPad Air CDMA", + @"iPad4,4" : @"iPad Mini 2nd gen. WiFi", + @"iPad4,5" : @"iPad Mini 2nd gen. GSM", + @"iPad4,6" : @"iPad Mini 2nd gen. CDMA", + @"iPad5,3" : @"iPad Air 2 WiFi", + @"iPad5,4" : @"iPad Air 2 GSM", + @"iPad6,3" : @"iPad Pro (9.7 inch) WiFi", + @"iPad6,4" : @"iPad Pro (9.7 inch) GSM", + @"iPad6,7" : @"iPad Pro (12.9 inch) WiFi", + @"iPad6,8" : @"iPad Pro (12.9 inch) GSM", + @"iPhone1,1" : @"iPhone", + @"iPhone1,2" : @"iPhone 3G", + @"iPhone2,1" : @"iPhone 3GS", + @"iPhone3,1" : @"iPhone 4 GSM", + @"iPhone3,2" : @"iPhone 4 CDMA", + @"iPhone3,3" : @"iPhone 4 GSM EV-DO", + @"iPhone4,1" : @"iPhone 4S", + @"iPhone4,2" : @"iPhone 4S", + @"iPhone4,3" : @"iPhone 4S", + @"iPhone5,1" : @"iPhone 5", + @"iPhone5,2" : @"iPhone 5", + @"iPhone5,3" : @"iPhone 5c", + @"iPhone5,4" : @"iPhone 5c", + @"iPhone6,1" : @"iPhone 5s", + @"iPhone6,2" : @"iPhone 5s", + @"iPhone7,1" : @"iPhone 6 Plus", + @"iPhone7,2" : @"iPhone 6", + @"iPhone8,1" : @"iPhone 6s", + @"iPhone8,2" : @"iPhone 6s Plus", + @"iPhone8,4" : @"iPhone SE", + @"iPod1,1" : @"iPod Touch", + @"iPod2,1" : @"iPod Touch 2nd gen.", + @"iPod3,1" : @"iPod Touch 3rd gen.", + @"iPod4,1" : @"iPod Touch 4th gen.", + @"iPod5,1" : @"iPod Touch 5th gen.", + @"x86_64" : @"Simulator", +}; + +namespace +{ +NSString * const kCommonReportActionTitle = L(@"leave_a_review"); +NSString * const kBugReportActionTitle = L(@"something_is_not_working"); +NSString * const kCancelActionTitle = L(@"cancel"); +NSString * const kiOSEmail = @"ios@maps.me"; +} + +@interface MWMHelpController ()<MFMailComposeViewControllerDelegate> + +@property(nonatomic) WebViewController * aboutViewController; + +@property(weak, nonatomic) IBOutlet UIView * separatorView; + +@end // namespace + +@implementation MWMHelpController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.title = L(@"help"); + + NSString * html; + if (GetPlatform().ConnectionStatus() == Platform::EConnectionType::CONNECTION_NONE) + { + NSString * path = [[NSBundle mainBundle] pathForResource:@"faq" ofType:@"html"]; + html = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil]; + self.aboutViewController = + [[WebViewController alloc] initWithHtml:html baseUrl:nil andTitleOrNil:nil]; + } + else + { + NSURL * url = [NSURL URLWithString:@"https://support.maps.me"]; + self.aboutViewController = [[WebViewController alloc] initWithUrl:url andTitleOrNil:nil]; + } + + self.aboutViewController.openInSafari = NO; + UIView * aboutView = self.aboutViewController.view; + [self addChildViewController:self.aboutViewController]; + [self.view addSubview:aboutView]; + + aboutView.translatesAutoresizingMaskIntoConstraints = NO; + NSLayoutConstraint * top = [NSLayoutConstraint constraintWithItem:self.view + attribute:NSLayoutAttributeTop + relatedBy:NSLayoutRelationEqual + toItem:aboutView + attribute:NSLayoutAttributeTop + multiplier:1.0 + constant:0.0]; + NSLayoutConstraint * bottom = [NSLayoutConstraint constraintWithItem:self.separatorView + attribute:NSLayoutAttributeTop + relatedBy:NSLayoutRelationEqual + toItem:aboutView + attribute:NSLayoutAttributeBottom + multiplier:1.0 + constant:0.0]; + NSLayoutConstraint * left = [NSLayoutConstraint constraintWithItem:self.view + attribute:NSLayoutAttributeLeft + relatedBy:NSLayoutRelationEqual + toItem:aboutView + attribute:NSLayoutAttributeLeft + multiplier:1.0 + constant:0.0]; + NSLayoutConstraint * right = [NSLayoutConstraint constraintWithItem:self.view + attribute:NSLayoutAttributeRight + relatedBy:NSLayoutRelationEqual + toItem:aboutView + attribute:NSLayoutAttributeRight + multiplier:1.0 + constant:0.0]; + + [self.view addConstraints:@[ top, bottom, left, right ]]; +} + +- (IBAction)reportBug +{ + UIAlertController * alert = + [UIAlertController alertControllerWithTitle:L(@"feedback") + message:nil + preferredStyle:UIAlertControllerStyleAlert]; + + UIAlertAction * commonReport = [UIAlertAction actionWithTitle:kCommonReportActionTitle + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * _Nonnull action) { + [self commonReportAction]; + }]; + [alert addAction:commonReport]; + + UIAlertAction * bugReport = [UIAlertAction actionWithTitle:kBugReportActionTitle + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * _Nonnull action) { + [self bugReportAction]; + }]; + [alert addAction:bugReport]; + + UIAlertAction * cancel = + [UIAlertAction actionWithTitle:kCancelActionTitle style:UIAlertActionStyleCancel handler:nil]; + [alert addAction:cancel]; + alert.preferredAction = cancel; + + [self presentViewController:alert animated:YES completion:nil]; +} + +#pragma mark - Actions + +- (void)commonReportAction +{ + [Statistics logEvent:kStatSettingsOpenSection withParameters:@{kStatName : kStatFeedback}]; + [Alohalytics logEvent:kAlohalyticsTapEventKey withValue:@"contactUs"]; + // Do not localize subject. Support team uses it to filter emails. + [self sendEmailWithSubject:@"Feedback from user" toRecipient:kiOSEmail]; +} + +- (void)bugReportAction +{ + [Statistics logEvent:kStatSettingsOpenSection withParameters:@{kStatName : kStatReport}]; + [Alohalytics logEvent:kAlohalyticsTapEventKey withValue:@"reportABug"]; + // Do not localize subject. Support team uses it to filter emails. + [self sendEmailWithSubject:@"Bug report from user" toRecipient:kiOSEmail]; +} + +#pragma mark - Email + +- (void)sendEmailWithSubject:(NSString *)subject toRecipient:(NSString *)email +{ + if ([MWMMailViewController canSendMail]) + { + struct utsname systemInfo; + uname(&systemInfo); + NSString * machine = + [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding]; + NSString * device = kDeviceNames[machine]; + if (!device) + device = machine; + NSString * languageCode = [[NSLocale preferredLanguages] firstObject]; + NSString * language = [[NSLocale localeWithLocaleIdentifier:kLocaleUsedInSupportEmails] + displayNameForKey:NSLocaleLanguageCode + value:languageCode]; + NSString * locale = [[NSLocale currentLocale] objectForKey:NSLocaleCountryCode]; + NSString * country = [[NSLocale localeWithLocaleIdentifier:kLocaleUsedInSupportEmails] + displayNameForKey:NSLocaleCountryCode + value:locale]; + NSString * bundleVersion = + [[NSBundle mainBundle] objectForInfoDictionaryKey:(NSString *)kCFBundleVersionKey]; + NSString * text = [NSString stringWithFormat:@"\n\n\n\n- %@ (%@)\n- MAPS.ME %@\n- %@/%@", + device, [UIDevice currentDevice].systemVersion, + bundleVersion, language, country]; + NSString * alohalyticsId = [Alohalytics installationId]; + if (alohalyticsId) + text = [NSString stringWithFormat:@"%@\n- %@", text, alohalyticsId]; + + MWMMailViewController * vc = [[MWMMailViewController alloc] init]; + vc.mailComposeDelegate = self; + [vc setSubject:[NSString stringWithFormat:@"[%@ iOS] %@", [AppInfo sharedInfo].bundleVersion, + subject]]; + [vc setMessageBody:text isHTML:NO]; + [vc setToRecipients:@[ email ]]; + [vc.navigationBar setTintColor:[UIColor whitePrimaryText]]; + [self presentViewController:vc animated:YES completion:nil]; + } + else + { + NSString * text = [NSString stringWithFormat:L(@"email_error_body"), email]; + [[[UIAlertView alloc] initWithTitle:L(@"email_error_title") + message:text + delegate:nil + cancelButtonTitle:L(@"ok") + otherButtonTitles:nil] show]; + } +} + +- (void)mailComposeController:(MFMailComposeViewController *)controller + didFinishWithResult:(MFMailComposeResult)result + error:(NSError *)error +{ + [self dismissViewControllerAnimated:YES completion:nil]; +} + +@end diff --git a/iphone/Maps/Settings/MWMMobileInternetViewController.h b/iphone/Maps/Settings/MWMMobileInternetViewController.h new file mode 100644 index 0000000000..bdd9ce1e5b --- /dev/null +++ b/iphone/Maps/Settings/MWMMobileInternetViewController.h @@ -0,0 +1,5 @@ +#import "MWMTableViewController.h" + +@interface MWMMobileInternetViewController : MWMTableViewController + +@end diff --git a/iphone/Maps/Settings/MWMMobileInternetViewController.mm b/iphone/Maps/Settings/MWMMobileInternetViewController.mm new file mode 100644 index 0000000000..822e791003 --- /dev/null +++ b/iphone/Maps/Settings/MWMMobileInternetViewController.mm @@ -0,0 +1,77 @@ +#import "MWMMobileInternetViewController.h" +#import "MWMNetworkPolicy.h" +#import "SelectableCell.h" +#import "Statistics.h" + +using namespace network_policy; +using np = platform::NetworkPolicy; + +@interface MWMMobileInternetViewController () + +@property(weak, nonatomic) IBOutlet SelectableCell * always; +@property(weak, nonatomic) IBOutlet SelectableCell * ask; +@property(weak, nonatomic) IBOutlet SelectableCell * never; +@property(weak, nonatomic) SelectableCell * selected; + +@end + +@implementation MWMMobileInternetViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + self.title = L(@"mobile_data"); + + SelectableCell * selected; + switch (GetStage()) + { + case np::Stage::Always: selected = self.always; break; + case np::Stage::Session: selected = self.ask; break; + case np::Stage::Never: selected = self.never; break; + } + selected.accessoryType = UITableViewCellAccessoryCheckmark; + self.selected = selected; +} + +- (void)setSelected:(SelectableCell *)selected +{ + if ([_selected isEqual:selected]) + return; + + _selected = selected; + NSString * statValue = nil; + if ([selected isEqual:self.always]) + { + statValue = kStatAlways; + SetStage(np::Stage::Always); + } + else if ([selected isEqual:self.ask]) + { + statValue = kStatAsk; + SetStage(np::Stage::Session); + } + else if ([selected isEqual:self.never]) + { + statValue = kStatNever; + SetStage(np::Stage::Never); + } + + [Statistics logEvent:kStatMobileInternet withParameters:@{kStatValue : statValue}]; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + SelectableCell * selected = self.selected; + selected.accessoryType = UITableViewCellAccessoryNone; + selected = [tableView cellForRowAtIndexPath:indexPath]; + selected.accessoryType = UITableViewCellAccessoryCheckmark; + selected.selected = NO; + self.selected = selected; +} + +- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section +{ + return L(@"mobile_data_description"); +} + +@end diff --git a/iphone/Maps/Settings/MWMNightModeController.h b/iphone/Maps/Settings/MWMNightModeController.h new file mode 100644 index 0000000000..27b77f6f56 --- /dev/null +++ b/iphone/Maps/Settings/MWMNightModeController.h @@ -0,0 +1,5 @@ +#import "MWMTableViewController.h" + +@interface MWMNightModeController : MWMTableViewController + +@end diff --git a/iphone/Maps/Settings/MWMNightModeController.mm b/iphone/Maps/Settings/MWMNightModeController.mm new file mode 100644 index 0000000000..0ffb6f81db --- /dev/null +++ b/iphone/Maps/Settings/MWMNightModeController.mm @@ -0,0 +1,102 @@ +#import "MWMNightModeController.h" +#import "MWMSettings.h" +#import "MapsAppDelegate.h" +#import "SelectableCell.h" +#import "Statistics.h" +#import "UIColor+MapsMeColor.h" + +#include "Framework.h" + +@interface MWMNightModeController () + +@property(weak, nonatomic) IBOutlet SelectableCell * autoSwitch; +@property(weak, nonatomic) IBOutlet SelectableCell * on; +@property(weak, nonatomic) IBOutlet SelectableCell * off; +@property(weak, nonatomic) SelectableCell * selectedCell; + +@end + +@implementation MWMNightModeController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + self.title = L(@"pref_map_style_title"); + if ([MWMSettings autoNightModeEnabled]) + { + self.autoSwitch.accessoryType = UITableViewCellAccessoryCheckmark; + _selectedCell = self.autoSwitch; + return; + } + + switch (GetFramework().GetMapStyle()) + { + case MapStyleDark: + self.on.accessoryType = UITableViewCellAccessoryCheckmark; + _selectedCell = self.on; + break; + case MapStyleClear: + case MapStyleLight: + self.off.accessoryType = UITableViewCellAccessoryCheckmark; + _selectedCell = self.off; + break; + case MapStyleMerged: + case MapStyleCount: break; + } +} + +- (void)setSelectedCell:(SelectableCell *)cell +{ + if ([_selectedCell isEqual:cell]) + return; + + _selectedCell = cell; + auto & f = GetFramework(); + auto const style = f.GetMapStyle(); + NSString * statValue = nil; + if ([cell isEqual:self.on]) + { + [MapsAppDelegate setAutoNightModeOff:YES]; + if (style == MapStyleDark) + return; + f.SetMapStyle(MapStyleDark); + [UIColor setNightMode:YES]; + [self mwm_refreshUI]; + statValue = kStatOn; + } + else if ([cell isEqual:self.off]) + { + [MapsAppDelegate setAutoNightModeOff:YES]; + if (style == MapStyleClear || style == MapStyleLight) + return; + f.SetMapStyle(MapStyleClear); + [UIColor setNightMode:NO]; + [self mwm_refreshUI]; + statValue = kStatOff; + } + else if ([cell isEqual:self.autoSwitch]) + { + [MapsAppDelegate setAutoNightModeOff:NO]; + [MapsAppDelegate changeMapStyleIfNedeed]; + if (style == MapStyleClear || style == MapStyleLight) + return; + [UIColor setNightMode:NO]; + f.SetMapStyle(MapStyleClear); + [self mwm_refreshUI]; + statValue = kStatValue; + } + + [Statistics logEvent:kStatNightMode withParameters:@{kStatValue : statValue}]; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + SelectableCell * selectedCell = self.selectedCell; + selectedCell.accessoryType = UITableViewCellAccessoryNone; + selectedCell = [tableView cellForRowAtIndexPath:indexPath]; + selectedCell.accessoryType = UITableViewCellAccessoryCheckmark; + selectedCell.selected = NO; + self.selectedCell = selectedCell; +} + +@end diff --git a/iphone/Maps/Settings/MWMRecentTrackSettingsController.h b/iphone/Maps/Settings/MWMRecentTrackSettingsController.h new file mode 100644 index 0000000000..4266571020 --- /dev/null +++ b/iphone/Maps/Settings/MWMRecentTrackSettingsController.h @@ -0,0 +1,5 @@ +#import "MWMTableViewController.h" + +@interface MWMRecentTrackSettingsController : MWMTableViewController + +@end diff --git a/iphone/Maps/Settings/MWMRecentTrackSettingsController.mm b/iphone/Maps/Settings/MWMRecentTrackSettingsController.mm new file mode 100644 index 0000000000..3b0ec4a2f8 --- /dev/null +++ b/iphone/Maps/Settings/MWMRecentTrackSettingsController.mm @@ -0,0 +1,106 @@ +#import "MWMRecentTrackSettingsController.h" +#import "SelectableCell.h" +#import "Statistics.h" + +#include "Framework.h" + +#include "map/gps_tracker.hpp" + +extern NSString * const kUDTrackWarningAlertWasShown = @"TrackWarningAlertWasShown"; + +typedef NS_ENUM(NSUInteger, DurationInHours) { One = 1, Two = 2, Six = 6, Twelve = 12, Day = 24 }; + +@interface MWMRecentTrackSettingsController () + +@property(weak, nonatomic) IBOutlet SelectableCell * none; +@property(weak, nonatomic) IBOutlet SelectableCell * oneHour; +@property(weak, nonatomic) IBOutlet SelectableCell * twoHours; +@property(weak, nonatomic) IBOutlet SelectableCell * sixHours; +@property(weak, nonatomic) IBOutlet SelectableCell * twelveHours; +@property(weak, nonatomic) IBOutlet SelectableCell * oneDay; +@property(weak, nonatomic) SelectableCell * selectedCell; + +@end + +@implementation MWMRecentTrackSettingsController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + self.title = L(@"pref_track_record_title"); + + if (!GpsTracker::Instance().IsEnabled()) + { + _selectedCell = self.none; + } + else + { + switch (GpsTracker::Instance().GetDuration().count()) + { + case One: _selectedCell = self.oneHour; break; + case Two: _selectedCell = self.twoHours; break; + case Six: _selectedCell = self.sixHours; break; + case Twelve: _selectedCell = self.twelveHours; break; + case Day: _selectedCell = self.oneDay; break; + default: NSAssert(false, @"Incorrect hours value"); break; + } + } + self.selectedCell.accessoryType = UITableViewCellAccessoryCheckmark; +} + +- (void)setSelectedCell:(SelectableCell *)selectedCell +{ + _selectedCell = selectedCell; + auto & f = GetFramework(); + auto & tracker = GpsTracker::Instance(); + NSString * statValue = nil; + if ([selectedCell isEqual:self.none]) + { + f.DisconnectFromGpsTracker(); + tracker.SetEnabled(false); + statValue = kStatOff; + } + else + { + if (!tracker.IsEnabled()) + { + tracker.SetEnabled(true); + NSUserDefaults * ud = [NSUserDefaults standardUserDefaults]; + [ud setBool:NO forKey:kUDTrackWarningAlertWasShown]; + [ud synchronize]; + } + f.ConnectToGpsTracker(); + + if ([selectedCell isEqual:self.oneHour]) + tracker.SetDuration(hours(One)); + else if ([selectedCell isEqual:self.twoHours]) + tracker.SetDuration(hours(Two)); + else if ([selectedCell isEqual:self.sixHours]) + tracker.SetDuration(hours(Six)); + else if ([selectedCell isEqual:self.twelveHours]) + tracker.SetDuration(hours(Twelve)); + else + tracker.SetDuration(hours(Day)); + + statValue = [NSString stringWithFormat:@"%@ hour(s)", @(tracker.GetDuration().count())]; + } + selectedCell.accessoryType = UITableViewCellAccessoryCheckmark; + [Statistics logEvent:kStatChangeRecentTrack withParameters:@{kStatValue : statValue}]; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + SelectableCell * selectedCell = self.selectedCell; + selectedCell.accessoryType = UITableViewCellAccessoryNone; + selectedCell = [tableView cellForRowAtIndexPath:indexPath]; + selectedCell.selected = NO; + self.selectedCell = selectedCell; +} + +- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section +{ + NSAssert(section == 0, @"Incorrect sections count"); + return L(@"recent_track_help_text"); +} + +@end diff --git a/iphone/Maps/Settings/MWMSettings.h b/iphone/Maps/Settings/MWMSettings.h new file mode 100644 index 0000000000..f2d612c6db --- /dev/null +++ b/iphone/Maps/Settings/MWMSettings.h @@ -0,0 +1,35 @@ +#include "platform/measurement_utils.hpp" + +@interface MWMSettings : NSObject + ++ (BOOL)adServerForbidden; ++ (void)setAdServerForbidden:(BOOL)adServerForbidden; + ++ (BOOL)adForbidden; ++ (void)setAdForbidden:(BOOL)adForbidden; + ++ (BOOL)autoDownloadEnabled; ++ (void)setAutoDownloadEnabled:(BOOL)autoDownloadEnabled; + ++ (measurement_utils::Units)measurementUnits; ++ (void)setMeasurementUnits:(measurement_utils::Units)measurementUnits; + ++ (BOOL)zoomButtonsEnabled; ++ (void)setZoomButtonsEnabled:(BOOL)zoomButtonsEnabled; + ++ (BOOL)compassCalibrationEnabled; ++ (void)setCompassCalibrationEnabled:(BOOL)compassCalibrationEnabled; + ++ (BOOL)statisticsEnabled; ++ (void)setStatisticsEnabled:(BOOL)statisticsEnabled; + ++ (BOOL)autoNightModeEnabled; ++ (void)setAutoNightModeEnabled:(BOOL)autoNightModeEnabled; + ++ (BOOL)routingDisclaimerApproved; ++ (void)setRoutingDisclaimerApproved; + ++ (NSString *)spotlightLocaleLanguageId; ++ (void)setSpotlightLocaleLanguageId:(NSString *)spotlightLocaleLanguageId; + +@end diff --git a/iphone/Maps/Settings/MWMSettings.mm b/iphone/Maps/Settings/MWMSettings.mm new file mode 100644 index 0000000000..bcb055a62b --- /dev/null +++ b/iphone/Maps/Settings/MWMSettings.mm @@ -0,0 +1,153 @@ +#import "MWMSettings.h" +#import "MWMMapViewControlsManager.h" + +#import "3party/Alohalytics/src/alohalytics_objc.h" + +#include "Framework.h" + +#include "platform/settings.hpp" + +namespace +{ +char const * kAdForbiddenSettingsKey = "AdForbidden"; +char const * kAdServerForbiddenKey = "AdServerForbidden"; +char const * kAutoDownloadEnabledKey = "AutoDownloadEnabled"; +char const * kZoomButtonsEnabledKey = "ZoomButtonsEnabled"; +char const * kCompassCalibrationEnabledKey = "CompassCalibrationEnabled"; +char const * kRoutingDisclaimerApprovedKey = "IsDisclaimerApproved"; +char const * kStatisticsEnabledSettingsKey = "StatisticsEnabled"; + +NSString * const kUDAutoNightModeOff = @"AutoNightModeOff"; +NSString * const kSpotlightLocaleLanguageId = @"SpotlightLocaleLanguageId"; +} // namespace + +@implementation MWMSettings + ++ (BOOL)adServerForbidden +{ + bool adServerForbidden = false; + UNUSED_VALUE(settings::Get(kAdServerForbiddenKey, adServerForbidden)); + return adServerForbidden; +} + ++ (void)setAdServerForbidden:(BOOL)adServerForbidden +{ + settings::Set(kAdServerForbiddenKey, static_cast<bool>(adServerForbidden)); +} + ++ (BOOL)adForbidden +{ + bool adForbidden = false; + UNUSED_VALUE(settings::Get(kAdForbiddenSettingsKey, adForbidden)); + return adForbidden; +} + ++ (void)setAdForbidden:(BOOL)adForbidden +{ + settings::Set(kAdForbiddenSettingsKey, static_cast<bool>(adForbidden)); +} + ++ (BOOL)autoDownloadEnabled +{ + bool autoDownloadEnabled = true; + UNUSED_VALUE(settings::Get(kAutoDownloadEnabledKey, autoDownloadEnabled)); + return autoDownloadEnabled; +} + ++ (void)setAutoDownloadEnabled:(BOOL)autoDownloadEnabled +{ + settings::Set(kAutoDownloadEnabledKey, static_cast<bool>(autoDownloadEnabled)); +} + ++ (measurement_utils::Units)measurementUnits +{ + auto units = measurement_utils::Units::Metric; + UNUSED_VALUE(settings::Get(settings::kMeasurementUnits, units)); + return units; +} + ++ (void)setMeasurementUnits:(measurement_utils::Units)measurementUnits +{ + settings::Set(settings::kMeasurementUnits, measurementUnits); + GetFramework().SetupMeasurementSystem(); +} + ++ (BOOL)zoomButtonsEnabled +{ + bool enabled = true; + UNUSED_VALUE(settings::Get(kZoomButtonsEnabledKey, enabled)); + return enabled; +} + ++ (void)setZoomButtonsEnabled:(BOOL)zoomButtonsEnabled +{ + settings::Set(kZoomButtonsEnabledKey, static_cast<bool>(zoomButtonsEnabled)); + [MWMMapViewControlsManager manager].zoomHidden = !zoomButtonsEnabled; +} + ++ (BOOL)compassCalibrationEnabled +{ + bool enabled = true; + UNUSED_VALUE(settings::Get(kCompassCalibrationEnabledKey, enabled)); + return enabled; +} + ++ (void)setCompassCalibrationEnabled:(BOOL)compassCalibrationEnabled +{ + settings::Set(kCompassCalibrationEnabledKey, static_cast<bool>(compassCalibrationEnabled)); +} + ++ (BOOL)statisticsEnabled +{ + bool enabled = true; + UNUSED_VALUE(settings::Get(kStatisticsEnabledSettingsKey, enabled)); + return enabled; +} + ++ (void)setStatisticsEnabled:(BOOL)statisticsEnabled +{ + if (statisticsEnabled) + { + [Alohalytics enable]; + } + else + { + [Alohalytics logEvent:@"statisticsDisabled"]; + [Alohalytics disable]; + } + settings::Set(kStatisticsEnabledSettingsKey, static_cast<bool>(statisticsEnabled)); +} + ++ (BOOL)autoNightModeEnabled +{ + return ![[NSUserDefaults standardUserDefaults] boolForKey:kUDAutoNightModeOff]; +} + ++ (void)setAutoNightModeEnabled:(BOOL)autoNightModeEnabled +{ + NSUserDefaults * ud = [NSUserDefaults standardUserDefaults]; + [ud setBool:!autoNightModeEnabled forKey:kUDAutoNightModeOff]; + [ud synchronize]; +} + ++ (BOOL)routingDisclaimerApproved +{ + bool enabled = false; + UNUSED_VALUE(settings::Get(kRoutingDisclaimerApprovedKey, enabled)); + return enabled; +} + ++ (void)setRoutingDisclaimerApproved { settings::Set(kRoutingDisclaimerApprovedKey, true); } ++ (NSString *)spotlightLocaleLanguageId +{ + return [[NSUserDefaults standardUserDefaults] stringForKey:kSpotlightLocaleLanguageId]; +} + ++ (void)setSpotlightLocaleLanguageId:(NSString *)spotlightLocaleLanguageId +{ + NSUserDefaults * ud = [NSUserDefaults standardUserDefaults]; + [ud setObject:spotlightLocaleLanguageId forKey:kSpotlightLocaleLanguageId]; + [ud synchronize]; +} + +@end diff --git a/iphone/Maps/Settings/MWMTTSLanguageViewController.h b/iphone/Maps/Settings/MWMTTSLanguageViewController.h new file mode 100644 index 0000000000..a7b6a64ac2 --- /dev/null +++ b/iphone/Maps/Settings/MWMTTSLanguageViewController.h @@ -0,0 +1,5 @@ +#import "MWMTableViewController.h" + +@interface MWMTTSLanguageViewController : MWMTableViewController + +@end diff --git a/iphone/Maps/Settings/MWMTTSLanguageViewController.mm b/iphone/Maps/Settings/MWMTTSLanguageViewController.mm new file mode 100644 index 0000000000..8b1e2b269a --- /dev/null +++ b/iphone/Maps/Settings/MWMTTSLanguageViewController.mm @@ -0,0 +1,41 @@ +#import "MWMTextToSpeech.h" +#import "MWMTTSLanguageViewController.h" +#import "MWMTTSSettingsViewController.h" +#import "SelectableCell.h" +#import "UIColor+MapsMeColor.h" + +static NSString * const kUnwingSegueIdentifier = @"UnwindToTTSSettings"; + +@implementation MWMTTSLanguageViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + self.title = L(@"pref_tts_other_section_title"); + self.tableView.separatorColor = [UIColor blackDividers]; +} + +- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(SelectableCell *)sender +{ + if (![segue.identifier isEqualToString:kUnwingSegueIdentifier]) + return; + MWMTTSSettingsViewController * dest = segue.destinationViewController; + NSUInteger const row = [self.tableView indexPathForCell:sender].row; + [dest setAdditionalTTSLanguage:[[MWMTextToSpeech tts] availableLanguages][row]]; +} + +#pragma mark - UITableViewDataSource && UITableViewDelegate + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return [[MWMTextToSpeech tts] availableLanguages].size(); +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + SelectableCell * cell = (SelectableCell *)[tableView dequeueReusableCellWithIdentifier:[SelectableCell className]]; + cell.titleLabel.text = @([[MWMTextToSpeech tts] availableLanguages][indexPath.row].second.c_str()); + return cell; +} + +@end diff --git a/iphone/Maps/Settings/MWMTTSSettingsViewController.h b/iphone/Maps/Settings/MWMTTSSettingsViewController.h new file mode 100644 index 0000000000..9c364a5247 --- /dev/null +++ b/iphone/Maps/Settings/MWMTTSSettingsViewController.h @@ -0,0 +1,10 @@ +#import "MWMTableViewController.h" + +#include "std/utility.hpp" +#include "std/string.hpp" + +@interface MWMTTSSettingsViewController : MWMTableViewController + +- (void)setAdditionalTTSLanguage:(pair<string, string> const &)l; + +@end diff --git a/iphone/Maps/Settings/MWMTTSSettingsViewController.mm b/iphone/Maps/Settings/MWMTTSSettingsViewController.mm new file mode 100644 index 0000000000..bc120aee3c --- /dev/null +++ b/iphone/Maps/Settings/MWMTTSSettingsViewController.mm @@ -0,0 +1,201 @@ +#import "MWMTTSSettingsViewController.h" +#import <AVFoundation/AVFoundation.h> +#import "LinkCell.h" +#import "MWMTextToSpeech.h" +#import "SelectableCell.h" +#import "Statistics.h" +#import "UIColor+MapsMeColor.h" +#import "WebViewController.h" + +#include "LocaleTranslator.h" + +static NSString * kSelectTTSLanguageSegueName = @"TTSLanguage"; + +using namespace locale_translator; + +@interface MWMTTSSettingsViewController () +{ + pair<string, string> _additionalTTSLanguage; + vector<pair<string, string>> _languages; +} + +@property(nonatomic) BOOL isLocaleLanguageAbsent; + +@end + +@implementation MWMTTSSettingsViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + self.title = L(@"pref_tts_language_title"); + self.tableView.separatorColor = [UIColor blackDividers]; + MWMTextToSpeech * tts = [MWMTextToSpeech tts]; + + _languages.reserve(3); + auto const & v = tts.availableLanguages; + NSAssert(!v.empty(), @"Vector can't be empty!"); + pair<string, string> const standart = v.front(); + _languages.push_back(standart); + + using namespace tts; + NSString * currentBcp47 = [AVSpeechSynthesisVoice currentLanguageCode]; + string const currentBcp47Str = [currentBcp47 UTF8String]; + string const currentTwineStr = bcp47ToTwineLanguage(currentBcp47); + if (currentBcp47Str != standart.first && !currentBcp47Str.empty()) + { + string const translated = translatedTwine(currentTwineStr); + pair<string, string> const cur{currentBcp47Str, translated}; + if (translated.empty() || find(v.begin(), v.end(), cur) != v.end()) + _languages.push_back(cur); + else + self.isLocaleLanguageAbsent = YES; + } + + NSString * nsSavedLanguage = [MWMTextToSpeech savedLanguage]; + if (nsSavedLanguage.length) + { + string const savedLanguage = nsSavedLanguage.UTF8String; + if (savedLanguage != currentBcp47Str && savedLanguage != standart.first && + !savedLanguage.empty()) + _languages.emplace_back( + make_pair(savedLanguage, translatedTwine(bcp47ToTwineLanguage(nsSavedLanguage)))); + } +} + +- (IBAction)unwind:(id)sender +{ + size_t const size = _languages.size(); + if (find(_languages.begin(), _languages.end(), _additionalTTSLanguage) != _languages.end()) + { + [self.tableView reloadData]; + return; + } + switch (size) + { + case 1: _languages.push_back(_additionalTTSLanguage); break; + case 2: + if (self.isLocaleLanguageAbsent) + _languages[size - 1] = _additionalTTSLanguage; + else + _languages.push_back(_additionalTTSLanguage); + break; + case 3: _languages[size - 1] = _additionalTTSLanguage; break; + default: NSAssert(false, @"Incorrect language's count"); break; + } + [self.tableView reloadData]; +} + +- (void)setAdditionalTTSLanguage:(pair<string, string> const &)l +{ + [[MWMTextToSpeech tts] setNotificationsLocale:@(l.first.c_str())]; + _additionalTTSLanguage = l; +} + +#pragma mark - UITableViewDataSource + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 2; } +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + if (section == 0) + return _languages.size() + 2; + else + return 1; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView + cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + if (indexPath.section == 0) + { + if (indexPath.row == 0) + { + SelectableCell * cell = (SelectableCell *)[tableView + dequeueReusableCellWithIdentifier:[SelectableCell className]]; + cell.titleLabel.text = L(@"duration_disabled"); + cell.accessoryType = [MWMTextToSpeech isTTSEnabled] ? UITableViewCellAccessoryNone : UITableViewCellAccessoryCheckmark; + return cell; + } + else + { + NSInteger const row = indexPath.row - 1; + if (row == _languages.size()) + { + LinkCell * cell = + (LinkCell *)[tableView dequeueReusableCellWithIdentifier:[LinkCell className]]; + cell.titleLabel.text = L(@"pref_tts_other_section_title"); + return cell; + } + else + { + SelectableCell * cell = (SelectableCell *)[tableView + dequeueReusableCellWithIdentifier:[SelectableCell className]]; + pair<string, string> const p = _languages[row]; + cell.titleLabel.text = @(p.second.c_str()); + BOOL const isSelected = + [@(p.first.c_str()) isEqualToString:[MWMTextToSpeech savedLanguage]]; + cell.accessoryType = [MWMTextToSpeech isTTSEnabled] && isSelected + ? UITableViewCellAccessoryCheckmark + : UITableViewCellAccessoryNone; + return cell; + } + } + } + else + { + LinkCell * cell = + (LinkCell *)[tableView dequeueReusableCellWithIdentifier:[LinkCell className]]; + cell.titleLabel.text = L(@"pref_tts_how_to_set_up_voice"); + return cell; + } +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + if (indexPath.section == 0) + { + if (indexPath.row == 0) + { + [Statistics logEvent:kStatEventName(kStatSettings, kStatTTS) + withParameters:@{kStatValue : kStatOff}]; + [MWMTextToSpeech setTTSEnabled:NO]; + [tableView reloadSections:[NSIndexSet indexSetWithIndex:0] + withRowAnimation:UITableViewRowAnimationFade]; + } + else + { + [Statistics logEvent:kStatEventName(kStatSettings, kStatTTS) + withParameters:@{kStatValue : kStatOn}]; + [MWMTextToSpeech setTTSEnabled:YES]; + NSInteger const row = indexPath.row - 1; + if (row == _languages.size()) + { + [Statistics logEvent:kStatEventName(kStatTTSSettings, kStatChangeLanguage) + withParameters:@{kStatValue : kStatOther}]; + [self performSegueWithIdentifier:kSelectTTSLanguageSegueName sender:nil]; + } + else + { + [[MWMTextToSpeech tts] setNotificationsLocale:@(_languages[row].first.c_str())]; + [tableView reloadSections:[NSIndexSet indexSetWithIndex:0] + withRowAnimation:UITableViewRowAnimationFade]; + } + } + } + else if (indexPath.section == 1) + { + [Statistics logEvent:kStatEventName(kStatTTSSettings, kStatHelp)]; + NSString * path = + [[NSBundle mainBundle] pathForResource:@"tts-how-to-set-up-voice" ofType:@"html"]; + NSString * html = + [[NSString alloc] initWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil]; + NSURL * baseURL = [NSURL fileURLWithPath:path]; + WebViewController * vc = + [[WebViewController alloc] initWithHtml:html + baseUrl:baseURL + andTitleOrNil:L(@"pref_tts_how_to_set_up_voice")]; + [self.navigationController pushViewController:vc animated:YES]; + } +} + +@end diff --git a/iphone/Maps/Settings/MWMUnitsController.h b/iphone/Maps/Settings/MWMUnitsController.h new file mode 100644 index 0000000000..9135e1df1e --- /dev/null +++ b/iphone/Maps/Settings/MWMUnitsController.h @@ -0,0 +1,5 @@ +#import "MWMTableViewController.h" + +@interface MWMUnitsController : MWMTableViewController + +@end diff --git a/iphone/Maps/Settings/MWMUnitsController.mm b/iphone/Maps/Settings/MWMUnitsController.mm new file mode 100644 index 0000000000..859b99e12c --- /dev/null +++ b/iphone/Maps/Settings/MWMUnitsController.mm @@ -0,0 +1,57 @@ +#import "MWMUnitsController.h" +#import "MWMSettings.h" +#import "SelectableCell.h" +#import "Statistics.h" + +@interface MWMUnitsController () + +@property(weak, nonatomic) IBOutlet SelectableCell * kilometers; +@property(weak, nonatomic) IBOutlet SelectableCell * miles; +@property(weak, nonatomic) SelectableCell * selectedCell; + +@end + +@implementation MWMUnitsController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + self.title = L(@"measurement_units"); + + switch ([MWMSettings measurementUnits]) + { + case measurement_utils::Units::Metric: self.selectedCell = self.kilometers; break; + case measurement_utils::Units::Imperial: self.selectedCell = self.miles; break; + } +} + +- (void)setSelectedCell:(SelectableCell *)cell +{ + SelectableCell * selectedCell = _selectedCell; + if (selectedCell == cell) + return; + + selectedCell.accessoryType = UITableViewCellAccessoryNone; + cell.accessoryType = UITableViewCellAccessoryCheckmark; + cell.selected = NO; + _selectedCell = cell; + if (cell == self.kilometers) + { + [Statistics logEvent:kStatEventName(kStatSettings, kStatChangeMeasureUnits) + withParameters:@{kStatValue : kStatKilometers}]; + [MWMSettings setMeasurementUnits:measurement_utils::Units::Metric]; + } + else + { + [Statistics logEvent:kStatEventName(kStatSettings, kStatChangeMeasureUnits) + withParameters:@{kStatValue : kStatMiles}]; + [MWMSettings setMeasurementUnits:measurement_utils::Units::Imperial]; + } +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + self.selectedCell = [tableView cellForRowAtIndexPath:indexPath]; +} + +@end |