From 62ff0faa0eddbcd7fec35d76f2d834b4167e1715 Mon Sep 17 00:00:00 2001 From: "o.bolovintseva" Date: Wed, 31 Oct 2018 12:57:12 +0300 Subject: [PATCH] [ios] direct link sharing --- .../BMCView/BMCViewController.swift | 1 + .../Sharing/BookmarksSharingFlow.storyboard | 78 ++++++++++++++---- .../BookmarksSharingViewController.swift | 73 +++++++++++++--- .../Categories/Sharing/UploadActionCell.swift | 67 +++++++++++++-- iphone/Maps/Categories/UIFont+MapsMeFonts.h | 1 + iphone/Maps/Categories/UIFont+MapsMeFonts.mm | 1 + .../Maps/Core/Bookmarks/MWMBookmarksManager.h | 6 +- .../Core/Bookmarks/MWMBookmarksManager.mm | 32 +++++-- iphone/Maps/Core/Bookmarks/MWMCatalogCommon.h | 18 +++- .../Maps/Core/Bookmarks/MWMCatalogObserver.h | 5 +- .../Maps/Core/Bookmarks/MWMCatalogObserver.mm | 52 ++++++++++-- .../ic24PxShare.imageset/Contents.json | 15 ++++ .../ic24PxShare.imageset/ic24PxShare.pdf | Bin 0 -> 6098 bytes platform/http_uploader_apple.mm | 4 + 14 files changed, 303 insertions(+), 50 deletions(-) create mode 100644 iphone/Maps/Images.xcassets/Sharing/ic24PxShare.imageset/Contents.json create mode 100644 iphone/Maps/Images.xcassets/Sharing/ic24PxShare.imageset/ic24PxShare.pdf 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 0000000000000000000000000000000000000000..b0692e7fae7c04ac3722ca2c45ab3913c534085a GIT binary patch literal 6098 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 BJCOhY literal 0 HcmV?d00001 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];