Panagiotis Triantafyllou

added map

......@@ -26,6 +26,10 @@
android:requestLegacyExternalStorage="true"
android:theme="@style/AppTheme">
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="@string/google_maps_key" />
<activity
android:name="warp.ly.android_sdk.activities.SplashActivity"
android:exported="true"
......
......@@ -81,6 +81,8 @@ dependencies {
//------------------------------ GMS -----------------------------//
implementation 'com.google.android.gms:play-services-base:18.7.2'
implementation 'com.google.android.gms:play-services-location:21.3.0'
implementation 'com.google.android.gms:play-services-maps:18.2.0'
implementation 'com.google.maps.android:android-maps-utils:0.5'
//------------------------------ Work Manager -----------------------------//
implementation 'androidx.work:work-runtime:2.10.3'
......
......@@ -63,6 +63,12 @@
android:theme="@style/SDKAppTheme" />
<activity
android:name=".activities.ShopsActivity"
android:exported="false"
android:screenOrientation="portrait"
android:theme="@style/SDKAppTheme" />
<activity
android:name=".dexter.PermissionsActivity"
android:exported="false"
android:launchMode="singleInstance"
......
package ly.warp.sdk.activities;
import static ly.warp.sdk.activities.SingleCouponActivity.EXTRA_MERCHANT_UUID;
import android.Manifest;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.FragmentActivity;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.request.target.CustomTarget;
import com.bumptech.glide.request.transition.Transition;
import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.material.bottomsheet.BottomSheetDialog;
import com.google.maps.android.clustering.Cluster;
import com.google.maps.android.clustering.ClusterManager;
import java.util.ArrayList;
import ly.warp.sdk.R;
import ly.warp.sdk.io.callbacks.CallbackReceiver;
import ly.warp.sdk.io.models.Coupon;
import ly.warp.sdk.io.models.Merchant;
import ly.warp.sdk.utils.WarpUtils;
import ly.warp.sdk.utils.WarplyManagerHelper;
import ly.warp.sdk.utils.WarplyProperty;
import ly.warp.sdk.utils.constants.WarpConstants;
import ly.warp.sdk.utils.managers.WarplyAnalyticsManager;
import ly.warp.sdk.utils.managers.WarplyManager;
public class ShopsActivity extends FragmentActivity implements View.OnClickListener,
OnMapReadyCallback, GoogleMap.OnMapLoadedCallback, ClusterManager.OnClusterClickListener<Merchant>,
GoogleMap.OnMarkerClickListener {
// ===========================================================
// Constants
// ===========================================================
public final static float DEFAULT_LOCATION_ZOOM = 6.2f;
// ===========================================================
// Fields
// ===========================================================
private ImageView mIvBack;
private Coupon mCoupon;
private GoogleMap mMap;
private ClusterManager<Merchant> mClusterManager;
private SupportMapFragment mMapView;
private AlertDialog mAlertDialogNoShopsAvailable;
private Merchant mMerchant, mMerchantParent;
private ArrayList<Merchant> mMerchantList = new ArrayList<>();
private String mMerchantUuid = "";
private TextView mTvHeaderTitle, mTvSearchTitle;
// ===========================================================
// Methods for/from SuperClass/Interfaces
// ===========================================================
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_shops);
initViews();
mMapView = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.mv_shops);
mMapView.getMapAsync(this);
mIvBack.setOnClickListener(this);
}
@Override
public void onResume() {
super.onResume();
}
@Override
public void onClick(View view) {
if (view.getId() == R.id.iv_back) {
onBackPressed();
}
}
// @Override
// public void onRequestPermissionsResult(
// int requestCode,
// String permissions[],
// int[] grantResults) {
// switch (requestCode) {
// case REQUEST_PERMISSION_PHONE_STATE:
// if (grantResults.length > 0
// && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Toast.makeText(MainActivity.this, "Permission Granted!", Toast.LENGTH_SHORT).show();
// } else {
// Toast.makeText(MainActivity.this, "Permission Denied!", Toast.LENGTH_SHORT).show();
// }
// }
// }
@Override
public void onMapReady(@NonNull GoogleMap googleMap) {
mMap = googleMap;
if (ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
mMap.setMyLocationEnabled(true);
}
} else {
mMap.setMyLocationEnabled(false);
// ActivityCompat.requestPermissions(this,
// new String[]{Manifest.permission.ACCESS_FINE_LOCATION,
// Manifest.permission.ACCESS_COARSE_LOCATION}, 501);
}
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
mMap.setMinZoomPreference(DEFAULT_LOCATION_ZOOM);
mMap.setLatLngBoundsForCameraTarget(WarpConstants.GREECE_BOUNDS);
mMap.getUiSettings().setZoomControlsEnabled(true);
mMap.getUiSettings().setZoomGesturesEnabled(true);
mMap.getUiSettings().setCompassEnabled(false);
mMap.getUiSettings().setMyLocationButtonEnabled(false);
mMap.getUiSettings().setMapToolbarEnabled(false);
mMap.getUiSettings().setTiltGesturesEnabled(false);
mMap.getUiSettings().setRotateGesturesEnabled(false);
mMap.setOnMapLoadedCallback(this);
mMap.setOnMarkerClickListener(/*mClusterManager*/this);
}
@Override
public void onMapLoaded() {
if (mMap != null) {
CameraUpdate camUpdate;
camUpdate = CameraUpdateFactory.newLatLngBounds(WarpConstants.GREECE_BOUNDS, 48);
mMap.animateCamera(camUpdate);
}
// if (mClusterManager == null) {
// mClusterManager = new ClusterManager<>(this, mMap);
// mClusterManager.setOnClusterClickListener(this);
//// mMap.setOnMarkerClickListener(/*mClusterManager*/this);
// }
if (!TextUtils.isEmpty(mMerchantUuid)) {
WarplyManager.getStores("86eba6980cf746cbbcca5c6446700121", mStoresCallback);
}
}
@Override
public boolean onClusterClick(Cluster<Merchant> cluster) {
if (mMap != null) {
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(cluster.getPosition(),
(float) Math.floor(mMap.getCameraPosition().zoom + 1)), 300, null);
// mMap.clear();
// mClusterManager.clearItems();
// mClusterManager.addItems(cluster.getItems());
// mClusterManager.cluster();
}
return true;
}
@Override
public boolean onMarkerClick(@NonNull Marker marker) {
// for (Merchant merch : mMerchantList) {
// if (merch.getUuid().equals(marker.getSnippet())) {
// final BottomSheetDialog bottomSheetDialog = new BottomSheetDialog(this, R.style.BottomSheetDialog);
// bottomSheetDialog.setContentView(R.layout.dl_map_pin);
// ImageView dialogClose = (ImageView) bottomSheetDialog.findViewById(R.id.iv_map_pin_close);
// dialogClose.setOnClickListener(view -> bottomSheetDialog.dismiss());
// TextView pinTitle = (TextView) bottomSheetDialog.findViewById(R.id.tv_pin_title);
// WarpUtils.renderCustomFont(ShopsActivity.this, R.font.pf_square_sans_pro_bold, pinTitle);
// if (mMerchantParentList != null && mMerchantParentList.size() > 0) {
// for (Merchant parentMerch : mMerchantParentList) {
// if (parentMerch.getUuid().equals(merch.getParent())) {
// pinTitle.setText(parentMerch.getAdminName());
// break;
// }
// }
// }
// ImageView pinLogo = (ImageView) bottomSheetDialog.findViewById(R.id.iv_pin_logo);
// if (!TextUtils.isEmpty(merch.getImgPreview())) {
// Glide.with(this)
//// .setDefaultRequestOptions(
//// RequestOptions
//// .placeholderOf(R.drawable.ic_default_contact_photo)
//// .error(R.drawable.ic_default_contact_photo))
// .load(merch.getImgPreview())
// .diskCacheStrategy(DiskCacheStrategy.DATA)
// .into(pinLogo);
// }
// TextView pinName = (TextView) bottomSheetDialog.findViewById(R.id.tv_pin_name);
// WarpUtils.renderCustomFont(ShopsActivity.this, R.font.pf_square_sans_pro_medium, pinName);
// pinName.setText(merch.getName());
// TextView pinDays = (TextView) bottomSheetDialog.findViewById(R.id.tv_pin_days);
// WarpUtils.renderCustomFont(ShopsActivity.this, R.font.pf_square_sans_pro_regular, pinDays);
// pinDays.setText(merch.getSnippet()); //TODO: wrong getter
// TextView pinTel = (TextView) bottomSheetDialog.findViewById(R.id.tv_pin_tel);
// WarpUtils.renderCustomFont(ShopsActivity.this, R.font.pf_square_sans_pro_medium, pinTel);
// pinTel.setText(merch.getTelephone());
// TextView pinAddress = (TextView) bottomSheetDialog.findViewById(R.id.tv_pin_address);
// WarpUtils.renderCustomFont(ShopsActivity.this, R.font.pf_square_sans_pro_medium, pinAddress);
// pinAddress.setText(merch.getAddress());
// TextView pinDirectionsText = (TextView) bottomSheetDialog.findViewById(R.id.tv_directions);
// WarpUtils.renderCustomFont(ShopsActivity.this, R.font.pf_square_sans_pro_medium, pinDirectionsText);
// LinearLayout pinDirections = (LinearLayout) bottomSheetDialog.findViewById(R.id.ll_directions);
// pinDirections.setOnClickListener(view -> {
// Uri gmmIntentUri = Uri.parse("google.navigation:q=" + merch.getLatitude() + "," + merch.getLongitude()/* + "&mode=w"*/);
// Intent mapIntent = new Intent(Intent.ACTION_VIEW, gmmIntentUri);
// mapIntent.setPackage("com.google.android.apps.maps");
// startActivity(mapIntent);
// });
// bottomSheetDialog.show();
// return false;
// }
// }
return false;
}
// ===========================================================
// Methods
// ===========================================================
private void initViews() {
mMerchantUuid = getIntent().getStringExtra(EXTRA_MERCHANT_UUID);
mIvBack = findViewById(R.id.iv_back);
mTvHeaderTitle = findViewById(R.id.tv_header_title);
mTvSearchTitle = findViewById(R.id.tv_search_title);
WarpUtils.renderCustomFont(this, R.font.ping_lcg_bold, mTvHeaderTitle);
WarpUtils.renderCustomFont(this, R.font.ping_lcg_regular, mTvSearchTitle);
}
private Bitmap overlayBitmaps(Bitmap staticImage, Bitmap poiImage, int poiImageWidth, int poiImageHeight, float scale) {
// Resize the POI image
Bitmap resizedPoiImage;
int poiImageWidthScale = 0;
int poiImageHeightScale = 0;
if (scale == 0)
resizedPoiImage = Bitmap.createScaledBitmap(poiImage, poiImageWidth, poiImageHeight, false);
else {
// Calculate the new dimensions for the POI image
poiImageWidthScale = (int) (poiImage.getWidth() * scale);
poiImageHeightScale = (int) (poiImage.getHeight() * scale);
resizedPoiImage = Bitmap.createScaledBitmap(poiImage, poiImageWidthScale, poiImageHeightScale, false);
}
// Create a new bitmap with the same size as the static image
Bitmap combinedBitmap = Bitmap.createBitmap(staticImage.getWidth(), staticImage.getHeight(), staticImage.getConfig());
Canvas canvas = new Canvas(combinedBitmap);
// Draw the static image on the canvas
canvas.drawBitmap(staticImage, 0, 0, null);
// Calculate the position to center the resized POI image on the static image
int left = (staticImage.getWidth() - resizedPoiImage.getWidth()) / 2;
int top = (staticImage.getHeight() - resizedPoiImage.getHeight()) / 3;
// Draw the resized POI image on the canvas
canvas.drawBitmap(resizedPoiImage, left, top, null);
return combinedBitmap;
}
private void showNoShopsAvailableDialog() {
if (!isFinishing()) {
mAlertDialogNoShopsAvailable = new AlertDialog.Builder(this)
.setTitle(R.string.lbl_stores)
.setMessage(R.string.lbl_no_shops)
.setCancelable(false)
.setPositiveButton(R.string.lbl_ok, (dialogPositive, whichPositive) -> {
dialogPositive.dismiss();
})
.show();
}
}
// ===========================================================
// Inner and Anonymous Classes
// ===========================================================
private final CallbackReceiver<ArrayList<Merchant>> mStoresCallback = new CallbackReceiver<ArrayList<Merchant>>() {
@Override
public void onSuccess(ArrayList<Merchant> result) {
if (result.isEmpty()) {
showNoShopsAvailableDialog();
return;
}
mMerchantList.clear();
mMerchantList.addAll(result);
for (Merchant merch : result) {
if (merch.getLatitude() == null || merch.getLongitude() == null) continue;
Glide.with(ShopsActivity.this)
.asBitmap()
.load(R.drawable.demo_map_pin)
.into(new CustomTarget<Bitmap>() {
@Override
public void onResourceReady(@NonNull Bitmap staticImage, @Nullable Transition<? super Bitmap> transition) {
if (!TextUtils.isEmpty(merch.getImgPreview())) {
Glide.with(ShopsActivity.this)
.asBitmap()
.load(merch.getImgPreview())
.diskCacheStrategy(DiskCacheStrategy.DATA)
.into(new CustomTarget<Bitmap>() {
@Override
public void onResourceReady(@NonNull Bitmap poiImage, @Nullable Transition<? super Bitmap> transition) {
Bitmap combinedBitmap = overlayBitmaps(staticImage, poiImage, 48, 48, 0);
if (mMap != null) {
mMap.addMarker(new MarkerOptions()
.position(new LatLng(merch.getLatitude(), merch.getLongitude()))
.icon(BitmapDescriptorFactory.fromBitmap(combinedBitmap))
.anchor(0.5f, 1.0f)
.snippet(merch.getUuid()));
}
}
@Override
public void onLoadCleared(@Nullable Drawable placeholder) {
if (mMap != null) {
mMap.addMarker(new MarkerOptions()
.position(new LatLng(merch.getLatitude(), merch.getLongitude()))
.icon(BitmapDescriptorFactory.fromBitmap(staticImage))
.anchor(0.5f, 1.0f)
.snippet(merch.getUuid()));
}
}
@Override
public void onLoadFailed(@Nullable Drawable errorDrawable) {
if (mMap != null) {
mMap.addMarker(new MarkerOptions()
.position(new LatLng(merch.getLatitude(), merch.getLongitude()))
.icon(BitmapDescriptorFactory.fromBitmap(staticImage))
.anchor(0.5f, 1.0f)
.snippet(merch.getUuid()));
}
}
});
} else {
if (mMap != null) {
mMap.addMarker(new MarkerOptions()
.position(new LatLng(merch.getLatitude(), merch.getLongitude()))
.icon(BitmapDescriptorFactory.fromBitmap(staticImage))
.anchor(0.5f, 1.0f)
.snippet(merch.getUuid()));
}
}
}
@Override
public void onLoadCleared(@Nullable Drawable placeholder) {
if (mMap != null) {
mMap.addMarker(new MarkerOptions()
.position(new LatLng(merch.getLatitude(), merch.getLongitude()))
.anchor(0.5f, 1.0f)
.snippet(merch.getUuid()));
}
}
});
}
}
@Override
public void onFailure(int errorCode) {
Toast.makeText(ShopsActivity.this, "STORES ERROR", Toast.LENGTH_SHORT).show();
}
};
}
\ No newline at end of file
......@@ -34,6 +34,7 @@ public class SingleCouponActivity extends Activity implements View.OnClickListen
// Constants
// ===========================================================
public static final String EXTRA_OFFER_ITEM = "coupon_item";
public static final String EXTRA_MERCHANT_UUID = "merchant_uuid";
// ===========================================================
// Fields
......@@ -44,7 +45,7 @@ public class SingleCouponActivity extends Activity implements View.OnClickListen
private TextView mTvSmallDescription;
private TextView mTvFullDescription;
private TextView mTvEndDate;
private LinearLayout mLlDate;
private LinearLayout mLlDate, mLlShopsButton;
private TextView mTvValue;
private TextView mTvMoreButton;
private ImageView mIvImage;
......@@ -96,6 +97,19 @@ public class SingleCouponActivity extends Activity implements View.OnClickListen
super.onResume();
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.iv_back) {
onBackPressed();
return;
}
if (v.getId() == R.id.ll_shops) {
Intent myIntent = new Intent(SingleCouponActivity.this, ShopsActivity.class);
myIntent.putExtra(SingleCouponActivity.EXTRA_MERCHANT_UUID, mOfferItem.getMerchantUuid());
startActivity(myIntent);
}
}
// ===========================================================
// Methods
// ===========================================================
......@@ -104,6 +118,9 @@ public class SingleCouponActivity extends Activity implements View.OnClickListen
mIvBack = findViewById(R.id.iv_back);
mIvBack.setOnClickListener(this);
mLlShopsButton = findViewById(R.id.ll_shops);
mLlShopsButton.setOnClickListener(this);
// Initialize views
mTvSmallDescription = findViewById(R.id.tv_coupon_small_description);
mTvFullDescription = findViewById(R.id.tv_coupon_full_description);
......@@ -336,13 +353,6 @@ public class SingleCouponActivity extends Activity implements View.OnClickListen
}
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.iv_back) {
onBackPressed();
}
}
// ===========================================================
// Inner and Anonymous Classes
// ===========================================================
......
......@@ -28,6 +28,9 @@ package ly.warp.sdk.io.models;
import android.os.Parcel;
import android.os.Parcelable;
import com.google.android.gms.maps.model.LatLng;
import com.google.maps.android.clustering.ClusterItem;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
......@@ -42,7 +45,7 @@ import ly.warp.sdk.utils.constants.WarpConstants;
* Created by Panagiotis Triantafyllou on 07-Dec-21.
*/
public class Merchant implements Parcelable, Serializable {
public class Merchant implements Parcelable, Serializable, ClusterItem {
private static final long serialVersionUID = -4754964462459705285L;
......@@ -73,6 +76,7 @@ public class Merchant implements Parcelable, Serializable {
private static final String CATEGORY_UUID = "category_uuid";
private static final String CREATED = "created";
private static final String PARENT = "parent";
private static final String PARENT_UUID = "parent_uuid";
private static final String IMG = "img";
private static final String IMG_PREVIEW = "img_preview";
private static final String ADMIN_NAME = "admin_name";
......@@ -125,6 +129,7 @@ public class Merchant implements Parcelable, Serializable {
private String category_uuid;
private String created;
private String parent;
private String parentUuid;
private JSONArray img;
private String img_preview;
private String admin_name;
......@@ -149,6 +154,7 @@ public class Merchant implements Parcelable, Serializable {
private String minPrice;
private String maxPrice;
private String urlName;
private LatLng coordinates;
/**
* Helper method to get a nullable String from a JSONObject.
......@@ -184,6 +190,7 @@ public class Merchant implements Parcelable, Serializable {
this.category_uuid = null;
this.created = null;
this.parent = null;
this.parentUuid = null;
this.img = null;
this.img_preview = null;
this.admin_name = null;
......@@ -208,6 +215,9 @@ public class Merchant implements Parcelable, Serializable {
this.minPrice = null;
this.maxPrice = null;
this.urlName = null;
this.coordinates = new LatLng(
this.latitude != null ? this.latitude : 0.0,
this.longitude != null ? this.longitude : 0.0);
}
public Merchant(boolean isUniversal) {
......@@ -269,6 +279,7 @@ public class Merchant implements Parcelable, Serializable {
this.category_uuid = optNullableString(json, CATEGORY_UUID);
this.created = optNullableString(json, CREATED);
this.parent = optNullableString(json, PARENT);
this.parentUuid = optNullableString(json, PARENT_UUID);
this.img = json.optJSONArray(IMG);
this.img_preview = optNullableString(json, IMG_PREVIEW);
this.admin_name = optNullableString(json, ADMIN_NAME);
......@@ -293,6 +304,9 @@ public class Merchant implements Parcelable, Serializable {
this.minPrice = optNullableString(json, MIN_PRICE);
this.maxPrice = optNullableString(json, MAX_PRICE);
this.urlName = optNullableString(json, URL_NAME);
this.coordinates = new LatLng(
this.latitude != null ? this.latitude : 0.0,
this.longitude != null ? this.longitude : 0.0);
}
}
......@@ -347,6 +361,7 @@ public class Merchant implements Parcelable, Serializable {
this.category_uuid = source.readString();
this.created = source.readString();
this.parent = source.readString();
this.parentUuid = source.readString();
try {
String imgStr = source.readString();
this.img = imgStr != null ? new JSONArray(imgStr) : null;
......@@ -393,6 +408,9 @@ public class Merchant implements Parcelable, Serializable {
this.minPrice = source.readString();
this.maxPrice = source.readString();
this.urlName = source.readString();
this.coordinates = new LatLng(
this.latitude != null ? this.latitude : 0.0,
this.longitude != null ? this.longitude : 0.0);
}
@Override
......@@ -422,6 +440,7 @@ public class Merchant implements Parcelable, Serializable {
dest.writeString(this.category_uuid);
dest.writeString(this.created);
dest.writeString(this.parent);
dest.writeString(this.parentUuid);
dest.writeString(this.img != null ? this.img.toString() : null);
dest.writeString(this.img_preview);
dest.writeString(this.admin_name);
......@@ -446,6 +465,7 @@ public class Merchant implements Parcelable, Serializable {
dest.writeString(this.minPrice);
dest.writeString(this.maxPrice);
dest.writeString(this.urlName);
dest.writeParcelable(coordinates, flags);
}
/**
......@@ -481,6 +501,7 @@ public class Merchant implements Parcelable, Serializable {
jObj.put(CATEGORY_UUID, this.category_uuid != null ? this.category_uuid : JSONObject.NULL);
jObj.put(CREATED, this.created != null ? this.created : JSONObject.NULL);
jObj.put(PARENT, this.parent != null ? this.parent : JSONObject.NULL);
jObj.put(PARENT_UUID, this.parentUuid != null ? this.parentUuid : JSONObject.NULL);
jObj.put(IMG, this.img != null ? this.img : JSONObject.NULL);
jObj.put(IMG_PREVIEW, this.img_preview != null ? this.img_preview : JSONObject.NULL);
jObj.put(ADMIN_NAME, this.admin_name != null ? this.admin_name : JSONObject.NULL);
......@@ -661,6 +682,10 @@ public class Merchant implements Parcelable, Serializable {
return parent;
}
public String getParentUuid() {
return parentUuid;
}
public ArrayList<String> getImg() {
return jsonArrayToList(img);
}
......@@ -869,6 +894,10 @@ public class Merchant implements Parcelable, Serializable {
this.parent = parent;
}
public void setParentUuid(String parentUuid) {
this.parentUuid = parentUuid;
}
public void setImg(JSONArray img) {
this.img = img;
}
......@@ -965,6 +994,10 @@ public class Merchant implements Parcelable, Serializable {
this.urlName = urlName;
}
public void setCoordinates(LatLng coordinates) {
this.coordinates = coordinates;
}
@Override
public int describeContents() {
return 0;
......@@ -989,4 +1022,17 @@ public class Merchant implements Parcelable, Serializable {
}
return listData;
}
@Override
public LatLng getPosition() {
return coordinates;
}
@Override
public String getTitle() {
return null;
}
@Override
public String getSnippet() {
return null;
}
}
......
......@@ -157,6 +157,17 @@ public interface ApiService {
@Header(WarpConstants.HEADER_WEB_ID) String webId,
@Header(WarpConstants.HEADER_SIGNATURE) String signature);
@Headers("Content-Type: application/json")
@POST("/api/mobile/v2/{appUuid}/context/")
Call<ResponseBody> getStores(@Path("appUuid") String appUuid,
@Body RequestBody request,
@Header(WarpConstants.HEADER_DATE) String timeStamp,
@Header(WarpConstants.HEADER_LOYALTY_BUNDLE_ID) String bundleId,
@Header(WarpConstants.HEADER_UNIQUE_DEVICE_ID) String deviceId,
@Header(WarpConstants.HEADER_CHANNEL) String channel,
@Header(WarpConstants.HEADER_WEB_ID) String webId,
@Header(WarpConstants.HEADER_SIGNATURE) String signature);
// ===========================================================
// Getter & Setter
// ===========================================================
......
package ly.warp.sdk.utils;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Paint;
import androidx.annotation.NonNull;
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
import com.bumptech.glide.load.resource.bitmap.BitmapTransformation;
import java.security.MessageDigest;
/**
* Glide transformation that renders a bitmap in grayscale
*/
public class GrayscaleTransformation extends BitmapTransformation {
private static final String ID = "ly.warp.sdk.utils.GrayscaleTransformation";
@Override
protected Bitmap transform(@NonNull BitmapPool pool, @NonNull Bitmap toTransform, int outWidth, int outHeight) {
Bitmap result = pool.get(toTransform.getWidth(), toTransform.getHeight(), Bitmap.Config.ARGB_8888);
if (result == null) {
result = Bitmap.createBitmap(toTransform.getWidth(), toTransform.getHeight(), Bitmap.Config.ARGB_8888);
}
ColorMatrix colorMatrix = new ColorMatrix();
colorMatrix.setSaturation(0f);
Paint paint = new Paint();
paint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));
Canvas canvas = new Canvas(result);
canvas.drawBitmap(toTransform, 0, 0, paint);
return result;
}
@Override
public void updateDiskCacheKey(@NonNull MessageDigest messageDigest) {
messageDigest.update(ID.getBytes());
}
@Override
public boolean equals(Object o) {
return o instanceof GrayscaleTransformation;
}
@Override
public int hashCode() {
return ID.hashCode();
}
}
......@@ -25,6 +25,9 @@
package ly.warp.sdk.utils.constants;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
public class WarpConstants {
/**
......@@ -87,6 +90,11 @@ public class WarpConstants {
public static boolean DEBUG;
public static String GCM_SENDER_ID;
public static final LatLngBounds GREECE_BOUNDS = new LatLngBounds(
new LatLng(34.75261, 19.33079),
new LatLng(41.97761, 28.62522)
);
/*
* if was received the campaign with this category need expires date define
* as 0 (for no show it in app need check on 0 or if the date is correct)
......
......@@ -27,6 +27,7 @@ package ly.warp.sdk.utils.managers;
import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;
import android.text.format.DateFormat;
import android.util.ArrayMap;
......@@ -455,6 +456,37 @@ public class WarplyManager {
return categorizedMap;
}
public static void getStores(String merchantUuid, final CallbackReceiver<ArrayList<Merchant>> receiver) {
WarpUtils.log("************* WARPLY Stores Request ********************");
WarpUtils.log("[WARP Trace] WARPLY Stores Request is active");
WarpUtils.log("**************************************************");
ApiService service = ApiClient.getRetrofitInstance().create(ApiService.class);
ListeningExecutorService executorService = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(1));
ListenableFuture<ArrayList<Merchant>> futureStores = getStoresRetro(merchantUuid, service);
ListenableFuture<List<Object>> allResultsFuture = Futures.allAsList(futureStores);
ListenableFuture<ArrayList<Merchant>> mergedResultFuture = Futures.transformAsync(allResultsFuture, results -> {
ArrayList<Merchant> resultStores = (ArrayList<Merchant>) results.get(0);
return executorService.submit(() -> resultStores);
}, executorService);
Futures.addCallback(mergedResultFuture, new FutureCallback<ArrayList<Merchant>>() {
@Override
public void onSuccess(ArrayList<Merchant> mergedResult) {
executorService.shutdownNow();
new Handler(Looper.getMainLooper()).post(() -> receiver.onSuccess(mergedResult));
}
@Override
public void onFailure(Throwable throwable) {
executorService.shutdownNow();
new Handler(Looper.getMainLooper()).post(() -> receiver.onFailure(2));
}
}, executorService);
}
public static void getCouponsets(final CallbackReceiver<LinkedHashMap<String, ArrayList<Couponset>>> receiver) {
WarpUtils.log("************* WARPLY Couponsets Request ********************");
WarpUtils.log("[WARP Trace] WARPLY Couponsets Request is active");
......@@ -538,13 +570,16 @@ public class WarplyManager {
final ExecutorService executorCouponsets = Executors.newFixedThreadPool(1);
JSONArray finalJCouponsetsBody = jCouponsetsBody;
executorCouponsets.submit(() -> {
for (int i = 0; i < finalJCouponsetsBody.length(); ++i) {
Couponset tempCouponset = new Couponset(finalJCouponsetsBody.optJSONObject(i));
mCouponsetList.add(tempCouponset);
try {
for (int i = 0; i < finalJCouponsetsBody.length(); ++i) {
Couponset tempCouponset = new Couponset(finalJCouponsetsBody.optJSONObject(i));
mCouponsetList.add(tempCouponset);
}
future.set(mCouponsetList);
} catch (Exception e) {
future.setException(e);
}
executorCouponsets.shutdownNow();
future.set(mCouponsetList);
});
}
} else {
......@@ -639,13 +674,98 @@ public class WarplyManager {
final ExecutorService executorCouponsets = Executors.newFixedThreadPool(1);
JSONArray finalJMerchantsBody = jMerchantsBody;
executorCouponsets.submit(() -> {
for (int i = 0; i < finalJMerchantsBody.length(); ++i) {
Merchant tempMerchant = new Merchant(finalJMerchantsBody.optJSONObject(i));
mMerchantList.add(tempMerchant);
try {
for (int i = 0; i < finalJMerchantsBody.length(); ++i) {
Merchant tempMerchant = new Merchant(finalJMerchantsBody.optJSONObject(i));
mMerchantList.add(tempMerchant);
}
future.set(mMerchantList);
} catch (Exception e) {
future.setException(e);
}
executorCouponsets.shutdownNow();
});
}
} else {
future.set(new ArrayList<Merchant>());
}
} else if (String.valueOf(response.code()).startsWith("5")) {
future.set(new ArrayList<Merchant>());
} else {
// future.set(new CouponsetsList());
future.setException(new Throwable());
}
}
@Override
public void onFailure(@NonNull Call<ResponseBody> call, @NonNull Throwable t) {
// future.set(new CouponsetsList());
future.setException(new Throwable());
}
});
return future;
}
private static ListenableFuture<ArrayList<Merchant>> getStoresRetro(String merchantUuid, ApiService service/*, Callback<ResponseBody> callback*/) {
SettableFuture<ArrayList<Merchant>> future = SettableFuture.create();
String timeStamp = DateFormat.format("yyyy-MM-dd hh:mm:ss", System.currentTimeMillis()).toString();
String apiKey = WarpUtils.getApiKey(Warply.getWarplyContext());
String webId = WarpUtils.getWebId(Warply.getWarplyContext());
Map<String, Object> jsonParamsMerchants = new ArrayMap<>();
Map<String, Object> jsonParams = new ArrayMap<>();
jsonParams.put("action", "retrieve_stores");
jsonParams.put("language", WarplyProperty.getLanguage(Warply.getWarplyContext()));
if (!TextUtils.isEmpty(merchantUuid)) {
jsonParams.put("merchant_uuid", merchantUuid);
}
jsonParamsMerchants.put("shops", jsonParams);
RequestBody merchantsRequest = RequestBody.create(MediaType.get("application/json; charset=utf-8"), (new JSONObject(jsonParamsMerchants)).toString());
Call<ResponseBody> merchantsCall = service.getStores(
WarplyProperty.getAppUuid(Warply.getWarplyContext()),
merchantsRequest,
timeStamp,
"android:" + Warply.getWarplyContext().getPackageName(),
new WarplyDeviceInfoCollector(Warply.getWarplyContext()).getUniqueDeviceId(),
"mobile",
webId,
WarpUtils.produceSignature(apiKey + timeStamp)
);
merchantsCall.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(@NonNull Call<ResponseBody> call, @NonNull Response<ResponseBody> response) {
if (response.code() == 200 && response.body() != null) {
JSONObject jobjMerchantsResponse = null;
try {
jobjMerchantsResponse = new JSONObject(response.body().string());
} catch (Exception e) {
e.printStackTrace();
}
if (jobjMerchantsResponse != null && jobjMerchantsResponse.has("status") && jobjMerchantsResponse.optString("status", "2").equals("1")) {
JSONArray jMerchantsBody = null;
try {
jMerchantsBody = jobjMerchantsResponse.optJSONObject("context").optJSONObject("MAPP_SHOPS").optJSONArray("result");
} catch (Exception e) {
e.printStackTrace();
}
if (jMerchantsBody != null) {
ArrayList<Merchant> mMerchantList = new ArrayList<Merchant>();
final ExecutorService executorCouponsets = Executors.newFixedThreadPool(1);
JSONArray finalJMerchantsBody = jMerchantsBody;
executorCouponsets.submit(() -> {
try {
for (int i = 0; i < finalJMerchantsBody.length(); ++i) {
Merchant tempMerchant = new Merchant(finalJMerchantsBody.optJSONObject(i));
mMerchantList.add(tempMerchant);
}
future.set(mMerchantList);
} catch (Exception e) {
future.setException(e);
}
executorCouponsets.shutdownNow();
future.set(mMerchantList);
});
}
} else {
......@@ -782,14 +902,16 @@ public class WarplyManager {
final ExecutorService executorCampaigns = Executors.newFixedThreadPool(1);
JSONArray finalCampaignsJBody = jCampaignsBody;
executorCampaigns.submit(() -> {
for (int i = 0; i < finalCampaignsJBody.length(); ++i) {
Campaign camp = new Campaign(finalCampaignsJBody.optJSONObject(i));
mCampaignsList.add(camp);
try {
for (int i = 0; i < finalCampaignsJBody.length(); ++i) {
Campaign camp = new Campaign(finalCampaignsJBody.optJSONObject(i));
mCampaignsList.add(camp);
}
future.set(mCampaignsList);
} catch (Exception e) {
future.setException(e);
}
executorCampaigns.shutdownNow();
// receiver.onSuccess(mCampaignsList);
future.set(mCampaignsList);
});
}
} else {
......@@ -859,14 +981,16 @@ public class WarplyManager {
final ExecutorService executorPersonalizedCampaigns = Executors.newFixedThreadPool(1);
JSONArray finalCampaignsJBody = jCampaignsBody;
executorPersonalizedCampaigns.submit(() -> {
for (int i = 0; i < finalCampaignsJBody.length(); ++i) {
Campaign camp = new Campaign(finalCampaignsJBody.optJSONObject(i));
mCampaignsList.add(camp);
try {
for (int i = 0; i < finalCampaignsJBody.length(); ++i) {
Campaign camp = new Campaign(finalCampaignsJBody.optJSONObject(i));
mCampaignsList.add(camp);
}
future.set(mCampaignsList);
} catch (Exception e) {
future.setException(e);
}
executorPersonalizedCampaigns.shutdownNow();
// receiver.onSuccess(mCampaignsList);
future.set(mCampaignsList);
});
}
} else {
......@@ -977,13 +1101,15 @@ public class WarplyManager {
final ExecutorService executorArticles = Executors.newFixedThreadPool(1);
JSONArray finalArticlesJBody = jArticlesBody;
executorArticles.submit(() -> {
for (int i = 0; i < finalArticlesJBody.length(); ++i) {
mArticlesList.add(new Content(finalArticlesJBody.optJSONObject(i)));
try {
for (int i = 0; i < finalArticlesJBody.length(); ++i) {
mArticlesList.add(new Content(finalArticlesJBody.optJSONObject(i)));
}
future.set(mArticlesList);
} catch (Exception e) {
future.setException(e);
}
executorArticles.shutdownNow();
// receiver.onSuccess(mCampaignsList);
future.set(mArticlesList);
});
}
} else {
......@@ -1053,18 +1179,18 @@ public class WarplyManager {
final ExecutorService executorCoupons = Executors.newFixedThreadPool(1);
JSONArray finalJCouponsBody = jCouponsBody;
executorCoupons.submit(() -> {
for (int i = 0; i < finalJCouponsBody.length(); ++i) {
Coupon tempCoupon = new Coupon(finalJCouponsBody.optJSONObject(i), true);
mCouponList.add(tempCoupon);
try {
for (int i = 0; i < finalJCouponsBody.length(); ++i) {
Coupon tempCoupon = new Coupon(finalJCouponsBody.optJSONObject(i), true);
mCouponList.add(tempCoupon);
}
WarplyManagerHelper.setCoupons(mCouponList);
Collections.sort(mCouponList, (coupon1, coupon2) -> coupon1.getExpirationDate().compareTo(coupon2.getExpirationDate()));
future.set(mCouponList);
} catch (Exception e) {
future.setException(e);
}
WarplyManagerHelper.setCoupons(mCouponList);
Collections.sort(mCouponList, (coupon1, coupon2) -> coupon1.getExpirationDate().compareTo(coupon2.getExpirationDate()));
executorCoupons.shutdownNow();
future.set(mCouponList);
});
} else {
future.set(new ArrayList<Coupon>());
......
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white">
<LinearLayout
android:id="@+id/header_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="@color/white"
android:baselineAligned="false"
android:orientation="horizontal"
android:padding="16dp">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_vertical"
android:orientation="horizontal">
<ImageView
android:id="@+id/iv_back"
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_marginEnd="24dp"
android:src="@drawable/ic_back" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/header_layout2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/header_layout"
android:background="@color/white"
android:orientation="vertical"
android:paddingHorizontal="16dp"
android:paddingBottom="16dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/tv_header_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:includeFontPadding="false"
android:text="@string/demo_partners_title"
android:textColor="@color/custom_black6"
android:textSize="28sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/ll_search_filter_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:background="@drawable/shape_rectangle_rounded_grey4"
android:gravity="center"
android:paddingHorizontal="20dp"
android:paddingVertical="12dp">
<TextView
android:id="@+id/tv_search_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:includeFontPadding="false"
android:text="@string/demo_search_title"
android:textColor="@color/custom_black6"
android:textSize="14sp" />
<View
android:layout_width="12dp"
android:layout_height="match_parent" />
<ImageView
android:layout_width="16dp"
android:layout_height="16dp"
android:src="@drawable/demo_filter" />
</LinearLayout>
</LinearLayout>
<RelativeLayout
android:id="@+id/cl_loyalty_info_view_inner"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/header_layout2">
<fragment
android:id="@+id/mv_shops"
class="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
</RelativeLayout>
\ No newline at end of file
......@@ -22,12 +22,6 @@
android:layout_height="260dp"
android:background="@color/custom_skyblue3">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="coupon_code_content" />
<ImageView
android:id="@+id/iv_coupon_image"
android:layout_width="match_parent"
......@@ -254,6 +248,7 @@
</androidx.constraintlayout.widget.ConstraintLayout>
<LinearLayout
android:id="@+id/ll_shops"
android:layout_width="match_parent"
android:layout_height="55dp"
android:layout_marginTop="32dp"
......
<resources>
<string name="google_maps_key">AIzaSyB-K6OiUDT_X0zp2jYjqHg54ThxEuZtr9I</string>
<string name="webview_permission_title">Demo App</string>
<string name="webview_permission_message">Το Demo App ζητάει πρόσβαση στην τοποθεσία σας.</string>
<string name="lbl_ok">Οκ</string>
<string name="lbl_ok">ΟΚ</string>
<string name="lbl_cancel">Άκυρο</string>
<string name="lbl_stores">Καταστήματα συνεργάτη</string>
<string name="lbl_no_shops">Δεν υπάρχουν καταστήματα συνεργάτη.</string>
<string name="welcome_user">User</string>
<string name="menu_home">Αρχική</string>
<string name="demo_home">Αρχική οθόνη</string>
......@@ -36,4 +39,6 @@
<string name="demo_my_coupons_title">My coupons</string>
<string name="demo_my_coupons_header">My Coupons</string>
<string name="demo_coupon_expired">Expired</string>
<string name="demo_partners_title">Partner businesses</string>
<string name="demo_search_title">Αναζήτηση</string>
</resources>
......