Panagiotis Triantafyllou

added map

...@@ -26,6 +26,10 @@ ...@@ -26,6 +26,10 @@
26 android:requestLegacyExternalStorage="true" 26 android:requestLegacyExternalStorage="true"
27 android:theme="@style/AppTheme"> 27 android:theme="@style/AppTheme">
28 28
29 + <meta-data
30 + android:name="com.google.android.geo.API_KEY"
31 + android:value="@string/google_maps_key" />
32 +
29 <activity 33 <activity
30 android:name="warp.ly.android_sdk.activities.SplashActivity" 34 android:name="warp.ly.android_sdk.activities.SplashActivity"
31 android:exported="true" 35 android:exported="true"
......
...@@ -81,6 +81,8 @@ dependencies { ...@@ -81,6 +81,8 @@ dependencies {
81 //------------------------------ GMS -----------------------------// 81 //------------------------------ GMS -----------------------------//
82 implementation 'com.google.android.gms:play-services-base:18.7.2' 82 implementation 'com.google.android.gms:play-services-base:18.7.2'
83 implementation 'com.google.android.gms:play-services-location:21.3.0' 83 implementation 'com.google.android.gms:play-services-location:21.3.0'
84 + implementation 'com.google.android.gms:play-services-maps:18.2.0'
85 + implementation 'com.google.maps.android:android-maps-utils:0.5'
84 86
85 //------------------------------ Work Manager -----------------------------// 87 //------------------------------ Work Manager -----------------------------//
86 implementation 'androidx.work:work-runtime:2.10.3' 88 implementation 'androidx.work:work-runtime:2.10.3'
......
...@@ -63,6 +63,12 @@ ...@@ -63,6 +63,12 @@
63 android:theme="@style/SDKAppTheme" /> 63 android:theme="@style/SDKAppTheme" />
64 64
65 <activity 65 <activity
66 + android:name=".activities.ShopsActivity"
67 + android:exported="false"
68 + android:screenOrientation="portrait"
69 + android:theme="@style/SDKAppTheme" />
70 +
71 + <activity
66 android:name=".dexter.PermissionsActivity" 72 android:name=".dexter.PermissionsActivity"
67 android:exported="false" 73 android:exported="false"
68 android:launchMode="singleInstance" 74 android:launchMode="singleInstance"
......
1 +package ly.warp.sdk.activities;
2 +
3 +import static ly.warp.sdk.activities.SingleCouponActivity.EXTRA_MERCHANT_UUID;
4 +
5 +import android.Manifest;
6 +import android.content.ActivityNotFoundException;
7 +import android.content.Intent;
8 +import android.content.pm.PackageManager;
9 +import android.graphics.Bitmap;
10 +import android.graphics.Canvas;
11 +import android.graphics.drawable.Drawable;
12 +import android.net.Uri;
13 +import android.os.Bundle;
14 +import android.text.TextUtils;
15 +import android.util.Log;
16 +import android.view.View;
17 +import android.widget.ImageView;
18 +import android.widget.LinearLayout;
19 +import android.widget.TextView;
20 +import android.widget.Toast;
21 +
22 +import androidx.annotation.NonNull;
23 +import androidx.annotation.Nullable;
24 +import androidx.appcompat.app.AlertDialog;
25 +import androidx.core.app.ActivityCompat;
26 +import androidx.core.content.ContextCompat;
27 +import androidx.fragment.app.FragmentActivity;
28 +
29 +import com.bumptech.glide.Glide;
30 +import com.bumptech.glide.load.engine.DiskCacheStrategy;
31 +import com.bumptech.glide.request.target.CustomTarget;
32 +import com.bumptech.glide.request.transition.Transition;
33 +import com.google.android.gms.maps.CameraUpdate;
34 +import com.google.android.gms.maps.CameraUpdateFactory;
35 +import com.google.android.gms.maps.GoogleMap;
36 +import com.google.android.gms.maps.OnMapReadyCallback;
37 +import com.google.android.gms.maps.SupportMapFragment;
38 +import com.google.android.gms.maps.model.BitmapDescriptorFactory;
39 +import com.google.android.gms.maps.model.LatLng;
40 +import com.google.android.gms.maps.model.Marker;
41 +import com.google.android.gms.maps.model.MarkerOptions;
42 +import com.google.android.material.bottomsheet.BottomSheetDialog;
43 +import com.google.maps.android.clustering.Cluster;
44 +import com.google.maps.android.clustering.ClusterManager;
45 +
46 +import java.util.ArrayList;
47 +
48 +import ly.warp.sdk.R;
49 +import ly.warp.sdk.io.callbacks.CallbackReceiver;
50 +import ly.warp.sdk.io.models.Coupon;
51 +import ly.warp.sdk.io.models.Merchant;
52 +import ly.warp.sdk.utils.WarpUtils;
53 +import ly.warp.sdk.utils.WarplyManagerHelper;
54 +import ly.warp.sdk.utils.WarplyProperty;
55 +import ly.warp.sdk.utils.constants.WarpConstants;
56 +import ly.warp.sdk.utils.managers.WarplyAnalyticsManager;
57 +import ly.warp.sdk.utils.managers.WarplyManager;
58 +
59 +public class ShopsActivity extends FragmentActivity implements View.OnClickListener,
60 + OnMapReadyCallback, GoogleMap.OnMapLoadedCallback, ClusterManager.OnClusterClickListener<Merchant>,
61 + GoogleMap.OnMarkerClickListener {
62 +
63 + // ===========================================================
64 + // Constants
65 + // ===========================================================
66 +
67 + public final static float DEFAULT_LOCATION_ZOOM = 6.2f;
68 +
69 + // ===========================================================
70 + // Fields
71 + // ===========================================================
72 +
73 + private ImageView mIvBack;
74 + private Coupon mCoupon;
75 + private GoogleMap mMap;
76 + private ClusterManager<Merchant> mClusterManager;
77 + private SupportMapFragment mMapView;
78 + private AlertDialog mAlertDialogNoShopsAvailable;
79 + private Merchant mMerchant, mMerchantParent;
80 + private ArrayList<Merchant> mMerchantList = new ArrayList<>();
81 + private String mMerchantUuid = "";
82 + private TextView mTvHeaderTitle, mTvSearchTitle;
83 +
84 + // ===========================================================
85 + // Methods for/from SuperClass/Interfaces
86 + // ===========================================================
87 +
88 + @Override
89 + public void onCreate(Bundle savedInstanceState) {
90 + super.onCreate(savedInstanceState);
91 + setContentView(R.layout.activity_shops);
92 +
93 + initViews();
94 +
95 + mMapView = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.mv_shops);
96 + mMapView.getMapAsync(this);
97 + mIvBack.setOnClickListener(this);
98 + }
99 +
100 + @Override
101 + public void onResume() {
102 + super.onResume();
103 + }
104 +
105 + @Override
106 + public void onClick(View view) {
107 + if (view.getId() == R.id.iv_back) {
108 + onBackPressed();
109 + }
110 + }
111 +
112 + // @Override
113 +// public void onRequestPermissionsResult(
114 +// int requestCode,
115 +// String permissions[],
116 +// int[] grantResults) {
117 +// switch (requestCode) {
118 +// case REQUEST_PERMISSION_PHONE_STATE:
119 +// if (grantResults.length > 0
120 +// && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
121 +// Toast.makeText(MainActivity.this, "Permission Granted!", Toast.LENGTH_SHORT).show();
122 +// } else {
123 +// Toast.makeText(MainActivity.this, "Permission Denied!", Toast.LENGTH_SHORT).show();
124 +// }
125 +// }
126 +// }
127 +
128 + @Override
129 + public void onMapReady(@NonNull GoogleMap googleMap) {
130 + mMap = googleMap;
131 + if (ActivityCompat.checkSelfPermission(this,
132 + Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
133 + && ActivityCompat.checkSelfPermission(this,
134 + Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
135 + if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
136 + mMap.setMyLocationEnabled(true);
137 + }
138 + } else {
139 + mMap.setMyLocationEnabled(false);
140 +// ActivityCompat.requestPermissions(this,
141 +// new String[]{Manifest.permission.ACCESS_FINE_LOCATION,
142 +// Manifest.permission.ACCESS_COARSE_LOCATION}, 501);
143 + }
144 + mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
145 + mMap.setMinZoomPreference(DEFAULT_LOCATION_ZOOM);
146 + mMap.setLatLngBoundsForCameraTarget(WarpConstants.GREECE_BOUNDS);
147 + mMap.getUiSettings().setZoomControlsEnabled(true);
148 + mMap.getUiSettings().setZoomGesturesEnabled(true);
149 + mMap.getUiSettings().setCompassEnabled(false);
150 + mMap.getUiSettings().setMyLocationButtonEnabled(false);
151 + mMap.getUiSettings().setMapToolbarEnabled(false);
152 + mMap.getUiSettings().setTiltGesturesEnabled(false);
153 + mMap.getUiSettings().setRotateGesturesEnabled(false);
154 + mMap.setOnMapLoadedCallback(this);
155 + mMap.setOnMarkerClickListener(/*mClusterManager*/this);
156 + }
157 +
158 + @Override
159 + public void onMapLoaded() {
160 + if (mMap != null) {
161 + CameraUpdate camUpdate;
162 + camUpdate = CameraUpdateFactory.newLatLngBounds(WarpConstants.GREECE_BOUNDS, 48);
163 + mMap.animateCamera(camUpdate);
164 + }
165 +// if (mClusterManager == null) {
166 +// mClusterManager = new ClusterManager<>(this, mMap);
167 +// mClusterManager.setOnClusterClickListener(this);
168 +//// mMap.setOnMarkerClickListener(/*mClusterManager*/this);
169 +// }
170 +
171 + if (!TextUtils.isEmpty(mMerchantUuid)) {
172 + WarplyManager.getStores("86eba6980cf746cbbcca5c6446700121", mStoresCallback);
173 + }
174 + }
175 +
176 + @Override
177 + public boolean onClusterClick(Cluster<Merchant> cluster) {
178 + if (mMap != null) {
179 + mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(cluster.getPosition(),
180 + (float) Math.floor(mMap.getCameraPosition().zoom + 1)), 300, null);
181 +// mMap.clear();
182 +// mClusterManager.clearItems();
183 +// mClusterManager.addItems(cluster.getItems());
184 +// mClusterManager.cluster();
185 + }
186 + return true;
187 + }
188 +
189 + @Override
190 + public boolean onMarkerClick(@NonNull Marker marker) {
191 +// for (Merchant merch : mMerchantList) {
192 +// if (merch.getUuid().equals(marker.getSnippet())) {
193 +// final BottomSheetDialog bottomSheetDialog = new BottomSheetDialog(this, R.style.BottomSheetDialog);
194 +// bottomSheetDialog.setContentView(R.layout.dl_map_pin);
195 +// ImageView dialogClose = (ImageView) bottomSheetDialog.findViewById(R.id.iv_map_pin_close);
196 +// dialogClose.setOnClickListener(view -> bottomSheetDialog.dismiss());
197 +// TextView pinTitle = (TextView) bottomSheetDialog.findViewById(R.id.tv_pin_title);
198 +// WarpUtils.renderCustomFont(ShopsActivity.this, R.font.pf_square_sans_pro_bold, pinTitle);
199 +// if (mMerchantParentList != null && mMerchantParentList.size() > 0) {
200 +// for (Merchant parentMerch : mMerchantParentList) {
201 +// if (parentMerch.getUuid().equals(merch.getParent())) {
202 +// pinTitle.setText(parentMerch.getAdminName());
203 +// break;
204 +// }
205 +// }
206 +// }
207 +// ImageView pinLogo = (ImageView) bottomSheetDialog.findViewById(R.id.iv_pin_logo);
208 +// if (!TextUtils.isEmpty(merch.getImgPreview())) {
209 +// Glide.with(this)
210 +//// .setDefaultRequestOptions(
211 +//// RequestOptions
212 +//// .placeholderOf(R.drawable.ic_default_contact_photo)
213 +//// .error(R.drawable.ic_default_contact_photo))
214 +// .load(merch.getImgPreview())
215 +// .diskCacheStrategy(DiskCacheStrategy.DATA)
216 +// .into(pinLogo);
217 +// }
218 +// TextView pinName = (TextView) bottomSheetDialog.findViewById(R.id.tv_pin_name);
219 +// WarpUtils.renderCustomFont(ShopsActivity.this, R.font.pf_square_sans_pro_medium, pinName);
220 +// pinName.setText(merch.getName());
221 +// TextView pinDays = (TextView) bottomSheetDialog.findViewById(R.id.tv_pin_days);
222 +// WarpUtils.renderCustomFont(ShopsActivity.this, R.font.pf_square_sans_pro_regular, pinDays);
223 +// pinDays.setText(merch.getSnippet()); //TODO: wrong getter
224 +// TextView pinTel = (TextView) bottomSheetDialog.findViewById(R.id.tv_pin_tel);
225 +// WarpUtils.renderCustomFont(ShopsActivity.this, R.font.pf_square_sans_pro_medium, pinTel);
226 +// pinTel.setText(merch.getTelephone());
227 +// TextView pinAddress = (TextView) bottomSheetDialog.findViewById(R.id.tv_pin_address);
228 +// WarpUtils.renderCustomFont(ShopsActivity.this, R.font.pf_square_sans_pro_medium, pinAddress);
229 +// pinAddress.setText(merch.getAddress());
230 +// TextView pinDirectionsText = (TextView) bottomSheetDialog.findViewById(R.id.tv_directions);
231 +// WarpUtils.renderCustomFont(ShopsActivity.this, R.font.pf_square_sans_pro_medium, pinDirectionsText);
232 +// LinearLayout pinDirections = (LinearLayout) bottomSheetDialog.findViewById(R.id.ll_directions);
233 +// pinDirections.setOnClickListener(view -> {
234 +// Uri gmmIntentUri = Uri.parse("google.navigation:q=" + merch.getLatitude() + "," + merch.getLongitude()/* + "&mode=w"*/);
235 +// Intent mapIntent = new Intent(Intent.ACTION_VIEW, gmmIntentUri);
236 +// mapIntent.setPackage("com.google.android.apps.maps");
237 +// startActivity(mapIntent);
238 +// });
239 +// bottomSheetDialog.show();
240 +// return false;
241 +// }
242 +// }
243 + return false;
244 + }
245 +
246 + // ===========================================================
247 + // Methods
248 + // ===========================================================
249 +
250 + private void initViews() {
251 + mMerchantUuid = getIntent().getStringExtra(EXTRA_MERCHANT_UUID);
252 +
253 + mIvBack = findViewById(R.id.iv_back);
254 + mTvHeaderTitle = findViewById(R.id.tv_header_title);
255 + mTvSearchTitle = findViewById(R.id.tv_search_title);
256 +
257 + WarpUtils.renderCustomFont(this, R.font.ping_lcg_bold, mTvHeaderTitle);
258 + WarpUtils.renderCustomFont(this, R.font.ping_lcg_regular, mTvSearchTitle);
259 + }
260 +
261 + private Bitmap overlayBitmaps(Bitmap staticImage, Bitmap poiImage, int poiImageWidth, int poiImageHeight, float scale) {
262 + // Resize the POI image
263 + Bitmap resizedPoiImage;
264 + int poiImageWidthScale = 0;
265 + int poiImageHeightScale = 0;
266 + if (scale == 0)
267 + resizedPoiImage = Bitmap.createScaledBitmap(poiImage, poiImageWidth, poiImageHeight, false);
268 + else {
269 + // Calculate the new dimensions for the POI image
270 + poiImageWidthScale = (int) (poiImage.getWidth() * scale);
271 + poiImageHeightScale = (int) (poiImage.getHeight() * scale);
272 + resizedPoiImage = Bitmap.createScaledBitmap(poiImage, poiImageWidthScale, poiImageHeightScale, false);
273 + }
274 + // Create a new bitmap with the same size as the static image
275 + Bitmap combinedBitmap = Bitmap.createBitmap(staticImage.getWidth(), staticImage.getHeight(), staticImage.getConfig());
276 + Canvas canvas = new Canvas(combinedBitmap);
277 + // Draw the static image on the canvas
278 + canvas.drawBitmap(staticImage, 0, 0, null);
279 + // Calculate the position to center the resized POI image on the static image
280 + int left = (staticImage.getWidth() - resizedPoiImage.getWidth()) / 2;
281 + int top = (staticImage.getHeight() - resizedPoiImage.getHeight()) / 3;
282 + // Draw the resized POI image on the canvas
283 + canvas.drawBitmap(resizedPoiImage, left, top, null);
284 + return combinedBitmap;
285 + }
286 +
287 + private void showNoShopsAvailableDialog() {
288 + if (!isFinishing()) {
289 + mAlertDialogNoShopsAvailable = new AlertDialog.Builder(this)
290 + .setTitle(R.string.lbl_stores)
291 + .setMessage(R.string.lbl_no_shops)
292 + .setCancelable(false)
293 + .setPositiveButton(R.string.lbl_ok, (dialogPositive, whichPositive) -> {
294 + dialogPositive.dismiss();
295 + })
296 + .show();
297 + }
298 + }
299 +
300 + // ===========================================================
301 + // Inner and Anonymous Classes
302 + // ===========================================================
303 +
304 + private final CallbackReceiver<ArrayList<Merchant>> mStoresCallback = new CallbackReceiver<ArrayList<Merchant>>() {
305 + @Override
306 + public void onSuccess(ArrayList<Merchant> result) {
307 + if (result.isEmpty()) {
308 + showNoShopsAvailableDialog();
309 + return;
310 + }
311 +
312 + mMerchantList.clear();
313 + mMerchantList.addAll(result);
314 +
315 + for (Merchant merch : result) {
316 + if (merch.getLatitude() == null || merch.getLongitude() == null) continue;
317 +
318 + Glide.with(ShopsActivity.this)
319 + .asBitmap()
320 + .load(R.drawable.demo_map_pin)
321 + .into(new CustomTarget<Bitmap>() {
322 + @Override
323 + public void onResourceReady(@NonNull Bitmap staticImage, @Nullable Transition<? super Bitmap> transition) {
324 + if (!TextUtils.isEmpty(merch.getImgPreview())) {
325 + Glide.with(ShopsActivity.this)
326 + .asBitmap()
327 + .load(merch.getImgPreview())
328 + .diskCacheStrategy(DiskCacheStrategy.DATA)
329 + .into(new CustomTarget<Bitmap>() {
330 + @Override
331 + public void onResourceReady(@NonNull Bitmap poiImage, @Nullable Transition<? super Bitmap> transition) {
332 + Bitmap combinedBitmap = overlayBitmaps(staticImage, poiImage, 48, 48, 0);
333 + if (mMap != null) {
334 + mMap.addMarker(new MarkerOptions()
335 + .position(new LatLng(merch.getLatitude(), merch.getLongitude()))
336 + .icon(BitmapDescriptorFactory.fromBitmap(combinedBitmap))
337 + .anchor(0.5f, 1.0f)
338 + .snippet(merch.getUuid()));
339 + }
340 + }
341 +
342 + @Override
343 + public void onLoadCleared(@Nullable Drawable placeholder) {
344 + if (mMap != null) {
345 + mMap.addMarker(new MarkerOptions()
346 + .position(new LatLng(merch.getLatitude(), merch.getLongitude()))
347 + .icon(BitmapDescriptorFactory.fromBitmap(staticImage))
348 + .anchor(0.5f, 1.0f)
349 + .snippet(merch.getUuid()));
350 + }
351 + }
352 +
353 + @Override
354 + public void onLoadFailed(@Nullable Drawable errorDrawable) {
355 + if (mMap != null) {
356 + mMap.addMarker(new MarkerOptions()
357 + .position(new LatLng(merch.getLatitude(), merch.getLongitude()))
358 + .icon(BitmapDescriptorFactory.fromBitmap(staticImage))
359 + .anchor(0.5f, 1.0f)
360 + .snippet(merch.getUuid()));
361 + }
362 + }
363 + });
364 + } else {
365 + if (mMap != null) {
366 + mMap.addMarker(new MarkerOptions()
367 + .position(new LatLng(merch.getLatitude(), merch.getLongitude()))
368 + .icon(BitmapDescriptorFactory.fromBitmap(staticImage))
369 + .anchor(0.5f, 1.0f)
370 + .snippet(merch.getUuid()));
371 + }
372 + }
373 + }
374 +
375 + @Override
376 + public void onLoadCleared(@Nullable Drawable placeholder) {
377 + if (mMap != null) {
378 + mMap.addMarker(new MarkerOptions()
379 + .position(new LatLng(merch.getLatitude(), merch.getLongitude()))
380 + .anchor(0.5f, 1.0f)
381 + .snippet(merch.getUuid()));
382 + }
383 + }
384 + });
385 + }
386 + }
387 +
388 + @Override
389 + public void onFailure(int errorCode) {
390 + Toast.makeText(ShopsActivity.this, "STORES ERROR", Toast.LENGTH_SHORT).show();
391 + }
392 + };
393 +}
...\ No newline at end of file ...\ No newline at end of file
...@@ -34,6 +34,7 @@ public class SingleCouponActivity extends Activity implements View.OnClickListen ...@@ -34,6 +34,7 @@ public class SingleCouponActivity extends Activity implements View.OnClickListen
34 // Constants 34 // Constants
35 // =========================================================== 35 // ===========================================================
36 public static final String EXTRA_OFFER_ITEM = "coupon_item"; 36 public static final String EXTRA_OFFER_ITEM = "coupon_item";
37 + public static final String EXTRA_MERCHANT_UUID = "merchant_uuid";
37 38
38 // =========================================================== 39 // ===========================================================
39 // Fields 40 // Fields
...@@ -44,7 +45,7 @@ public class SingleCouponActivity extends Activity implements View.OnClickListen ...@@ -44,7 +45,7 @@ public class SingleCouponActivity extends Activity implements View.OnClickListen
44 private TextView mTvSmallDescription; 45 private TextView mTvSmallDescription;
45 private TextView mTvFullDescription; 46 private TextView mTvFullDescription;
46 private TextView mTvEndDate; 47 private TextView mTvEndDate;
47 - private LinearLayout mLlDate; 48 + private LinearLayout mLlDate, mLlShopsButton;
48 private TextView mTvValue; 49 private TextView mTvValue;
49 private TextView mTvMoreButton; 50 private TextView mTvMoreButton;
50 private ImageView mIvImage; 51 private ImageView mIvImage;
...@@ -96,6 +97,19 @@ public class SingleCouponActivity extends Activity implements View.OnClickListen ...@@ -96,6 +97,19 @@ public class SingleCouponActivity extends Activity implements View.OnClickListen
96 super.onResume(); 97 super.onResume();
97 } 98 }
98 99
100 + @Override
101 + public void onClick(View v) {
102 + if (v.getId() == R.id.iv_back) {
103 + onBackPressed();
104 + return;
105 + }
106 + if (v.getId() == R.id.ll_shops) {
107 + Intent myIntent = new Intent(SingleCouponActivity.this, ShopsActivity.class);
108 + myIntent.putExtra(SingleCouponActivity.EXTRA_MERCHANT_UUID, mOfferItem.getMerchantUuid());
109 + startActivity(myIntent);
110 + }
111 + }
112 +
99 // =========================================================== 113 // ===========================================================
100 // Methods 114 // Methods
101 // =========================================================== 115 // ===========================================================
...@@ -104,6 +118,9 @@ public class SingleCouponActivity extends Activity implements View.OnClickListen ...@@ -104,6 +118,9 @@ public class SingleCouponActivity extends Activity implements View.OnClickListen
104 mIvBack = findViewById(R.id.iv_back); 118 mIvBack = findViewById(R.id.iv_back);
105 mIvBack.setOnClickListener(this); 119 mIvBack.setOnClickListener(this);
106 120
121 + mLlShopsButton = findViewById(R.id.ll_shops);
122 + mLlShopsButton.setOnClickListener(this);
123 +
107 // Initialize views 124 // Initialize views
108 mTvSmallDescription = findViewById(R.id.tv_coupon_small_description); 125 mTvSmallDescription = findViewById(R.id.tv_coupon_small_description);
109 mTvFullDescription = findViewById(R.id.tv_coupon_full_description); 126 mTvFullDescription = findViewById(R.id.tv_coupon_full_description);
...@@ -336,13 +353,6 @@ public class SingleCouponActivity extends Activity implements View.OnClickListen ...@@ -336,13 +353,6 @@ public class SingleCouponActivity extends Activity implements View.OnClickListen
336 } 353 }
337 } 354 }
338 355
339 - @Override
340 - public void onClick(View v) {
341 - if (v.getId() == R.id.iv_back) {
342 - onBackPressed();
343 - }
344 - }
345 -
346 // =========================================================== 356 // ===========================================================
347 // Inner and Anonymous Classes 357 // Inner and Anonymous Classes
348 // =========================================================== 358 // ===========================================================
......
...@@ -28,6 +28,9 @@ package ly.warp.sdk.io.models; ...@@ -28,6 +28,9 @@ package ly.warp.sdk.io.models;
28 import android.os.Parcel; 28 import android.os.Parcel;
29 import android.os.Parcelable; 29 import android.os.Parcelable;
30 30
31 +import com.google.android.gms.maps.model.LatLng;
32 +import com.google.maps.android.clustering.ClusterItem;
33 +
31 import org.json.JSONArray; 34 import org.json.JSONArray;
32 import org.json.JSONException; 35 import org.json.JSONException;
33 import org.json.JSONObject; 36 import org.json.JSONObject;
...@@ -42,7 +45,7 @@ import ly.warp.sdk.utils.constants.WarpConstants; ...@@ -42,7 +45,7 @@ import ly.warp.sdk.utils.constants.WarpConstants;
42 * Created by Panagiotis Triantafyllou on 07-Dec-21. 45 * Created by Panagiotis Triantafyllou on 07-Dec-21.
43 */ 46 */
44 47
45 -public class Merchant implements Parcelable, Serializable { 48 +public class Merchant implements Parcelable, Serializable, ClusterItem {
46 49
47 private static final long serialVersionUID = -4754964462459705285L; 50 private static final long serialVersionUID = -4754964462459705285L;
48 51
...@@ -73,6 +76,7 @@ public class Merchant implements Parcelable, Serializable { ...@@ -73,6 +76,7 @@ public class Merchant implements Parcelable, Serializable {
73 private static final String CATEGORY_UUID = "category_uuid"; 76 private static final String CATEGORY_UUID = "category_uuid";
74 private static final String CREATED = "created"; 77 private static final String CREATED = "created";
75 private static final String PARENT = "parent"; 78 private static final String PARENT = "parent";
79 + private static final String PARENT_UUID = "parent_uuid";
76 private static final String IMG = "img"; 80 private static final String IMG = "img";
77 private static final String IMG_PREVIEW = "img_preview"; 81 private static final String IMG_PREVIEW = "img_preview";
78 private static final String ADMIN_NAME = "admin_name"; 82 private static final String ADMIN_NAME = "admin_name";
...@@ -125,6 +129,7 @@ public class Merchant implements Parcelable, Serializable { ...@@ -125,6 +129,7 @@ public class Merchant implements Parcelable, Serializable {
125 private String category_uuid; 129 private String category_uuid;
126 private String created; 130 private String created;
127 private String parent; 131 private String parent;
132 + private String parentUuid;
128 private JSONArray img; 133 private JSONArray img;
129 private String img_preview; 134 private String img_preview;
130 private String admin_name; 135 private String admin_name;
...@@ -149,6 +154,7 @@ public class Merchant implements Parcelable, Serializable { ...@@ -149,6 +154,7 @@ public class Merchant implements Parcelable, Serializable {
149 private String minPrice; 154 private String minPrice;
150 private String maxPrice; 155 private String maxPrice;
151 private String urlName; 156 private String urlName;
157 + private LatLng coordinates;
152 158
153 /** 159 /**
154 * Helper method to get a nullable String from a JSONObject. 160 * Helper method to get a nullable String from a JSONObject.
...@@ -184,6 +190,7 @@ public class Merchant implements Parcelable, Serializable { ...@@ -184,6 +190,7 @@ public class Merchant implements Parcelable, Serializable {
184 this.category_uuid = null; 190 this.category_uuid = null;
185 this.created = null; 191 this.created = null;
186 this.parent = null; 192 this.parent = null;
193 + this.parentUuid = null;
187 this.img = null; 194 this.img = null;
188 this.img_preview = null; 195 this.img_preview = null;
189 this.admin_name = null; 196 this.admin_name = null;
...@@ -208,6 +215,9 @@ public class Merchant implements Parcelable, Serializable { ...@@ -208,6 +215,9 @@ public class Merchant implements Parcelable, Serializable {
208 this.minPrice = null; 215 this.minPrice = null;
209 this.maxPrice = null; 216 this.maxPrice = null;
210 this.urlName = null; 217 this.urlName = null;
218 + this.coordinates = new LatLng(
219 + this.latitude != null ? this.latitude : 0.0,
220 + this.longitude != null ? this.longitude : 0.0);
211 } 221 }
212 222
213 public Merchant(boolean isUniversal) { 223 public Merchant(boolean isUniversal) {
...@@ -269,6 +279,7 @@ public class Merchant implements Parcelable, Serializable { ...@@ -269,6 +279,7 @@ public class Merchant implements Parcelable, Serializable {
269 this.category_uuid = optNullableString(json, CATEGORY_UUID); 279 this.category_uuid = optNullableString(json, CATEGORY_UUID);
270 this.created = optNullableString(json, CREATED); 280 this.created = optNullableString(json, CREATED);
271 this.parent = optNullableString(json, PARENT); 281 this.parent = optNullableString(json, PARENT);
282 + this.parentUuid = optNullableString(json, PARENT_UUID);
272 this.img = json.optJSONArray(IMG); 283 this.img = json.optJSONArray(IMG);
273 this.img_preview = optNullableString(json, IMG_PREVIEW); 284 this.img_preview = optNullableString(json, IMG_PREVIEW);
274 this.admin_name = optNullableString(json, ADMIN_NAME); 285 this.admin_name = optNullableString(json, ADMIN_NAME);
...@@ -293,6 +304,9 @@ public class Merchant implements Parcelable, Serializable { ...@@ -293,6 +304,9 @@ public class Merchant implements Parcelable, Serializable {
293 this.minPrice = optNullableString(json, MIN_PRICE); 304 this.minPrice = optNullableString(json, MIN_PRICE);
294 this.maxPrice = optNullableString(json, MAX_PRICE); 305 this.maxPrice = optNullableString(json, MAX_PRICE);
295 this.urlName = optNullableString(json, URL_NAME); 306 this.urlName = optNullableString(json, URL_NAME);
307 + this.coordinates = new LatLng(
308 + this.latitude != null ? this.latitude : 0.0,
309 + this.longitude != null ? this.longitude : 0.0);
296 } 310 }
297 } 311 }
298 312
...@@ -347,6 +361,7 @@ public class Merchant implements Parcelable, Serializable { ...@@ -347,6 +361,7 @@ public class Merchant implements Parcelable, Serializable {
347 this.category_uuid = source.readString(); 361 this.category_uuid = source.readString();
348 this.created = source.readString(); 362 this.created = source.readString();
349 this.parent = source.readString(); 363 this.parent = source.readString();
364 + this.parentUuid = source.readString();
350 try { 365 try {
351 String imgStr = source.readString(); 366 String imgStr = source.readString();
352 this.img = imgStr != null ? new JSONArray(imgStr) : null; 367 this.img = imgStr != null ? new JSONArray(imgStr) : null;
...@@ -393,6 +408,9 @@ public class Merchant implements Parcelable, Serializable { ...@@ -393,6 +408,9 @@ public class Merchant implements Parcelable, Serializable {
393 this.minPrice = source.readString(); 408 this.minPrice = source.readString();
394 this.maxPrice = source.readString(); 409 this.maxPrice = source.readString();
395 this.urlName = source.readString(); 410 this.urlName = source.readString();
411 + this.coordinates = new LatLng(
412 + this.latitude != null ? this.latitude : 0.0,
413 + this.longitude != null ? this.longitude : 0.0);
396 } 414 }
397 415
398 @Override 416 @Override
...@@ -422,6 +440,7 @@ public class Merchant implements Parcelable, Serializable { ...@@ -422,6 +440,7 @@ public class Merchant implements Parcelable, Serializable {
422 dest.writeString(this.category_uuid); 440 dest.writeString(this.category_uuid);
423 dest.writeString(this.created); 441 dest.writeString(this.created);
424 dest.writeString(this.parent); 442 dest.writeString(this.parent);
443 + dest.writeString(this.parentUuid);
425 dest.writeString(this.img != null ? this.img.toString() : null); 444 dest.writeString(this.img != null ? this.img.toString() : null);
426 dest.writeString(this.img_preview); 445 dest.writeString(this.img_preview);
427 dest.writeString(this.admin_name); 446 dest.writeString(this.admin_name);
...@@ -446,6 +465,7 @@ public class Merchant implements Parcelable, Serializable { ...@@ -446,6 +465,7 @@ public class Merchant implements Parcelable, Serializable {
446 dest.writeString(this.minPrice); 465 dest.writeString(this.minPrice);
447 dest.writeString(this.maxPrice); 466 dest.writeString(this.maxPrice);
448 dest.writeString(this.urlName); 467 dest.writeString(this.urlName);
468 + dest.writeParcelable(coordinates, flags);
449 } 469 }
450 470
451 /** 471 /**
...@@ -481,6 +501,7 @@ public class Merchant implements Parcelable, Serializable { ...@@ -481,6 +501,7 @@ public class Merchant implements Parcelable, Serializable {
481 jObj.put(CATEGORY_UUID, this.category_uuid != null ? this.category_uuid : JSONObject.NULL); 501 jObj.put(CATEGORY_UUID, this.category_uuid != null ? this.category_uuid : JSONObject.NULL);
482 jObj.put(CREATED, this.created != null ? this.created : JSONObject.NULL); 502 jObj.put(CREATED, this.created != null ? this.created : JSONObject.NULL);
483 jObj.put(PARENT, this.parent != null ? this.parent : JSONObject.NULL); 503 jObj.put(PARENT, this.parent != null ? this.parent : JSONObject.NULL);
504 + jObj.put(PARENT_UUID, this.parentUuid != null ? this.parentUuid : JSONObject.NULL);
484 jObj.put(IMG, this.img != null ? this.img : JSONObject.NULL); 505 jObj.put(IMG, this.img != null ? this.img : JSONObject.NULL);
485 jObj.put(IMG_PREVIEW, this.img_preview != null ? this.img_preview : JSONObject.NULL); 506 jObj.put(IMG_PREVIEW, this.img_preview != null ? this.img_preview : JSONObject.NULL);
486 jObj.put(ADMIN_NAME, this.admin_name != null ? this.admin_name : JSONObject.NULL); 507 jObj.put(ADMIN_NAME, this.admin_name != null ? this.admin_name : JSONObject.NULL);
...@@ -661,6 +682,10 @@ public class Merchant implements Parcelable, Serializable { ...@@ -661,6 +682,10 @@ public class Merchant implements Parcelable, Serializable {
661 return parent; 682 return parent;
662 } 683 }
663 684
685 + public String getParentUuid() {
686 + return parentUuid;
687 + }
688 +
664 public ArrayList<String> getImg() { 689 public ArrayList<String> getImg() {
665 return jsonArrayToList(img); 690 return jsonArrayToList(img);
666 } 691 }
...@@ -869,6 +894,10 @@ public class Merchant implements Parcelable, Serializable { ...@@ -869,6 +894,10 @@ public class Merchant implements Parcelable, Serializable {
869 this.parent = parent; 894 this.parent = parent;
870 } 895 }
871 896
897 + public void setParentUuid(String parentUuid) {
898 + this.parentUuid = parentUuid;
899 + }
900 +
872 public void setImg(JSONArray img) { 901 public void setImg(JSONArray img) {
873 this.img = img; 902 this.img = img;
874 } 903 }
...@@ -965,6 +994,10 @@ public class Merchant implements Parcelable, Serializable { ...@@ -965,6 +994,10 @@ public class Merchant implements Parcelable, Serializable {
965 this.urlName = urlName; 994 this.urlName = urlName;
966 } 995 }
967 996
997 + public void setCoordinates(LatLng coordinates) {
998 + this.coordinates = coordinates;
999 + }
1000 +
968 @Override 1001 @Override
969 public int describeContents() { 1002 public int describeContents() {
970 return 0; 1003 return 0;
...@@ -989,4 +1022,17 @@ public class Merchant implements Parcelable, Serializable { ...@@ -989,4 +1022,17 @@ public class Merchant implements Parcelable, Serializable {
989 } 1022 }
990 return listData; 1023 return listData;
991 } 1024 }
1025 +
1026 + @Override
1027 + public LatLng getPosition() {
1028 + return coordinates;
1029 + }
1030 + @Override
1031 + public String getTitle() {
1032 + return null;
1033 + }
1034 + @Override
1035 + public String getSnippet() {
1036 + return null;
1037 + }
992 } 1038 }
......
...@@ -157,6 +157,17 @@ public interface ApiService { ...@@ -157,6 +157,17 @@ public interface ApiService {
157 @Header(WarpConstants.HEADER_WEB_ID) String webId, 157 @Header(WarpConstants.HEADER_WEB_ID) String webId,
158 @Header(WarpConstants.HEADER_SIGNATURE) String signature); 158 @Header(WarpConstants.HEADER_SIGNATURE) String signature);
159 159
160 + @Headers("Content-Type: application/json")
161 + @POST("/api/mobile/v2/{appUuid}/context/")
162 + Call<ResponseBody> getStores(@Path("appUuid") String appUuid,
163 + @Body RequestBody request,
164 + @Header(WarpConstants.HEADER_DATE) String timeStamp,
165 + @Header(WarpConstants.HEADER_LOYALTY_BUNDLE_ID) String bundleId,
166 + @Header(WarpConstants.HEADER_UNIQUE_DEVICE_ID) String deviceId,
167 + @Header(WarpConstants.HEADER_CHANNEL) String channel,
168 + @Header(WarpConstants.HEADER_WEB_ID) String webId,
169 + @Header(WarpConstants.HEADER_SIGNATURE) String signature);
170 +
160 // =========================================================== 171 // ===========================================================
161 // Getter & Setter 172 // Getter & Setter
162 // =========================================================== 173 // ===========================================================
......
1 +package ly.warp.sdk.utils;
2 +
3 +import android.graphics.Bitmap;
4 +import android.graphics.Canvas;
5 +import android.graphics.ColorMatrix;
6 +import android.graphics.ColorMatrixColorFilter;
7 +import android.graphics.Paint;
8 +
9 +import androidx.annotation.NonNull;
10 +
11 +import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
12 +import com.bumptech.glide.load.resource.bitmap.BitmapTransformation;
13 +
14 +import java.security.MessageDigest;
15 +
16 +/**
17 + * Glide transformation that renders a bitmap in grayscale
18 + */
19 +public class GrayscaleTransformation extends BitmapTransformation {
20 + private static final String ID = "ly.warp.sdk.utils.GrayscaleTransformation";
21 +
22 + @Override
23 + protected Bitmap transform(@NonNull BitmapPool pool, @NonNull Bitmap toTransform, int outWidth, int outHeight) {
24 + Bitmap result = pool.get(toTransform.getWidth(), toTransform.getHeight(), Bitmap.Config.ARGB_8888);
25 + if (result == null) {
26 + result = Bitmap.createBitmap(toTransform.getWidth(), toTransform.getHeight(), Bitmap.Config.ARGB_8888);
27 + }
28 +
29 + ColorMatrix colorMatrix = new ColorMatrix();
30 + colorMatrix.setSaturation(0f);
31 +
32 + Paint paint = new Paint();
33 + paint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));
34 +
35 + Canvas canvas = new Canvas(result);
36 + canvas.drawBitmap(toTransform, 0, 0, paint);
37 +
38 + return result;
39 + }
40 +
41 + @Override
42 + public void updateDiskCacheKey(@NonNull MessageDigest messageDigest) {
43 + messageDigest.update(ID.getBytes());
44 + }
45 +
46 + @Override
47 + public boolean equals(Object o) {
48 + return o instanceof GrayscaleTransformation;
49 + }
50 +
51 + @Override
52 + public int hashCode() {
53 + return ID.hashCode();
54 + }
55 +}
...@@ -25,6 +25,9 @@ ...@@ -25,6 +25,9 @@
25 25
26 package ly.warp.sdk.utils.constants; 26 package ly.warp.sdk.utils.constants;
27 27
28 +import com.google.android.gms.maps.model.LatLng;
29 +import com.google.android.gms.maps.model.LatLngBounds;
30 +
28 public class WarpConstants { 31 public class WarpConstants {
29 32
30 /** 33 /**
...@@ -87,6 +90,11 @@ public class WarpConstants { ...@@ -87,6 +90,11 @@ public class WarpConstants {
87 public static boolean DEBUG; 90 public static boolean DEBUG;
88 public static String GCM_SENDER_ID; 91 public static String GCM_SENDER_ID;
89 92
93 + public static final LatLngBounds GREECE_BOUNDS = new LatLngBounds(
94 + new LatLng(34.75261, 19.33079),
95 + new LatLng(41.97761, 28.62522)
96 + );
97 +
90 /* 98 /*
91 * if was received the campaign with this category need expires date define 99 * if was received the campaign with this category need expires date define
92 * as 0 (for no show it in app need check on 0 or if the date is correct) 100 * 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; ...@@ -27,6 +27,7 @@ package ly.warp.sdk.utils.managers;
27 27
28 import android.os.Handler; 28 import android.os.Handler;
29 import android.os.Looper; 29 import android.os.Looper;
30 +import android.text.TextUtils;
30 import android.text.format.DateFormat; 31 import android.text.format.DateFormat;
31 import android.util.ArrayMap; 32 import android.util.ArrayMap;
32 33
...@@ -455,6 +456,37 @@ public class WarplyManager { ...@@ -455,6 +456,37 @@ public class WarplyManager {
455 return categorizedMap; 456 return categorizedMap;
456 } 457 }
457 458
459 + public static void getStores(String merchantUuid, final CallbackReceiver<ArrayList<Merchant>> receiver) {
460 + WarpUtils.log("************* WARPLY Stores Request ********************");
461 + WarpUtils.log("[WARP Trace] WARPLY Stores Request is active");
462 + WarpUtils.log("**************************************************");
463 +
464 + ApiService service = ApiClient.getRetrofitInstance().create(ApiService.class);
465 + ListeningExecutorService executorService = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(1));
466 +
467 + ListenableFuture<ArrayList<Merchant>> futureStores = getStoresRetro(merchantUuid, service);
468 +
469 + ListenableFuture<List<Object>> allResultsFuture = Futures.allAsList(futureStores);
470 + ListenableFuture<ArrayList<Merchant>> mergedResultFuture = Futures.transformAsync(allResultsFuture, results -> {
471 + ArrayList<Merchant> resultStores = (ArrayList<Merchant>) results.get(0);
472 + return executorService.submit(() -> resultStores);
473 + }, executorService);
474 +
475 + Futures.addCallback(mergedResultFuture, new FutureCallback<ArrayList<Merchant>>() {
476 + @Override
477 + public void onSuccess(ArrayList<Merchant> mergedResult) {
478 + executorService.shutdownNow();
479 + new Handler(Looper.getMainLooper()).post(() -> receiver.onSuccess(mergedResult));
480 + }
481 +
482 + @Override
483 + public void onFailure(Throwable throwable) {
484 + executorService.shutdownNow();
485 + new Handler(Looper.getMainLooper()).post(() -> receiver.onFailure(2));
486 + }
487 + }, executorService);
488 + }
489 +
458 public static void getCouponsets(final CallbackReceiver<LinkedHashMap<String, ArrayList<Couponset>>> receiver) { 490 public static void getCouponsets(final CallbackReceiver<LinkedHashMap<String, ArrayList<Couponset>>> receiver) {
459 WarpUtils.log("************* WARPLY Couponsets Request ********************"); 491 WarpUtils.log("************* WARPLY Couponsets Request ********************");
460 WarpUtils.log("[WARP Trace] WARPLY Couponsets Request is active"); 492 WarpUtils.log("[WARP Trace] WARPLY Couponsets Request is active");
...@@ -538,13 +570,16 @@ public class WarplyManager { ...@@ -538,13 +570,16 @@ public class WarplyManager {
538 final ExecutorService executorCouponsets = Executors.newFixedThreadPool(1); 570 final ExecutorService executorCouponsets = Executors.newFixedThreadPool(1);
539 JSONArray finalJCouponsetsBody = jCouponsetsBody; 571 JSONArray finalJCouponsetsBody = jCouponsetsBody;
540 executorCouponsets.submit(() -> { 572 executorCouponsets.submit(() -> {
541 - for (int i = 0; i < finalJCouponsetsBody.length(); ++i) { 573 + try {
542 - Couponset tempCouponset = new Couponset(finalJCouponsetsBody.optJSONObject(i)); 574 + for (int i = 0; i < finalJCouponsetsBody.length(); ++i) {
543 - mCouponsetList.add(tempCouponset); 575 + Couponset tempCouponset = new Couponset(finalJCouponsetsBody.optJSONObject(i));
576 + mCouponsetList.add(tempCouponset);
577 + }
578 + future.set(mCouponsetList);
579 + } catch (Exception e) {
580 + future.setException(e);
544 } 581 }
545 -
546 executorCouponsets.shutdownNow(); 582 executorCouponsets.shutdownNow();
547 - future.set(mCouponsetList);
548 }); 583 });
549 } 584 }
550 } else { 585 } else {
...@@ -639,13 +674,98 @@ public class WarplyManager { ...@@ -639,13 +674,98 @@ public class WarplyManager {
639 final ExecutorService executorCouponsets = Executors.newFixedThreadPool(1); 674 final ExecutorService executorCouponsets = Executors.newFixedThreadPool(1);
640 JSONArray finalJMerchantsBody = jMerchantsBody; 675 JSONArray finalJMerchantsBody = jMerchantsBody;
641 executorCouponsets.submit(() -> { 676 executorCouponsets.submit(() -> {
642 - for (int i = 0; i < finalJMerchantsBody.length(); ++i) { 677 + try {
643 - Merchant tempMerchant = new Merchant(finalJMerchantsBody.optJSONObject(i)); 678 + for (int i = 0; i < finalJMerchantsBody.length(); ++i) {
644 - mMerchantList.add(tempMerchant); 679 + Merchant tempMerchant = new Merchant(finalJMerchantsBody.optJSONObject(i));
680 + mMerchantList.add(tempMerchant);
681 + }
682 + future.set(mMerchantList);
683 + } catch (Exception e) {
684 + future.setException(e);
645 } 685 }
686 + executorCouponsets.shutdownNow();
687 + });
688 + }
689 + } else {
690 + future.set(new ArrayList<Merchant>());
691 + }
692 + } else if (String.valueOf(response.code()).startsWith("5")) {
693 + future.set(new ArrayList<Merchant>());
694 + } else {
695 +// future.set(new CouponsetsList());
696 + future.setException(new Throwable());
697 + }
698 + }
699 +
700 + @Override
701 + public void onFailure(@NonNull Call<ResponseBody> call, @NonNull Throwable t) {
702 +// future.set(new CouponsetsList());
703 + future.setException(new Throwable());
704 + }
705 + });
706 + return future;
707 + }
708 +
709 + private static ListenableFuture<ArrayList<Merchant>> getStoresRetro(String merchantUuid, ApiService service/*, Callback<ResponseBody> callback*/) {
710 + SettableFuture<ArrayList<Merchant>> future = SettableFuture.create();
646 711
712 + String timeStamp = DateFormat.format("yyyy-MM-dd hh:mm:ss", System.currentTimeMillis()).toString();
713 + String apiKey = WarpUtils.getApiKey(Warply.getWarplyContext());
714 + String webId = WarpUtils.getWebId(Warply.getWarplyContext());
715 +
716 + Map<String, Object> jsonParamsMerchants = new ArrayMap<>();
717 + Map<String, Object> jsonParams = new ArrayMap<>();
718 + jsonParams.put("action", "retrieve_stores");
719 + jsonParams.put("language", WarplyProperty.getLanguage(Warply.getWarplyContext()));
720 + if (!TextUtils.isEmpty(merchantUuid)) {
721 + jsonParams.put("merchant_uuid", merchantUuid);
722 + }
723 + jsonParamsMerchants.put("shops", jsonParams);
724 +
725 + RequestBody merchantsRequest = RequestBody.create(MediaType.get("application/json; charset=utf-8"), (new JSONObject(jsonParamsMerchants)).toString());
726 + Call<ResponseBody> merchantsCall = service.getStores(
727 + WarplyProperty.getAppUuid(Warply.getWarplyContext()),
728 + merchantsRequest,
729 + timeStamp,
730 + "android:" + Warply.getWarplyContext().getPackageName(),
731 + new WarplyDeviceInfoCollector(Warply.getWarplyContext()).getUniqueDeviceId(),
732 + "mobile",
733 + webId,
734 + WarpUtils.produceSignature(apiKey + timeStamp)
735 + );
736 + merchantsCall.enqueue(new Callback<ResponseBody>() {
737 + @Override
738 + public void onResponse(@NonNull Call<ResponseBody> call, @NonNull Response<ResponseBody> response) {
739 + if (response.code() == 200 && response.body() != null) {
740 + JSONObject jobjMerchantsResponse = null;
741 + try {
742 + jobjMerchantsResponse = new JSONObject(response.body().string());
743 + } catch (Exception e) {
744 + e.printStackTrace();
745 + }
746 + if (jobjMerchantsResponse != null && jobjMerchantsResponse.has("status") && jobjMerchantsResponse.optString("status", "2").equals("1")) {
747 + JSONArray jMerchantsBody = null;
748 + try {
749 + jMerchantsBody = jobjMerchantsResponse.optJSONObject("context").optJSONObject("MAPP_SHOPS").optJSONArray("result");
750 + } catch (Exception e) {
751 + e.printStackTrace();
752 + }
753 +
754 + if (jMerchantsBody != null) {
755 + ArrayList<Merchant> mMerchantList = new ArrayList<Merchant>();
756 + final ExecutorService executorCouponsets = Executors.newFixedThreadPool(1);
757 + JSONArray finalJMerchantsBody = jMerchantsBody;
758 + executorCouponsets.submit(() -> {
759 + try {
760 + for (int i = 0; i < finalJMerchantsBody.length(); ++i) {
761 + Merchant tempMerchant = new Merchant(finalJMerchantsBody.optJSONObject(i));
762 + mMerchantList.add(tempMerchant);
763 + }
764 + future.set(mMerchantList);
765 + } catch (Exception e) {
766 + future.setException(e);
767 + }
647 executorCouponsets.shutdownNow(); 768 executorCouponsets.shutdownNow();
648 - future.set(mMerchantList);
649 }); 769 });
650 } 770 }
651 } else { 771 } else {
...@@ -782,14 +902,16 @@ public class WarplyManager { ...@@ -782,14 +902,16 @@ public class WarplyManager {
782 final ExecutorService executorCampaigns = Executors.newFixedThreadPool(1); 902 final ExecutorService executorCampaigns = Executors.newFixedThreadPool(1);
783 JSONArray finalCampaignsJBody = jCampaignsBody; 903 JSONArray finalCampaignsJBody = jCampaignsBody;
784 executorCampaigns.submit(() -> { 904 executorCampaigns.submit(() -> {
785 - for (int i = 0; i < finalCampaignsJBody.length(); ++i) { 905 + try {
786 - Campaign camp = new Campaign(finalCampaignsJBody.optJSONObject(i)); 906 + for (int i = 0; i < finalCampaignsJBody.length(); ++i) {
787 - mCampaignsList.add(camp); 907 + Campaign camp = new Campaign(finalCampaignsJBody.optJSONObject(i));
908 + mCampaignsList.add(camp);
909 + }
910 + future.set(mCampaignsList);
911 + } catch (Exception e) {
912 + future.setException(e);
788 } 913 }
789 -
790 executorCampaigns.shutdownNow(); 914 executorCampaigns.shutdownNow();
791 -// receiver.onSuccess(mCampaignsList);
792 - future.set(mCampaignsList);
793 }); 915 });
794 } 916 }
795 } else { 917 } else {
...@@ -859,14 +981,16 @@ public class WarplyManager { ...@@ -859,14 +981,16 @@ public class WarplyManager {
859 final ExecutorService executorPersonalizedCampaigns = Executors.newFixedThreadPool(1); 981 final ExecutorService executorPersonalizedCampaigns = Executors.newFixedThreadPool(1);
860 JSONArray finalCampaignsJBody = jCampaignsBody; 982 JSONArray finalCampaignsJBody = jCampaignsBody;
861 executorPersonalizedCampaigns.submit(() -> { 983 executorPersonalizedCampaigns.submit(() -> {
862 - for (int i = 0; i < finalCampaignsJBody.length(); ++i) { 984 + try {
863 - Campaign camp = new Campaign(finalCampaignsJBody.optJSONObject(i)); 985 + for (int i = 0; i < finalCampaignsJBody.length(); ++i) {
864 - mCampaignsList.add(camp); 986 + Campaign camp = new Campaign(finalCampaignsJBody.optJSONObject(i));
987 + mCampaignsList.add(camp);
988 + }
989 + future.set(mCampaignsList);
990 + } catch (Exception e) {
991 + future.setException(e);
865 } 992 }
866 -
867 executorPersonalizedCampaigns.shutdownNow(); 993 executorPersonalizedCampaigns.shutdownNow();
868 -// receiver.onSuccess(mCampaignsList);
869 - future.set(mCampaignsList);
870 }); 994 });
871 } 995 }
872 } else { 996 } else {
...@@ -977,13 +1101,15 @@ public class WarplyManager { ...@@ -977,13 +1101,15 @@ public class WarplyManager {
977 final ExecutorService executorArticles = Executors.newFixedThreadPool(1); 1101 final ExecutorService executorArticles = Executors.newFixedThreadPool(1);
978 JSONArray finalArticlesJBody = jArticlesBody; 1102 JSONArray finalArticlesJBody = jArticlesBody;
979 executorArticles.submit(() -> { 1103 executorArticles.submit(() -> {
980 - for (int i = 0; i < finalArticlesJBody.length(); ++i) { 1104 + try {
981 - mArticlesList.add(new Content(finalArticlesJBody.optJSONObject(i))); 1105 + for (int i = 0; i < finalArticlesJBody.length(); ++i) {
1106 + mArticlesList.add(new Content(finalArticlesJBody.optJSONObject(i)));
1107 + }
1108 + future.set(mArticlesList);
1109 + } catch (Exception e) {
1110 + future.setException(e);
982 } 1111 }
983 -
984 executorArticles.shutdownNow(); 1112 executorArticles.shutdownNow();
985 -// receiver.onSuccess(mCampaignsList);
986 - future.set(mArticlesList);
987 }); 1113 });
988 } 1114 }
989 } else { 1115 } else {
...@@ -1053,18 +1179,18 @@ public class WarplyManager { ...@@ -1053,18 +1179,18 @@ public class WarplyManager {
1053 final ExecutorService executorCoupons = Executors.newFixedThreadPool(1); 1179 final ExecutorService executorCoupons = Executors.newFixedThreadPool(1);
1054 JSONArray finalJCouponsBody = jCouponsBody; 1180 JSONArray finalJCouponsBody = jCouponsBody;
1055 executorCoupons.submit(() -> { 1181 executorCoupons.submit(() -> {
1056 - for (int i = 0; i < finalJCouponsBody.length(); ++i) { 1182 + try {
1057 - Coupon tempCoupon = new Coupon(finalJCouponsBody.optJSONObject(i), true); 1183 + for (int i = 0; i < finalJCouponsBody.length(); ++i) {
1058 - mCouponList.add(tempCoupon); 1184 + Coupon tempCoupon = new Coupon(finalJCouponsBody.optJSONObject(i), true);
1185 + mCouponList.add(tempCoupon);
1186 + }
1187 + WarplyManagerHelper.setCoupons(mCouponList);
1188 + Collections.sort(mCouponList, (coupon1, coupon2) -> coupon1.getExpirationDate().compareTo(coupon2.getExpirationDate()));
1189 + future.set(mCouponList);
1190 + } catch (Exception e) {
1191 + future.setException(e);
1059 } 1192 }
1060 -
1061 - WarplyManagerHelper.setCoupons(mCouponList);
1062 -
1063 - Collections.sort(mCouponList, (coupon1, coupon2) -> coupon1.getExpirationDate().compareTo(coupon2.getExpirationDate()));
1064 -
1065 executorCoupons.shutdownNow(); 1193 executorCoupons.shutdownNow();
1066 -
1067 - future.set(mCouponList);
1068 }); 1194 });
1069 } else { 1195 } else {
1070 future.set(new ArrayList<Coupon>()); 1196 future.set(new ArrayList<Coupon>());
......
1 +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
2 + android:layout_width="match_parent"
3 + android:layout_height="match_parent"
4 + android:background="@color/white">
5 +
6 + <LinearLayout
7 + android:id="@+id/header_layout"
8 + android:layout_width="match_parent"
9 + android:layout_height="wrap_content"
10 + android:layout_gravity="center"
11 + android:background="@color/white"
12 + android:baselineAligned="false"
13 + android:orientation="horizontal"
14 + android:padding="16dp">
15 +
16 + <LinearLayout
17 + android:layout_width="0dp"
18 + android:layout_height="wrap_content"
19 + android:layout_weight="1"
20 + android:gravity="center_vertical"
21 + android:orientation="horizontal">
22 +
23 + <ImageView
24 + android:id="@+id/iv_back"
25 + android:layout_width="16dp"
26 + android:layout_height="16dp"
27 + android:layout_marginEnd="24dp"
28 + android:src="@drawable/ic_back" />
29 + </LinearLayout>
30 + </LinearLayout>
31 +
32 + <LinearLayout
33 + android:id="@+id/header_layout2"
34 + android:layout_width="match_parent"
35 + android:layout_height="wrap_content"
36 + android:layout_below="@+id/header_layout"
37 + android:background="@color/white"
38 + android:orientation="vertical"
39 + android:paddingHorizontal="16dp"
40 + android:paddingBottom="16dp">
41 +
42 + <LinearLayout
43 + android:layout_width="wrap_content"
44 + android:layout_height="wrap_content"
45 + android:orientation="vertical">
46 +
47 + <TextView
48 + android:id="@+id/tv_header_title"
49 + android:layout_width="wrap_content"
50 + android:layout_height="wrap_content"
51 + android:includeFontPadding="false"
52 + android:text="@string/demo_partners_title"
53 + android:textColor="@color/custom_black6"
54 + android:textSize="28sp" />
55 + </LinearLayout>
56 +
57 + <LinearLayout
58 + android:id="@+id/ll_search_filter_button"
59 + android:layout_width="wrap_content"
60 + android:layout_height="wrap_content"
61 + android:layout_marginTop="12dp"
62 + android:background="@drawable/shape_rectangle_rounded_grey4"
63 + android:gravity="center"
64 + android:paddingHorizontal="20dp"
65 + android:paddingVertical="12dp">
66 +
67 + <TextView
68 + android:id="@+id/tv_search_title"
69 + android:layout_width="wrap_content"
70 + android:layout_height="wrap_content"
71 + android:gravity="center"
72 + android:includeFontPadding="false"
73 + android:text="@string/demo_search_title"
74 + android:textColor="@color/custom_black6"
75 + android:textSize="14sp" />
76 +
77 + <View
78 + android:layout_width="12dp"
79 + android:layout_height="match_parent" />
80 +
81 + <ImageView
82 + android:layout_width="16dp"
83 + android:layout_height="16dp"
84 + android:src="@drawable/demo_filter" />
85 + </LinearLayout>
86 + </LinearLayout>
87 +
88 + <RelativeLayout
89 + android:id="@+id/cl_loyalty_info_view_inner"
90 + android:layout_width="match_parent"
91 + android:layout_height="match_parent"
92 + android:layout_below="@+id/header_layout2">
93 +
94 + <fragment
95 + android:id="@+id/mv_shops"
96 + class="com.google.android.gms.maps.SupportMapFragment"
97 + android:layout_width="match_parent"
98 + android:layout_height="match_parent" />
99 + </RelativeLayout>
100 +</RelativeLayout>
...\ No newline at end of file ...\ No newline at end of file
...@@ -22,12 +22,6 @@ ...@@ -22,12 +22,6 @@
22 android:layout_height="260dp" 22 android:layout_height="260dp"
23 android:background="@color/custom_skyblue3"> 23 android:background="@color/custom_skyblue3">
24 24
25 - <TextView
26 - android:id="@+id/textView"
27 - android:layout_width="wrap_content"
28 - android:layout_height="wrap_content"
29 - android:text="coupon_code_content" />
30 -
31 <ImageView 25 <ImageView
32 android:id="@+id/iv_coupon_image" 26 android:id="@+id/iv_coupon_image"
33 android:layout_width="match_parent" 27 android:layout_width="match_parent"
...@@ -254,6 +248,7 @@ ...@@ -254,6 +248,7 @@
254 </androidx.constraintlayout.widget.ConstraintLayout> 248 </androidx.constraintlayout.widget.ConstraintLayout>
255 249
256 <LinearLayout 250 <LinearLayout
251 + android:id="@+id/ll_shops"
257 android:layout_width="match_parent" 252 android:layout_width="match_parent"
258 android:layout_height="55dp" 253 android:layout_height="55dp"
259 android:layout_marginTop="32dp" 254 android:layout_marginTop="32dp"
......
1 <resources> 1 <resources>
2 + <string name="google_maps_key">AIzaSyB-K6OiUDT_X0zp2jYjqHg54ThxEuZtr9I</string>
2 <string name="webview_permission_title">Demo App</string> 3 <string name="webview_permission_title">Demo App</string>
3 <string name="webview_permission_message">Το Demo App ζητάει πρόσβαση στην τοποθεσία σας.</string> 4 <string name="webview_permission_message">Το Demo App ζητάει πρόσβαση στην τοποθεσία σας.</string>
4 - <string name="lbl_ok">Οκ</string> 5 + <string name="lbl_ok">ΟΚ</string>
5 <string name="lbl_cancel">Άκυρο</string> 6 <string name="lbl_cancel">Άκυρο</string>
7 + <string name="lbl_stores">Καταστήματα συνεργάτη</string>
8 + <string name="lbl_no_shops">Δεν υπάρχουν καταστήματα συνεργάτη.</string>
6 <string name="welcome_user">User</string> 9 <string name="welcome_user">User</string>
7 <string name="menu_home">Αρχική</string> 10 <string name="menu_home">Αρχική</string>
8 <string name="demo_home">Αρχική οθόνη</string> 11 <string name="demo_home">Αρχική οθόνη</string>
...@@ -36,4 +39,6 @@ ...@@ -36,4 +39,6 @@
36 <string name="demo_my_coupons_title">My coupons</string> 39 <string name="demo_my_coupons_title">My coupons</string>
37 <string name="demo_my_coupons_header">My Coupons</string> 40 <string name="demo_my_coupons_header">My Coupons</string>
38 <string name="demo_coupon_expired">Expired</string> 41 <string name="demo_coupon_expired">Expired</string>
42 + <string name="demo_partners_title">Partner businesses</string>
43 + <string name="demo_search_title">Αναζήτηση</string>
39 </resources> 44 </resources>
......