forked from organicmaps/organicmaps-tmp
[MAPSME-6783] [ios] Updated network policy.
This commit is contained in:
parent
8c08668bed
commit
e9ddb58a66
18 changed files with 240 additions and 287 deletions
|
@ -4,3 +4,15 @@ extension String {
|
|||
self.init(format: format, arguments: arguments.map { "\($0)" })
|
||||
}
|
||||
}
|
||||
|
||||
extension NSString {
|
||||
@objc
|
||||
static func string(coreFormat: String, arguments: [AnyObject]) -> NSString {
|
||||
return NSString(coreFormat: coreFormat, arguments: arguments)
|
||||
}
|
||||
|
||||
@objc
|
||||
convenience init(coreFormat: String, arguments: [AnyObject]) {
|
||||
self.init(string: String(coreFormat: coreFormat, arguments: arguments as! [CVarArg]))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,21 +30,21 @@ NSString * const kStatisticsEvent = @"Mobile Internet Settings Alert";
|
|||
- (IBAction)alwaysTap
|
||||
{
|
||||
[Statistics logEvent:kStatMobileInternet withParameters:@{kStatValue : kStatAlways}];
|
||||
SetStage(np::Stage::Always);
|
||||
SetStage(Stage::Always);
|
||||
[self close:self.completionBlock];
|
||||
}
|
||||
|
||||
- (IBAction)askTap
|
||||
{
|
||||
[Statistics logEvent:kStatMobileInternet withParameters:@{kStatValue : kStatAsk}];
|
||||
SetStage(np::Stage::Session);
|
||||
[Statistics logEvent:kStatMobileInternet withParameters:@{kStatValue: kStatToday}];
|
||||
SetStage(Stage::Today);
|
||||
[self close:self.completionBlock];
|
||||
}
|
||||
|
||||
- (IBAction)neverTap
|
||||
{
|
||||
[Statistics logEvent:kStatisticsEvent withParameters:@{kStatAction : kStatNever}];
|
||||
SetStage(np::Stage::Never);
|
||||
[Statistics logEvent:kStatisticsEvent withParameters:@{kStatAction: kStatNotToday}];
|
||||
SetStage(Stage::NotToday);
|
||||
[self close:self.completionBlock];
|
||||
}
|
||||
|
||||
|
|
|
@ -101,7 +101,7 @@
|
|||
</state>
|
||||
<state key="highlighted" backgroundImage="dialog_btn_press"/>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="localizedText" value="mobile_data_option_never"/>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="localizedText" value="mobile_data_option_not_today"/>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="textColorName" value="linkBlue"/>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="fontName" value="medium17"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
|
|
|
@ -118,22 +118,10 @@ extern NSString * const kAlohalyticsTapEventKey;
|
|||
|
||||
- (void)showPlacePage:(place_page::Info const &)info
|
||||
{
|
||||
auto show = ^(place_page::Info const & info) {
|
||||
network_policy::CallPartnersApi([self, info](auto const & /* canUseNetwork */) {
|
||||
self.trafficButtonHidden = YES;
|
||||
[self.placePageManager show:info];
|
||||
};
|
||||
|
||||
using namespace network_policy;
|
||||
if (GetPlatform().ConnectionStatus() == Platform::EConnectionType::CONNECTION_WWAN &&
|
||||
!CanUseNetwork() && GetStage() == platform::NetworkPolicy::Stage::Session)
|
||||
{
|
||||
[[MWMAlertViewController activeAlertController]
|
||||
presentMobileInternetAlertWithBlock:[show, info] { show(info); }];
|
||||
}
|
||||
else
|
||||
{
|
||||
show(info);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
- (void)searchTextOnMap:(NSString *)text forInputLocale:(NSString *)locale
|
||||
|
|
|
@ -94,101 +94,91 @@ using namespace taxi;
|
|||
cv.hidden = YES;
|
||||
cv.pageControl.hidden = YES;
|
||||
|
||||
network_policy::CallPartnersApi(
|
||||
[self, completion, failure](platform::NetworkPolicy const & canUseNetwork) {
|
||||
auto const engine = GetFramework().GetTaxiEngine(canUseNetwork);
|
||||
if (!engine) {
|
||||
failure(L(@"dialog_taxi_error"));
|
||||
return;
|
||||
}
|
||||
network_policy::CallPartnersApi([self, completion, failure](auto const & canUseNetwork) {
|
||||
auto const engine = GetFramework().GetTaxiEngine(canUseNetwork);
|
||||
if (!engine)
|
||||
{
|
||||
failure(L(@"dialog_taxi_error"));
|
||||
return;
|
||||
}
|
||||
|
||||
auto success = [self, completion, failure](taxi::ProvidersContainer const & providers,
|
||||
uint64_t const requestId) {
|
||||
dispatch_async(dispatch_get_main_queue(), [self, completion, failure, providers,
|
||||
requestId] {
|
||||
if (self->m_requestId != requestId)
|
||||
return;
|
||||
if (providers.empty())
|
||||
{
|
||||
failure(L(@"taxi_no_providers"));
|
||||
[Statistics logEvent:kStatRoutingBuildTaxi
|
||||
withParameters:@{
|
||||
@"error" : @"No providers (Taxi isn't in the city)"
|
||||
}];
|
||||
return;
|
||||
}
|
||||
auto const & provider = providers.front();
|
||||
auto const & products = provider.GetProducts();
|
||||
auto const type = provider.GetType();
|
||||
self->m_products = products;
|
||||
NSString * providerName = nil;
|
||||
switch (type)
|
||||
{
|
||||
case taxi::Provider::Type::Uber:
|
||||
self.type = MWMRoutePreviewTaxiCellTypeUber;
|
||||
providerName = kStatUber;
|
||||
break;
|
||||
case taxi::Provider::Type::Yandex:
|
||||
self.type = MWMRoutePreviewTaxiCellTypeYandex;
|
||||
providerName = kStatYandex;
|
||||
break;
|
||||
}
|
||||
[Statistics logEvent:kStatRoutingBuildTaxi
|
||||
withParameters:@{
|
||||
@"provider" : providerName
|
||||
}];
|
||||
auto cv = self.collectionView;
|
||||
cv.hidden = NO;
|
||||
cv.pageControl.hidden = products.size() == 1;
|
||||
cv.numberOfPages = products.size();
|
||||
cv.contentOffset = {};
|
||||
cv.currentPage = 0;
|
||||
[cv reloadData];
|
||||
completion();
|
||||
});
|
||||
};
|
||||
auto success = [self, completion, failure](taxi::ProvidersContainer const & providers,
|
||||
uint64_t const requestId) {
|
||||
dispatch_async(dispatch_get_main_queue(), [self, completion, failure, providers, requestId] {
|
||||
if (self->m_requestId != requestId)
|
||||
return;
|
||||
if (providers.empty())
|
||||
{
|
||||
failure(L(@"taxi_no_providers"));
|
||||
[Statistics logEvent:kStatRoutingBuildTaxi
|
||||
withParameters:@{@"error": @"No providers (Taxi isn't in the city)"}];
|
||||
return;
|
||||
}
|
||||
auto const & provider = providers.front();
|
||||
auto const & products = provider.GetProducts();
|
||||
auto const type = provider.GetType();
|
||||
self->m_products = products;
|
||||
NSString * providerName = nil;
|
||||
switch (type)
|
||||
{
|
||||
case taxi::Provider::Type::Uber:
|
||||
self.type = MWMRoutePreviewTaxiCellTypeUber;
|
||||
providerName = kStatUber;
|
||||
break;
|
||||
case taxi::Provider::Type::Yandex:
|
||||
self.type = MWMRoutePreviewTaxiCellTypeYandex;
|
||||
providerName = kStatYandex;
|
||||
break;
|
||||
}
|
||||
[Statistics logEvent:kStatRoutingBuildTaxi withParameters:@{@"provider": providerName}];
|
||||
auto cv = self.collectionView;
|
||||
cv.hidden = NO;
|
||||
cv.pageControl.hidden = products.size() == 1;
|
||||
cv.numberOfPages = products.size();
|
||||
cv.contentOffset = {};
|
||||
cv.currentPage = 0;
|
||||
[cv reloadData];
|
||||
completion();
|
||||
});
|
||||
};
|
||||
|
||||
auto error = [self, failure](taxi::ErrorsContainer const & errors,
|
||||
uint64_t const requestId) {
|
||||
dispatch_async(dispatch_get_main_queue(), [self, failure, errors, requestId] {
|
||||
if (self->m_requestId != requestId)
|
||||
return;
|
||||
if (errors.empty())
|
||||
{
|
||||
NSCAssert(false, @"Errors container is empty");
|
||||
return;
|
||||
}
|
||||
auto const & error = errors.front();
|
||||
auto const errorCode = error.m_code;
|
||||
auto const type = error.m_type;
|
||||
NSString * provider = nil;
|
||||
switch (type)
|
||||
{
|
||||
case taxi::Provider::Type::Uber: provider = kStatUber; break;
|
||||
case taxi::Provider::Type::Yandex: provider = kStatYandex; break;
|
||||
}
|
||||
NSString * errorValue = nil;
|
||||
switch (errorCode)
|
||||
{
|
||||
case taxi::ErrorCode::NoProducts:
|
||||
errorValue = @"No products (Taxi is in the city, but no offers)";
|
||||
failure(L(@"taxi_not_found"));
|
||||
break;
|
||||
case taxi::ErrorCode::RemoteError:
|
||||
errorValue = @"Server error (The taxi server responded with an error)";
|
||||
failure(L(@"dialog_taxi_error"));
|
||||
break;
|
||||
}
|
||||
[Statistics logEvent:kStatRoutingBuildTaxi
|
||||
withParameters:@{
|
||||
@"provider" : provider,
|
||||
@"error" : errorValue
|
||||
}];
|
||||
});
|
||||
};
|
||||
auto error = [self, failure](taxi::ErrorsContainer const & errors, uint64_t const requestId) {
|
||||
dispatch_async(dispatch_get_main_queue(), [self, failure, errors, requestId] {
|
||||
if (self->m_requestId != requestId)
|
||||
return;
|
||||
if (errors.empty())
|
||||
{
|
||||
NSCAssert(false, @"Errors container is empty");
|
||||
return;
|
||||
}
|
||||
auto const & error = errors.front();
|
||||
auto const errorCode = error.m_code;
|
||||
auto const type = error.m_type;
|
||||
NSString * provider = nil;
|
||||
switch (type)
|
||||
{
|
||||
case taxi::Provider::Type::Uber: provider = kStatUber; break;
|
||||
case taxi::Provider::Type::Yandex: provider = kStatYandex; break;
|
||||
}
|
||||
NSString * errorValue = nil;
|
||||
switch (errorCode)
|
||||
{
|
||||
case taxi::ErrorCode::NoProducts:
|
||||
errorValue = @"No products (Taxi is in the city, but no offers)";
|
||||
failure(L(@"taxi_not_found"));
|
||||
break;
|
||||
case taxi::ErrorCode::RemoteError:
|
||||
errorValue = @"Server error (The taxi server responded with an error)";
|
||||
failure(L(@"dialog_taxi_error"));
|
||||
break;
|
||||
}
|
||||
[Statistics logEvent:kStatRoutingBuildTaxi
|
||||
withParameters:@{@"provider": provider, @"error": errorValue}];
|
||||
});
|
||||
};
|
||||
|
||||
m_requestId = engine->GetAvailableProducts(m_from, m_to, success, error);
|
||||
});
|
||||
m_requestId = engine->GetAvailableProducts(m_from, m_to, success, error);
|
||||
});
|
||||
}
|
||||
|
||||
- (BOOL)isTaxiInstalled
|
||||
|
@ -210,25 +200,23 @@ using namespace taxi;
|
|||
|
||||
auto const index = [self.collectionView indexPathsForVisibleItems].firstObject.row;
|
||||
auto const productId = m_products[index].m_productId;
|
||||
network_policy::CallPartnersApi(
|
||||
[self, productId, block](platform::NetworkPolicy const & canUseNetwork)
|
||||
network_policy::CallPartnersApi([self, productId, block](auto const & canUseNetwork) {
|
||||
auto const engine = GetFramework().GetTaxiEngine(canUseNetwork);
|
||||
if (!engine)
|
||||
return;
|
||||
Provider::Type type;
|
||||
switch (self.type)
|
||||
{
|
||||
auto const engine = GetFramework().GetTaxiEngine(canUseNetwork);
|
||||
if (!engine)
|
||||
return;
|
||||
Provider::Type type;
|
||||
switch (self.type)
|
||||
{
|
||||
case MWMRoutePreviewTaxiCellTypeTaxi: return;
|
||||
case MWMRoutePreviewTaxiCellTypeUber: type = Provider::Type::Uber; break;
|
||||
case MWMRoutePreviewTaxiCellTypeYandex: type = Provider::Type::Yandex; break;
|
||||
}
|
||||
case MWMRoutePreviewTaxiCellTypeTaxi: return;
|
||||
case MWMRoutePreviewTaxiCellTypeUber: type = Provider::Type::Uber; break;
|
||||
case MWMRoutePreviewTaxiCellTypeYandex: type = Provider::Type::Yandex; break;
|
||||
}
|
||||
|
||||
auto links = engine->GetRideRequestLinks(type, productId, m_from, m_to);
|
||||
auto url = [NSURL URLWithString:self.isTaxiInstalled ? @(links.m_deepLink.c_str()) :
|
||||
@(links.m_universalLink.c_str())];
|
||||
block(url);
|
||||
});
|
||||
auto links = engine->GetRideRequestLinks(type, productId, m_from, m_to);
|
||||
auto url = [NSURL URLWithString:self.isTaxiInstalled ? @(links.m_deepLink.c_str())
|
||||
: @(links.m_universalLink.c_str())];
|
||||
block(url);
|
||||
});
|
||||
}
|
||||
|
||||
#pragma mark - UICollectionViewDataSource
|
||||
|
|
|
@ -52,8 +52,7 @@ final class RoutePreviewTaxiCell: UICollectionViewCell {
|
|||
|
||||
let timeString = { () -> String in
|
||||
let timeValue = DateComponentsFormatter.etaString(from: TimeInterval(eta)!)!
|
||||
let format = L("taxi_wait").replacingOccurrences(of: "%s", with: "%@")
|
||||
return String(format: format, arguments: [timeValue])
|
||||
return String(coreFormat: L("taxi_wait"), arguments: [timeValue])
|
||||
}
|
||||
|
||||
icon.image = iconImage()
|
||||
|
|
|
@ -190,6 +190,7 @@ static NSString * const kStatNo = @"No";
|
|||
static NSString * const kStatNoConnection = @"no_connection";
|
||||
static NSString * const kStatNoSpace = @"no_space";
|
||||
static NSString * const kStatNone = @"none";
|
||||
static NSString * const kStatNotToday = @"NotToday";
|
||||
static NSString * const kStatOSM = @"OSM";
|
||||
static NSString * const kStatOSMUserName = @"osm_username";
|
||||
static NSString * const kStatObjectLat = @"object_lat";
|
||||
|
@ -318,6 +319,7 @@ static NSString * const kStatTaxi = @"Taxi";
|
|||
static NSString * const kStatThingsToDo = @"Things to do";
|
||||
static NSString * const kStatToLocation = @"to_location";
|
||||
static NSString * const kStatToMyPosition = @"To my position";
|
||||
static NSString * const kStatToday = @"Today";
|
||||
static NSString * const kStatToggleBookmark = @"Toggle bookmark";
|
||||
static NSString * const kStatToggleCompassCalibration = @"Toggle compass calibration";
|
||||
static NSString * const kStatToggleCoordinates = @"Toggle coordinates";
|
||||
|
|
|
@ -4,10 +4,19 @@
|
|||
|
||||
namespace network_policy
|
||||
{
|
||||
enum Stage
|
||||
{
|
||||
Ask,
|
||||
Always,
|
||||
Never,
|
||||
Today,
|
||||
NotToday
|
||||
};
|
||||
|
||||
void CallPartnersApi(platform::PartnersApiFn fn, bool force = false);
|
||||
|
||||
void SetStage(platform::NetworkPolicy::Stage state);
|
||||
platform::NetworkPolicy::Stage GetStage();
|
||||
void SetStage(Stage state);
|
||||
Stage const GetStage();
|
||||
|
||||
bool CanUseNetwork();
|
||||
} // namespace network_policy
|
||||
|
|
|
@ -3,16 +3,34 @@
|
|||
|
||||
#include "platform/platform.hpp"
|
||||
|
||||
using np = platform::NetworkPolicy;
|
||||
|
||||
namespace
|
||||
{
|
||||
NSString * const kNetworkingPolicyTimeStamp = @"NetworkingPolicyTimeStamp";
|
||||
NSString * const kNetworkingPolicyStage = @"NetworkingPolicyStage";
|
||||
NSTimeInterval const kSessionDurationSeconds = 24 * 60 * 60;
|
||||
} // namespace
|
||||
|
||||
namespace network_policy
|
||||
{
|
||||
void SetStage(Stage stage)
|
||||
{
|
||||
NSUserDefaults * ud = NSUserDefaults.standardUserDefaults;
|
||||
[ud setInteger:static_cast<NSInteger>(stage) forKey:kNetworkingPolicyStage];
|
||||
[ud setObject:[NSDate dateWithTimeIntervalSinceNow:kSessionDurationSeconds]
|
||||
forKey:kNetworkingPolicyTimeStamp];
|
||||
}
|
||||
|
||||
Stage const GetStage()
|
||||
{
|
||||
return static_cast<Stage>(
|
||||
[NSUserDefaults.standardUserDefaults integerForKey:kNetworkingPolicyStage]);
|
||||
}
|
||||
|
||||
NSDate * GetPolicyDate()
|
||||
{
|
||||
return [NSUserDefaults.standardUserDefaults objectForKey:kNetworkingPolicyTimeStamp];
|
||||
}
|
||||
|
||||
void CallPartnersApi(platform::PartnersApiFn fn, bool force)
|
||||
{
|
||||
auto const connectionType = GetPlatform().ConnectionStatus();
|
||||
|
@ -28,19 +46,26 @@ void CallPartnersApi(platform::PartnersApiFn fn, bool force)
|
|||
}
|
||||
|
||||
auto checkAndApply = ^bool {
|
||||
NSUserDefaults * ud = NSUserDefaults.standardUserDefaults;
|
||||
NSDate * policyDate = [ud objectForKey:kNetworkingPolicyTimeStamp];
|
||||
if ([policyDate compare:[NSDate date]] == NSOrderedDescending)
|
||||
switch (GetStage())
|
||||
{
|
||||
fn(true);
|
||||
return true;
|
||||
case Stage::Ask: return false;
|
||||
case Stage::Always: fn(true); return true;
|
||||
case Stage::Never: fn(false); return true;
|
||||
case Stage::Today:
|
||||
if ([GetPolicyDate() compare:[NSDate date]] == NSOrderedDescending)
|
||||
{
|
||||
fn(true);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
case Stage::NotToday:
|
||||
if ([GetPolicyDate() compare:[NSDate date]] == NSOrderedDescending)
|
||||
{
|
||||
fn(false);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if ([policyDate isEqualToDate:NSDate.distantPast])
|
||||
{
|
||||
fn(false);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
if (checkAndApply())
|
||||
|
@ -55,32 +80,6 @@ void CallPartnersApi(platform::PartnersApiFn fn, bool force)
|
|||
});
|
||||
}
|
||||
|
||||
void SetStage(np::Stage state)
|
||||
{
|
||||
NSUserDefaults * ud = NSUserDefaults.standardUserDefaults;
|
||||
NSDate * policyDate = nil;
|
||||
switch (state)
|
||||
{
|
||||
case np::Stage::Always: policyDate = NSDate.distantFuture; break;
|
||||
case np::Stage::Session:
|
||||
policyDate = [NSDate dateWithTimeIntervalSinceNow:kSessionDurationSeconds];
|
||||
break;
|
||||
case np::Stage::Never: policyDate = NSDate.distantPast; break;
|
||||
}
|
||||
[ud setObject:policyDate forKey:kNetworkingPolicyTimeStamp];
|
||||
}
|
||||
|
||||
np::Stage GetStage()
|
||||
{
|
||||
NSUserDefaults * ud = NSUserDefaults.standardUserDefaults;
|
||||
NSDate * policyDate = [ud objectForKey:kNetworkingPolicyTimeStamp];
|
||||
if ([policyDate isEqualToDate:NSDate.distantFuture])
|
||||
return np::Stage::Always;
|
||||
if ([policyDate isEqualToDate:NSDate.distantPast])
|
||||
return np::Stage::Never;
|
||||
return np::Stage::Session;
|
||||
}
|
||||
|
||||
bool CanUseNetwork()
|
||||
{
|
||||
using ct = Platform::EConnectionType;
|
||||
|
@ -89,11 +88,14 @@ bool CanUseNetwork()
|
|||
case ct::CONNECTION_NONE: return false;
|
||||
case ct::CONNECTION_WIFI: return true;
|
||||
case ct::CONNECTION_WWAN:
|
||||
{
|
||||
NSUserDefaults * ud = NSUserDefaults.standardUserDefaults;
|
||||
NSDate * policyDate = [ud objectForKey:kNetworkingPolicyTimeStamp];
|
||||
return [policyDate compare:[NSDate date]] == NSOrderedDescending;
|
||||
}
|
||||
switch (GetStage())
|
||||
{
|
||||
case Stage::Ask: return false;
|
||||
case Stage::Always: return true;
|
||||
case Stage::Never: return false;
|
||||
case Stage::Today: return [GetPolicyDate() compare:[NSDate date]] == NSOrderedDescending;
|
||||
case Stage::NotToday: return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace network_policy
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#import "MWMFrameworkListener.h"
|
||||
#import "MWMStorage.h"
|
||||
#import "Statistics.h"
|
||||
#import "SwiftBridge.h"
|
||||
#import "UIButton+RuntimeAttributes.h"
|
||||
|
||||
#include <unordered_set>
|
||||
|
@ -44,7 +45,6 @@ enum class State
|
|||
|
||||
- (void)startSpinner;
|
||||
- (void)stopSpinner;
|
||||
- (void)setProgress:(MapFilesDownloader::TProgress)progress nodeName:(NSString *)nodeName;
|
||||
- (void)updateForSize:(CGSize)size;
|
||||
|
||||
@end
|
||||
|
@ -80,9 +80,9 @@ enum class State
|
|||
[self stopSpinner];
|
||||
self.primaryButton.hidden = NO;
|
||||
self.secondaryButton.localizedText = L(@"whats_new_auto_update_button_later");
|
||||
NSString * pattern = [L(@"whats_new_auto_update_button_size") stringByReplacingOccurrencesOfString:@"%s"
|
||||
withString:@"%@"];
|
||||
self.primaryButton.localizedText = [NSString stringWithFormat:pattern, self.updateSize];
|
||||
self.primaryButton.localizedText =
|
||||
[NSString stringWithCoreFormat:L(@"whats_new_auto_update_button_size")
|
||||
arguments:@[self.updateSize]];
|
||||
}
|
||||
|
||||
- (void)startSpinner
|
||||
|
@ -108,32 +108,22 @@ enum class State
|
|||
|
||||
- (void)setStatusForNodeName:(NSString *)nodeName rootAttributes:(NodeAttrs const &)nodeAttrs
|
||||
{
|
||||
auto updatePlaceholder = ^NSString *(NSString * str)
|
||||
{
|
||||
return [str stringByReplacingOccurrencesOfString:@"%s" withString:@"%@"];
|
||||
};
|
||||
|
||||
auto const progress = nodeAttrs.m_downloadingProgress;
|
||||
CGFloat const prog = kMaxProgress * static_cast<CGFloat>(progress.first) / progress.second;
|
||||
self.spinner.progress = prog;
|
||||
|
||||
NSString * percent =
|
||||
[L(@"downloader_percent") stringByReplacingOccurrencesOfString:@"%s" withString:@"%@"];
|
||||
NSNumberFormatter * numberFormatter = [[NSNumberFormatter alloc] init];
|
||||
[numberFormatter setNumberStyle:NSNumberFormatterPercentStyle];
|
||||
[numberFormatter setMaximumFractionDigits:0];
|
||||
[numberFormatter setMultiplier:@100];
|
||||
NSString * percentString = [numberFormatter stringFromNumber:@(prog)];
|
||||
NSString * sizeString = formattedSize(progress.second);
|
||||
self.progressLabel.text = [NSString stringWithFormat:percent, percentString, sizeString];
|
||||
self.progressLabel.text = [NSString stringWithCoreFormat:L(@"downloader_percent")
|
||||
arguments:@[percentString, sizeString]];
|
||||
|
||||
NSString * process = nil;
|
||||
if (nodeAttrs.m_status == storage::NodeStatus::Applying)
|
||||
process = L(@"downloader_applying");
|
||||
else
|
||||
process = L(@"downloader_process");
|
||||
process = [process stringByReplacingOccurrencesOfString:@"%s" withString:@"%@"];
|
||||
self.legendLabel.text = [NSString stringWithFormat:process, nodeName];
|
||||
BOOL const isApplying = nodeAttrs.m_status == storage::NodeStatus::Applying;
|
||||
NSString * format = L(isApplying ? @"downloader_applying" : @"downloader_process");
|
||||
self.legendLabel.text = [NSString stringWithCoreFormat:format arguments:@[nodeName]];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -293,32 +293,16 @@ typedef NS_ENUM(NSUInteger, MWMBottomMenuViewCell) {
|
|||
|
||||
- (IBAction)discoveryTap
|
||||
{
|
||||
auto mode = ^MWMDiscoveryMode (BOOL canUseNetwork) {
|
||||
return canUseNetwork ? MWMDiscoveryModeOnline : MWMDiscoveryModeOffline;
|
||||
};
|
||||
|
||||
auto const connectionType = GetPlatform().ConnectionStatus();
|
||||
|
||||
[Statistics logEvent:kStatDiscoveryButtonOpen
|
||||
withParameters:@{kStatNetwork: [Statistics connectionTypeToString:connectionType]}];
|
||||
|
||||
self.state = self.restoreState;
|
||||
|
||||
auto discovery = [MWMDiscoveryController instance];
|
||||
using namespace network_policy;
|
||||
auto const canUseNetwork = CanUseNetwork();
|
||||
if (!canUseNetwork && connectionType == Platform::EConnectionType::CONNECTION_WWAN &&
|
||||
GetStage() == platform::NetworkPolicy::Stage::Session)
|
||||
{
|
||||
[[MWMAlertViewController activeAlertController] presentMobileInternetAlertWithBlock:^{
|
||||
discovery.mode = mode(CanUseNetwork());
|
||||
[self.controller.navigationController pushViewController:discovery animated:YES];
|
||||
}];
|
||||
return;
|
||||
}
|
||||
|
||||
discovery.mode = mode(canUseNetwork);
|
||||
[self.controller.navigationController pushViewController:discovery animated:YES];
|
||||
network_policy::CallPartnersApi([self](auto const & canUseNetwork) {
|
||||
auto discovery = [MWMDiscoveryController instanceWithConnection:canUseNetwork.CanUse()];
|
||||
[self.controller.navigationController pushViewController:discovery animated:YES];
|
||||
});
|
||||
}
|
||||
|
||||
- (IBAction)bookmarksButtonTouchUpInside
|
||||
|
|
|
@ -1,14 +1,7 @@
|
|||
#import "MWMViewController.h"
|
||||
|
||||
typedef NS_ENUM(NSUInteger, MWMDiscoveryMode)
|
||||
{
|
||||
MWMDiscoveryModeOnline,
|
||||
MWMDiscoveryModeOffline
|
||||
};
|
||||
|
||||
@interface MWMDiscoveryController : MWMViewController
|
||||
|
||||
+ (instancetype)instance;
|
||||
- (void)setMode:(MWMDiscoveryMode)mode;
|
||||
+ (instancetype)instanceWithConnection:(BOOL)connection;
|
||||
|
||||
@end
|
||||
|
|
|
@ -80,16 +80,17 @@ struct Callback
|
|||
|
||||
@property(weak, nonatomic) IBOutlet UITableView * tableView;
|
||||
@property(nonatomic) MWMDiscoveryTableManager * tableManager;
|
||||
@property(nonatomic) MWMDiscoveryMode mode;
|
||||
@property(nonatomic) BOOL canUseNetwork;
|
||||
|
||||
@end
|
||||
|
||||
@implementation MWMDiscoveryController
|
||||
|
||||
+ (instancetype)instance
|
||||
+ (instancetype)instanceWithConnection:(BOOL)canUseNetwork
|
||||
{
|
||||
auto instance = [[MWMDiscoveryController alloc] initWithNibName:self.className bundle:nil];
|
||||
instance.title = L(@"discovery_button_title");
|
||||
instance.canUseNetwork = canUseNetwork;
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
@ -116,14 +117,14 @@ struct Callback
|
|||
delegate:self
|
||||
model:move(callback)];
|
||||
|
||||
auto getTypes = [](MWMDiscoveryMode m) -> vector<ItemType> {
|
||||
if (m == MWMDiscoveryModeOnline)
|
||||
auto getTypes = [](BOOL canUseNetwork) -> vector<ItemType> {
|
||||
if (canUseNetwork)
|
||||
return {ItemType::Hotels, ItemType::Viator, ItemType::Attractions, ItemType::Cafes,
|
||||
ItemType::LocalExperts};
|
||||
return {ItemType::Hotels, ItemType::Attractions, ItemType::Cafes};
|
||||
};
|
||||
|
||||
vector<ItemType> types = getTypes(self.mode);
|
||||
vector<ItemType> types = getTypes(self.canUseNetwork);
|
||||
[self.tableManager loadItems:types];
|
||||
ClientParams p;
|
||||
p.m_itemTypes = move(types);
|
||||
|
|
|
@ -289,10 +289,7 @@ NSString * const kUserDefaultsLatLonAsDMSKey = @"UserDefaultsLatLonAsDMS";
|
|||
if (!self.isViator)
|
||||
return;
|
||||
|
||||
if (Platform::ConnectionStatus() == Platform::EConnectionType::CONNECTION_NONE)
|
||||
return;
|
||||
|
||||
network_policy::CallPartnersApi([self](platform::NetworkPolicy const & canUseNetwork) {
|
||||
network_policy::CallPartnersApi([self](auto const & canUseNetwork) {
|
||||
auto api = GetFramework().GetViatorApi(canUseNetwork);
|
||||
if (!api)
|
||||
return;
|
||||
|
@ -346,10 +343,7 @@ NSString * const kUserDefaultsLatLonAsDMSKey = @"UserDefaultsLatLonAsDMS";
|
|||
if (!self.isBooking)
|
||||
return;
|
||||
|
||||
if (Platform::ConnectionStatus() == Platform::EConnectionType::CONNECTION_NONE)
|
||||
return;
|
||||
|
||||
network_policy::CallPartnersApi([self](platform::NetworkPolicy const & canUseNetwork) {
|
||||
network_policy::CallPartnersApi([self](auto const & canUseNetwork) {
|
||||
auto api = GetFramework().GetBookingApi(canUseNetwork);
|
||||
if (!api)
|
||||
return;
|
||||
|
@ -569,42 +563,38 @@ NSString * const kUserDefaultsLatLonAsDMSKey = @"UserDefaultsLatLonAsDMS";
|
|||
return;
|
||||
}
|
||||
|
||||
if (Platform::ConnectionStatus() == Platform::EConnectionType::CONNECTION_NONE)
|
||||
return;
|
||||
|
||||
std::string const currency = self.currencyFormatter.currencyCode.UTF8String;
|
||||
|
||||
auto const func = [self, label, currency](std::string const & hotelId, std::string const & minPrice,
|
||||
std::string const & priceCurrency) {
|
||||
if (currency != priceCurrency)
|
||||
network_policy::CallPartnersApi([self, label](auto const & canUseNetwork) {
|
||||
auto const api = GetFramework().GetBookingApi(canUseNetwork);
|
||||
if (!api)
|
||||
return;
|
||||
|
||||
NSNumberFormatter * decimalFormatter = [[NSNumberFormatter alloc] init];
|
||||
decimalFormatter.numberStyle = NSNumberFormatterDecimalStyle;
|
||||
std::string const currency = self.currencyFormatter.currencyCode.UTF8String;
|
||||
|
||||
NSNumber * currencyNumber = [decimalFormatter
|
||||
numberFromString:[@(minPrice.c_str())
|
||||
stringByReplacingOccurrencesOfString:@"."
|
||||
withString:decimalFormatter
|
||||
.decimalSeparator]];
|
||||
NSString * currencyString = [self.currencyFormatter stringFromNumber:currencyNumber];
|
||||
auto const func = [self, label, currency](std::string const & hotelId,
|
||||
std::string const & minPrice,
|
||||
std::string const & priceCurrency) {
|
||||
if (currency != priceCurrency)
|
||||
return;
|
||||
|
||||
NSString * pattern =
|
||||
[L(@"place_page_starting_from") stringByReplacingOccurrencesOfString:@"%s"
|
||||
withString:@"%@"];
|
||||
NSNumberFormatter * decimalFormatter = [[NSNumberFormatter alloc] init];
|
||||
decimalFormatter.numberStyle = NSNumberFormatterDecimalStyle;
|
||||
|
||||
self.cachedMinPrice = [NSString stringWithFormat:pattern, currencyString];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
label.text = self.cachedMinPrice;
|
||||
});
|
||||
};
|
||||
NSNumber * currencyNumber = [decimalFormatter
|
||||
numberFromString:[@(minPrice.c_str())
|
||||
stringByReplacingOccurrencesOfString:@"."
|
||||
withString:decimalFormatter
|
||||
.decimalSeparator]];
|
||||
NSString * currencyString = [self.currencyFormatter stringFromNumber:currencyNumber];
|
||||
|
||||
network_policy::CallPartnersApi(
|
||||
[self, currency, func](platform::NetworkPolicy const & canUseNetwork) {
|
||||
auto const api = GetFramework().GetBookingApi(canUseNetwork);
|
||||
if (api)
|
||||
api->GetMinPrice(self.sponsoredId.UTF8String, currency, func);
|
||||
self.cachedMinPrice = [NSString stringWithCoreFormat:L(@"place_page_starting_from")
|
||||
arguments:@[currencyString]];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
label.text = self.cachedMinPrice;
|
||||
});
|
||||
};
|
||||
|
||||
api->GetMinPrice(self.sponsoredId.UTF8String, currency, func);
|
||||
});
|
||||
}
|
||||
|
||||
- (NSNumberFormatter *)currencyFormatter
|
||||
|
|
|
@ -25,9 +25,11 @@ using np = platform::NetworkPolicy;
|
|||
SettingsTableViewSelectableCell * 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;
|
||||
case Always: selected = self.always; break;
|
||||
case Never: selected = self.never; break;
|
||||
case Ask:
|
||||
case Today:
|
||||
case NotToday: selected = self.ask; break;
|
||||
}
|
||||
selected.accessoryType = UITableViewCellAccessoryCheckmark;
|
||||
self.selected = selected;
|
||||
|
@ -43,17 +45,17 @@ using np = platform::NetworkPolicy;
|
|||
if ([selected isEqual:self.always])
|
||||
{
|
||||
statValue = kStatAlways;
|
||||
SetStage(np::Stage::Always);
|
||||
SetStage(Always);
|
||||
}
|
||||
else if ([selected isEqual:self.ask])
|
||||
{
|
||||
statValue = kStatAsk;
|
||||
SetStage(np::Stage::Session);
|
||||
SetStage(Ask);
|
||||
}
|
||||
else if ([selected isEqual:self.never])
|
||||
{
|
||||
statValue = kStatNever;
|
||||
SetStage(np::Stage::Never);
|
||||
SetStage(Never);
|
||||
}
|
||||
|
||||
[Statistics logEvent:kStatMobileInternet withParameters:@{kStatValue : statValue}];
|
||||
|
|
|
@ -89,16 +89,16 @@ extern NSString * const kAlohalyticsTapEventKey;
|
|||
isOn:![MWMSettings autoDownloadEnabled]];
|
||||
|
||||
NSString * mobileInternet = nil;
|
||||
using stage = platform::NetworkPolicy::Stage;
|
||||
switch (network_policy::GetStage())
|
||||
{
|
||||
case stage::Always: mobileInternet = L(@"mobile_data_option_always"); break;
|
||||
case stage::Session: mobileInternet = L(@"mobile_data_option_today"); break;
|
||||
case stage::Never: mobileInternet = L(@"mobile_data_option_never"); break;
|
||||
case network_policy::Ask:
|
||||
case network_policy::Today:
|
||||
case network_policy::NotToday: mobileInternet = L(@"mobile_data_option_ask"); break;
|
||||
case network_policy::Always: mobileInternet = L(@"mobile_data_option_always"); break;
|
||||
case network_policy::Never: mobileInternet = L(@"mobile_data_option_never"); break;
|
||||
}
|
||||
[self.mobileInternetCell configWithTitle:L(@"mobile_data") info:mobileInternet];
|
||||
|
||||
|
||||
NSString * recentTrack = nil;
|
||||
if (!GpsTracker::Instance().IsEnabled())
|
||||
{
|
||||
|
|
|
@ -446,7 +446,7 @@
|
|||
<rect key="frame" x="0.0" y="702.5" width="375" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="QNt-XC-xma" id="fBV-aJ-Mo8">
|
||||
<rect key="frame" x="0.0" y="0.0" width="341" height="43.5"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="342" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Ночной режим" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="q7P-cj-3tZ">
|
||||
|
@ -549,7 +549,7 @@
|
|||
<rect key="frame" x="0.0" y="834.5" width="375" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="nED-2n-gN6" id="2oQ-0g-poj">
|
||||
<rect key="frame" x="0.0" y="0.0" width="341" height="43.5"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="342" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Голосовые инструкции" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="2v2-mU-aWi">
|
||||
|
@ -1580,7 +1580,7 @@
|
|||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="colorName" value="blackPrimaryText"/>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="fontName" value="regular17"/>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="localizedText" value="mobile_data_option_today"/>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="localizedText" value="mobile_data_option_ask"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</label>
|
||||
</subviews>
|
||||
|
|
|
@ -30,13 +30,6 @@ class NetworkPolicy
|
|||
friend void network_policy::CallPartnersApi(platform::PartnersApiFn fn, bool force);
|
||||
|
||||
public:
|
||||
enum class Stage
|
||||
{
|
||||
Always,
|
||||
Session,
|
||||
Never
|
||||
};
|
||||
|
||||
bool CanUse() const { return m_canUse; }
|
||||
|
||||
private:
|
||||
|
|
Loading…
Add table
Reference in a new issue