forked from organicmaps/organicmaps
[ios] export single track from the place page as kml/gpx
Signed-off-by: Kiryl Kaveryn <kirylkaveryn@gmail.com>
This commit is contained in:
parent
524f3fe358
commit
98ef2d61fb
11 changed files with 122 additions and 13 deletions
|
@ -116,6 +116,14 @@ NS_SWIFT_NAME(BookmarksManager)
|
|||
- urlToALocalFile: The local file URL containing the shared data. This parameter is guaranteed to be non-nil only if `status` is `MWMBookmarksShareStatusSuccess`. In other cases, it will be nil.
|
||||
*/
|
||||
- (void)shareAllCategoriesWithCompletion:(SharingResultCompletionHandler)completion;
|
||||
|
||||
/**
|
||||
Shares a specific track with the given track ID.
|
||||
|
||||
@param trackId The identifier for the track to be shared.
|
||||
@param fileType Text/Binary/GPX
|
||||
*/
|
||||
- (void)shareTrack:(MWMTrackID)trackId fileType:(MWMKmlFileType)fileType completion:(SharingResultCompletionHandler)completion;
|
||||
- (void)finishShareCategory;
|
||||
|
||||
- (void)setNotificationsEnabled:(BOOL)enabled;
|
||||
|
|
|
@ -622,6 +622,12 @@ static KmlFileType convertFileTypeToCore(MWMKmlFileType fileType) {
|
|||
});
|
||||
}
|
||||
|
||||
- (void)shareTrack:(MWMTrackID)trackId fileType:(MWMKmlFileType)fileType completion:(SharingResultCompletionHandler)completion {
|
||||
self.bm.PrepareTrackFileForSharing(trackId, [self, completion](auto sharingResult) {
|
||||
[self handleSharingResult:sharingResult completion:completion];
|
||||
}, convertFileTypeToCore(fileType));
|
||||
}
|
||||
|
||||
- (void)handleSharingResult:(BookmarkManager::SharingResult)sharingResult completion:(SharingResultCompletionHandler)completion {
|
||||
NSURL *urlToALocalFile = nil;
|
||||
MWMBookmarksShareStatus status;
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
class PlacePageHeaderBuilder {
|
||||
static func build(data: PlacePagePreviewData,
|
||||
static func build(data: PlacePageData,
|
||||
delegate: PlacePageHeaderViewControllerDelegate?,
|
||||
headerType: PlacePageHeaderPresenter.HeaderType) -> PlacePageHeaderViewController {
|
||||
let storyboard = UIStoryboard.instance(.placePage)
|
||||
let viewController = storyboard.instantiateViewController(ofType: PlacePageHeaderViewController.self);
|
||||
let presenter = PlacePageHeaderPresenter(view: viewController,
|
||||
placePagePreviewData: data,
|
||||
placePagePreviewData: data.previewData,
|
||||
objectType: data.objectType,
|
||||
delegate: delegate,
|
||||
headerType: headerType)
|
||||
|
||||
|
|
|
@ -1,14 +1,18 @@
|
|||
protocol PlacePageHeaderPresenterProtocol: AnyObject {
|
||||
var objectType: PlacePageObjectType { get }
|
||||
|
||||
func configure()
|
||||
func onClosePress()
|
||||
func onExpandPress()
|
||||
func onShareButtonPress(from sourceView: UIView)
|
||||
func onExportTrackButtonPress(_ type: KmlFileType, from sourceView: UIView)
|
||||
}
|
||||
|
||||
protocol PlacePageHeaderViewControllerDelegate: AnyObject {
|
||||
func previewDidPressClose()
|
||||
func previewDidPressExpand()
|
||||
func previewDidPressShare(from sourceView: UIView)
|
||||
func previewDidPressExportTrack(_ type: KmlFileType, from sourceView: UIView)
|
||||
}
|
||||
|
||||
class PlacePageHeaderPresenter {
|
||||
|
@ -19,16 +23,19 @@ class PlacePageHeaderPresenter {
|
|||
|
||||
private weak var view: PlacePageHeaderViewProtocol?
|
||||
private let placePagePreviewData: PlacePagePreviewData
|
||||
let objectType: PlacePageObjectType
|
||||
private weak var delegate: PlacePageHeaderViewControllerDelegate?
|
||||
private let headerType: HeaderType
|
||||
|
||||
init(view: PlacePageHeaderViewProtocol,
|
||||
placePagePreviewData: PlacePagePreviewData,
|
||||
objectType: PlacePageObjectType,
|
||||
delegate: PlacePageHeaderViewControllerDelegate?,
|
||||
headerType: HeaderType) {
|
||||
self.view = view
|
||||
self.delegate = delegate
|
||||
self.placePagePreviewData = placePagePreviewData
|
||||
self.objectType = objectType
|
||||
self.headerType = headerType
|
||||
}
|
||||
}
|
||||
|
@ -45,7 +52,7 @@ extension PlacePageHeaderPresenter: PlacePageHeaderPresenterProtocol {
|
|||
view?.isShadowViewHidden = false
|
||||
}
|
||||
// TODO: (KK) Enable share button for the tracks to share the whole track gpx/kml
|
||||
view?.isShareButtonHidden = placePagePreviewData.coordinates == nil
|
||||
view?.isShareButtonHidden = false
|
||||
}
|
||||
|
||||
func onClosePress() {
|
||||
|
@ -59,4 +66,8 @@ extension PlacePageHeaderPresenter: PlacePageHeaderPresenterProtocol {
|
|||
func onShareButtonPress(from sourceView: UIView) {
|
||||
delegate?.previewDidPressShare(from: sourceView)
|
||||
}
|
||||
|
||||
func onExportTrackButtonPress(_ type: KmlFileType, from sourceView: UIView) {
|
||||
delegate?.previewDidPressExportTrack(type, from: sourceView)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ protocol PlacePageHeaderViewProtocol: AnyObject {
|
|||
var isShareButtonHidden: Bool { get set }
|
||||
|
||||
func setTitle(_ title: String?, secondaryTitle: String?)
|
||||
func showShareTrackMenu()
|
||||
}
|
||||
|
||||
class PlacePageHeaderViewController: UIViewController {
|
||||
|
@ -33,6 +34,10 @@ class PlacePageHeaderViewController: UIViewController {
|
|||
}
|
||||
closeButton.setImage(UIImage(named: "ic_close")!)
|
||||
shareButton.setImage(UIImage(named: "ic_share")!)
|
||||
|
||||
if presenter?.objectType == .track {
|
||||
configureTrackSharingMenu()
|
||||
}
|
||||
}
|
||||
|
||||
@objc func onExpandPressed(sender: UITapGestureRecognizer) {
|
||||
|
@ -114,4 +119,40 @@ extension PlacePageHeaderViewController: PlacePageHeaderViewProtocol {
|
|||
attributedText.append(NSAttributedString(string: "\n" + unwrappedSecondaryTitle, attributes: secondaryTitleAttributes))
|
||||
titleLabel?.attributedText = attributedText
|
||||
}
|
||||
|
||||
func showShareTrackMenu() {
|
||||
if #available(iOS 14.0, *) {
|
||||
// The menu will be shown by the shareButton itself
|
||||
} else {
|
||||
let alert = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
|
||||
let kmlAction = UIAlertAction(title: L("export_file"), style: .default) { [weak self] _ in
|
||||
guard let self else { return }
|
||||
self.presenter?.onExportTrackButtonPress(.text, from: self.shareButton)
|
||||
}
|
||||
let gpxAction = UIAlertAction(title: L("export_file_gpx"), style: .default) { [weak self] _ in
|
||||
guard let self else { return }
|
||||
self.presenter?.onExportTrackButtonPress(.gpx, from: self.shareButton)
|
||||
}
|
||||
alert.addAction(kmlAction)
|
||||
alert.addAction(gpxAction)
|
||||
present(alert, animated: true, completion: nil)
|
||||
}
|
||||
}
|
||||
|
||||
private func configureTrackSharingMenu() {
|
||||
if #available(iOS 14.0, *) {
|
||||
let menu = UIMenu(title: "", image: nil, children: [
|
||||
UIAction(title: L("export_file"), image: nil, handler: { [weak self] _ in
|
||||
guard let self else { return }
|
||||
self.presenter?.onExportTrackButtonPress(.text, from: self.shareButton)
|
||||
}),
|
||||
UIAction(title: L("export_file_gpx"), image: nil, handler: { [weak self] _ in
|
||||
guard let self else { return }
|
||||
self.presenter?.onExportTrackButtonPress(.gpx, from: self.shareButton)
|
||||
}),
|
||||
])
|
||||
shareButton.menu = menu
|
||||
shareButton.showsMenuAsPrimaryAction = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
@unknown default:
|
||||
fatalError()
|
||||
}
|
||||
let presenter = PlacePagePresenter(view: viewController)
|
||||
let presenter = PlacePagePresenter(view: viewController, headerView: layout.headerViewController)
|
||||
viewController.setLayout(layout)
|
||||
viewController.interactor = interactor
|
||||
interactor.presenter = presenter
|
||||
|
@ -45,7 +45,7 @@
|
|||
@unknown default:
|
||||
fatalError()
|
||||
}
|
||||
let presenter = PlacePagePresenter(view: viewController)
|
||||
let presenter = PlacePagePresenter(view: viewController, headerView: layout.headerViewController)
|
||||
viewController.interactor = interactor
|
||||
interactor.presenter = presenter
|
||||
layout.presenter = presenter
|
||||
|
|
|
@ -295,8 +295,42 @@ extension PlacePageInteractor: PlacePageHeaderViewControllerDelegate {
|
|||
|
||||
func previewDidPressShare(from sourceView: UIView) {
|
||||
guard let mapViewController else { return }
|
||||
let shareViewController = ActivityViewController.share(forPlacePage: placePageData)
|
||||
shareViewController.present(inParentViewController: mapViewController, anchorView: sourceView)
|
||||
switch placePageData.objectType {
|
||||
case .POI, .bookmark:
|
||||
let shareViewController = ActivityViewController.share(forPlacePage: placePageData)
|
||||
shareViewController.present(inParentViewController: mapViewController, anchorView: sourceView)
|
||||
case .track:
|
||||
presenter?.showShareTrackMenu()
|
||||
default:
|
||||
fatalError()
|
||||
}
|
||||
}
|
||||
|
||||
func previewDidPressExportTrack(_ type: KmlFileType, from sourceView: UIView) {
|
||||
guard let trackId = placePageData.trackData?.trackId else {
|
||||
fatalError("Track data should not be nil during the track export")
|
||||
}
|
||||
bookmarksManager.shareTrack(trackId, fileType: type) { [weak self] status, url in
|
||||
guard let self, let mapViewController else { return }
|
||||
switch status {
|
||||
case .success:
|
||||
guard let url else { fatalError("Invalid sharing url") }
|
||||
let shareViewController = ActivityViewController.share(for: url, message: self.placePageData.previewData.title!) { _,_,_,_ in
|
||||
self.bookmarksManager.finishShareCategory()
|
||||
}
|
||||
shareViewController.present(inParentViewController: mapViewController, anchorView: sourceView)
|
||||
case .emptyCategory:
|
||||
self.showAlert(withTitle: L("bookmarks_error_title_share_empty"),
|
||||
message: L("bookmarks_error_message_share_empty"))
|
||||
case .archiveError, .fileError:
|
||||
self.showAlert(withTitle: L("dialog_routing_system_error"),
|
||||
message: L("bookmarks_error_message_share_general"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func showAlert(withTitle title: String, message: String) {
|
||||
MWMAlertViewController.activeAlert().presentInfoAlert(title, text: message)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ enum PlacePageState {
|
|||
protocol IPlacePageLayout: AnyObject {
|
||||
var presenter: PlacePagePresenterProtocol? { get set }
|
||||
var headerViewControllers: [UIViewController] { get }
|
||||
var headerViewController: PlacePageHeaderViewController { get }
|
||||
var bodyViewControllers: [UIViewController] { get }
|
||||
var actionBar: ActionBarViewController? { get }
|
||||
var navigationBar: UIViewController? { get }
|
||||
|
|
|
@ -27,7 +27,7 @@ class PlacePageCommonLayout: NSObject, IPlacePageLayout {
|
|||
}
|
||||
|
||||
lazy var headerViewController: PlacePageHeaderViewController = {
|
||||
PlacePageHeaderBuilder.build(data: placePageData.previewData, delegate: interactor, headerType: .flexible)
|
||||
PlacePageHeaderBuilder.build(data: placePageData, delegate: interactor, headerType: .flexible)
|
||||
}()
|
||||
|
||||
lazy var previewViewController: PlacePagePreviewViewController = {
|
||||
|
@ -81,7 +81,7 @@ class PlacePageCommonLayout: NSObject, IPlacePageLayout {
|
|||
} ()
|
||||
|
||||
lazy var placePageNavigationViewController: PlacePageHeaderViewController = {
|
||||
return PlacePageHeaderBuilder.build(data: placePageData.previewData, delegate: interactor, headerType: .fixed)
|
||||
return PlacePageHeaderBuilder.build(data: placePageData, delegate: interactor, headerType: .fixed)
|
||||
} ()
|
||||
|
||||
init(interactor: PlacePageInteractor, storyboard: UIStoryboard, data: PlacePageData) {
|
||||
|
|
|
@ -22,7 +22,7 @@ class PlacePageTrackLayout: IPlacePageLayout {
|
|||
}()
|
||||
|
||||
lazy var headerViewController: PlacePageHeaderViewController = {
|
||||
PlacePageHeaderBuilder.build(data: placePageData.previewData, delegate: interactor, headerType: .flexible)
|
||||
PlacePageHeaderBuilder.build(data: placePageData, delegate: interactor, headerType: .flexible)
|
||||
}()
|
||||
|
||||
lazy var previewViewController: PlacePagePreviewViewController = {
|
||||
|
@ -32,7 +32,7 @@ class PlacePageTrackLayout: IPlacePageLayout {
|
|||
}()
|
||||
|
||||
lazy var placePageNavigationViewController: PlacePageHeaderViewController = {
|
||||
return PlacePageHeaderBuilder.build(data: placePageData.previewData, delegate: interactor, headerType: .fixed)
|
||||
return PlacePageHeaderBuilder.build(data: placePageData, delegate: interactor, headerType: .fixed)
|
||||
}()
|
||||
|
||||
lazy var editTrackViewController: PlacePageEditBookmarkOrTrackViewController = {
|
||||
|
|
|
@ -4,13 +4,16 @@ protocol PlacePagePresenterProtocol: AnyObject {
|
|||
func showNextStop()
|
||||
func closeAnimated()
|
||||
func showAlert(_ alert: UIAlertController)
|
||||
func showShareTrackMenu()
|
||||
}
|
||||
|
||||
class PlacePagePresenter: NSObject {
|
||||
final class PlacePagePresenter: NSObject {
|
||||
private weak var view: PlacePageViewProtocol!
|
||||
private weak var headerView: PlacePageHeaderViewProtocol!
|
||||
|
||||
init(view: PlacePageViewProtocol) {
|
||||
init(view: PlacePageViewProtocol, headerView: PlacePageHeaderViewProtocol) {
|
||||
self.view = view
|
||||
self.headerView = headerView
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36,4 +39,8 @@ extension PlacePagePresenter: PlacePagePresenterProtocol {
|
|||
func showAlert(_ alert: UIAlertController) {
|
||||
view.showAlert(alert)
|
||||
}
|
||||
|
||||
func showShareTrackMenu() {
|
||||
headerView.showShareTrackMenu()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue