diff --git a/android/res/layout/catalog_promo_container.xml b/android/res/layout/catalog_promo_container.xml
index 7227ca7a3f..0af3f9ffa4 100644
--- a/android/res/layout/catalog_promo_container.xml
+++ b/android/res/layout/catalog_promo_container.xml
@@ -28,14 +28,14 @@
android:layout_height="@dimen/divider_height"
layout="@layout/list_divider"/>
diff --git a/android/res/values/dimens.xml b/android/res/values/dimens.xml
index 4146542b17..9f03b0c907 100644
--- a/android/res/values/dimens.xml
+++ b/android/res/values/dimens.xml
@@ -277,5 +277,4 @@
164dp
52dp
194dp
- 28dp
diff --git a/android/src/com/mapswithme/maps/bookmarks/data/MapObject.java b/android/src/com/mapswithme/maps/bookmarks/data/MapObject.java
index f109342f5d..c786aeaa08 100644
--- a/android/src/com/mapswithme/maps/bookmarks/data/MapObject.java
+++ b/android/src/com/mapswithme/maps/bookmarks/data/MapObject.java
@@ -364,6 +364,19 @@ public class MapObject implements Parcelable, PopularityProvider
return mReachableByTaxiTypes;
}
+ @NonNull
+ public String[] getRawTypes()
+ {
+ String[] types = new String[0];
+ if (mRawTypes != null)
+ {
+ types = new String[mRawTypes.size()];
+ mRawTypes.toArray(types);
+ }
+
+ return types;
+ }
+
public void setLat(double lat)
{
mLat = lat;
diff --git a/android/src/com/mapswithme/maps/promo/CatalogPromoController.java b/android/src/com/mapswithme/maps/promo/CatalogPromoController.java
new file mode 100644
index 0000000000..84ce7938ea
--- /dev/null
+++ b/android/src/com/mapswithme/maps/promo/CatalogPromoController.java
@@ -0,0 +1,228 @@
+package com.mapswithme.maps.promo;
+
+import android.annotation.SuppressLint;
+import android.app.Activity;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.text.Html;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.bumptech.glide.Glide;
+import com.mapswithme.maps.R;
+import com.mapswithme.maps.base.Detachable;
+import com.mapswithme.maps.bookmarks.data.MapObject;
+import com.mapswithme.maps.gallery.GalleryAdapter;
+import com.mapswithme.maps.gallery.impl.Factory;
+import com.mapswithme.maps.gallery.impl.RegularCatalogPromoListener;
+import com.mapswithme.maps.widget.placepage.PlacePageView;
+import com.mapswithme.maps.widget.placepage.Sponsored;
+import com.mapswithme.maps.widget.recycler.ItemDecoratorFactory;
+import com.mapswithme.util.NetworkPolicy;
+import com.mapswithme.util.UTM;
+import com.mapswithme.util.UiUtils;
+import com.mapswithme.util.statistics.GalleryPlacement;
+import com.mapswithme.util.statistics.GalleryType;
+import com.mapswithme.util.statistics.Statistics;
+
+import java.util.Objects;
+
+public class CatalogPromoController implements Promo.Listener, Detachable
+{
+ @Nullable
+ private Activity mActivity;
+ @NonNull
+ private RecyclerView mPromoRecycler;
+ @NonNull
+ private TextView mPromoTitle;
+ @NonNull
+ private final PlacePageView mPlacePageView;
+
+ public CatalogPromoController(@NonNull PlacePageView placePageView)
+ {
+ mPlacePageView = placePageView;
+ mPromoRecycler = mPlacePageView.findViewById(R.id.catalog_promo_recycler);
+ mPromoTitle = mPlacePageView.findViewById(R.id.catalog_promo_title);
+ mPromoRecycler.setNestedScrollingEnabled(false);
+ LinearLayoutManager layoutManager = new LinearLayoutManager(mPlacePageView.getContext(),
+ LinearLayoutManager.HORIZONTAL,
+ false);
+ mPromoRecycler.setLayoutManager(layoutManager);
+ RecyclerView.ItemDecoration decor =
+ ItemDecoratorFactory.createPlacePagePromoGalleryDecorator(mPlacePageView.getContext(),
+ LinearLayoutManager.HORIZONTAL);
+ mPromoRecycler.addItemDecoration(decor);
+ }
+
+ @Override
+ public void onCityGalleryReceived(@NonNull PromoCityGallery promo)
+ {
+ if (mActivity == null)
+ throw new AssertionError("Activity cannot be null if promo listener is triggered!");
+
+ Sponsored sponsored = mPlacePageView.getSponsored();
+ if (sponsored == null)
+ return;
+
+ PromoResponseHandler handler = createPromoResponseHandler(promo);
+ if (handler == null)
+ return;
+
+ handler.handleResponse(promo);
+ }
+
+ @Override
+ public void onErrorReceived()
+ {
+ Statistics.INSTANCE.trackGalleryError(GalleryType.PROMO, GalleryPlacement.PLACEPAGE,
+ Statistics.ParamValue.NO_PRODUCTS);
+ }
+
+ public void updateCatalogPromo(@NonNull NetworkPolicy policy, @Nullable MapObject mapObject)
+ {
+ if (mActivity == null)
+ throw new AssertionError("Activity must be non-null at this point!");
+
+ UiUtils.hide(mPlacePageView, R.id.catalog_promo_container);
+
+ Sponsored sponsored = mPlacePageView.getSponsored();
+ if (sponsored == null || mapObject == null)
+ return;
+
+ PromoRequester requester = createPromoRequester(sponsored.getType());
+ if (requester == null)
+ return;
+
+ requester.requestPromo(policy, mapObject);
+ }
+
+ @Override
+ public void attach(@NonNull Activity object)
+ {
+ mActivity = object;
+ Promo.INSTANCE.setListener(this);
+ }
+
+ @Override
+ public void detach()
+ {
+ mActivity = null;
+ Promo.INSTANCE.setListener(null);
+ }
+
+ @SuppressLint("SwitchIntDef")
+ @Nullable
+ private static PromoRequester createPromoRequester(@Sponsored.SponsoredType int type)
+ {
+ switch (type)
+ {
+ case Sponsored.TYPE_PROMO_CATALOG_POI:
+ return new PoiPromoRequester();
+ case Sponsored.TYPE_PROMO_CATALOG_CITY:
+ return new CityPromoRequester();
+ default:
+ return null;
+ }
+ }
+
+ @Nullable
+ private PromoResponseHandler createPromoResponseHandler(@NonNull PromoCityGallery promo)
+ {
+ PromoCityGallery.Item[] items = promo.getItems();
+ if (items.length <= 0)
+ return null;
+
+ if (items.length == 1)
+ return new PoiPromoResponseHandler();
+
+ return new CityPromoResponseHandler();
+ }
+
+ interface PromoRequester
+ {
+ void requestPromo(@NonNull NetworkPolicy policy, @NonNull MapObject mapObject);
+ }
+
+ static class PoiPromoRequester implements PromoRequester
+ {
+ @Override
+ public void requestPromo(@NonNull NetworkPolicy policy, @NonNull MapObject mapObject)
+ {
+ Promo.INSTANCE.nativeRequestPoiGallery(policy, mapObject.getLat(), mapObject.getLon(),
+ mapObject.getRawTypes(), UTM.UTM_SIGHTSEEINGS_PLACEPAGE_GALLERY);
+ }
+ }
+
+ static class CityPromoRequester implements PromoRequester
+ {
+ @Override
+ public void requestPromo(@NonNull NetworkPolicy policy, @NonNull MapObject mapObject)
+ {
+ Promo.INSTANCE.nativeRequestCityGallery(policy, mapObject.getLat(), mapObject.getLon(),
+ UTM.UTM_LARGE_TOPONYMS_PLACEPAGE_GALLERY);
+ }
+ }
+
+ interface PromoResponseHandler
+ {
+ void handleResponse(@NonNull PromoCityGallery promo);
+ }
+
+ class PoiPromoResponseHandler implements PromoResponseHandler
+ {
+ @Override
+ public void handleResponse(@NonNull PromoCityGallery promo)
+ {
+ PromoCityGallery.Item[] items = promo.getItems();
+ if (items.length <= 0)
+ return;
+
+ UiUtils.show(mPlacePageView, R.id.catalog_promo_container,
+ R.id.promo_poi_description_container, R.id.promo_poi_description_divider,
+ R.id.promo_poi_card);
+ UiUtils.hide(mPromoRecycler);
+ mPromoTitle.setText(R.string.pp_discovery_place_related_header);
+
+ PromoCityGallery.Item item = items[0];
+ PromoCityGallery.Place place = item.getPlace();
+
+ TextView poiName = mPlacePageView.findViewById(R.id.promo_poi_name);
+ poiName.setText(place.getName());
+ TextView poiDescription = mPlacePageView.findViewById(R.id.promo_poi_description);
+ poiDescription.setText(Html.fromHtml(place.getDescription()));
+
+ ImageView poiImage = mPlacePageView.findViewById(R.id.promo_poi_image);
+ Glide.with(poiImage.getContext())
+ .load(item.getImageUrl())
+ .centerCrop()
+ .into(poiImage);
+ TextView bookmarkName = mPlacePageView.findViewById(R.id.place_single_bookmark_name);
+ bookmarkName.setText(item.getName());
+ TextView authorName = mPlacePageView.findViewById(R.id.place_single_bookmark_author);
+ authorName.setText(item.getAuthor().getName());
+ }
+ }
+
+ class CityPromoResponseHandler implements PromoResponseHandler
+ {
+ @Override
+ public void handleResponse(@NonNull PromoCityGallery promo)
+ {
+ UiUtils.show(mPlacePageView, R.id.catalog_promo_container,
+ R.id.catalog_promo_title_divider, R.id.catalog_promo_recycler);
+ UiUtils.hide(mPlacePageView, R.id.promo_poi_description_container,
+ R.id.promo_poi_description_divider, R.id.promo_poi_card);
+ // TODO: we need to add additional field for title in server protocol (tag).
+ mPromoTitle.setText(R.string.guides);
+ String url = promo.getMoreUrl();
+ RegularCatalogPromoListener promoListener = new RegularCatalogPromoListener(Objects.requireNonNull(mActivity),
+ GalleryPlacement.PLACEPAGE);
+ GalleryAdapter adapter = Factory.createCatalogPromoAdapter(mActivity, promo, url,
+ promoListener,
+ GalleryPlacement.PLACEPAGE);
+ mPromoRecycler.setAdapter(adapter);
+ }
+ }
+}
diff --git a/android/src/com/mapswithme/maps/widget/placepage/PlacePageView.java b/android/src/com/mapswithme/maps/widget/placepage/PlacePageView.java
index b6b76dafa3..64fdf6848c 100644
--- a/android/src/com/mapswithme/maps/widget/placepage/PlacePageView.java
+++ b/android/src/com/mapswithme/maps/widget/placepage/PlacePageView.java
@@ -65,12 +65,9 @@ import com.mapswithme.maps.editor.data.Timetable;
import com.mapswithme.maps.gallery.Constants;
import com.mapswithme.maps.gallery.FullScreenGalleryActivity;
import com.mapswithme.maps.gallery.GalleryActivity;
-import com.mapswithme.maps.gallery.Items;
-import com.mapswithme.maps.gallery.impl.Factory;
-import com.mapswithme.maps.gallery.impl.RegularCatalogPromoListener;
import com.mapswithme.maps.location.LocationHelper;
import com.mapswithme.maps.metrics.UserActionsLogger;
-import com.mapswithme.maps.promo.Promo;
+import com.mapswithme.maps.promo.CatalogPromoController;
import com.mapswithme.maps.promo.PromoCityGallery;
import com.mapswithme.maps.promo.PromoEntity;
import com.mapswithme.maps.review.Review;
@@ -93,7 +90,6 @@ 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;
@@ -101,8 +97,6 @@ import com.mapswithme.util.log.Logger;
import com.mapswithme.util.log.LoggerFactory;
import com.mapswithme.util.sharing.ShareOption;
import com.mapswithme.util.statistics.AlohaHelper;
-import com.mapswithme.util.statistics.GalleryPlacement;
-import com.mapswithme.util.statistics.GalleryType;
import com.mapswithme.util.statistics.Statistics;
import java.util.ArrayList;
@@ -131,8 +125,8 @@ public class PlacePageView extends NestedScrollView
RecyclerClickListener,
NearbyAdapter.OnItemClickListener,
EditBookmarkFragment.EditBookmarkListener,
- Detachable,
- Promo.Listener
+ Detachable
+
{
private static final Logger LOGGER = LoggerFactory.INSTANCE.getLogger(LoggerFactory.Type.MISC);
private static final String TAG = PlacePageView.class.getSimpleName();
@@ -229,6 +223,10 @@ public class PlacePageView extends NestedScrollView
@NonNull
private UGCController mUgcController;
+ @SuppressWarnings("NullableProblems")
+ @NonNull
+ private CatalogPromoController mCatalogPromoController;
+
// Data
@Nullable
private MapObject mMapObject;
@@ -331,18 +329,10 @@ public class PlacePageView extends NestedScrollView
@Nullable
private RoutingModeListener mRoutingModeListener;
- @SuppressWarnings("NullableProblems")
- @NonNull
- private RecyclerView mCatalogPromoRecycler;
-
@SuppressWarnings("NullableProblems")
@NonNull
private View mCatalogPromoTitleView;
- @SuppressWarnings("NullableProblems")
- @NonNull
- private com.mapswithme.maps.gallery.GalleryAdapter mCatalogPromoLoadingAdapter;
-
void setScrollable(boolean scrollable)
{
mScrollable = scrollable;
@@ -374,38 +364,13 @@ public class PlacePageView extends NestedScrollView
@Override
public void attach(@NonNull Activity object)
{
- Promo.INSTANCE.setListener(this);
+ mCatalogPromoController.attach(object);
}
@Override
public void detach()
{
- Promo.INSTANCE.setListener(null);
- }
-
- @Override
- public void onCityGalleryReceived(@NonNull PromoCityGallery gallery)
- {
- String url = gallery.getMoreUrl();
- RegularCatalogPromoListener promoListener = new RegularCatalogPromoListener(getActivity(),
- GalleryPlacement.PLACEPAGE);
- com.mapswithme.maps.gallery.GalleryAdapter adapter = Factory.createCatalogPromoAdapter(getContext(),
- gallery,
- url,
- promoListener,
- GalleryPlacement.PLACEPAGE);
- mCatalogPromoRecycler.setAdapter(adapter);
- }
-
- @Override
- public void onErrorReceived()
- {
- ErrorCatalogPromoListener listener =
- new ErrorCatalogPromoListener<>(getActivity(), networkPolicy -> onNetworkPolicyResult(networkPolicy, mMapObject));
- com.mapswithme.maps.gallery.GalleryAdapter adapter = Factory.createCatalogPromoErrorAdapter(listener);
- mCatalogPromoRecycler.setAdapter(adapter);
- Statistics.INSTANCE.trackGalleryError(GalleryType.PROMO, GalleryPlacement.PLACEPAGE,
- Statistics.ParamValue.NO_PRODUCTS);
+ mCatalogPromoController.detach();
}
public interface SetMapObjectListener
@@ -519,7 +484,8 @@ public class PlacePageView extends NestedScrollView
initHotelGalleryView();
initHotelNearbyView();
initHotelRatingView();
- initCatalogPromoView();
+
+ mCatalogPromoController = new CatalogPromoController(this);
mUgcController = new UGCController(this);
@@ -874,23 +840,6 @@ public class PlacePageView extends NestedScrollView
mRvHotelGallery.setAdapter(mGalleryAdapter);
}
- private void initCatalogPromoView()
- {
- mCatalogPromoRecycler = findViewById(R.id.catalog_promo_recycler);
- mCatalogPromoTitleView = findViewById(R.id.catalog_promo_title);
- mCatalogPromoLoadingAdapter = Factory.createCatalogPromoLoadingAdapter();
- mCatalogPromoRecycler.setNestedScrollingEnabled(false);
- LinearLayoutManager layoutManager = new LinearLayoutManager(getContext(),
- LinearLayoutManager.HORIZONTAL,
- false);
- mCatalogPromoRecycler.setLayoutManager(layoutManager);
- RecyclerView.ItemDecoration decor =
- ItemDecoratorFactory.createPlacePagePromoGalleryDecorator(getContext(),
- LinearLayoutManager.HORIZONTAL);
- mCatalogPromoRecycler.addItemDecoration(decor);
- mCatalogPromoRecycler.setAdapter(mCatalogPromoLoadingAdapter);
- }
-
private void initHotelFacilitiesView()
{
mHotelFacilities = findViewById(R.id.ll__place_hotel_facilities);
@@ -1250,7 +1199,7 @@ public class PlacePageView extends NestedScrollView
private void processSponsored(@NonNull NetworkPolicy policy)
{
- updateCatalogPromoGallery(policy);
+ mCatalogPromoController.updateCatalogPromo(policy, mMapObject);
if (mSponsored == null || mMapObject == null)
return;
@@ -1269,41 +1218,6 @@ public class PlacePageView extends NestedScrollView
Sponsored.requestInfo(mSponsored, Locale.getDefault().toString(), policy);
}
- private void updateCatalogPromoGallery(@NonNull NetworkPolicy policy)
- {
- boolean hasPromoGallery = mSponsored != null && mSponsored.getType() == Sponsored.TYPE_PROMO_CATALOG_CITY;
- toggleCatalogPromoGallery(hasPromoGallery);
-
- if (mSponsored == null || mMapObject == null)
- return;
-
- if (hasPromoGallery && policy.canUseNetwork())
- {
- mCatalogPromoRecycler.setAdapter(mCatalogPromoLoadingAdapter);
- // TODO: set correct UTM
- Promo.INSTANCE.nativeRequestCityGallery(policy, mMapObject.getLat(), mMapObject.getLon(),
- UTM.UTM_LARGE_TOPONYMS_PLACEPAGE_GALLERY);
- }
- else if (hasPromoGallery)
- {
- ErrorCatalogPromoListener listener =
- new ErrorCatalogPromoListener<>(getActivity(), networkPolicy -> onNetworkPolicyResult(networkPolicy, mMapObject));
- com.mapswithme.maps.gallery.GalleryAdapter adapter = Factory.createCatalogPromoErrorAdapter(listener);
- mCatalogPromoRecycler.setAdapter(adapter);
- }
- }
-
- private void onNetworkPolicyResult(@NonNull NetworkPolicy policy, @NonNull MapObject mapObject)
- {
- if (policy.canUseNetwork())
- {
- // TODO: set correct UTM
- Promo.INSTANCE.nativeRequestCityGallery(policy, mapObject.getLat(), mapObject.getLon(),
- UTM.UTM_LARGE_TOPONYMS_PLACEPAGE_GALLERY);
- mCatalogPromoRecycler.setAdapter(Factory.createCatalogPromoLoadingAdapter());
- }
- }
-
private boolean isNetworkNeeded()
{
return mMapObject != null && (isSponsored() || mMapObject.getBanners() != null);
@@ -1322,7 +1236,7 @@ public class PlacePageView extends NestedScrollView
refreshHotelDetailViews(policy);
refreshViewsInternal(mMapObject);
mUgcController.getUGC(mMapObject);
- updateCatalogPromoGallery(policy);
+ mCatalogPromoController.updateCatalogPromo(policy, mMapObject);
}
private void refreshViewsInternal(@NonNull MapObject mapObject)