diff --git a/iphone/CoreApi/CoreApi/Common/MWMCommon.h b/iphone/CoreApi/CoreApi/Common/MWMCommon.h index f2d541d0e5..c3c52938aa 100644 --- a/iphone/CoreApi/CoreApi/Common/MWMCommon.h +++ b/iphone/CoreApi/CoreApi/Common/MWMCommon.h @@ -1,5 +1,7 @@ #import +#import "MWMTypes.h" + NS_ASSUME_NONNULL_BEGIN static inline BOOL firstVersionIsLessThanSecond(NSString * first, NSString * second) @@ -54,4 +56,12 @@ static inline CGFloat statusBarHeight() return MIN(statusBarSize.height, statusBarSize.width); } +static inline void performOnce(MWMVoidBlock block, NSString *key) { + BOOL performed = [[NSUserDefaults standardUserDefaults] boolForKey:key]; + if (!performed) { + block(); + [[NSUserDefaults standardUserDefaults] setBool:YES forKey:key]; + } +} + NS_ASSUME_NONNULL_END diff --git a/iphone/CoreApi/CoreApi/Traffic/MWMMapOverlayManager.h b/iphone/CoreApi/CoreApi/Traffic/MWMMapOverlayManager.h index 5a68b6164d..b124e92409 100644 --- a/iphone/CoreApi/CoreApi/Traffic/MWMMapOverlayManager.h +++ b/iphone/CoreApi/CoreApi/Traffic/MWMMapOverlayManager.h @@ -27,7 +27,9 @@ typedef NS_ENUM(NSUInteger, MWMMapOverlayIsolinesState) { typedef NS_ENUM(NSUInteger, MWMMapOverlayGuidesState) { MWMMapOverlayGuidesStateDisabled, MWMMapOverlayGuidesStateEnabled, + MWMMapOverlayGuidesStateHasData, MWMMapOverlayGuidesStateNetworkError, + MWMMapOverlayGuidesStateFatalNetworkError, MWMMapOverlayGuidesStateNoData, } NS_SWIFT_NAME(MapOverlayGuidesState); diff --git a/iphone/CoreApi/CoreApi/Traffic/MWMMapOverlayManager.mm b/iphone/CoreApi/CoreApi/Traffic/MWMMapOverlayManager.mm index 4653fc3cac..69df8bf35c 100644 --- a/iphone/CoreApi/CoreApi/Traffic/MWMMapOverlayManager.mm +++ b/iphone/CoreApi/CoreApi/Traffic/MWMMapOverlayManager.mm @@ -123,13 +123,13 @@ static NSString *kGuidesWasShown = @"guidesWasShown"; case GuidesManager::GuidesState::Enabled: return MWMMapOverlayGuidesStateEnabled; case GuidesManager::GuidesState::HasData: - return MWMMapOverlayGuidesStateEnabled; + return MWMMapOverlayGuidesStateHasData; case GuidesManager::GuidesState::NoData: return MWMMapOverlayGuidesStateNoData; case GuidesManager::GuidesState::NetworkError: return MWMMapOverlayGuidesStateNetworkError; case GuidesManager::GuidesState::FatalNetworkError: - return MWMMapOverlayGuidesStateNetworkError; + return MWMMapOverlayGuidesStateFatalNetworkError; } } diff --git a/iphone/Maps/Classes/CustomAlert/Toast/Toast.swift b/iphone/Maps/Classes/CustomAlert/Toast/Toast.swift index 46d18fc9a9..c83e7b94fd 100644 --- a/iphone/Maps/Classes/CustomAlert/Toast/Toast.swift +++ b/iphone/Maps/Classes/CustomAlert/Toast/Toast.swift @@ -1,10 +1,14 @@ @objc(MWMToast) -@objcMembers final class Toast: NSObject { + @objc(MWMToastAlignment) + enum Alignment: Int { + case bottom + case top + } private var blurView = UIVisualEffectView(effect: UIBlurEffect(style: .dark)) - static func toast(withText text: String) -> Toast { + @objc static func toast(withText text: String) -> Toast { return Toast(text) } @@ -34,11 +38,15 @@ final class Toast: NSObject { views: views)) } - func show() { - show(in: UIApplication.shared.keyWindow) + @objc func show() { + show(in: UIApplication.shared.keyWindow, alignment: .bottom) } - func show(in view: UIView?) { + @objc func show(withAlignment alignment: Alignment) { + show(in: UIApplication.shared.keyWindow, alignment: alignment) + } + + @objc func show(in view: UIView?, alignment: Alignment) { guard let v = view else { return } blurView.translatesAutoresizingMaskIntoConstraints = false v.addSubview(blurView) @@ -47,7 +55,8 @@ final class Toast: NSObject { options: [], metrics: [:], views: views)) - v.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:[bv]-50-|", + let formatString = alignment == .bottom ? "V:[bv]-50-|" : "V:|-50-[bv]" + v.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: formatString, options: [], metrics: [:], views: views)) diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/TrafficButton/MWMTrafficButtonViewController.mm b/iphone/Maps/Classes/CustomViews/MapViewControls/TrafficButton/MWMTrafficButtonViewController.mm index fd0c2d83b7..70eebd9749 100644 --- a/iphone/Maps/Classes/CustomViews/MapViewControls/TrafficButton/MWMTrafficButtonViewController.mm +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/TrafficButton/MWMTrafficButtonViewController.mm @@ -89,6 +89,66 @@ NSArray *imagesWithName(NSString *name) { }); } +- (void)handleTrafficState:(MWMMapOverlayTrafficState)state { + MWMButton *btn = (MWMButton *)self.view; + UIImageView *iv = btn.imageView; + switch (state) { + case MWMMapOverlayTrafficStateDisabled: + CHECK(false, ("Incorrect traffic manager state.")); + break; + case MWMMapOverlayTrafficStateEnabled: + btn.imageName = @"btn_traffic_on"; + break; + case MWMMapOverlayTrafficStateWaitingData: + iv.animationImages = imagesWithName(@"btn_traffic_update"); + iv.animationDuration = 0.8; + [iv startAnimating]; + break; + case MWMMapOverlayTrafficStateOutdated: + btn.imageName = @"btn_traffic_outdated"; + break; + case MWMMapOverlayTrafficStateNoData: + btn.imageName = @"btn_traffic_on"; + [[MWMToast toastWithText:L(@"traffic_data_unavailable")] show]; + break; + case MWMMapOverlayTrafficStateNetworkError: + [MWMMapOverlayManager setTrafficEnabled:NO]; + [[MWMAlertViewController activeAlertController] presentNoConnectionAlert]; + break; + case MWMMapOverlayTrafficStateExpiredData: + btn.imageName = @"btn_traffic_outdated"; + [[MWMToast toastWithText:L(@"traffic_update_maps_text")] show]; + break; + case MWMMapOverlayTrafficStateExpiredApp: + btn.imageName = @"btn_traffic_outdated"; + [[MWMToast toastWithText:L(@"traffic_update_app_message")] show]; + break; + } +} + +- (void)handleGuidesState:(MWMMapOverlayGuidesState)state { + switch (state) { + case MWMMapOverlayGuidesStateDisabled: + case MWMMapOverlayGuidesStateEnabled: + break; + case MWMMapOverlayGuidesStateHasData: + performOnce(^{ + [[MWMToast toastWithText:L(@"routes_layer_is_on_toast")] showWithAlignment:MWMToastAlignmentTop]; + }, @"routes_layer_is_on_toast"); + break; + case MWMMapOverlayGuidesStateNetworkError: + [[MWMToast toastWithText:L(@"connection_error_toast_guides")] show]; + break; + case MWMMapOverlayGuidesStateFatalNetworkError: + [MWMMapOverlayManager setGuidesEnabled:NO]; + [[MWMAlertViewController activeAlertController] presentNoConnectionAlert]; + break; + case MWMMapOverlayGuidesStateNoData: + [[MWMToast toastWithText:L(@"no_routes_in_the_area_toast")] show]; + break; + } +} + - (void)applyTheme { MWMButton *btn = static_cast(self.view); UIImageView *iv = btn.imageView; @@ -96,38 +156,7 @@ NSArray *imagesWithName(NSString *name) { // Traffic state machine: https://confluence.mail.ru/pages/viewpage.action?pageId=103680959 [iv stopAnimating]; if ([MWMMapOverlayManager trafficEnabled]) { - switch ([MWMMapOverlayManager trafficState]) { - case MWMMapOverlayTrafficStateDisabled: - CHECK(false, ("Incorrect traffic manager state.")); - break; - case MWMMapOverlayTrafficStateEnabled: - btn.imageName = @"btn_traffic_on"; - break; - case MWMMapOverlayTrafficStateWaitingData: - iv.animationImages = imagesWithName(@"btn_traffic_update"); - iv.animationDuration = 0.8; - [iv startAnimating]; - break; - case MWMMapOverlayTrafficStateOutdated: - btn.imageName = @"btn_traffic_outdated"; - break; - case MWMMapOverlayTrafficStateNoData: - btn.imageName = @"btn_traffic_on"; - [[MWMToast toastWithText:L(@"traffic_data_unavailable")] show]; - break; - case MWMMapOverlayTrafficStateNetworkError: - [MWMMapOverlayManager setTrafficEnabled:NO]; - [[MWMAlertViewController activeAlertController] presentNoConnectionAlert]; - break; - case MWMMapOverlayTrafficStateExpiredData: - btn.imageName = @"btn_traffic_outdated"; - [[MWMToast toastWithText:L(@"traffic_update_maps_text")] show]; - break; - case MWMMapOverlayTrafficStateExpiredApp: - btn.imageName = @"btn_traffic_outdated"; - [[MWMToast toastWithText:L(@"traffic_update_app_message")] show]; - break; - } + [self handleTrafficState:[MWMMapOverlayManager trafficState]]; } else if ([MWMMapOverlayManager transitEnabled]) { btn.imageName = @"btn_subway_on"; if ([MWMMapOverlayManager transitState] == MWMMapOverlayTransitStateNoData) @@ -145,12 +174,7 @@ NSArray *imagesWithName(NSString *name) { [MWMAlertViewController.activeAlertController presentInfoAlert:L(@"isolines_activation_error_dialog") text:@""]; } else if ([MWMMapOverlayManager guidesEnabled]) { btn.imageName = @"btn_layers_off"; - if ([MWMMapOverlayManager guidesState] == MWMMapOverlayGuidesStateNoData) - [[MWMToast toastWithText:L(@"no_routes_in_the_area_toast")] show]; - else if ([MWMMapOverlayManager guidesState] == MWMMapOverlayGuidesStateNetworkError) { - [MWMMapOverlayManager setGuidesEnabled:NO]; - [[MWMAlertViewController activeAlertController] presentNoConnectionAlert]; - } + [self handleGuidesState:[MWMMapOverlayManager guidesState]]; } else { btn.imageName = @"btn_layers"; } diff --git a/iphone/Maps/UI/BottomMenu/Menu/BottomMenuViewController.swift b/iphone/Maps/UI/BottomMenu/Menu/BottomMenuViewController.swift index e15ffaddd3..d0fb437f00 100644 --- a/iphone/Maps/UI/BottomMenu/Menu/BottomMenuViewController.swift +++ b/iphone/Maps/UI/BottomMenu/Menu/BottomMenuViewController.swift @@ -32,6 +32,9 @@ class BottomMenuViewController: MWMViewController { tableView.delegate = presenter tableView.registerNib(cell: BottomMenuItemCell.self) tableView.registerNib(cell: BottomMenuLayersCell.self) + performOnce({ + Toast.toast(withText: L("routes_layer_in_menu_toast")).show(withAlignment: .top) + }, "routes_layer_in_menu_toast") } override func viewDidLayoutSubviews() { diff --git a/iphone/Maps/UI/PlacePage/Components/GuidesGallery/GuidesGalleryPresenter.swift b/iphone/Maps/UI/PlacePage/Components/GuidesGallery/GuidesGalleryPresenter.swift index 07109f95d2..d438892463 100644 --- a/iphone/Maps/UI/PlacePage/Components/GuidesGallery/GuidesGalleryPresenter.swift +++ b/iphone/Maps/UI/PlacePage/Components/GuidesGallery/GuidesGalleryPresenter.swift @@ -120,7 +120,7 @@ fileprivate struct GalleryCityItemViewModel: IGuidesGalleryCityItemViewModel { subtitle = item.hasTrack ? L("routes_card_routes_tag") : L("routes_card_set_tag") imageUrl = URL(string: item.imageUrl) downloaded = item.downloaded - var infoString = String(coreFormat: "routes_card_number_of_points", arguments: [item.bookmarksCount]) + var infoString = String(coreFormat: L("routes_card_number_of_points"), arguments: [item.bookmarksCount]) if item.hasTrack { infoString.append(" \(L("routes_card_plus_track"))") }