[new downloader][ios] Added map download dialog.

This commit is contained in:
Ilya Grechuhin 2016-02-16 11:15:07 +03:00 committed by Sergey Yershov
parent e183512ade
commit e2cda5d723
4 changed files with 366 additions and 4 deletions

View file

@ -2,19 +2,20 @@
#import "BookmarksVC.h"
#import "Common.h"
#import "EAGLView.h"
#import "MWMAPIBar.h"
#import "MapsAppDelegate.h"
#import "MapViewController.h"
#import "MWMAlertViewController.h"
#import "MWMAPIBar.h"
#import "MWMAuthorizationCommon.h"
#import "MWMAuthorizationLoginViewController.h"
#import "MWMEditorViewController.h"
#import "MWMMapDownloadDialog.h"
#import "MWMMapDownloaderViewController.h"
#import "MWMMapViewControlsManager.h"
#import "MWMPageController.h"
#import "MWMPlacePageEntity.h"
#import "MWMTableViewController.h"
#import "MWMTextToSpeech.h"
#import "MapViewController.h"
#import "MapsAppDelegate.h"
#import "RouteState.h"
#import "Statistics.h"
#import "UIColor+MapsMeColor.h"
@ -44,7 +45,6 @@ extern NSString * const kAlohalyticsTapEventKey = @"$onClick";
extern NSString * const kUDWhatsNewWasShown = @"WhatsNewWithNightModeWasShown";
extern char const * kAdForbiddenSettingsKey;
extern char const * kAdServerForbiddenKey;
extern char const * kAutoDownloadEnabledKey;
typedef NS_ENUM(NSUInteger, ForceRoutingStateChange)
{
@ -109,6 +109,7 @@ NSString * const kEditorSegue = @"Map2EditorSegue";
@property (nonatomic) UserTouchesAction userTouchesAction;
@property (nonatomic) MWMPageController * pageViewController;
@property (nonatomic) MWMMapDownloadDialog * downloadDialog;
@property (nonatomic) BOOL skipForceTouch;
@ -385,6 +386,7 @@ NSString * const kEditorSegue = @"Map2EditorSegue";
self.view.clipsToBounds = YES;
[MTRGManager setMyCom:YES];
self.controlsManager = [[MWMMapViewControlsManager alloc] initWithParentController:self];
self.downloadDialog = [MWMMapDownloadDialog dialogForController:self];
}
- (void)mwm_refreshUI

View file

@ -0,0 +1,5 @@
@interface MWMMapDownloadDialog : UIView
+ (instancetype)dialogForController:(MWMViewController *)controller;
@end

View file

@ -0,0 +1,224 @@
#import "Common.h"
#import "MapsAppDelegate.h"
#import "MWMCircularProgress.h"
#import "MWMMapDownloadDialog.h"
#include "Framework.h"
#include "storage/index.hpp"
extern char const * kAutoDownloadEnabledKey;
using namespace storage;
@interface MWMMapDownloadDialog ()<MWMFrameworkDrapeObserver, MWMFrameworkStorageObserver,
MWMCircularProgressProtocol>
@property (weak, nonatomic) IBOutlet UILabel * parentNode;
@property (weak, nonatomic) IBOutlet UILabel * node;
@property (weak, nonatomic) IBOutlet UILabel * nodeSize;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint * nodeTopOffset;
@property (weak, nonatomic) IBOutlet UIButton * downloadButton;
@property (weak, nonatomic) IBOutlet UIView * progressWrapper;
@property (weak, nonatomic) MWMViewController * controller;
@property (nonatomic) MWMCircularProgress * progressView;
@end
@implementation MWMMapDownloadDialog
{
TCountryId m_countryId;
}
+ (instancetype)dialogForController:(MWMViewController *)controller
{
MWMMapDownloadDialog * dialog = [[NSBundle mainBundle] loadNibNamed:[self className] owner:nil options:nil].firstObject;
dialog.autoresizingMask = UIViewAutoresizingFlexibleHeight;
dialog.controller = controller;
[[MWMFrameworkListener listener] addObserver:dialog];
return dialog;
}
- (void)layoutSubviews
{
[super layoutSubviews];
self.size = [self systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
UIView * superview = self.superview;
self.center = {superview.midX, superview.midY};
[super layoutSubviews];
}
- (void)configDialog
{
auto & s = GetFramework().Storage();
NodeAttrs nodeAttrs;
s.GetNodeAttrs(m_countryId, nodeAttrs);
BOOL const isMultiParent = nodeAttrs.m_parentInfo.size() > 1;
BOOL const noParrent = (nodeAttrs.m_parentInfo[0].m_id == s.GetRootId());
BOOL const hideParent = (noParrent || isMultiParent);
self.parentNode.hidden = hideParent;
self.nodeTopOffset.priority = hideParent ? UILayoutPriorityDefaultHigh : UILayoutPriorityDefaultLow;
if (!hideParent)
self.parentNode.text = @(nodeAttrs.m_parentInfo[0].m_localName.c_str());
self.node.text = @(nodeAttrs.m_nodeLocalName.c_str());
self.nodeSize.text = formattedSize(nodeAttrs.m_mwmSize);
auto addSubview = ^
{
if (!self.superview)
[self.controller.view addSubview:self];
};
auto removeSubview = ^
{
self.progressView.state = MWMCircularProgressStateNormal;
[self removeFromSuperview];
};
switch (nodeAttrs.m_status)
{
case NodeStatus::NotDownloaded:
{
bool autoDownloadEnabled = true;
(void)Settings::Get(kAutoDownloadEnabledKey, autoDownloadEnabled);
if (autoDownloadEnabled)
{
[self showInQueue];
s.DownloadNode(m_countryId);
}
else
{
[self showDownloadRequest];
}
addSubview();
break;
}
case NodeStatus::Downloading:
[self showDownloading:static_cast<CGFloat>(nodeAttrs.m_downloadingProgress) / 100.0];
addSubview();
break;
case NodeStatus::InQueue:
[self showInQueue];
addSubview();
break;
case NodeStatus::Undefined:
case NodeStatus::Error:
[self showError:nodeAttrs.m_error];
removeSubview();
break;
case NodeStatus::OnDisk:
case NodeStatus::OnDiskOutOfDate:
case NodeStatus::Mixed:
removeSubview();
break;
}
}
- (void)showError:(NodeErrorCode)errorCode
{
MWMAlertViewController * avc = self.controller.alertController;
switch (errorCode)
{
case NodeErrorCode::NoError:
break;
case NodeErrorCode::UnknownError:
[avc presentInternalErrorAlert];
break;
case NodeErrorCode::OutOfMemFailed:
[avc presentDownloaderNotEnoughSpaceAlert];
break;
case NodeErrorCode::NoInetConnection:
[avc presentDownloaderNoConnectionAlertWithOkBlock:^
{
GetFramework().Storage().RetryDownloadNode(self->m_countryId);
}];
break;
}
}
- (void)showDownloadRequest
{
self.downloadButton.hidden = NO;
self.progressWrapper.hidden = YES;
}
- (void)showDownloading:(CGFloat)progress
{
self.downloadButton.hidden = YES;
self.progressWrapper.hidden = NO;
self.progressView.progress = progress;
}
- (void)showInQueue
{
self.downloadButton.hidden = YES;
self.progressWrapper.hidden = NO;
[self.progressView startSpinner:NO];
}
#pragma mark - MWMFrameworkDrapeObserver
- (void)processViewportCountryEvent:(TCountryId const &)countryId
{
if (m_countryId == countryId)
return;
m_countryId = countryId;
if (countryId == kInvalidCountryId)
[self removeFromSuperview];
else
[self configDialog];
}
#pragma mark - MWMFrameworkStorageObserver
- (void)processCountryEvent:(TCountryId const &)countryId
{
if (self.superview && m_countryId == countryId)
[self configDialog];
}
- (void)processCountry:(TCountryId const &)countryId progress:(TLocalAndRemoteSize const &)progress
{
if (self.superview && m_countryId == countryId)
[self showDownloading:static_cast<CGFloat>(progress.first) / static_cast<CGFloat>(progress.second)];
}
#pragma mark - MWMCircularProgressDelegate
- (void)progressButtonPressed:(nonnull MWMCircularProgress *)progress
{
auto & s = GetFramework().Storage();
if (progress.state == MWMCircularProgressStateFailed)
{
s.RetryDownloadNode(m_countryId);
[self.progressView startSpinner:NO];
}
else
{
s.CancelDownloadNode(m_countryId);
}
}
#pragma mark - Actions
- (IBAction)downloadAction
{
[MapsAppDelegate downloadNode:m_countryId alertController:self.controller.alertController onSuccess:nil];
}
#pragma mark - Properties
- (MWMCircularProgress *)progressView
{
if (!_progressView)
{
_progressView = [[MWMCircularProgress alloc] initWithParentView:self.progressWrapper];
_progressView.delegate = self;
[_progressView setImage:[UIImage imageNamed:@"ic_close_spinner"] forState:MWMCircularProgressStateNormal];
[_progressView setImage:[UIImage imageNamed:@"ic_close_spinner"] forState:MWMCircularProgressStateSelected];
[_progressView setImage:[UIImage imageNamed:@"ic_close_spinner"] forState:MWMCircularProgressStateProgress];
[_progressView setImage:[UIImage imageNamed:@"ic_download_error"] forState:MWMCircularProgressStateFailed];
[_progressView setImage:[UIImage imageNamed:@"ic_check"] forState:MWMCircularProgressStateCompleted];
}
return _progressView;
}
@end

View file

@ -0,0 +1,131 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="9531" systemVersion="15D21" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9529"/>
</dependencies>
<customFonts key="customFonts">
<mutableArray key="HelveticaNeue.ttc">
<string>HelveticaNeue-Medium</string>
</mutableArray>
</customFonts>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view clipsSubviews="YES" contentMode="scaleToFill" id="I6H-BQ-1TG" customClass="MWMMapDownloadDialog">
<rect key="frame" x="0.0" y="0.0" width="200" height="197"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" verticalCompressionResistancePriority="751" text="Россия" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" preferredMaxLayoutWidth="180" translatesAutoresizingMaskIntoConstraints="NO" id="GQf-xO-gh1">
<rect key="frame" x="10" y="20" width="180" height="27"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="0.54000000000000004" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="colorName" value="blackSecondaryText"/>
<userDefinedRuntimeAttribute type="string" keyPath="fontName" value="medium16"/>
</userDefinedRuntimeAttributes>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="260" verticalCompressionResistancePriority="751" text="Доминиканская республика" textAlignment="center" lineBreakMode="wordWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" preferredMaxLayoutWidth="180" translatesAutoresizingMaskIntoConstraints="NO" id="vMH-GY-Vm2">
<rect key="frame" x="10" y="49" width="180" height="47"/>
<fontDescription key="fontDescription" name="HelveticaNeue" family="Helvetica Neue" pointSize="20"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="colorName" value="blackPrimaryText"/>
<userDefinedRuntimeAttribute type="string" keyPath="fontName" value="medium20"/>
</userDefinedRuntimeAttributes>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="260" text="16 МБ" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" preferredMaxLayoutWidth="180" translatesAutoresizingMaskIntoConstraints="NO" id="vU4-G9-kcd">
<rect key="frame" x="10" y="104" width="180" height="17"/>
<fontDescription key="fontDescription" name="HelveticaNeue-Medium" family="Helvetica Neue" pointSize="14"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="0.54000000000000004" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="colorName" value="blackSecondaryText"/>
<userDefinedRuntimeAttribute type="string" keyPath="fontName" value="medium14"/>
</userDefinedRuntimeAttributes>
</label>
<button opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="iyV-Rb-bea">
<rect key="frame" x="20" y="133" width="160" height="44"/>
<color key="backgroundColor" red="0.1176470588" green="0.58823529409999997" blue="0.94117647059999998" alpha="1" colorSpace="calibratedRGB"/>
<constraints>
<constraint firstAttribute="height" constant="44" id="i64-mO-Txs"/>
<constraint firstAttribute="width" constant="160" id="tIM-Zn-N9S"/>
</constraints>
<fontDescription key="fontDescription" name="HelveticaNeue" family="Helvetica Neue" pointSize="16"/>
<state key="normal" title="Скачать карту">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="textColorName" value="white"/>
<userDefinedRuntimeAttribute type="string" keyPath="backgroundColorName" value="linkBlue"/>
<userDefinedRuntimeAttribute type="string" keyPath="fontName" value="regular16"/>
<userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius">
<integer key="value" value="8"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="string" keyPath="backgroundHighlightedColorName" value="linkBlueHighlighted"/>
</userDefinedRuntimeAttributes>
<connections>
<action selector="downloadAction" destination="I6H-BQ-1TG" eventType="touchUpInside" id="gK1-oH-Xye"/>
</connections>
</button>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="usc-Cm-gmg" userLabel="ProgressViewWrapper">
<rect key="frame" x="84" y="139" width="32" height="32"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstAttribute="width" constant="32" id="LiD-Zk-ocz"/>
<constraint firstAttribute="height" constant="32" id="jrx-nU-VSG"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstItem="GQf-xO-gh1" firstAttribute="top" secondItem="I6H-BQ-1TG" secondAttribute="top" priority="500" constant="20" id="1zT-cE-XI3"/>
<constraint firstItem="usc-Cm-gmg" firstAttribute="centerX" secondItem="iyV-Rb-bea" secondAttribute="centerX" id="7DI-KV-B8S"/>
<constraint firstItem="GQf-xO-gh1" firstAttribute="leading" secondItem="I6H-BQ-1TG" secondAttribute="leading" constant="10" id="8Ve-AJ-XZP"/>
<constraint firstAttribute="trailing" secondItem="iyV-Rb-bea" secondAttribute="trailing" constant="20" id="C8t-0i-lpV"/>
<constraint firstItem="vMH-GY-Vm2" firstAttribute="top" secondItem="I6H-BQ-1TG" secondAttribute="top" priority="250" constant="20" id="Fy8-YF-nqF"/>
<constraint firstAttribute="bottom" secondItem="iyV-Rb-bea" secondAttribute="bottom" constant="20" id="HSh-rd-XIZ"/>
<constraint firstItem="vMH-GY-Vm2" firstAttribute="top" secondItem="GQf-xO-gh1" secondAttribute="bottom" priority="500" constant="2" id="Kje-IL-qJy"/>
<constraint firstItem="vU4-G9-kcd" firstAttribute="leading" secondItem="I6H-BQ-1TG" secondAttribute="leading" constant="10" id="REP-8b-3rF"/>
<constraint firstItem="vU4-G9-kcd" firstAttribute="top" secondItem="vMH-GY-Vm2" secondAttribute="bottom" constant="8" id="S4i-o8-W4I"/>
<constraint firstItem="iyV-Rb-bea" firstAttribute="top" secondItem="vU4-G9-kcd" secondAttribute="bottom" constant="12" id="VN6-NK-qgb"/>
<constraint firstItem="iyV-Rb-bea" firstAttribute="leading" secondItem="I6H-BQ-1TG" secondAttribute="leading" constant="20" id="atf-Me-rzF"/>
<constraint firstAttribute="trailing" secondItem="GQf-xO-gh1" secondAttribute="trailing" constant="10" id="fk3-dL-ayj"/>
<constraint firstAttribute="trailing" secondItem="vMH-GY-Vm2" secondAttribute="trailing" constant="10" id="hg5-RI-ugS"/>
<constraint firstItem="vMH-GY-Vm2" firstAttribute="leading" secondItem="I6H-BQ-1TG" secondAttribute="leading" constant="10" id="jH6-er-pmN"/>
<constraint firstItem="usc-Cm-gmg" firstAttribute="centerY" secondItem="iyV-Rb-bea" secondAttribute="centerY" id="pxa-11-yUj"/>
<constraint firstAttribute="trailing" secondItem="vU4-G9-kcd" secondAttribute="trailing" constant="10" id="zl8-cq-RDc"/>
</constraints>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius">
<integer key="value" value="8"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="number" keyPath="layer.shadowRadius">
<integer key="value" value="2"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="color" keyPath="layer.shadowUIColor">
<color key="value" red="0.0" green="0.0" blue="0.0" alpha="0.23999999999999999" colorSpace="calibratedRGB"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="number" keyPath="layer.shadowOpacity">
<integer key="value" value="1"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="size" keyPath="layer.shadowOffset">
<size key="value" width="0.0" height="1"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="string" keyPath="backgroundColorName" value="white"/>
</userDefinedRuntimeAttributes>
<connections>
<outlet property="downloadButton" destination="iyV-Rb-bea" id="6fy-CY-zos"/>
<outlet property="node" destination="vMH-GY-Vm2" id="LJq-UU-a3U"/>
<outlet property="nodeSize" destination="vU4-G9-kcd" id="DMJ-NW-mxf"/>
<outlet property="nodeTopOffset" destination="Fy8-YF-nqF" id="eWV-H6-oXU"/>
<outlet property="parentNode" destination="GQf-xO-gh1" id="gWT-r0-LTv"/>
<outlet property="progressWrapper" destination="usc-Cm-gmg" id="NTd-bU-rDE"/>
</connections>
<point key="canvasLocation" x="359" y="425"/>
</view>
</objects>
</document>