Repo created

This commit is contained in:
Fr4nz D13trich 2025-11-22 13:58:55 +01:00
parent 4af19165ec
commit 68073add76
12458 changed files with 12350765 additions and 2 deletions

View file

@ -0,0 +1,16 @@
#import "MWMAlert+CPP.h"
#include "routing/routing_callbacks.hpp"
#include "storage/storage_defines.hpp"
@interface MWMDownloadTransitMapAlert : MWMAlert
+ (instancetype)downloaderAlertWithMaps:(storage::CountriesSet const &)countries
code:(routing::RouterResultCode)code
cancelBlock:(MWMVoidBlock)cancelBlock
downloadBlock:(MWMDownloadBlock)downloadBlock
downloadCompleteBlock:(MWMVoidBlock)downloadCompleteBlock;
- (void)showDownloadDetail:(UIButton *)sender;
@end

View file

@ -0,0 +1,352 @@
#import "MWMDownloadTransitMapAlert.h"
#import "MWMCircularProgress.h"
#import "MWMDownloaderDialogCell.h"
#import "MWMDownloaderDialogHeader.h"
#import "MWMStorage+UI.h"
#import "SwiftBridge.h"
#include <CoreApi/Framework.h>
#include "platform/downloader_defines.hpp"
namespace
{
NSString * const kDownloadTransitMapAlertNibName = @"MWMDownloadTransitMapAlert";
CGFloat const kCellHeight = 32.;
CGFloat const kHeaderHeight = 44.;
CGFloat const kMinimumOffset = 20.;
CGFloat const kAnimationDuration = .05;
} // namespace
@interface MWMDownloadTransitMapAlert () <UITableViewDataSource, UITableViewDelegate, MWMStorageObserver, MWMCircularProgressProtocol>
@property(copy, nonatomic) MWMVoidBlock cancelBlock;
@property(copy, nonatomic) MWMDownloadBlock downloadBlock;
@property(copy, nonatomic) MWMVoidBlock downloadCompleteBlock;
@property (nonatomic) MWMCircularProgress * progress;
@property (weak, nonatomic) IBOutlet UIView * containerView;
@property (weak, nonatomic) IBOutlet UILabel * titleLabel;
@property (weak, nonatomic) IBOutlet UILabel * messageLabel;
@property (weak, nonatomic) IBOutlet UITableView * dialogsTableView;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint * tableViewHeight;
@property (nonatomic) MWMDownloaderDialogHeader * listHeader;
@property (nonatomic) BOOL listExpanded;
@property (weak, nonatomic) IBOutlet UIView * progressWrapper;
@property (weak, nonatomic) IBOutlet UIView * hDivider;
@property (weak, nonatomic) IBOutlet UIView * vDivider;
@property (weak, nonatomic) IBOutlet UIButton * leftButton;
@property (weak, nonatomic) IBOutlet UIButton * rightButton;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint * dialogsBottomOffset;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint * progressWrapperBottomOffset;
@property (copy, nonatomic) NSArray<NSString *> * countriesNames;
@property (copy, nonatomic) NSString * countriesSize;
@end
@implementation MWMDownloadTransitMapAlert
{
storage::CountriesVec m_countries;
}
+ (instancetype)downloaderAlertWithMaps:(storage::CountriesSet const &)countries
code:(routing::RouterResultCode)code
cancelBlock:(MWMVoidBlock)cancelBlock
downloadBlock:(MWMDownloadBlock)downloadBlock
downloadCompleteBlock:(MWMVoidBlock)downloadCompleteBlock
{
MWMDownloadTransitMapAlert * alert = [self alertWithCountries:countries];
switch (code)
{
case routing::RouterResultCode::InconsistentMWMandRoute:
case routing::RouterResultCode::RouteNotFound:
case routing::RouterResultCode::RouteFileNotExist:
alert.titleLabel.text = L(@"dialog_routing_download_files");
alert.messageLabel.text = L(@"dialog_routing_download_and_update_all");
break;
case routing::RouterResultCode::FileTooOld:
alert.titleLabel.text = L(@"dialog_routing_download_files");
alert.messageLabel.text = L(@"dialog_routing_download_and_update_maps");
break;
case routing::RouterResultCode::NeedMoreMaps:
alert.titleLabel.text = L(@"dialog_routing_download_and_build_cross_route");
alert.messageLabel.text = L(@"dialog_routing_download_cross_route");
break;
default:
NSAssert(false, @"Incorrect code!");
break;
}
alert.cancelBlock = cancelBlock;
alert.downloadBlock = downloadBlock;
alert.downloadCompleteBlock = downloadCompleteBlock;
return alert;
}
+ (instancetype)alertWithCountries:(storage::CountriesSet const &)countries
{
NSAssert(!countries.empty(), @"countries can not be empty.");
MWMDownloadTransitMapAlert * alert =
[NSBundle.mainBundle loadNibNamed:kDownloadTransitMapAlertNibName owner:nil options:nil]
.firstObject;
alert->m_countries = storage::CountriesVec(countries.begin(), countries.end());
[alert configure];
[alert updateCountriesList];
[[MWMStorage sharedStorage] addObserver:alert];
return alert;
}
- (void)configure
{
[self.dialogsTableView registerNibWithCellClass:[MWMDownloaderDialogCell class]];
self.listExpanded = NO;
CALayer * containerViewLayer = self.containerView.layer;
containerViewLayer.shouldRasterize = YES;
containerViewLayer.rasterizationScale = [[UIScreen mainScreen] scale];
[self.dialogsTableView reloadData];
}
- (void)updateCountriesList
{
auto const & s = GetFramework().GetStorage();
m_countries.erase(
remove_if(m_countries.begin(), m_countries.end(),
[&s](storage::CountryId const & countryId) { return s.HasLatestVersion(countryId); }),
m_countries.end());
NSMutableArray<NSString *> * titles = [@[] mutableCopy];
MwmSize totalSize = 0;
for (auto const & countryId : m_countries)
{
storage::NodeAttrs attrs;
s.GetNodeAttrs(countryId, attrs);
[titles addObject:@(attrs.m_nodeLocalName.c_str())];
totalSize += attrs.m_mwmSize;
}
self.countriesNames = titles;
self.countriesSize = formattedSize(totalSize);
}
#pragma mark - MWMCircularProgressProtocol
- (void)progressButtonPressed:(nonnull MWMCircularProgress *)progress
{
for (auto const & countryId : m_countries)
[[MWMStorage sharedStorage] cancelDownloadNode:@(countryId.c_str())];
[self cancelButtonTap];
}
#pragma mark - MWMStorageObserver
- (void)processCountryEvent:(NSString *)countryId
{
if (find(m_countries.begin(), m_countries.end(), countryId.UTF8String) == m_countries.end())
return;
if (self.rightButton.hidden)
{
auto const & s = GetFramework().GetStorage();
auto const & p = GetFramework().GetDownloadingPolicy();
if (s.CheckFailedCountries(m_countries))
{
if (p.IsAutoRetryDownloadFailed())
[self close:nil];
return;
}
auto const overallProgress = s.GetOverallProgress(m_countries);
// Test if downloading has finished by comparing downloaded and total sizes.
if (overallProgress.m_bytesDownloaded == overallProgress.m_bytesTotal)
[self close:self.downloadCompleteBlock];
}
else
{
[self updateCountriesList];
[self.dialogsTableView reloadSections:[NSIndexSet indexSetWithIndex:0]
withRowAnimation:UITableViewRowAnimationAutomatic];
if (m_countries.empty())
[self close:self.downloadCompleteBlock];
}
}
- (void)processCountry:(NSString *)countryId
downloadedBytes:(uint64_t)downloadedBytes
totalBytes:(uint64_t)totalBytes
{
if (!self.rightButton.hidden ||
find(m_countries.begin(), m_countries.end(), countryId.UTF8String) == m_countries.end())
return;
auto const overallProgress = GetFramework().GetStorage().GetOverallProgress(m_countries);
CGFloat const progressValue =
static_cast<CGFloat>(overallProgress.m_bytesDownloaded) / overallProgress.m_bytesTotal;
self.progress.progress = progressValue;
self.titleLabel.text = [NSString stringWithFormat:@"%@%@%%", L(@"downloading"), @(floor(progressValue * 100))];
}
#pragma mark - Actions
- (IBAction)cancelButtonTap
{
[self close:self.cancelBlock];
}
- (IBAction)downloadButtonTap
{
[self updateCountriesList];
if (m_countries.empty())
{
[self close:self.downloadCompleteBlock];
return;
}
self.downloadBlock(m_countries, ^{
self.titleLabel.text = L(@"downloading");
self.messageLabel.hidden = YES;
self.progressWrapper.hidden = NO;
self.progress.state = MWMCircularProgressStateSpinner;
self.hDivider.hidden = YES;
self.vDivider.hidden = YES;
self.leftButton.hidden = YES;
self.rightButton.hidden = YES;
self.dialogsBottomOffset.priority = UILayoutPriorityDefaultHigh;
self.progressWrapperBottomOffset.priority = UILayoutPriorityDefaultHigh;
[UIView animateWithDuration:kAnimationDuration
animations:^{
[self layoutSubviews];
}];
});
}
- (void)showDownloadDetail:(UIButton *)sender
{
self.listExpanded = sender.selected;
}
- (void)setListExpanded:(BOOL)listExpanded
{
_listExpanded = listExpanded;
[self layoutIfNeeded];
auto const updateCells = ^(BOOL show)
{
for (MWMDownloaderDialogCell * cell in self.dialogsTableView.visibleCells)
{
cell.titleLabel.alpha = show ? 1. : 0.;
}
[self.dialogsTableView refresh];
};
if (listExpanded)
{
CGFloat const actualHeight = kCellHeight * m_countries.size() + kHeaderHeight;
CGFloat const height = [self bounded:actualHeight withHeight:self.superview.height];
self.tableViewHeight.constant = height;
self.dialogsTableView.scrollEnabled = actualHeight > self.tableViewHeight.constant;
[UIView animateWithDuration:kAnimationDuration animations:^{ [self layoutSubviews]; }
completion:^(BOOL finished)
{
[UIView animateWithDuration:kDefaultAnimationDuration animations:^{ updateCells(YES); }];
}];
}
else
{
self.tableViewHeight.constant = kHeaderHeight;
self.dialogsTableView.scrollEnabled = NO;
updateCells(NO);
[UIView animateWithDuration:kAnimationDuration animations:^{ [self layoutSubviews]; }];
}
}
- (CGFloat)bounded:(CGFloat)f withHeight:(CGFloat)h
{
CGFloat const currentHeight = [self.subviews.firstObject height];
CGFloat const maximumHeight = h - 2. * kMinimumOffset;
CGFloat const availableHeight = maximumHeight - currentHeight;
return MIN(f, availableHeight + self.tableViewHeight.constant);
}
- (void)invalidateTableConstraintWithHeight:(CGFloat)height
{
if (self.listExpanded)
{
CGFloat const actualHeight = kCellHeight * m_countries.size() + kHeaderHeight;
self.tableViewHeight.constant = [self bounded:actualHeight withHeight:height];
self.dialogsTableView.scrollEnabled = actualHeight > self.tableViewHeight.constant;
}
else
{
self.tableViewHeight.constant = kHeaderHeight;
}
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)orientation
{
CGFloat const height = UIInterfaceOrientationIsLandscape(orientation) ? MIN(self.superview.width, self.superview.height) : MAX(self.superview.width, self.superview.height);
[self invalidateTableConstraintWithHeight:height];
}
- (void)close:(MWMVoidBlock)completion
{
[[MWMStorage sharedStorage] removeObserver:self];
[super close:completion];
}
#pragma mark - UITableViewDelegate
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return m_countries.size();
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return kHeaderHeight;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return kCellHeight;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
return self.listHeader;
}
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
UIView * view = [[UIView alloc] init];
view.styleName = @"BlackOpaqueBackground";
return view;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
Class cls = [MWMDownloaderDialogCell class];
auto cell = static_cast<MWMDownloaderDialogCell *>(
[tableView dequeueReusableCellWithCellClass:cls indexPath:indexPath]);
cell.titleLabel.text = self.countriesNames[indexPath.row];
return cell;
}
#pragma mark - Properties
- (MWMDownloaderDialogHeader *)listHeader
{
if (!_listHeader)
_listHeader = [MWMDownloaderDialogHeader headerForOwnerAlert:self];
[_listHeader setTitle:[NSString stringWithFormat:@"%@ (%@)", L(@"downloader_status_maps"), @(m_countries.size())]
size:self.countriesSize];
return _listHeader;
}
- (MWMCircularProgress *)progress
{
if (!_progress)
{
_progress = [MWMCircularProgress downloaderProgressForParentView:self.progressWrapper];
_progress.delegate = self;
}
return _progress;
}
@end

View file

@ -0,0 +1,192 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="15702" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15704"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="jqI-GQ-yDh" customClass="MWMDownloadTransitMapAlert" propertyAccessControl="none">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<subviews>
<view clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Hay-Qx-kVw" userLabel="ContainerView">
<rect key="frame" x="47.5" y="218.5" width="280" height="230"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Title" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="MvX-7q-CIH" userLabel="Title">
<rect key="frame" x="20" y="20" width="240" height="29"/>
<constraints>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="29" id="018-Nz-384"/>
<constraint firstAttribute="width" constant="240" id="cHd-lJ-pXe"/>
</constraints>
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="18"/>
<color key="textColor" red="0.12941176470588234" green="0.12941176470588234" blue="0.12941176470588234" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
<size key="shadowOffset" width="0.0" height="0.0"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="localizedText" value="routing_download_maps_along"/>
<userDefinedRuntimeAttribute type="string" keyPath="styleName" value="medium18:blackPrimaryText"/>
</userDefinedRuntimeAttributes>
</label>
<view hidden="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="bco-zh-ekL">
<rect key="frame" x="122" y="65" width="36" height="36"/>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="height" constant="36" id="0Pg-8w-QZa"/>
<constraint firstAttribute="width" constant="36" id="cjU-dH-SAG"/>
</constraints>
</view>
<label opaque="NO" userInteractionEnabled="NO" contentMode="center" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Message" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Q3X-9G-3PT">
<rect key="frame" x="23" y="61" width="234" height="17"/>
<constraints>
<constraint firstAttribute="width" constant="234" id="YLG-PG-WHS"/>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="17" id="iOI-5t-pEY"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="0.54000000000000004" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="localizedText" value="routing_requires_all_map"/>
<userDefinedRuntimeAttribute type="string" keyPath="styleName" value="regular14:blackSecondaryText"/>
</userDefinedRuntimeAttributes>
</label>
<tableView clipsSubviews="YES" contentMode="scaleToFill" verticalHuggingPriority="1000" alwaysBounceVertical="YES" scrollEnabled="NO" style="grouped" separatorStyle="none" rowHeight="32" sectionHeaderHeight="44" sectionFooterHeight="1" translatesAutoresizingMaskIntoConstraints="NO" id="1lL-cj-2oS">
<rect key="frame" x="0.0" y="98" width="280" height="88"/>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="height" constant="88" id="92H-Th-Xgt"/>
</constraints>
<color key="separatorColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
<color key="sectionIndexBackgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
<color key="sectionIndexTrackingBackgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
<connections>
<outlet property="dataSource" destination="jqI-GQ-yDh" id="8mP-kY-rEz"/>
<outlet property="delegate" destination="jqI-GQ-yDh" id="9Fy-MW-IYa"/>
</connections>
</tableView>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="2nQ-k3-Rx3" userLabel="hDivider">
<rect key="frame" x="0.0" y="186" width="280" height="1"/>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.12" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="width" constant="280" id="YGc-0s-8yD"/>
<constraint firstAttribute="height" constant="1" id="l1s-jg-dng"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="styleName" value="Divider"/>
</userDefinedRuntimeAttributes>
</view>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="q87-qQ-0rn">
<rect key="frame" x="140" y="186" width="140" height="44"/>
<accessibility key="accessibilityConfiguration" identifier="downloadNowButton"/>
<constraints>
<constraint firstAttribute="width" constant="140" id="1Io-1t-Odn"/>
<constraint firstAttribute="height" constant="44" id="CeP-fJ-qZs"/>
</constraints>
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="17"/>
<state key="normal" title="right">
<color key="titleColor" red="0.090196078430000007" green="0.61960784310000006" blue="0.30196078430000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" backgroundImage="dialog_btn_press"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="localizedText" value="download"/>
<userDefinedRuntimeAttribute type="string" keyPath="styleName" value="medium17:linkBlueText"/>
</userDefinedRuntimeAttributes>
<connections>
<action selector="downloadButtonTap" destination="jqI-GQ-yDh" eventType="touchUpInside" id="wBd-0C-U51"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="dhS-fg-rNl">
<rect key="frame" x="0.0" y="186" width="140" height="44"/>
<accessibility key="accessibilityConfiguration" identifier="notNowButton"/>
<constraints>
<constraint firstAttribute="height" constant="44" id="7gw-Uu-UEK"/>
<constraint firstAttribute="width" constant="140" id="EMA-LM-Zje"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<state key="normal" title="left">
<color key="titleColor" red="0.090196078430000007" green="0.61960784310000006" blue="0.30196078430000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" backgroundImage="dialog_btn_press"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="localizedText" value="later"/>
<userDefinedRuntimeAttribute type="string" keyPath="styleName" value="medium17:linkBlueText"/>
</userDefinedRuntimeAttributes>
<connections>
<action selector="cancelButtonTap" destination="jqI-GQ-yDh" eventType="touchUpInside" id="xii-qA-4BV"/>
</connections>
</button>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Jjh-VP-emP" userLabel="vDivider">
<rect key="frame" x="139" y="186" width="1" height="44"/>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.12" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="width" constant="1" id="8kQ-Yd-0D3"/>
<constraint firstAttribute="height" constant="44" id="vYd-td-NOl"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="styleName" value="Divider"/>
</userDefinedRuntimeAttributes>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="0.88" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="dhS-fg-rNl" firstAttribute="top" secondItem="1lL-cj-2oS" secondAttribute="bottom" priority="500" id="2aT-au-ilL"/>
<constraint firstAttribute="bottom" secondItem="dhS-fg-rNl" secondAttribute="bottom" id="2bS-ac-iDr"/>
<constraint firstItem="bco-zh-ekL" firstAttribute="centerX" secondItem="Hay-Qx-kVw" secondAttribute="centerX" id="3xy-PQ-9lP"/>
<constraint firstAttribute="bottom" secondItem="q87-qQ-0rn" secondAttribute="bottom" id="3yg-r8-Lm3"/>
<constraint firstAttribute="bottom" secondItem="1lL-cj-2oS" secondAttribute="bottom" priority="250" id="58e-JY-U6g"/>
<constraint firstAttribute="centerX" secondItem="2nQ-k3-Rx3" secondAttribute="centerX" id="5S3-Lh-pMR"/>
<constraint firstAttribute="trailing" secondItem="q87-qQ-0rn" secondAttribute="trailing" id="Bud-qr-UTy"/>
<constraint firstItem="bco-zh-ekL" firstAttribute="top" secondItem="MvX-7q-CIH" secondAttribute="bottom" constant="16" id="D9b-za-yb8"/>
<constraint firstItem="q87-qQ-0rn" firstAttribute="top" secondItem="1lL-cj-2oS" secondAttribute="bottom" priority="500" id="Lpk-cS-FHG"/>
<constraint firstItem="Q3X-9G-3PT" firstAttribute="top" secondItem="MvX-7q-CIH" secondAttribute="bottom" constant="12" id="PN3-Vl-yKe"/>
<constraint firstAttribute="width" constant="280" id="PoR-0E-Yd5"/>
<constraint firstItem="1lL-cj-2oS" firstAttribute="top" secondItem="bco-zh-ekL" secondAttribute="bottom" priority="250" constant="20" id="QQh-zT-bWE"/>
<constraint firstAttribute="centerX" secondItem="1lL-cj-2oS" secondAttribute="centerX" id="Td0-Pa-b2s"/>
<constraint firstAttribute="centerX" secondItem="MvX-7q-CIH" secondAttribute="centerX" id="Uwa-a8-9bd"/>
<constraint firstAttribute="bottom" secondItem="Jjh-VP-emP" secondAttribute="bottom" id="YL8-fj-ENd"/>
<constraint firstAttribute="bottom" secondItem="2nQ-k3-Rx3" secondAttribute="bottom" constant="43" id="YPn-NL-TPQ"/>
<constraint firstItem="q87-qQ-0rn" firstAttribute="leading" secondItem="Jjh-VP-emP" secondAttribute="trailing" id="hwW-Pw-fPz"/>
<constraint firstItem="dhS-fg-rNl" firstAttribute="leading" secondItem="Hay-Qx-kVw" secondAttribute="leading" id="hzI-MA-Jal"/>
<constraint firstItem="1lL-cj-2oS" firstAttribute="width" secondItem="Hay-Qx-kVw" secondAttribute="width" id="i3L-zR-0ay"/>
<constraint firstAttribute="centerX" secondItem="Q3X-9G-3PT" secondAttribute="centerX" id="l5p-jN-Vvq"/>
<constraint firstItem="MvX-7q-CIH" firstAttribute="top" secondItem="Hay-Qx-kVw" secondAttribute="top" constant="20" id="xBi-k5-Mze"/>
<constraint firstItem="1lL-cj-2oS" firstAttribute="top" secondItem="Q3X-9G-3PT" secondAttribute="bottom" priority="500" constant="20" id="xQk-cL-cLn"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="styleName" value="AlertView"/>
</userDefinedRuntimeAttributes>
</view>
</subviews>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="centerY" secondItem="Hay-Qx-kVw" secondAttribute="centerY" id="5Z9-NF-BEW"/>
<constraint firstAttribute="centerX" secondItem="Hay-Qx-kVw" secondAttribute="centerX" id="e0c-Aj-Anh"/>
</constraints>
<viewLayoutGuide key="safeArea" id="ZL2-Bv-eBx"/>
<connections>
<outlet property="containerView" destination="Hay-Qx-kVw" id="YBK-zz-Ejj"/>
<outlet property="dialogsBottomOffset" destination="58e-JY-U6g" id="D2s-m8-XQl"/>
<outlet property="dialogsTableView" destination="1lL-cj-2oS" id="QPh-bX-GfH"/>
<outlet property="hDivider" destination="2nQ-k3-Rx3" id="5BD-2K-Qcc"/>
<outlet property="leftButton" destination="dhS-fg-rNl" id="t6u-5i-zwZ"/>
<outlet property="messageLabel" destination="Q3X-9G-3PT" id="AUA-bn-mAy"/>
<outlet property="progressWrapper" destination="bco-zh-ekL" id="AB4-SS-xCc"/>
<outlet property="progressWrapperBottomOffset" destination="QQh-zT-bWE" id="vBy-LT-WOC"/>
<outlet property="rightButton" destination="q87-qQ-0rn" id="91J-mu-sXT"/>
<outlet property="tableViewHeight" destination="92H-Th-Xgt" id="qnm-KF-Hb7"/>
<outlet property="titleLabel" destination="MvX-7q-CIH" id="hej-5l-48z"/>
<outlet property="vDivider" destination="Jjh-VP-emP" id="bNj-9y-l3s"/>
</connections>
<point key="canvasLocation" x="295" y="401"/>
</view>
</objects>
<resources>
<image name="dialog_btn_press" width="280" height="44"/>
</resources>
</document>

View file

@ -0,0 +1,7 @@
#import "MWMTableViewCell.h"
@interface MWMDownloaderDialogCell : MWMTableViewCell
@property (weak, nonatomic) IBOutlet UILabel * titleLabel;
@end

View file

@ -0,0 +1,5 @@
#import "MWMDownloaderDialogCell.h"
@implementation MWMDownloaderDialogCell
@end

View file

@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="15702" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15704"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" reuseIdentifier="MWMDownloaderDialogCell" rowHeight="33" id="LWd-Zy-XGd" customClass="MWMDownloaderDialogCell" propertyAccessControl="none">
<rect key="frame" x="0.0" y="0.0" width="280" height="33"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="LWd-Zy-XGd" id="gf8-bS-tvq">
<rect key="frame" x="0.0" y="0.0" width="280" height="33"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="1B4-T1-g4X">
<rect key="frame" x="20" y="8" width="240" height="17"/>
<constraints>
<constraint firstAttribute="height" constant="17" id="u5A-6l-INO"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="0.54000000000000004" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="styleName" value="regular14:blackSecondaryText"/>
</userDefinedRuntimeAttributes>
</label>
</subviews>
<color key="backgroundColor" red="0.90196078431372551" green="0.90196078431372551" blue="0.90196078431372551" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="centerX" secondItem="1B4-T1-g4X" secondAttribute="centerX" id="2AW-qe-sgg"/>
<constraint firstAttribute="centerY" secondItem="1B4-T1-g4X" secondAttribute="centerY" id="TD9-6y-WM8"/>
<constraint firstAttribute="trailing" secondItem="1B4-T1-g4X" secondAttribute="trailing" constant="20" id="ruG-JF-m2y"/>
<constraint firstItem="1B4-T1-g4X" firstAttribute="leading" secondItem="gf8-bS-tvq" secondAttribute="leading" constant="20" id="sZo-pt-LJL"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="styleName" value="PressBackground"/>
</userDefinedRuntimeAttributes>
</tableViewCellContentView>
<color key="backgroundColor" red="0.90196078431372551" green="0.90196078431372551" blue="0.90196078431372551" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<viewLayoutGuide key="safeArea" id="hHf-it-4Q9"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="styleName" value="PressBackground"/>
</userDefinedRuntimeAttributes>
<connections>
<outlet property="titleLabel" destination="1B4-T1-g4X" id="m4n-H9-1Ta"/>
</connections>
<point key="canvasLocation" x="235" y="180"/>
</tableViewCell>
</objects>
</document>

View file

@ -0,0 +1,14 @@
#import <UIKit/UIKit.h>
@class MWMDownloadTransitMapAlert;
@interface MWMDownloaderDialogHeader : UIView
@property (weak, nonatomic) IBOutlet UIButton * headerButton;
@property (weak, nonatomic) IBOutlet UIImageView * expandImage;
+ (instancetype)headerForOwnerAlert:(MWMDownloadTransitMapAlert *)alert;
- (void)layoutSizeLabel;
- (void)setTitle:(NSString *)title size:(NSString *)size;
@end

View file

@ -0,0 +1,53 @@
#import "MWMDownloaderDialogHeader.h"
#import "MWMDownloadTransitMapAlert.h"
static NSString * const kDownloaderDialogHeaderNibName = @"MWMDownloaderDialogHeader";
@interface MWMDownloaderDialogHeader ()
@property (weak, nonatomic) IBOutlet UILabel * title;
@property (weak, nonatomic) IBOutlet UILabel * size;
@property (weak, nonatomic) IBOutlet UIView * dividerView;
@property (weak, nonatomic) MWMDownloadTransitMapAlert * ownerAlert;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint * sizeTrailing;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint * titleLeading;
@end
@implementation MWMDownloaderDialogHeader
+ (instancetype)headerForOwnerAlert:(MWMDownloadTransitMapAlert *)alert
{
MWMDownloaderDialogHeader * header =
[NSBundle.mainBundle loadNibNamed:kDownloaderDialogHeaderNibName owner:nil options:nil]
.firstObject;
header.ownerAlert = alert;
return header;
}
- (IBAction)headerButtonTap:(UIButton *)sender
{
BOOL const currentState = sender.selected;
sender.selected = !currentState;
self.dividerView.hidden = currentState;
[UIView animateWithDuration:kDefaultAnimationDuration animations:^
{
self.expandImage.transform = sender.selected ? CGAffineTransformMakeRotation(M_PI) : CGAffineTransformIdentity;
}];
[self.ownerAlert showDownloadDetail:sender];
}
- (void)layoutSizeLabel
{
if (self.expandImage.hidden)
self.sizeTrailing.constant = self.titleLeading.constant;
[self layoutIfNeeded];
}
- (void)setTitle:(NSString *)title size:(NSString *)size
{
self.title.text = title;
self.size.text = size;
}
@end

View file

@ -0,0 +1,111 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="15702" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15704"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="iN0-l3-epB" customClass="MWMDownloaderDialogHeader" propertyAccessControl="none">
<rect key="frame" x="0.0" y="0.0" width="280" height="44"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="hh9-2l-gu2">
<rect key="frame" x="20" y="14" width="160" height="16"/>
<constraints>
<constraint firstAttribute="width" constant="160" id="4WE-p5-RdF"/>
<constraint firstAttribute="height" constant="16" id="FQE-Zk-gXr"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<color key="textColor" red="0.0977349653840065" green="0.0977320596575737" blue="0.09773370623588562" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="styleName" value="regular14:blackPrimaryText"/>
</userDefinedRuntimeAttributes>
</label>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="ic_arrow_gray_down" translatesAutoresizingMaskIntoConstraints="NO" id="eqn-NQ-zOk">
<rect key="frame" x="248" y="8" width="28" height="28"/>
<constraints>
<constraint firstAttribute="width" constant="28" id="CkX-aX-oaf"/>
<constraint firstAttribute="height" constant="28" id="mLX-ow-5er"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="styleName" value="MWMGray"/>
</userDefinedRuntimeAttributes>
</imageView>
<view hidden="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="tqG-fM-g6J">
<rect key="frame" x="0.0" y="43" width="280" height="1"/>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.12" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="height" constant="1" id="Vc3-uM-vHv"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="styleName" value="Divider"/>
</userDefinedRuntimeAttributes>
</view>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="size" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="m8f-ps-pFV">
<rect key="frame" x="180" y="14" width="64" height="16"/>
<constraints>
<constraint firstAttribute="height" constant="16" id="7Hg-8z-e56"/>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="64" id="hct-Jz-zGl"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<color key="textColor" red="0.0977349653840065" green="0.0977320596575737" blue="0.09773370623588562" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="styleName" value="regular14:blackPrimaryText"/>
</userDefinedRuntimeAttributes>
</label>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="eIt-Yb-1Yl">
<rect key="frame" x="0.0" y="0.0" width="280" height="44"/>
<state key="normal">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" backgroundImage="dialog_btn_press"/>
<connections>
<action selector="headerButtonTap:" destination="iN0-l3-epB" eventType="touchUpInside" id="SW0-Mx-TVi"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.059999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="bottom" secondItem="eIt-Yb-1Yl" secondAttribute="bottom" id="61x-d3-FtO"/>
<constraint firstAttribute="trailing" secondItem="eqn-NQ-zOk" secondAttribute="trailing" constant="4" id="8Xd-cJ-b0r"/>
<constraint firstAttribute="trailing" secondItem="tqG-fM-g6J" secondAttribute="trailing" id="9Xc-Au-fuY"/>
<constraint firstItem="eqn-NQ-zOk" firstAttribute="centerY" secondItem="m8f-ps-pFV" secondAttribute="centerY" id="DOo-JP-5fj"/>
<constraint firstAttribute="centerY" secondItem="m8f-ps-pFV" secondAttribute="centerY" id="F82-yF-6kJ"/>
<constraint firstAttribute="centerY" secondItem="hh9-2l-gu2" secondAttribute="centerY" id="GYb-1Q-mMG"/>
<constraint firstItem="eIt-Yb-1Yl" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="Jdx-uy-XaA"/>
<constraint firstAttribute="trailing" secondItem="eIt-Yb-1Yl" secondAttribute="trailing" id="MSS-uK-Dby"/>
<constraint firstItem="eIt-Yb-1Yl" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="Xxs-g9-ygX"/>
<constraint firstItem="hh9-2l-gu2" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" id="ZfI-xz-HEx"/>
<constraint firstAttribute="trailing" secondItem="m8f-ps-pFV" secondAttribute="trailing" constant="36" id="kwN-VG-nEr"/>
<constraint firstItem="tqG-fM-g6J" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="rDI-mo-gnf"/>
<constraint firstItem="tqG-fM-g6J" firstAttribute="top" secondItem="m8f-ps-pFV" secondAttribute="bottom" constant="13" id="v0U-Qb-rW1"/>
</constraints>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<viewLayoutGuide key="safeArea" id="gAS-Hf-5F8"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="styleName" value="BlackOpaqueBackground"/>
</userDefinedRuntimeAttributes>
<connections>
<outlet property="dividerView" destination="tqG-fM-g6J" id="eOr-3y-kbn"/>
<outlet property="expandImage" destination="eqn-NQ-zOk" id="fGc-MN-ss7"/>
<outlet property="headerButton" destination="eIt-Yb-1Yl" id="f0E-0A-6UG"/>
<outlet property="size" destination="m8f-ps-pFV" id="5ax-Hb-xEm"/>
<outlet property="sizeTrailing" destination="kwN-VG-nEr" id="K52-ZK-LuH"/>
<outlet property="title" destination="hh9-2l-gu2" id="JNQ-ls-kgI"/>
<outlet property="titleLeading" destination="ZfI-xz-HEx" id="Vzg-Cd-ztu"/>
</connections>
<point key="canvasLocation" x="202" y="259"/>
</view>
</objects>
<resources>
<image name="dialog_btn_press" width="280" height="44"/>
<image name="ic_arrow_gray_down" width="28" height="28"/>
</resources>
</document>