diff --git a/iphone/Maps/Bookmarks/Categories/BMCView/BMCViewController.swift b/iphone/Maps/Bookmarks/Categories/BMCView/BMCViewController.swift
index 98765d093f..e0d07dddd7 100644
--- a/iphone/Maps/Bookmarks/Categories/BMCView/BMCViewController.swift
+++ b/iphone/Maps/Bookmarks/Categories/BMCView/BMCViewController.swift
@@ -75,6 +75,7 @@ final class BMCViewController: MWMViewController {
private func shareCategory(category: BMCCategory, anchor: UIView) {
let storyboard = UIStoryboard.instance(.sharing)
let shareController = storyboard.instantiateInitialViewController() as! BookmarksSharingViewController
+ shareController.categoryId = category.identifier
MapViewController.topViewController().navigationController?.pushViewController(shareController,
animated: true)
diff --git a/iphone/Maps/Bookmarks/Categories/Sharing/BookmarksSharingFlow.storyboard b/iphone/Maps/Bookmarks/Categories/Sharing/BookmarksSharingFlow.storyboard
index 8aeaf0f049..149c278b72 100644
--- a/iphone/Maps/Bookmarks/Categories/Sharing/BookmarksSharingFlow.storyboard
+++ b/iphone/Maps/Bookmarks/Categories/Sharing/BookmarksSharingFlow.storyboard
@@ -44,17 +44,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -65,7 +89,7 @@
-
-
+
+
-
-
+
+
-
+
-
+
@@ -107,8 +131,8 @@
-
-
+
+
@@ -118,7 +142,7 @@
-
+
@@ -141,28 +165,52 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
@@ -194,6 +242,7 @@
+
@@ -201,5 +250,6 @@
+
diff --git a/iphone/Maps/Bookmarks/Categories/Sharing/BookmarksSharingViewController.swift b/iphone/Maps/Bookmarks/Categories/Sharing/BookmarksSharingViewController.swift
index 2d5c79a499..94d084aebb 100644
--- a/iphone/Maps/Bookmarks/Categories/Sharing/BookmarksSharingViewController.swift
+++ b/iphone/Maps/Bookmarks/Categories/Sharing/BookmarksSharingViewController.swift
@@ -3,6 +3,9 @@ import SafariServices
final class BookmarksSharingViewController: MWMTableViewController {
typealias ViewModel = MWMAuthorizationViewModel
+ var categoryId: MWMMarkGroupID?
+ var categoryUrl: URL?
+
@IBOutlet weak var uploadAndPublishCell: UploadActionCell!
@IBOutlet weak var getDirectLinkCell: UploadActionCell!
@@ -21,12 +24,21 @@ final class BookmarksSharingViewController: MWMTableViewController {
super.viewDidLoad()
title = L("sharing_options") //"Sharing options"
- self.configureActionCells()
+ configureActionCells()
+
+ assert(categoryId != nil, "We can't share nothing")
}
func configureActionCells() {
- uploadAndPublishCell.config(title: L("upload_and_publish"), image: UIImage(named: "ic24PxGlobe")!)
- getDirectLinkCell.config(title: L("upload_and_get_direct_link"), image: UIImage(named: "ic24PxLink")!)
+ uploadAndPublishCell.config(titles: [ .normal : L("upload_and_publish"),
+ .inProgress : L("upload_and_publish_progress_text"),
+ .completed : L("upload_and_publish_success") ],
+ image: UIImage(named: "ic24PxGlobe"),
+ delegate: self)
+ getDirectLinkCell.config(titles: [ .normal : L("upload_and_get_direct_link"),
+ .inProgress : L("direct_link_progress_text"),
+ .completed : L("direct_link_success") ],
+ image: UIImage(named: "ic24PxLink"), delegate: self)
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
@@ -38,27 +50,56 @@ final class BookmarksSharingViewController: MWMTableViewController {
return section == 0 ? L("public_access") : L("limited_access")
}
+ override func tableView(_ tableView: UITableView,
+ willSelectRowAt indexPath: IndexPath) -> IndexPath? {
+ let cell = tableView.cellForRow(at: indexPath)
+ if cell == getDirectLinkCell {
+ if getDirectLinkCell.cellState != .normal {
+ return nil
+ }
+ }
+
+ return indexPath
+ }
+
override func tableView(_ tableView: UITableView,
didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
let cell = tableView.cellForRow(at: indexPath)
- if (cell == self.uploadAndPublishCell) {
- self.uploadAndPublish()
- } else if (cell == self.getDirectLinkCell) {
- self.getDirectLink()
+ if cell == uploadAndPublishCell {
+ uploadAndPublish()
+ } else if cell == getDirectLinkCell {
+ uploadAndGetDirectLink()
}
}
func uploadAndPublish() {
- self.performAfterValidation {
+ performAfterValidation {
//implementation
}
}
- func getDirectLink() {
- self.performAfterValidation {
- //implementation
+ func uploadAndGetDirectLink() {
+ performAfterValidation { [weak self] in
+ guard let categoryId = self?.categoryId else {
+ assert(false, "categoryId must not be nil")
+ return
+ }
+
+ MWMBookmarksManager.shared().uploadAndGetDirectLinkCategory(withId: categoryId, progress: { (progress) in
+ if progress == .uploadStarted {
+ self?.getDirectLinkCell.cellState = .inProgress
+ }
+ }, completion: { (url, error) in
+ if error != nil {
+ self?.getDirectLinkCell.cellState = .normal
+ //handle errors
+ } else {
+ self?.getDirectLinkCell.cellState = .completed
+ self?.categoryUrl = url
+ }
+ })
}
}
@@ -76,7 +117,15 @@ final class BookmarksSharingViewController: MWMTableViewController {
extension BookmarksSharingViewController: UITextViewDelegate {
func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange) -> Bool {
let safari = SFSafariViewController(url: URL)
- self.present(safari, animated: true, completion: nil)
+ present(safari, animated: true, completion: nil)
return false;
}
}
+
+extension BookmarksSharingViewController: UploadActionCellDelegate {
+ func cellDidPressShareButton(_ cell: UploadActionCell) {
+ let message = L("share_bookmarks_email_body")
+ let shareController = MWMActivityViewController.share(for: categoryUrl, message: message)
+ shareController?.present(inParentViewController: self, anchorView: nil)
+ }
+}
diff --git a/iphone/Maps/Bookmarks/Categories/Sharing/UploadActionCell.swift b/iphone/Maps/Bookmarks/Categories/Sharing/UploadActionCell.swift
index 1c943d5e61..860c3f41c6 100644
--- a/iphone/Maps/Bookmarks/Categories/Sharing/UploadActionCell.swift
+++ b/iphone/Maps/Bookmarks/Categories/Sharing/UploadActionCell.swift
@@ -1,14 +1,65 @@
-final class UploadActionCell: MWMTableViewCell {
- @IBOutlet private weak var actionImage: UIImageView! {
+protocol UploadActionCellDelegate: AnyObject {
+ func cellDidPressShareButton(_ cell: UploadActionCell)
+}
+
+enum UploadActionCellState: String {
+ case normal
+ case inProgress
+ case completed
+}
+
+final class UploadActionCell: MWMTableViewCell {
+ @IBOutlet private weak var actionImage: UIImageView!
+ @IBOutlet private weak var actionTitle: UILabel!
+ @IBOutlet private weak var progressView: UIView!
+ @IBOutlet private weak var shareButton: UIButton!
+
+ weak var delegate: UploadActionCellDelegate?
+ private var titles: [UploadActionCellState : String]?
+ private lazy var progress: MWMCircularProgress = {
+ return MWMCircularProgress(parentView: self.progressView)
+ }()
+
+ func config(titles: [UploadActionCellState : String], image: UIImage?, delegate: UploadActionCellDelegate?) {
+ actionImage.image = image
+ self.titles = titles
+ self.delegate = delegate
+ self.cellState = .normal
+ }
+
+ var cellState: UploadActionCellState = .normal {
didSet {
- actionImage.tintColor = .linkBlue()
+ switch cellState {
+ case .normal:
+ progress.state = .normal
+ actionImage.tintColor = .linkBlue()
+ actionTitle.textColor = .linkBlue()
+ actionTitle.font = .regular16()
+ actionTitle.text = titles?[.normal]
+ shareButton.isHidden = true
+ break
+ case .inProgress:
+ progress.state = .spinner
+ actionImage.tintColor = .blackSecondaryText()
+ actionTitle.textColor = .blackSecondaryText()
+ actionTitle.font = .italic16()
+ actionTitle.text = titles?[.inProgress]
+ shareButton.isHidden = true
+ break
+ case .completed:
+ progress.state = .completed
+ actionImage.tintColor = .blackSecondaryText()
+ actionTitle.textColor = .blackSecondaryText()
+ actionTitle.font = .regular16()
+ actionTitle.text = titles?[.completed]
+ shareButton.isHidden = false
+ break
+ }
}
}
- @IBOutlet private weak var actionTitle: UILabel!
-
- func config(title: String, image: UIImage) {
- actionImage.image = image
- actionTitle.text = title
+ @IBAction func shareButtonPressed(_ sender: Any) {
+ assert(cellState == .completed, "Share button can only be pressed while the cell is in .completed state")
+ delegate?.cellDidPressShareButton(self)
}
}
diff --git a/iphone/Maps/Categories/UIFont+MapsMeFonts.h b/iphone/Maps/Categories/UIFont+MapsMeFonts.h
index 3466c8c89f..60c5979783 100644
--- a/iphone/Maps/Categories/UIFont+MapsMeFonts.h
+++ b/iphone/Maps/Categories/UIFont+MapsMeFonts.h
@@ -39,6 +39,7 @@
+ (UIFont *)bold28;
+ (UIFont *)bold36;
+ (UIFont *)bold48;
++ (UIFont *)italic16;
+ (UIFont *)fontWithName:(NSString *)fontName;
diff --git a/iphone/Maps/Categories/UIFont+MapsMeFonts.mm b/iphone/Maps/Categories/UIFont+MapsMeFonts.mm
index 185d7e860c..fe8925f2db 100644
--- a/iphone/Maps/Categories/UIFont+MapsMeFonts.mm
+++ b/iphone/Maps/Categories/UIFont+MapsMeFonts.mm
@@ -44,6 +44,7 @@ NSString * const kLightFontName = @"HelveticaNeue-Light";
+ (UIFont *)bold28 { return [UIFont boldSystemFontOfSize:28]; }
+ (UIFont *)bold36 { return [UIFont boldSystemFontOfSize:26]; }
+ (UIFont *)bold48 { return [UIFont boldSystemFontOfSize:48]; }
++ (UIFont *)italic16 { return [UIFont italicSystemFontOfSize:16]; }
+ (UIFont *)fontWithName:(NSString *)fontName
{
#pragma clang diagnostic push
diff --git a/iphone/Maps/Core/Bookmarks/MWMBookmarksManager.h b/iphone/Maps/Core/Bookmarks/MWMBookmarksManager.h
index 74366e6403..95f4650b61 100644
--- a/iphone/Maps/Core/Bookmarks/MWMBookmarksManager.h
+++ b/iphone/Maps/Core/Bookmarks/MWMBookmarksManager.h
@@ -53,12 +53,16 @@ NS_ASSUME_NONNULL_BEGIN
- (void)downloadItemWithId:(NSString *)itemId
name:(NSString *)name
progress:(_Nullable ProgressBlock)progress
- completion:(_Nullable CompletionBlock)completion;
+ completion:(_Nullable DownloadCompletionBlock)completion;
- (BOOL)isCategoryFromCatalog:(MWMMarkGroupID)groupId;
- (NSArray *)categoriesFromCatalog;
- (NSInteger)getCatalogDownloadsCount;
- (BOOL)isCategoryDownloading:(NSString *)itemId;
- (BOOL)hasCategoryDownloaded:(NSString *)itemId;
+- (void)uploadAndGetDirectLinkCategoryWithId:(MWMMarkGroupID)itemId
+ progress:(ProgressBlock)progress
+ completion:(UploadCompletionBlock)completion;
+
@end
NS_ASSUME_NONNULL_END
diff --git a/iphone/Maps/Core/Bookmarks/MWMBookmarksManager.mm b/iphone/Maps/Core/Bookmarks/MWMBookmarksManager.mm
index 92d3491da5..19faf666c3 100644
--- a/iphone/Maps/Core/Bookmarks/MWMBookmarksManager.mm
+++ b/iphone/Maps/Core/Bookmarks/MWMBookmarksManager.mm
@@ -158,14 +158,22 @@ NSString * const CloudErrorToString(Cloud::SynchronizationResult result)
[self.catalogObservers removeObjectForKey:observer.categoryId];
}
};
- auto onUploadStarted = [](kml::MarkGroupId originCategoryId)
+ auto onUploadStarted = [self](kml::MarkGroupId originCategoryId)
{
- //TODO(@beloal): Implement me.
+ auto observer = self.catalogObservers[[NSString stringWithFormat:@"%lld", originCategoryId]];
+ if (observer)
+ [observer onUploadStart];
};
- auto onUploadFinished = [](BookmarkCatalog::UploadResult uploadResult,std::string const & description,
+ auto onUploadFinished = [self](BookmarkCatalog::UploadResult uploadResult,std::string const & description,
kml::MarkGroupId originCategoryId, kml::MarkGroupId resultCategoryId)
{
- //TODO(@beloal): Implement me.
+ auto observer = self.catalogObservers[[NSString stringWithFormat:@"%lld", originCategoryId]];
+ if (observer)
+ {
+ NSURL * url = [self sharingUrlForCategoryId:resultCategoryId];
+ [observer onUploadComplete:uploadResult withUrl:url];
+ [self.catalogObservers removeObjectForKey:observer.categoryId];
+ }
};
self.bm.SetCatalogHandlers(std::move(onDownloadStarted),
std::move(onDownloadFinished),
@@ -499,16 +507,28 @@ NSString * const CloudErrorToString(Cloud::SynchronizationResult result)
- (void)downloadItemWithId:(NSString *)itemId
name:(NSString *)name
progress:(ProgressBlock)progress
- completion:(CompletionBlock)completion
+ completion:(DownloadCompletionBlock)completion
{
auto observer = [[MWMCatalogObserver alloc] init];
observer.categoryId = itemId;
observer.progressBlock = progress;
- observer.completionBlock = completion;
+ observer.downloadCompletionBlock = completion;
[self.catalogObservers setObject:observer forKey:itemId];
self.bm.DownloadFromCatalogAndImport(itemId.UTF8String, name.UTF8String);
}
+- (void)uploadAndGetDirectLinkCategoryWithId:(MWMMarkGroupID)itemId
+ progress:(ProgressBlock)progress
+ completion:(UploadCompletionBlock)completion
+{
+ auto observer = [[MWMCatalogObserver alloc] init];
+ observer.categoryId = [NSString stringWithFormat:@"%lld", itemId];
+ observer.progressBlock = progress;
+ observer.uploadCompletionBlock = completion;
+ [self.catalogObservers setObject:observer forKey:observer.categoryId];
+ GetFramework().GetBookmarkManager().UploadToCatalog(itemId, kml::AccessRules::DirectLink);
+}
+
- (BOOL)isCategoryFromCatalog:(MWMMarkGroupID)groupId
{
return self.bm.IsCategoryFromCatalog(groupId);
diff --git a/iphone/Maps/Core/Bookmarks/MWMCatalogCommon.h b/iphone/Maps/Core/Bookmarks/MWMCatalogCommon.h
index 70f2939141..e6bc96cfec 100644
--- a/iphone/Maps/Core/Bookmarks/MWMCatalogCommon.h
+++ b/iphone/Maps/Core/Bookmarks/MWMCatalogCommon.h
@@ -3,7 +3,8 @@ typedef NS_ENUM(NSInteger, MWMCategoryProgress)
MWMCategoryProgressDownloadStarted,
MWMCategoryProgressDownloadFinished,
MWMCategoryProgressImportStarted,
- MWMCategoryProgressImportFinished
+ MWMCategoryProgressImportFinished,
+ MWMCategoryProgressUploadStarted
};
typedef NS_ENUM(NSInteger, MWMCategoryDownloadStatus)
@@ -14,13 +15,26 @@ typedef NS_ENUM(NSInteger, MWMCategoryDownloadStatus)
MWMCategoryDownloadStatusDiskError
};
+typedef NS_ENUM(NSInteger, MWMCategoryUploadStatus)
+{
+ MWMCategoryUploadStatusNetworkError,
+ MWMCategoryUploadStatusServerError,
+ MWMCategoryUploadStatusAuthError,
+ MWMCategoryUploadStatusMalformedData,
+ MWMCategoryUploadStatusAccessError,
+ MWMCategoryUploadStatusInvalidCall
+};
+
static NSErrorDomain const kCatalogErrorDomain = @"com.mapswithme.catalog.error";
static NSInteger const kCategoryDownloadFailedCode = -10;
static NSInteger const kCategoryImportFailedCode = -11;
+static NSInteger const kCategoryUploadFailedCode = -12;
static NSString * const kCategoryDownloadStatusKey = @"kCategoryDownloadStatusKey";
+static NSString * const kCategoryUploadStatusKey = @"kCategoryUploadStatusKey";
typedef void (^ProgressBlock)(MWMCategoryProgress progress);
-typedef void (^CompletionBlock)(UInt64 categoryId, NSError * error);
+typedef void (^DownloadCompletionBlock)(UInt64 categoryId, NSError * error);
+typedef void (^UploadCompletionBlock)(NSURL * url, NSError * error);
diff --git a/iphone/Maps/Core/Bookmarks/MWMCatalogObserver.h b/iphone/Maps/Core/Bookmarks/MWMCatalogObserver.h
index bdf2b73669..e9943df3d0 100644
--- a/iphone/Maps/Core/Bookmarks/MWMCatalogObserver.h
+++ b/iphone/Maps/Core/Bookmarks/MWMCatalogObserver.h
@@ -8,11 +8,14 @@
@property (copy, nonatomic) NSString * categoryId;
@property (copy, nonatomic) ProgressBlock progressBlock;
-@property (copy, nonatomic) CompletionBlock completionBlock;
+@property (copy, nonatomic) DownloadCompletionBlock downloadCompletionBlock;
+@property (copy, nonatomic) UploadCompletionBlock uploadCompletionBlock;
- (void)onDownloadStart;
- (void)onDownloadComplete:(BookmarkCatalog::DownloadResult)result;
- (void)onImportStart;
- (void)onImportCompleteSuccessful:(BOOL)success forCategoryId:(UInt64)categoryId;
+- (void)onUploadStart;
+- (void)onUploadComplete:(BookmarkCatalog::UploadResult)result withUrl:(NSURL *)categoryUrl;
@end
diff --git a/iphone/Maps/Core/Bookmarks/MWMCatalogObserver.mm b/iphone/Maps/Core/Bookmarks/MWMCatalogObserver.mm
index 1ae1f3363e..41dce97e49 100644
--- a/iphone/Maps/Core/Bookmarks/MWMCatalogObserver.mm
+++ b/iphone/Maps/Core/Bookmarks/MWMCatalogObserver.mm
@@ -33,10 +33,10 @@
//TODO(@beloal)
break;
}
- if (self.completionBlock)
- self.completionBlock(0, [[NSError alloc] initWithDomain:kCatalogErrorDomain
- code:kCategoryDownloadFailedCode
- userInfo:@{kCategoryDownloadStatusKey : @(downloadStatus)}]);
+ if (self.downloadCompletionBlock)
+ self.downloadCompletionBlock(0, [[NSError alloc] initWithDomain:kCatalogErrorDomain
+ code:kCategoryDownloadFailedCode
+ userInfo:@{kCategoryDownloadStatusKey : @(downloadStatus)}]);
}
- (void)onImportStart
@@ -47,12 +47,52 @@
- (void)onImportCompleteSuccessful:(BOOL)success forCategoryId:(UInt64)categoryId
{
- if (self.completionBlock) {
+ if (self.downloadCompletionBlock) {
NSError * error = success ? nil : [[NSError alloc] initWithDomain:kCatalogErrorDomain
code:kCategoryImportFailedCode
userInfo:nil];
- self.completionBlock(categoryId, error);
+ self.downloadCompletionBlock(categoryId, error);
}
}
+- (void)onUploadStart
+{
+ if (self.progressBlock)
+ self.progressBlock(MWMCategoryProgressUploadStarted);
+}
+
+- (void)onUploadComplete:(BookmarkCatalog::UploadResult)result withUrl:(NSURL *)categoryUrl
+{
+ MWMCategoryUploadStatus uploadStatus;
+ switch (result)
+ {
+ case BookmarkCatalog::UploadResult::Success:
+ if (self.uploadCompletionBlock)
+ self.uploadCompletionBlock(categoryUrl, nil);
+ return;
+ case BookmarkCatalog::UploadResult::NetworkError:
+ uploadStatus = MWMCategoryUploadStatusNetworkError;
+ break;
+ case BookmarkCatalog::UploadResult::ServerError:
+ uploadStatus = MWMCategoryUploadStatusServerError;
+ break;
+ case BookmarkCatalog::UploadResult::AuthError:
+ uploadStatus = MWMCategoryUploadStatusAuthError;
+ break;
+ case BookmarkCatalog::UploadResult::MalformedDataError:
+ uploadStatus = MWMCategoryUploadStatusMalformedData;
+ break;
+ case BookmarkCatalog::UploadResult::AccessError:
+ uploadStatus = MWMCategoryUploadStatusAccessError;
+ break;
+ case BookmarkCatalog::UploadResult::InvalidCall:
+ uploadStatus = MWMCategoryUploadStatusInvalidCall;
+ break;
+ }
+ if (self.uploadCompletionBlock)
+ self.uploadCompletionBlock(nil, [[NSError alloc] initWithDomain:kCatalogErrorDomain
+ code:kCategoryUploadFailedCode
+ userInfo:@{kCategoryUploadStatusKey : @(uploadStatus)}]);
+}
+
@end
diff --git a/iphone/Maps/Images.xcassets/Sharing/ic24PxShare.imageset/Contents.json b/iphone/Maps/Images.xcassets/Sharing/ic24PxShare.imageset/Contents.json
new file mode 100644
index 0000000000..ceb50af3e1
--- /dev/null
+++ b/iphone/Maps/Images.xcassets/Sharing/ic24PxShare.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "ic24PxShare.pdf"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
\ No newline at end of file
diff --git a/iphone/Maps/Images.xcassets/Sharing/ic24PxShare.imageset/ic24PxShare.pdf b/iphone/Maps/Images.xcassets/Sharing/ic24PxShare.imageset/ic24PxShare.pdf
new file mode 100644
index 0000000000..b0692e7fae
Binary files /dev/null and b/iphone/Maps/Images.xcassets/Sharing/ic24PxShare.imageset/ic24PxShare.pdf differ
diff --git a/platform/http_uploader_apple.mm b/platform/http_uploader_apple.mm
index c37a11e32e..72032dd3ce 100644
--- a/platform/http_uploader_apple.mm
+++ b/platform/http_uploader_apple.mm
@@ -91,6 +91,10 @@
NSString * boundary = [NSString stringWithFormat:@"Boundary-%@", [[NSUUID UUID] UUIDString]];
NSString * contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
[uploadRequest setValue:contentType forHTTPHeaderField:@"Content-Type"];
+
+ [self.headers enumerateKeysAndObjectsUsingBlock:^(NSString * key, NSString * value, BOOL * stop) {
+ [uploadRequest setValue:value forHTTPHeaderField:key];
+ }];
NSData * postData = [self requestDataWithBoundary:boundary];