diff --git a/android/jni/com/mapswithme/maps/Framework.cpp b/android/jni/com/mapswithme/maps/Framework.cpp index 0f81231d04..b01987e55d 100644 --- a/android/jni/com/mapswithme/maps/Framework.cpp +++ b/android/jni/com/mapswithme/maps/Framework.cpp @@ -798,7 +798,8 @@ uint64_t Framework::GetLocals(JNIEnv * env, jobject policy, double lat, double l return api->GetLocals(lat, lon, langStr, kResultsOnPage, kPageNumber, successFn, errorFn); } -void Framework::GetPromoCityGallery(JNIEnv * env, jobject policy, m2::PointD const & point, +void Framework::GetPromoCityGallery(JNIEnv * env, jobject policy, + m2::PointD const & point, UTM utm, promo::CityGalleryCallback const & onSuccess, promo::OnError const & onError) { @@ -806,8 +807,7 @@ void Framework::GetPromoCityGallery(JNIEnv * env, jobject policy, m2::PointD con if (api == nullptr) return; - api->GetCityGallery(point, languages::GetCurrentNorm(), onSuccess, - onError); + api->GetCityGallery(point, languages::GetCurrentNorm(), utm, onSuccess, onError); } void Framework::LogLocalAdsEvent(local_ads::EventType type, double lat, double lon, uint16_t accuracy) diff --git a/android/jni/com/mapswithme/maps/Framework.hpp b/android/jni/com/mapswithme/maps/Framework.hpp index f32f20dd9d..651bbad727 100644 --- a/android/jni/com/mapswithme/maps/Framework.hpp +++ b/android/jni/com/mapswithme/maps/Framework.hpp @@ -20,6 +20,7 @@ #include "partners_api/booking_api.hpp" #include "partners_api/locals_api.hpp" #include "partners_api/promo_api.hpp" +#include "partners_api/utm.hpp" #include "platform/country_defines.hpp" #include "platform/location.hpp" @@ -219,7 +220,8 @@ namespace android uint64_t GetLocals(JNIEnv * env, jobject policy, double lat, double lon, locals::LocalsSuccessCallback const & successFn, locals::LocalsErrorCallback const & errorFn); - void GetPromoCityGallery(JNIEnv * env, jobject policy, m2::PointD const & point, + void GetPromoCityGallery(JNIEnv * env, jobject policy, + m2::PointD const & point, UTM utm, promo::CityGalleryCallback const & onSuccess, promo::OnError const & onError); diff --git a/android/jni/com/mapswithme/maps/bookmarks/data/BookmarkManager.cpp b/android/jni/com/mapswithme/maps/bookmarks/data/BookmarkManager.cpp index a72448938c..53ff373b98 100644 --- a/android/jni/com/mapswithme/maps/bookmarks/data/BookmarkManager.cpp +++ b/android/jni/com/mapswithme/maps/bookmarks/data/BookmarkManager.cpp @@ -5,6 +5,8 @@ #include "map/bookmark_helpers.hpp" #include "map/place_page_info.hpp" +#include "partners_api/utm.hpp" + #include "coding/zip_creator.hpp" #include "platform/preferred_languages.hpp" @@ -885,10 +887,10 @@ Java_com_mapswithme_maps_bookmarks_data_BookmarkManager_nativeGetWebEditorUrl( JNIEXPORT jstring JNICALL Java_com_mapswithme_maps_bookmarks_data_BookmarkManager_nativeGetCatalogFrontendUrl( - JNIEnv * env, jobject) + JNIEnv * env, jobject, jint utm) { auto & bm = frm()->GetBookmarkManager(); - return ToJavaString(env, bm.GetCatalog().GetFrontendUrl()); + return ToJavaString(env, bm.GetCatalog().GetFrontendUrl(static_cast(utm))); } JNIEXPORT jboolean JNICALL diff --git a/android/jni/com/mapswithme/maps/promo/CityGallery.cpp b/android/jni/com/mapswithme/maps/promo/CityGallery.cpp index 1450eaeead..3e0f90a38d 100644 --- a/android/jni/com/mapswithme/maps/promo/CityGallery.cpp +++ b/android/jni/com/mapswithme/maps/promo/CityGallery.cpp @@ -127,12 +127,13 @@ extern "C" { JNIEXPORT void JNICALL Java_com_mapswithme_maps_promo_Promo_nativeRequestCityGallery(JNIEnv * env, jclass, jobject policy, jdouble lat, - jdouble lon) + jdouble lon, jint utm) { PrepareClassRefs(env); auto const point = MercatorBounds::FromLatLon(static_cast(lat), static_cast(lon)); ++g_lastRequestId; - g_framework->GetPromoCityGallery(env, policy, point, std::bind(OnSuccess, g_lastRequestId, _1), + g_framework->GetPromoCityGallery(env, policy, point, static_cast(utm), + std::bind(OnSuccess, g_lastRequestId, _1), std::bind(OnError, g_lastRequestId)); } } // extern "C" diff --git a/android/src/com/mapswithme/maps/MwmActivity.java b/android/src/com/mapswithme/maps/MwmActivity.java index 9c0d31d659..d7de778c0e 100644 --- a/android/src/com/mapswithme/maps/MwmActivity.java +++ b/android/src/com/mapswithme/maps/MwmActivity.java @@ -117,6 +117,7 @@ import com.mapswithme.util.InputUtils; import com.mapswithme.util.PermissionsUtils; import com.mapswithme.util.ThemeSwitcher; import com.mapswithme.util.ThemeUtils; +import com.mapswithme.util.UTM; import com.mapswithme.util.UiUtils; import com.mapswithme.util.Utils; import com.mapswithme.util.log.Logger; @@ -2429,7 +2430,7 @@ public class MwmActivity extends BaseMwmFragmentActivity void onPostStatisticMenuItemClick() { int requestCode = BookmarkCategoriesActivity.REQ_CODE_DOWNLOAD_BOOKMARK_CATEGORY; - String catalogUrl = BookmarkManager.INSTANCE.getCatalogFrontendUrl(); + String catalogUrl = BookmarkManager.INSTANCE.getCatalogFrontendUrl(UTM.UTM_TOOLBAR_BUTTON); getActivity().closeMenu(() -> BookmarksCatalogActivity.startForResult(getActivity(), requestCode, catalogUrl)); diff --git a/android/src/com/mapswithme/maps/bookmarks/CachedBookmarkCategoriesFragment.java b/android/src/com/mapswithme/maps/bookmarks/CachedBookmarkCategoriesFragment.java index 54bbeb5ed5..5be94eae1c 100644 --- a/android/src/com/mapswithme/maps/bookmarks/CachedBookmarkCategoriesFragment.java +++ b/android/src/com/mapswithme/maps/bookmarks/CachedBookmarkCategoriesFragment.java @@ -17,6 +17,7 @@ import com.mapswithme.maps.bookmarks.data.BookmarkManager; import com.mapswithme.maps.bookmarks.data.CatalogCustomProperty; import com.mapswithme.maps.bookmarks.data.CatalogTagsGroup; import com.mapswithme.util.SharedPropertiesUtils; +import com.mapswithme.util.UTM; import com.mapswithme.util.UiUtils; import com.mapswithme.util.sharing.TargetUtils; import com.mapswithme.util.statistics.Statistics; @@ -133,7 +134,8 @@ public class CachedBookmarkCategoriesFragment extends BaseBookmarkCategoriesFrag private void openBookmarksCatalogScreen() { - String catalogUrl = BookmarkManager.INSTANCE.getCatalogFrontendUrl(); + String catalogUrl = BookmarkManager.INSTANCE.getCatalogFrontendUrl( + UTM.UTM_BOOKMARKS_PAGE_CATALOG_BUTTON); BookmarksCatalogActivity.startForResult(this, BookmarksCatalogActivity.REQ_CODE_CATALOG, catalogUrl); Statistics.INSTANCE.trackOpenCatalogScreen(); diff --git a/android/src/com/mapswithme/maps/bookmarks/data/BookmarkManager.java b/android/src/com/mapswithme/maps/bookmarks/data/BookmarkManager.java index 4d5721d956..0491979646 100644 --- a/android/src/com/mapswithme/maps/bookmarks/data/BookmarkManager.java +++ b/android/src/com/mapswithme/maps/bookmarks/data/BookmarkManager.java @@ -7,6 +7,7 @@ import android.support.annotation.NonNull; import com.mapswithme.maps.PrivateVariables; import com.mapswithme.maps.R; import com.mapswithme.maps.metrics.UserActionsLogger; +import com.mapswithme.util.UTM; import com.mapswithme.util.statistics.Statistics; import java.io.File; @@ -640,9 +641,9 @@ public enum BookmarkManager } @NonNull - public String getCatalogFrontendUrl() + public String getCatalogFrontendUrl(@UTM.UTMType int utm) { - return nativeGetCatalogFrontendUrl(); + return nativeGetCatalogFrontendUrl(utm); } public void requestRouteTags() @@ -794,7 +795,7 @@ public enum BookmarkManager private static native String nativeGetWebEditorUrl(@NonNull String serverId); @NonNull - private static native String nativeGetCatalogFrontendUrl(); + private static native String nativeGetCatalogFrontendUrl(@UTM.UTMType int utm); private static native boolean nativeIsCategoryFromCatalog(long catId); diff --git a/android/src/com/mapswithme/maps/intent/Factory.java b/android/src/com/mapswithme/maps/intent/Factory.java index 8caafd1b1e..62234413a9 100644 --- a/android/src/com/mapswithme/maps/intent/Factory.java +++ b/android/src/com/mapswithme/maps/intent/Factory.java @@ -37,6 +37,7 @@ import com.mapswithme.maps.ugc.UGC; import com.mapswithme.maps.ugc.UGCEditorActivity; import com.mapswithme.util.Constants; import com.mapswithme.util.StorageUtils; +import com.mapswithme.util.UTM; import com.mapswithme.util.Utils; import com.mapswithme.util.concurrency.ThreadPool; import com.mapswithme.util.log.Logger; @@ -145,7 +146,7 @@ public class Factory @NonNull private static String convertUrlToGuidesPageDeeplink(@NonNull String url) { - String baseCatalogUrl = BookmarkManager.INSTANCE.getCatalogFrontendUrl(); + String baseCatalogUrl = BookmarkManager.INSTANCE.getCatalogFrontendUrl(UTM.UTM_NONE); String relativePath = Uri.parse(url).getQueryParameter("url"); return Uri.parse(baseCatalogUrl) .buildUpon().appendEncodedPath(relativePath).toString(); diff --git a/android/src/com/mapswithme/maps/promo/Promo.java b/android/src/com/mapswithme/maps/promo/Promo.java index 4caf92da03..97460dab68 100644 --- a/android/src/com/mapswithme/maps/promo/Promo.java +++ b/android/src/com/mapswithme/maps/promo/Promo.java @@ -5,6 +5,7 @@ import android.support.annotation.NonNull; import android.support.annotation.Nullable; import com.mapswithme.util.NetworkPolicy; +import com.mapswithme.util.UTM; import com.mapswithme.util.concurrency.UiThread; public enum Promo @@ -49,5 +50,6 @@ public enum Promo mListener.onErrorReceived(); } - public native void nativeRequestCityGallery(@NonNull NetworkPolicy policy, double lat, double lon); + public native void nativeRequestCityGallery(@NonNull NetworkPolicy policy, + double lat, double lon, @UTM.UTMType int utm); } diff --git a/android/src/com/mapswithme/maps/tips/ClickInterceptorFactory.java b/android/src/com/mapswithme/maps/tips/ClickInterceptorFactory.java index 7054be7b08..467ec165f1 100644 --- a/android/src/com/mapswithme/maps/tips/ClickInterceptorFactory.java +++ b/android/src/com/mapswithme/maps/tips/ClickInterceptorFactory.java @@ -8,6 +8,7 @@ import com.mapswithme.maps.bookmarks.BookmarkCategoriesActivity; import com.mapswithme.maps.bookmarks.BookmarksCatalogActivity; import com.mapswithme.maps.bookmarks.data.BookmarkManager; import com.mapswithme.maps.maplayer.Mode; +import com.mapswithme.util.UTM; class ClickInterceptorFactory { @@ -45,7 +46,7 @@ class ClickInterceptorFactory @Override public void onInterceptClickInternal(@NonNull MwmActivity activity) { - String catalogUrl = BookmarkManager.INSTANCE.getCatalogFrontendUrl(); + String catalogUrl = BookmarkManager.INSTANCE.getCatalogFrontendUrl(UTM.UTM_TIPS_AND_TRICKS); BookmarksCatalogActivity.startForResult(activity, BookmarkCategoriesActivity .REQ_CODE_DOWNLOAD_BOOKMARK_CATEGORY, catalogUrl); diff --git a/android/src/com/mapswithme/maps/widget/placepage/PlacePageView.java b/android/src/com/mapswithme/maps/widget/placepage/PlacePageView.java index eed5df6530..5480aefcaa 100644 --- a/android/src/com/mapswithme/maps/widget/placepage/PlacePageView.java +++ b/android/src/com/mapswithme/maps/widget/placepage/PlacePageView.java @@ -93,6 +93,7 @@ import com.mapswithme.util.NetworkPolicy; import com.mapswithme.util.SponsoredLinks; import com.mapswithme.util.StringUtils; import com.mapswithme.util.ThemeUtils; +import com.mapswithme.util.UTM; import com.mapswithme.util.UiUtils; import com.mapswithme.util.Utils; import com.mapswithme.util.concurrency.UiThread; @@ -1243,7 +1244,8 @@ public class PlacePageView extends NestedScrollView if (mSponsored == null || mMapObject == null) return; - Promo.INSTANCE.nativeRequestCityGallery(policy, mMapObject.getLat(), mMapObject.getLon()); + Promo.INSTANCE.nativeRequestCityGallery(policy, mMapObject.getLat(), mMapObject.getLon(), + UTM.UTM_PLACEPAGE_GALLERY); mSponsored.updateId(mMapObject); mSponsoredPrice = mSponsored.getPrice(); String currencyCode = Utils.getCurrencyCode(); diff --git a/android/src/com/mapswithme/util/UTM.java b/android/src/com/mapswithme/util/UTM.java new file mode 100644 index 0000000000..213c028a0a --- /dev/null +++ b/android/src/com/mapswithme/util/UTM.java @@ -0,0 +1,23 @@ +package com.mapswithme.util; + +import android.support.annotation.IntDef; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +public class UTM +{ + @Retention(RetentionPolicy.SOURCE) + @IntDef({ UTM_NONE, UTM_BOOKMARKS_PAGE_CATALOG_BUTTON, UTM_TOOLBAR_BUTTON, + UTM_DOWNLOAD_MWM_BANNER, UTM_PLACEPAGE_GALLERY, UTM_DISCOVERY_PAGE_GALLERY, + UTM_TIPS_AND_TRICKS }) + public @interface UTMType {} + + // The order of these constants must correspond to C++ enumeration in partners_api/utm.hpp. + public static final int UTM_NONE = 0; + public static final int UTM_BOOKMARKS_PAGE_CATALOG_BUTTON = 1; + public static final int UTM_TOOLBAR_BUTTON = 2; + public static final int UTM_DOWNLOAD_MWM_BANNER = 3; + public static final int UTM_PLACEPAGE_GALLERY = 4; + public static final int UTM_DISCOVERY_PAGE_GALLERY = 5; + public static final int UTM_TIPS_AND_TRICKS = 6; +} diff --git a/iphone/Maps/Bookmarks/Catalog/CatalogWebViewController.swift b/iphone/Maps/Bookmarks/Catalog/CatalogWebViewController.swift index bdbe23c433..a8fc3449d6 100644 --- a/iphone/Maps/Bookmarks/Catalog/CatalogWebViewController.swift +++ b/iphone/Maps/Bookmarks/Catalog/CatalogWebViewController.swift @@ -32,13 +32,13 @@ final class CatalogWebViewController: WebViewController { var toolbar = UIToolbar() var billing = InAppPurchase.inAppBilling() - @objc init(_ deeplinkURL: URL? = nil) { - var catalogUrl = MWMBookmarksManager.shared().catalogFrontendUrl()! + @objc init(_ deeplinkURL: URL? = nil, utm: MWMUTM = .none) { + var catalogUrl = MWMBookmarksManager.shared().catalogFrontendUrl(utm)! if let dl = deeplinkURL { if dl.host == "guides_page" { if let urlComponents = URLComponents(url: dl, resolvingAgainstBaseURL: false), let path = urlComponents.queryItems?.reduce(into: "", { if $1.name == "url" { $0 = $1.value } }), - let url = MWMBookmarksManager.shared().catalogFrontendUrlPlusPath(path) { + let url = MWMBookmarksManager.shared().catalogFrontendUrlPlusPath(path, utm: utm) { catalogUrl = url } } else { diff --git a/iphone/Maps/Bookmarks/Catalog/DownloadedBookmarksViewController.swift b/iphone/Maps/Bookmarks/Catalog/DownloadedBookmarksViewController.swift index e3a60f60e0..7b19aaaa11 100644 --- a/iphone/Maps/Bookmarks/Catalog/DownloadedBookmarksViewController.swift +++ b/iphone/Maps/Bookmarks/Catalog/DownloadedBookmarksViewController.swift @@ -58,7 +58,7 @@ class DownloadedBookmarksViewController: MWMViewController { return } Statistics.logEvent(kStatCatalogOpen, withParameters: [kStatFrom: kStatDownloaded]) - let webViewController = CatalogWebViewController() + let webViewController = CatalogWebViewController(nil, utm: .bookmarksPageCatalogButton) MapViewController.topViewController().navigationController?.pushViewController(webViewController, animated: true) } diff --git a/iphone/Maps/Bookmarks/Catalog/MWMUTM.h b/iphone/Maps/Bookmarks/Catalog/MWMUTM.h new file mode 100644 index 0000000000..9824232330 --- /dev/null +++ b/iphone/Maps/Bookmarks/Catalog/MWMUTM.h @@ -0,0 +1,10 @@ +// This enumeration must correspond to C++ enumeration in partners_api/utm.hpp. +typedef NS_ENUM(NSInteger, MWMUTM) { + MWMUTMNone = 0, + MWMUTMBookmarksPageCatalogButton, + MWMUTMToolbarButton, + MWMUTMDownloadMwmBanner, + MWMUTMPlacepageGallery, + MWMUTMDiscoveryPageGallery, + MWMUTMTipsAndTricks +}; diff --git a/iphone/Maps/Bridging-Header.h b/iphone/Maps/Bridging-Header.h index ab6de79bb0..feaf1d83d1 100644 --- a/iphone/Maps/Bridging-Header.h +++ b/iphone/Maps/Bridging-Header.h @@ -97,3 +97,4 @@ #import "MWMRouterResultCode.h" #import "MWMLocationModeListener.h" #import "MWMSpeedCameraManagerMode.h" +#import "MWMUTM.h" diff --git a/iphone/Maps/Classes/DeepLinkHelper.mm b/iphone/Maps/Classes/DeepLinkHelper.mm index bbc97cb18c..33bc99eb15 100644 --- a/iphone/Maps/Classes/DeepLinkHelper.mm +++ b/iphone/Maps/Classes/DeepLinkHelper.mm @@ -102,10 +102,10 @@ break; } case ParsedMapApi::ParsingResult::Catalogue: - [MapViewController.sharedController openCatalogDeeplink:url animated:NO]; + [MapViewController.sharedController openCatalogDeeplink:url animated:NO utm:MWMUTMNone]; break; case ParsedMapApi::ParsingResult::CataloguePath: - [MapViewController.sharedController openCatalogDeeplink:url animated:NO]; + [MapViewController.sharedController openCatalogDeeplink:url animated:NO utm:MWMUTMNone]; break; case ParsedMapApi::ParsingResult::Lead: break; } diff --git a/iphone/Maps/Classes/MapViewController.h b/iphone/Maps/Classes/MapViewController.h index c9faab78d5..1ce6406f4b 100644 --- a/iphone/Maps/Classes/MapViewController.h +++ b/iphone/Maps/Classes/MapViewController.h @@ -1,6 +1,7 @@ #import "MWMMapDownloaderMode.h" #import "MWMViewController.h" #import "MWMMyPositionMode.h" +#import "MWMUTM.h" @class MWMWelcomePageController; @class MWMMapViewControlsManager; @@ -32,8 +33,10 @@ - (void)openFullPlaceDescriptionWithHtml:(NSString *)htmlString; - (void)showUGCAuth; - (void)showBookmarksLoadedAlert:(UInt64)categoryId; -- (void)openCatalogAnimated:(BOOL)animated; -- (void)openCatalogDeeplink:(NSURL * _Nullable)deeplinkUrl animated:(BOOL)animated; +- (void)openCatalogAnimated:(BOOL)animated utm:(MWMUTM)utm; +- (void)openCatalogDeeplink:(NSURL * _Nullable)deeplinkUrl + animated:(BOOL)animated + utm:(MWMUTM)utm; - (void)searchText:(NSString *)text; - (void)openDrivingOptions; diff --git a/iphone/Maps/Classes/MapViewController.mm b/iphone/Maps/Classes/MapViewController.mm index 9ed79f9e74..b877f96bb2 100644 --- a/iphone/Maps/Classes/MapViewController.mm +++ b/iphone/Maps/Classes/MapViewController.mm @@ -19,6 +19,7 @@ #import "MapsAppDelegate.h" #import "SwiftBridge.h" #import "MWMLocationModeListener.h" +#import "MWMUTM.h" #include "Framework.h" @@ -503,22 +504,22 @@ BOOL gIsFirstMyPositionMode = YES; [[MWMToast toastWithText:L(@"guide_downloaded_title")] show]; } -- (void)openCatalogAnimated:(BOOL)animated +- (void)openCatalogAnimated:(BOOL)animated utm:(MWMUTM)utm { [Statistics logEvent:kStatCatalogOpen withParameters:@{kStatFrom : kStatMenu}]; - [self openCatalogDeeplink:nil animated:animated]; + [self openCatalogDeeplink:nil animated:animated utm:utm]; } -- (void)openCatalogDeeplink:(NSURL *)deeplinkUrl animated:(BOOL)animated +- (void)openCatalogDeeplink:(NSURL *)deeplinkUrl animated:(BOOL)animated utm:(MWMUTM)utm { [self.navigationController popToRootViewControllerAnimated:NO]; auto bookmarks = [[MWMBookmarksTabViewController alloc] init]; bookmarks.activeTab = ActiveTabCatalog; MWMCatalogWebViewController *catalog; if (deeplinkUrl) - catalog = [[MWMCatalogWebViewController alloc] init:deeplinkUrl]; + catalog = [[MWMCatalogWebViewController alloc] init:deeplinkUrl utm:utm]; else - catalog = [[MWMCatalogWebViewController alloc] init:nil]; + catalog = [[MWMCatalogWebViewController alloc] init:nil utm:utm]; NSMutableArray * controllers = [self.navigationController.viewControllers mutableCopy]; [controllers addObjectsFromArray:@[bookmarks, catalog]]; diff --git a/iphone/Maps/Core/Bookmarks/MWMBookmarksManager.h b/iphone/Maps/Core/Bookmarks/MWMBookmarksManager.h index aaecdc8b77..d9672011da 100644 --- a/iphone/Maps/Core/Bookmarks/MWMBookmarksManager.h +++ b/iphone/Maps/Core/Bookmarks/MWMBookmarksManager.h @@ -1,6 +1,7 @@ #import "MWMBookmarksObserver.h" #import "MWMTypes.h" #import "MWMCatalogCommon.h" +#import "MWMUTM.h" @class MWMCategory; @class MWMCarPlayBookmarkObject; @@ -60,8 +61,9 @@ typedef void (^LoadTagsCompletionBlock)(NSArray * _Nullable tags, - (void)setNotificationsEnabled:(BOOL)enabled; - (BOOL)areNotificationsEnabled; -- (NSURL * _Nullable)catalogFrontendUrl; -- (NSURL * _Nullable)catalogFrontendUrlPlusPath:(NSString *)path; +- (NSURL * _Nullable)catalogFrontendUrl:(MWMUTM)utm; +- (NSURL * _Nullable)catalogFrontendUrlPlusPath:(NSString *)path + utm:(MWMUTM)utm; - (NSURL * _Nullable)sharingUrlForCategoryId:(MWMMarkGroupID)groupId; - (NSURL * _Nullable)webEditorUrlForCategoryId:(MWMMarkGroupID)groupId; - (void)downloadItemWithId:(NSString *)itemId diff --git a/iphone/Maps/Core/Bookmarks/MWMBookmarksManager.mm b/iphone/Maps/Core/Bookmarks/MWMBookmarksManager.mm index d81a5bf302..89ceb51ceb 100644 --- a/iphone/Maps/Core/Bookmarks/MWMBookmarksManager.mm +++ b/iphone/Maps/Core/Bookmarks/MWMBookmarksManager.mm @@ -10,6 +10,8 @@ #include "Framework.h" +#include "partners_api/utm.hpp" + #include "coding/internal/file_data.hpp" #include "base/stl_helpers.hpp" @@ -554,15 +556,16 @@ NSString * const CloudErrorToString(Cloud::SynchronizationResult result) #pragma mark - Catalog -- (NSURL *)catalogFrontendUrl +- (NSURL *)catalogFrontendUrl:(MWMUTM)utm { - NSString * urlString = @(self.bm.GetCatalog().GetFrontendUrl().c_str()); + NSString * urlString = @(self.bm.GetCatalog().GetFrontendUrl((UTM)utm).c_str()); return urlString ? [NSURL URLWithString:urlString] : nil; } - (NSURL * _Nullable)catalogFrontendUrlPlusPath:(NSString *)path + utm:(MWMUTM)utm { - NSString * urlString = @(self.bm.GetCatalog().GetFrontendUrl().c_str()); + NSString * urlString = @(self.bm.GetCatalog().GetFrontendUrl((UTM)utm).c_str()); return urlString ? [NSURL URLWithString:[urlString stringByAppendingPathComponent:path]] : nil; } diff --git a/iphone/Maps/Maps.xcodeproj/project.pbxproj b/iphone/Maps/Maps.xcodeproj/project.pbxproj index ce7731fcfa..43d0074b67 100644 --- a/iphone/Maps/Maps.xcodeproj/project.pbxproj +++ b/iphone/Maps/Maps.xcodeproj/project.pbxproj @@ -1408,6 +1408,7 @@ 4598438521394CFD00F8CAB2 /* MetalPerformanceShaders.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MetalPerformanceShaders.framework; path = System/Library/Frameworks/MetalPerformanceShaders.framework; sourceTree = SDKROOT; }; 4598438921394D7700F8CAB2 /* shaders_metal.metallib */ = {isa = PBXFileReference; explicitFileType = "archive.metal-library"; path = shaders_metal.metallib; sourceTree = BUILT_PRODUCTS_DIR; }; 45A37B9D20B33F5D005FBDBB /* FBAudienceNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FBAudienceNetwork.framework; path = MoPubSDK/AdNetworkSupport/FacebookAudienceNetwork/SDK/FBAudienceNetwork.framework; sourceTree = ""; }; + 45AC339022C4F57C004DC574 /* MWMUTM.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MWMUTM.h; sourceTree = ""; }; 45CBCCBB20590AAB006B55C2 /* libkml.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libkml.a; sourceTree = BUILT_PRODUCTS_DIR; }; 45FFD65C1E965EBE00DB854E /* liblocal_ads.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = liblocal_ads.a; path = "/Users/r.kuznetsov/Dev/Projects/omim/xcode/local_ads/../../../omim-build/xcode/Debug/liblocal_ads.a"; sourceTree = ""; }; 46F26CD610F623BA00ECCA39 /* EAGLView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = EAGLView.h; sourceTree = ""; }; @@ -3581,6 +3582,7 @@ 47E3C72021108E9F008B3B27 /* BookmarksLoadedViewController.xib */, 470F5A592181DE7400754295 /* PaidRouteViewController.swift */, 470F5A5A2181DE7400754295 /* PaidRouteViewController.xib */, + 45AC339022C4F57C004DC574 /* MWMUTM.h */, ); path = Catalog; sourceTree = ""; diff --git a/iphone/Maps/TipsAndTricks/TutorialViewController.swift b/iphone/Maps/TipsAndTricks/TutorialViewController.swift index 951447ee80..391b0d84f2 100644 --- a/iphone/Maps/TipsAndTricks/TutorialViewController.swift +++ b/iphone/Maps/TipsAndTricks/TutorialViewController.swift @@ -124,7 +124,7 @@ extension TutorialViewController { private static func bookmarksTutorialBlur() -> TutorialViewController { let result = TutorialViewController(nibName: "BookmarksTutorialBlur", bundle: nil) result.customAction = { - MapViewController.shared().openCatalog(animated: true) + MapViewController.shared().openCatalog(animated: true, utm: .tipsAndTricks) } return result } diff --git a/iphone/Maps/UI/BottomMenu/MWMBottomMenuViewController.mm b/iphone/Maps/UI/BottomMenu/MWMBottomMenuViewController.mm index 7cedb95df0..5c95f5b8e8 100644 --- a/iphone/Maps/UI/BottomMenu/MWMBottomMenuViewController.mm +++ b/iphone/Maps/UI/BottomMenu/MWMBottomMenuViewController.mm @@ -246,7 +246,7 @@ typedef NS_ENUM(NSUInteger, MWMBottomMenuViewCell) { { [Statistics logEvent:kStatToolbarMenuClick withParameters:@{kStatItem : kStatDownloadGuides}]; self.state = self.restoreState; - [self.mapViewController openCatalogAnimated:YES]; + [self.mapViewController openCatalogAnimated:YES utm:MWMUTMToolbarButton]; } - (void)menuActionBookingSearch diff --git a/iphone/Maps/UI/Discovery/MWMDiscoveryController.mm b/iphone/Maps/UI/Discovery/MWMDiscoveryController.mm index 647ac38b2f..9c1623520d 100644 --- a/iphone/Maps/UI/Discovery/MWMDiscoveryController.mm +++ b/iphone/Maps/UI/Discovery/MWMDiscoveryController.mm @@ -344,7 +344,8 @@ struct Callback - (void)openCatalogForURL:(NSURL *)url { auto bookmarks = [[MWMBookmarksTabViewController alloc] init]; bookmarks.activeTab = ActiveTabCatalog; - MWMCatalogWebViewController *catalog = [[MWMCatalogWebViewController alloc] init:url]; + // NOTE: UTM is already is URL, core part does it for Discovery page. + MWMCatalogWebViewController *catalog = [[MWMCatalogWebViewController alloc] init:url utm:MWMUTMNone]; NSMutableArray * controllers = [self.navigationController.viewControllers mutableCopy]; [controllers addObjectsFromArray:@[bookmarks, catalog]]; [self.navigationController setViewControllers:controllers animated:YES]; diff --git a/iphone/Maps/UI/PlacePage/MWMPlacePageData.mm b/iphone/Maps/UI/PlacePage/MWMPlacePageData.mm index 1e217bd7cf..6971c51774 100644 --- a/iphone/Maps/UI/PlacePage/MWMPlacePageData.mm +++ b/iphone/Maps/UI/PlacePage/MWMPlacePageData.mm @@ -892,7 +892,7 @@ NSString * const kUserDefaultsLatLonAsDMSKey = @"UserDefaultsLatLonAsDMS"; }; auto appInfo = AppInfo.sharedInfo; auto locale = appInfo.twoLetterLanguageId.UTF8String; - api->GetCityGallery(self.mercator, locale, resultHandler, errorHandler); + api->GetCityGallery(self.mercator, locale, UTM::PlacepageGallery, resultHandler, errorHandler); }); } diff --git a/iphone/Maps/UI/PlacePage/MWMPlacePageManager.mm b/iphone/Maps/UI/PlacePage/MWMPlacePageManager.mm index 35d2b03fbf..7fffa2f9d1 100644 --- a/iphone/Maps/UI/PlacePage/MWMPlacePageManager.mm +++ b/iphone/Maps/UI/PlacePage/MWMPlacePageManager.mm @@ -791,7 +791,8 @@ void RegisterEventIfPossible(eye::MapObject::Event::Type const type, place_page: - (void)openCatalogForURL:(NSURL *)url { auto bookmarks = [[MWMBookmarksTabViewController alloc] init]; bookmarks.activeTab = ActiveTabCatalog; - MWMCatalogWebViewController *catalog = [[MWMCatalogWebViewController alloc] init:url]; + // NOTE: UTM is already is URL, core part does it for Placepage Gallery. + MWMCatalogWebViewController *catalog = [[MWMCatalogWebViewController alloc] init:url utm:MWMUTMNone]; NSMutableArray * controllers = [self.ownerViewController.navigationController.viewControllers mutableCopy]; [controllers addObjectsFromArray:@[bookmarks, catalog]]; [self.ownerViewController.navigationController setViewControllers:controllers animated:YES]; diff --git a/map/bookmark_catalog.cpp b/map/bookmark_catalog.cpp index 24d1a4d798..1d3f37cb34 100644 --- a/map/bookmark_catalog.cpp +++ b/map/bookmark_catalog.cpp @@ -289,9 +289,9 @@ std::string BookmarkCatalog::GetWebEditorUrl(std::string const & serverId, return BuildWebEditorUrl(serverId, language); } -std::string BookmarkCatalog::GetFrontendUrl() const +std::string BookmarkCatalog::GetFrontendUrl(UTM utm) const { - return kCatalogFrontendServer + languages::GetCurrentNorm() + "/v2/mobilefront/"; + return InjectUTM(kCatalogFrontendServer + languages::GetCurrentNorm() + "/v2/mobilefront/", utm); } void BookmarkCatalog::RequestTagGroups(std::string const & language, diff --git a/map/bookmark_catalog.hpp b/map/bookmark_catalog.hpp index c033713575..192f58b65c 100644 --- a/map/bookmark_catalog.hpp +++ b/map/bookmark_catalog.hpp @@ -1,5 +1,7 @@ #pragma once +#include "partners_api/utm.hpp" + #include "kml/types.hpp" #include "platform/remote_file.hpp" @@ -76,7 +78,7 @@ public: std::string GetDownloadUrl(std::string const & serverId) const; std::string GetWebEditorUrl(std::string const & serverId, std::string const & language) const; - std::string GetFrontendUrl() const; + std::string GetFrontendUrl(UTM utm) const; void RequestTagGroups(std::string const & language, TagGroupsCallback && callback) const; diff --git a/map/discovery/discovery_manager.hpp b/map/discovery/discovery_manager.hpp index ecf1e3109d..6c4f2d0d59 100644 --- a/map/discovery/discovery_manager.hpp +++ b/map/discovery/discovery_manager.hpp @@ -114,7 +114,7 @@ public: case ItemType::Promo: { m_promoApi.GetCityGallery( - params.m_viewportCenter, params.m_lang, + params.m_viewportCenter, params.m_lang, UTM::DiscoveryPageGallery, [this, requestId, onResult](promo::CityGallery const & cityGallery) { CHECK_THREAD_CHECKER(m_threadChecker, ()); onResult(requestId, cityGallery); diff --git a/partners_api/CMakeLists.txt b/partners_api/CMakeLists.txt index 867f9c2d9a..c32397c1d7 100644 --- a/partners_api/CMakeLists.txt +++ b/partners_api/CMakeLists.txt @@ -54,6 +54,7 @@ set( uber_api.hpp utils.cpp utils.hpp + utm.hpp yandex_api.cpp yandex_api.hpp ) diff --git a/partners_api/partners_api_tests/promo_tests.cpp b/partners_api/partners_api_tests/promo_tests.cpp index dc9c40c7e8..4135781a83 100644 --- a/partners_api/partners_api_tests/promo_tests.cpp +++ b/partners_api/partners_api_tests/promo_tests.cpp @@ -144,7 +144,7 @@ UNIT_CLASS_TEST(ScopedEyeWithAsyncGuiThread, Promo_GetCityGallery) { promo::CityGallery result{}; - api.GetCityGallery({}, lang, [&result](promo::CityGallery const & gallery) + api.GetCityGallery({}, lang, UTM::None, [&result](promo::CityGallery const & gallery) { result = gallery; testing::Notify(); @@ -160,7 +160,7 @@ UNIT_CLASS_TEST(ScopedEyeWithAsyncGuiThread, Promo_GetCityGallery) { promo::CityGallery result{}; m2::PointD pt; - api.GetCityGallery(pt, lang, [&result](promo::CityGallery const & gallery) + api.GetCityGallery(pt, lang, UTM::None, [&result](promo::CityGallery const & gallery) { result = gallery; testing::Notify(); diff --git a/partners_api/promo_api.cpp b/partners_api/promo_api.cpp index 2f37a7ddb7..bd2f108a72 100644 --- a/partners_api/promo_api.cpp +++ b/partners_api/promo_api.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include "3party/jansson/myjansson.hpp" @@ -45,7 +46,7 @@ bool NeedToShowImpl(std::string const & bookingPromoAwaitingForId, eye::Eye::Inf timeSinceLastShown > kShowPromoNotRaterThan; } -void ParseCityGallery(std::string const & src, promo::CityGallery & result) +void ParseCityGallery(std::string const & src, UTM utm, promo::CityGallery & result) { base::Json root(src.c_str()); auto const dataArray = json_object_get(root.get(), "data"); @@ -80,6 +81,7 @@ void ParseCityGallery(std::string const & src, promo::CityGallery & result) auto const meta = json_object_get(root.get(), "meta"); FromJSONObject(meta, "more", result.m_moreUrl); result.m_moreUrl.insert(0, BOOKMARKS_CATALOG_FRONT_URL); + result.m_moreUrl = InjectUTM(result.m_moreUrl, utm); } std::string ToSignedId(std::string const & id) @@ -109,7 +111,8 @@ std::string GetPictureUrl(std::string const & baseUrl, std::string const & id) } void GetPromoCityGalleryImpl(std::string const & baseUrl, std::string const & id, - std::string const & lang, CityGalleryCallback const & onSuccess, + std::string const & lang, UTM utm, + CityGalleryCallback const & onSuccess, OnError const & onError) { ASSERT(!baseUrl.empty(), ()); @@ -121,7 +124,7 @@ void GetPromoCityGalleryImpl(std::string const & baseUrl, std::string const & id return; } - GetPlatform().RunTask(Platform::Thread::Network, [baseUrl, id, lang, onSuccess, onError]() + GetPlatform().RunTask(Platform::Thread::Network, [baseUrl, id, lang, utm, onSuccess, onError]() { ASSERT(!id.empty(), ()); @@ -135,7 +138,7 @@ void GetPromoCityGalleryImpl(std::string const & baseUrl, std::string const & id try { - ParseCityGallery(httpResult, result); + ParseCityGallery(httpResult, utm, result); } catch (base::Json::Exception const & e) { @@ -207,7 +210,7 @@ AfterBooking Api::GetAfterBooking(std::string const & lang) const std::string Api::GetPromoLinkForDownloader(std::string const & id, std::string const & lang) const { - return MakeCityGalleryUrl(m_baseUrl, id, lang); + return InjectUTM(MakeCityGalleryUrl(m_baseUrl, id, lang), UTM::DownloadMwmBanner); } std::string Api::GetMoreUrl(std::string const & id) const @@ -218,12 +221,12 @@ std::string Api::GetMoreUrl(std::string const & id) const return m_baseUrl + "v2/mobilefront/city/" + ToSignedId(id); } -void Api::GetCityGallery(m2::PointD const & point, std::string const & lang, +void Api::GetCityGallery(m2::PointD const & point, std::string const & lang, UTM utm, CityGalleryCallback const & onSuccess, OnError const & onError) const { CHECK(m_delegate, ()); - GetPromoCityGalleryImpl(m_baseUrl, m_delegate->GetCityId(point), lang, onSuccess, onError); + GetPromoCityGalleryImpl(m_baseUrl, m_delegate->GetCityId(point), lang, utm, onSuccess, onError); } void Api::OnMapObjectEvent(eye::MapObject const & mapObject) diff --git a/partners_api/promo_api.hpp b/partners_api/promo_api.hpp index c58e1fd6eb..12820bea54 100644 --- a/partners_api/promo_api.hpp +++ b/partners_api/promo_api.hpp @@ -1,5 +1,7 @@ #pragma once +#include "partners_api/utm.hpp" + #include "metrics/eye.hpp" #include "platform/safe_callback.hpp" @@ -69,6 +71,7 @@ public: virtual std::string GetCityId(m2::PointD const & point) = 0; }; + Api(std::string const & baseUrl = BOOKMARKS_CATALOG_FRONT_URL, std::string const & basePicturesUrl = PICTURES_URL); @@ -78,7 +81,7 @@ public: AfterBooking GetAfterBooking(std::string const & lang) const; std::string GetPromoLinkForDownloader(std::string const & id, std::string const & lang) const; std::string GetMoreUrl(std::string const & id) const; - void GetCityGallery(m2::PointD const & point, std::string const & lang, + void GetCityGallery(m2::PointD const & point, std::string const & lang, UTM utm, CityGalleryCallback const & onSuccess, OnError const & onError) const; // eye::Subscriber overrides: diff --git a/partners_api/utm.hpp b/partners_api/utm.hpp new file mode 100644 index 0000000000..070422108e --- /dev/null +++ b/partners_api/utm.hpp @@ -0,0 +1,53 @@ +#pragma once + +#include "base/url_helpers.hpp" + +#include +#include + +enum class UTM : uint8_t +{ + None = 0, + BookmarksPageCatalogButton, + ToolbarButton, + DownloadMwmBanner, + PlacepageGallery, + DiscoveryPageGallery, + TipsAndTricks +}; + +inline std::string InjectUTM(std::string const & url, UTM utm) +{ + base::url::Params params; + params.emplace_back("utm_source", "maps.me"); + switch (utm) + { + case UTM::BookmarksPageCatalogButton: + params.emplace_back("utm_medium", "button"); + params.emplace_back("utm_campaign", "bookmarks_downloaded"); + break; + case UTM::ToolbarButton: + params.emplace_back("utm_medium", "button"); + params.emplace_back("utm_campaign", "toolbar_menu"); + break; + case UTM::DownloadMwmBanner: + params.emplace_back("utm_medium", "banner"); + params.emplace_back("utm_campaign", "download_map_popup"); + break; + case UTM::PlacepageGallery: + params.emplace_back("utm_medium", "gallery"); + params.emplace_back("utm_campaign", "placepage_gallery"); + break; + case UTM::DiscoveryPageGallery: + params.emplace_back("utm_medium", "gallery"); + params.emplace_back("utm_campaign", "discovery_button_gallery"); + break; + case UTM::TipsAndTricks: + params.emplace_back("utm_medium", "button"); + params.emplace_back("utm_campaign", "tips_and_tricks"); + break; + case UTM::None: + return url; + } + return base::url::Make(url, params); +} diff --git a/xcode/partners_api/partners_api.xcodeproj/project.pbxproj b/xcode/partners_api/partners_api.xcodeproj/project.pbxproj index c973a32988..1791f9eda9 100644 --- a/xcode/partners_api/partners_api.xcodeproj/project.pbxproj +++ b/xcode/partners_api/partners_api.xcodeproj/project.pbxproj @@ -66,6 +66,7 @@ 4566605120D91FEE0085E8C1 /* megafon_countries.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 4566604F20D91FEE0085E8C1 /* megafon_countries.hpp */; }; 4566605320D920000085E8C1 /* megafon_countries_tests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4566605220D920000085E8C1 /* megafon_countries_tests.cpp */; }; 4566605520D920220085E8C1 /* libstorage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4566605420D920220085E8C1 /* libstorage.a */; }; + 45AC338F22C4F449004DC574 /* utm.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 45AC338E22C4F448004DC574 /* utm.hpp */; }; 45BABC33229812830060FA53 /* downloader_promo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 45BABC31229812820060FA53 /* downloader_promo.cpp */; }; 45BABC34229812830060FA53 /* downloader_promo.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 45BABC32229812830060FA53 /* downloader_promo.hpp */; }; 45C380772094C5B400C18D81 /* partners.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 45C380752094C5B400C18D81 /* partners.cpp */; }; @@ -160,6 +161,7 @@ 4566604F20D91FEE0085E8C1 /* megafon_countries.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = megafon_countries.hpp; sourceTree = ""; }; 4566605220D920000085E8C1 /* megafon_countries_tests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = megafon_countries_tests.cpp; sourceTree = ""; }; 4566605420D920220085E8C1 /* libstorage.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libstorage.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 45AC338E22C4F448004DC574 /* utm.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = utm.hpp; sourceTree = ""; }; 45BABC31229812820060FA53 /* downloader_promo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = downloader_promo.cpp; sourceTree = ""; }; 45BABC32229812830060FA53 /* downloader_promo.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = downloader_promo.hpp; sourceTree = ""; }; 45C380752094C5B400C18D81 /* partners.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = partners.cpp; sourceTree = ""; }; @@ -295,6 +297,7 @@ F6B5363F1DA520E40067EEA5 /* uber_api.hpp */, 3D4E997E1FB439300025B48C /* utils.cpp */, 3D47B2B01F14FA14000828D2 /* utils.hpp */, + 45AC338E22C4F448004DC574 /* utm.hpp */, 3DFEBF831EF82BEA00317D5C /* viator_api.cpp */, 3DFEBF841EF82BEA00317D5C /* viator_api.hpp */, 3DFEBF981EFBFC1500317D5C /* yandex_api.cpp */, @@ -389,6 +392,7 @@ 349CFD0A2045720000569949 /* maxim_api.hpp in Headers */, 3D4E997C1FB439260025B48C /* booking_availability_params.hpp in Headers */, 3DFEBF9C1EFBFC1500317D5C /* taxi_engine.hpp in Headers */, + 45AC338F22C4F449004DC574 /* utm.hpp in Headers */, 4566605120D91FEE0085E8C1 /* megafon_countries.hpp in Headers */, F6B536431DA520E40067EEA5 /* uber_api.hpp in Headers */, 3DBC1C551E4B14920016897F /* facebook_ads.hpp in Headers */,