Panagiotis Triantafyllou

get coupons request, single coupon activity

Showing 25 changed files with 612 additions and 376 deletions
......@@ -18,11 +18,6 @@ Debug=true
# DEH Development: https://engage-uat.dei.gr
BaseURL=https://engage-uat.dei.gr
# For Verify Ticket request
VerifyURL=/partners/dei/verify
#WebActionHandler=app_package_name.WarplyWebActionHandler
# Replace the color with one you want the progress bar to have depending on you app theme-coloring
# If not defined the colorPrimary will used
#ProgressColor=red
......@@ -46,13 +41,10 @@ SendPackages=false
# The app language
Language=el
# The merchant id for some requests
MerchantId=20113
# The login type must be one of the below:
# email, msisdn, username
LoginType=username
LoginType=email
# The deeplink url scheme for react native campaigns:
# Example visit.greece.gr
DL_URL_SCHEME=demo
\ No newline at end of file
# Example demo.app.gr
DL_URL_SCHEME=demo.app.gr
\ No newline at end of file
......
#Fri Jul 26 17:08:44 EEST 2024
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
......
This diff is collapsed. Click to expand it.
......@@ -5,7 +5,7 @@ android.buildFeatures.buildConfig = true
ext {
PUBLISH_GROUP_ID = 'ly.warp'
PUBLISH_VERSION = '4.5.5.4deh3'
PUBLISH_VERSION = '4.5.5.6deh4'
PUBLISH_ARTIFACT_ID = 'warply-android-sdk'
}
......
......@@ -45,6 +45,12 @@
android:theme="@style/SDKAppTheme" />
<activity
android:name=".activities.SingleCouponsetActivity"
android:exported="false"
android:screenOrientation="portrait"
android:theme="@style/SDKAppTheme" />
<activity
android:name=".activities.ProfileActivity"
android:exported="false"
android:screenOrientation="portrait"
......
......@@ -1343,8 +1343,6 @@ public enum Warply {
else {
if (warplyPath.equals("handle_image"))
sb = new StringBuilder(WarplyProperty.getBaseUrl(mContext) + WarpConstants.BASE_URL_API);
else if (warplyPath.equals("verify"))
sb = new StringBuilder(WarplyProperty.getBaseUrl(mContext) + WarplyProperty.getVerifyUrl(mContext));
else if (warplyPath.equals("cosuser"))
sb = new StringBuilder(WarplyProperty.getBaseUrl(mContext) + "/partners/oauth/" + WarplyProperty.getAppUuid(mContext) + "/token");
else
......
......@@ -3,6 +3,7 @@ package ly.warp.sdk.activities;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
......@@ -93,9 +94,9 @@ public class HomeActivity extends Activity implements View.OnClickListener, Coup
@Override
public void onCouponsetClick(Couponset couponset, int position) {
// Intent myIntent = new Intent(HomeActivity.this, SingleCouponActivity.class);
// myIntent.putExtra(SingleCouponActivity.EXTRA_OFFER_ITEM, couponset);
// startActivity(myIntent);
Intent myIntent = new Intent(HomeActivity.this, SingleCouponsetActivity.class);
myIntent.putExtra(SingleCouponsetActivity.EXTRA_OFFER_ITEM, (Parcelable) couponset);
startActivity(myIntent);
}
// ===========================================================
......@@ -114,59 +115,6 @@ public class HomeActivity extends Activity implements View.OnClickListener, Coup
mIvProfile.setOnClickListener(this);
}
private void setupCouponsetSections(LinkedHashMap<String, ArrayList<Couponset>> categorizedMap) {
mSectionsContainer.removeAllViews();
if (categorizedMap == null || categorizedMap.isEmpty()) {
mSectionsLoading.setVisibility(View.GONE);
return;
}
LayoutInflater inflater = LayoutInflater.from(this);
int spacingInPixels = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 8, getResources().getDisplayMetrics());
for (Map.Entry<String, ArrayList<Couponset>> entry : categorizedMap.entrySet()) {
String categoryName = entry.getKey();
ArrayList<Couponset> couponsets = entry.getValue();
if (couponsets == null || couponsets.isEmpty()) {
continue;
}
View sectionView = inflater.inflate(R.layout.item_couponset_section, mSectionsContainer, false);
TextView tvTitle = sectionView.findViewById(R.id.tv_section_title);
String titleText = categoryName + " (" + couponsets.size() + ")";
tvTitle.setText(titleText);
WarpUtils.renderCustomFont(this, R.font.ping_lcg_bold, tvTitle);
TextView tvAll = sectionView.findViewById(R.id.tv_section_all);
WarpUtils.renderCustomFont(this, R.font.ping_lcg_regular, tvAll);
RecyclerView rvSection = sectionView.findViewById(R.id.rv_section_list);
LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
rvSection.setLayoutManager(layoutManager);
rvSection.setHasFixedSize(true);
rvSection.addItemDecoration(new HorizontalSpaceItemDecoration(spacingInPixels));
List<Couponset> displayList = couponsets.size() > MAX_ITEMS_PER_SECTION
? new ArrayList<>(couponsets.subList(0, MAX_ITEMS_PER_SECTION))
: couponsets;
CouponsetAdapter adapter = new CouponsetAdapter(this, displayList);
adapter.setOnCouponsetClickListener(this);
rvSection.setAdapter(adapter);
mSectionsContainer.addView(sectionView);
}
mSectionsLoading.setVisibility(View.GONE);
}
// ===========================================================
// Banner Methods
// ===========================================================
private void setupBannerCarousel() {
mBannerViewPager = findViewById(R.id.banner_viewpager);
mDotsContainer = findViewById(R.id.dots_container);
......@@ -176,7 +124,17 @@ public class HomeActivity extends Activity implements View.OnClickListener, Coup
startActivity(WarpViewActivity.createIntentFromURL(this, WarplyManagerHelper.constructCampaignUrl(campaign)));
});
mBannerAdapter.setOnBannerContentClickListener(article -> {
//TODO: click article
if (article != null && article.getExtraFields() != null) {
String couponsetUuid = article.getExtraFields().optString("url_link", null);
if (couponsetUuid != null && !couponsetUuid.isEmpty()) {
Couponset matchedCouponset = findCouponsetByUuid(couponsetUuid);
if (matchedCouponset != null) {
Intent myIntent = new Intent(HomeActivity.this, SingleCouponsetActivity.class);
myIntent.putExtra(SingleCouponsetActivity.EXTRA_OFFER_ITEM, (Parcelable) matchedCouponset);
startActivity(myIntent);
}
}
}
});
// Set the number of pages to preload for adjacent items
......@@ -220,9 +178,68 @@ public class HomeActivity extends Activity implements View.OnClickListener, Coup
}
}
// ===========================================================
// Callbacks
// ===========================================================
private void setupCouponsetSections(LinkedHashMap<String, ArrayList<Couponset>> categorizedMap) {
mSectionsContainer.removeAllViews();
if (categorizedMap == null || categorizedMap.isEmpty()) {
mSectionsLoading.setVisibility(View.GONE);
return;
}
LayoutInflater inflater = LayoutInflater.from(this);
int spacingInPixels = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 8, getResources().getDisplayMetrics());
for (Map.Entry<String, ArrayList<Couponset>> entry : categorizedMap.entrySet()) {
String categoryName = entry.getKey();
ArrayList<Couponset> couponsets = entry.getValue();
if (couponsets == null || couponsets.isEmpty()) {
continue;
}
View sectionView = inflater.inflate(R.layout.item_couponset_section, mSectionsContainer, false);
TextView tvTitle = sectionView.findViewById(R.id.tv_section_title);
String titleText = categoryName + " (" + couponsets.size() + ")";
tvTitle.setText(titleText);
WarpUtils.renderCustomFont(this, R.font.ping_lcg_bold, tvTitle);
TextView tvAll = sectionView.findViewById(R.id.tv_section_all);
WarpUtils.renderCustomFont(this, R.font.ping_lcg_regular, tvAll);
RecyclerView rvSection = sectionView.findViewById(R.id.rv_section_list);
LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
rvSection.setLayoutManager(layoutManager);
rvSection.setHasFixedSize(true);
rvSection.addItemDecoration(new HorizontalSpaceItemDecoration(spacingInPixels));
List<Couponset> displayList = couponsets.size() > MAX_ITEMS_PER_SECTION
? new ArrayList<>(couponsets.subList(0, MAX_ITEMS_PER_SECTION))
: couponsets;
CouponsetAdapter adapter = new CouponsetAdapter(this, displayList);
adapter.setOnCouponsetClickListener(this);
rvSection.setAdapter(adapter);
mSectionsContainer.addView(sectionView);
}
mSectionsLoading.setVisibility(View.GONE);
}
private Couponset findCouponsetByUuid(String uuid) {
LinkedHashMap<String, ArrayList<Couponset>> categorizedMap = WarplyManagerHelper.getCouponsetCategorizedMap();
if (categorizedMap != null) {
for (ArrayList<Couponset> couponsets : categorizedMap.values()) {
for (Couponset couponset : couponsets) {
if (uuid.equals(couponset.getUuid())) {
return couponset;
}
}
}
}
return null;
}
private final CallbackReceiver<ArrayList<BannerItem>> mCampaignsCallback = new CallbackReceiver<ArrayList<BannerItem>>() {
@Override
......
......@@ -3,28 +3,28 @@ package ly.warp.sdk.activities;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.TypedValue;
import android.view.View;
import android.view.WindowInsetsController;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
import java.util.ArrayList;
import ly.warp.sdk.R;
import ly.warp.sdk.io.adapters.CouponAdapter;
import ly.warp.sdk.io.adapters.OfferAdapter;
import ly.warp.sdk.io.models.CouponItem;
import ly.warp.sdk.io.models.DummyDataProvider;
import ly.warp.sdk.io.models.OfferCategory;
import ly.warp.sdk.io.callbacks.CallbackReceiver;
import ly.warp.sdk.io.models.Coupon;
import ly.warp.sdk.io.models.OfferItem;
import ly.warp.sdk.utils.WarpUtils;
import ly.warp.sdk.views.HorizontalSpaceItemDecoration;
import ly.warp.sdk.utils.WarplyManagerHelper;
import ly.warp.sdk.utils.managers.WarplyManager;
import ly.warp.sdk.views.VerticalSpaceItemDecoration;
public class ProfileActivity extends Activity implements View.OnClickListener, OfferAdapter.OnOfferClickListener, CouponAdapter.OnCouponClickListener {
......@@ -37,6 +37,7 @@ public class ProfileActivity extends Activity implements View.OnClickListener, O
// Fields
// ===========================================================
private RelativeLayout mPbLoading;
private TextView mTvHeaderTitle;
private ImageView mIvBack;
......@@ -51,7 +52,6 @@ public class ProfileActivity extends Activity implements View.OnClickListener, O
private RecyclerView mRvCoupons;
private CouponAdapter mCouponsAdapter;
private TextView mBtnFilterActive, mBtnFilterFavorites, mBtnFilterRedeemed;
private List<CouponItem> mCouponItems;
// ===========================================================
// Methods for/from SuperClass/Interfaces
......@@ -68,11 +68,8 @@ public class ProfileActivity extends Activity implements View.OnClickListener, O
findViewById(R.id.header_layout),
null);
// Setup profile suggestions section
setupProfileSuggestionsSection();
// Setup my coupons section
setupMyCouponsSection();
mPbLoading.setVisibility(View.VISIBLE);
WarplyManager.getCoupons(mCouponsCallback);
}
@Override
......@@ -86,19 +83,19 @@ public class ProfileActivity extends Activity implements View.OnClickListener, O
if (id == R.id.iv_back) {
onBackPressed();
} else if (id == R.id.btn_filter_active) {
filterCoupons(CouponItem.STATUS_ACTIVE);
// filterCoupons(CouponItem.STATUS_ACTIVE);
} else if (id == R.id.btn_filter_favorites) {
filterCoupons(CouponItem.STATUS_FAVORITE);
// filterCoupons(CouponItem.STATUS_FAVORITE);
} else if (id == R.id.btn_filter_redeemed) {
filterCoupons(CouponItem.STATUS_REDEEMED);
// filterCoupons(CouponItem.STATUS_REDEEMED);
}
}
@Override
public void onOfferClick(OfferItem offerItem, int position) {
Intent myIntent = new Intent(ProfileActivity.this, SingleCouponActivity.class);
myIntent.putExtra(SingleCouponActivity.EXTRA_OFFER_ITEM, offerItem);
startActivity(myIntent);
// Intent myIntent = new Intent(ProfileActivity.this, SingleCouponActivity.class);
// myIntent.putExtra(SingleCouponActivity.EXTRA_OFFER_ITEM, offerItem);
// startActivity(myIntent);
}
@Override
......@@ -107,14 +104,14 @@ public class ProfileActivity extends Activity implements View.OnClickListener, O
}
@Override
public void onCouponClick(CouponItem couponItem, int position) {
public void onCouponClick(Coupon couponItem, int position) {
Intent myIntent = new Intent(ProfileActivity.this, SingleCouponActivity.class);
myIntent.putExtra(SingleCouponActivity.EXTRA_OFFER_ITEM, couponItem);
myIntent.putExtra(SingleCouponActivity.EXTRA_OFFER_ITEM, (Parcelable) couponItem);
startActivity(myIntent);
}
@Override
public void onFavoriteClick(CouponItem couponItem, int position) {
public void onFavoriteClick(Coupon couponItem, int position) {
// Handle favorite click if needed
}
......@@ -126,6 +123,9 @@ public class ProfileActivity extends Activity implements View.OnClickListener, O
mIvBack = findViewById(R.id.iv_back);
mIvBack.setOnClickListener(this);
mPbLoading = findViewById(R.id.pb_loading);
mPbLoading.setOnTouchListener((v, event) -> true);
mTvHeaderTitle = findViewById(R.id.tv_header_title);
// Initialize Profile Suggestions section
......@@ -151,63 +151,22 @@ public class ProfileActivity extends Activity implements View.OnClickListener, O
mBtnFilterActive, mBtnFilterFavorites, mBtnFilterRedeemed);
}
/**
* Set up the Profile Suggestions section with dummy data
*/
private void setupProfileSuggestionsSection() {
// Get Profile Suggestions data
OfferCategory profileSuggestionsCategory = DummyDataProvider.getProfileSuggestions();
// Set category title with item count
String categoryTitle = profileSuggestionsCategory.getName() + " (" + profileSuggestionsCategory.getItems().size() + ")";
mTvCategoryProfileSuggestions.setText(categoryTitle);
// Set up RecyclerView
LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
mRvProfileSuggestions.setLayoutManager(layoutManager);
// Add spacing between items
int spacingInPixels = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 8, getResources().getDisplayMetrics());
mRvProfileSuggestions.addItemDecoration(new HorizontalSpaceItemDecoration(spacingInPixels));
// Create and set adapter
mProfileSuggestionsAdapter = new OfferAdapter(this, profileSuggestionsCategory.getItems());
mProfileSuggestionsAdapter.setOnOfferClickListener(this);
mRvProfileSuggestions.setAdapter(mProfileSuggestionsAdapter);
}
/**
* Set up the My Coupons section with dummy data and filters
*/
private void setupMyCouponsSection() {
// Get coupons data
mCouponItems = DummyDataProvider.getCoupons();
// Set up RecyclerView
LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
mRvCoupons.setLayoutManager(layoutManager);
mRvCoupons.setHasFixedSize(true);
// Create and set adapter
mCouponsAdapter = new CouponAdapter(this, mCouponItems);
mCouponsAdapter = new CouponAdapter(this, WarplyManagerHelper.getCoupons());
mCouponsAdapter.setOnCouponClickListener(this);
mRvCoupons.setAdapter(mCouponsAdapter);
// Add 16dp spacing between coupon items
int verticalSpacingInPixels = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 16, getResources().getDisplayMetrics());
mRvCoupons.addItemDecoration(new VerticalSpaceItemDecoration(verticalSpacingInPixels));
// Filter by active coupons by default
filterCoupons(CouponItem.STATUS_ACTIVE);
// filterCoupons(CouponItem.STATUS_ACTIVE);
}
/**
* Filter coupons by status
*
* @param status The status to filter by
*/
private void filterCoupons(String status) {
// Reset all filter button styles
mBtnFilterActive.setBackgroundResource(R.drawable.shape_transparent_black_border);
......@@ -220,22 +179,35 @@ public class ProfileActivity extends Activity implements View.OnClickListener, O
mBtnFilterRedeemed.setTextColor(getResources().getColor(R.color.custom_black2));
// Set selected filter button style
if (CouponItem.STATUS_ACTIVE.equals(status)) {
mBtnFilterActive.setBackgroundResource(R.drawable.shape_rectangle_rounded_black);
mBtnFilterActive.setTextColor(Color.WHITE);
} else if (CouponItem.STATUS_FAVORITE.equals(status)) {
mBtnFilterFavorites.setBackgroundResource(R.drawable.shape_rectangle_rounded_black);
mBtnFilterFavorites.setTextColor(Color.WHITE);
} else if (CouponItem.STATUS_REDEEMED.equals(status)) {
mBtnFilterRedeemed.setBackgroundResource(R.drawable.shape_rectangle_rounded_black);
mBtnFilterRedeemed.setTextColor(Color.WHITE);
}
// if (CouponItem.STATUS_ACTIVE.equals(status)) {
// mBtnFilterActive.setBackgroundResource(R.drawable.shape_rectangle_rounded_black);
// mBtnFilterActive.setTextColor(Color.WHITE);
// } else if (CouponItem.STATUS_FAVORITE.equals(status)) {
// mBtnFilterFavorites.setBackgroundResource(R.drawable.shape_rectangle_rounded_black);
// mBtnFilterFavorites.setTextColor(Color.WHITE);
// } else if (CouponItem.STATUS_REDEEMED.equals(status)) {
// mBtnFilterRedeemed.setBackgroundResource(R.drawable.shape_rectangle_rounded_black);
// mBtnFilterRedeemed.setTextColor(Color.WHITE);
// }
// Apply filter to adapter
mCouponsAdapter.filterByStatus(status);
// mCouponsAdapter.filterByStatus(status);
}
// ===========================================================
// Inner and Anonymous Classes
// ===========================================================
private final CallbackReceiver<ArrayList<Coupon>> mCouponsCallback = new CallbackReceiver<ArrayList<Coupon>>() {
@Override
public void onSuccess(ArrayList<Coupon> result) {
mPbLoading.setVisibility(View.GONE);
setupMyCouponsSection();
}
@Override
public void onFailure(int errorCode) {
mPbLoading.setVisibility(View.GONE);
}
};
}
......
......@@ -5,32 +5,40 @@ import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.view.WindowInsetsController;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.core.text.HtmlCompat;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import ly.warp.sdk.R;
import ly.warp.sdk.io.models.OfferItem;
import ly.warp.sdk.io.models.Coupon;
import ly.warp.sdk.utils.WarpUtils;
public class SingleCouponActivity extends Activity implements View.OnClickListener {
// ===========================================================
// Constants
// ===========================================================
public static final String EXTRA_OFFER_ITEM = "offer_item";
public static final String EXTRA_OFFER_ITEM = "coupon_item";
// ===========================================================
// Fields
// ===========================================================
private ImageView mIvBack;
private OfferItem mOfferItem;
private Coupon mOfferItem;
private TextView mTvSmallDescription;
private TextView mTvFullDescription;
private TextView mTvEndDate;
......@@ -80,10 +88,9 @@ public class SingleCouponActivity extends Activity implements View.OnClickListen
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_single_coupon);
// Get offer item from intent
Intent intent = getIntent();
if (intent != null && intent.hasExtra(EXTRA_OFFER_ITEM)) {
mOfferItem = (OfferItem) intent.getSerializableExtra(EXTRA_OFFER_ITEM);
mOfferItem = (Coupon) intent.getSerializableExtra(EXTRA_OFFER_ITEM);
}
initViews();
......@@ -151,34 +158,35 @@ public class SingleCouponActivity extends Activity implements View.OnClickListen
mTvEndDate, mTvFullDescription, mTvCouponCodeTitle, mTvQrCodeTitle, mTvTermsText,
mTVMoreTitle, mTvMoreButton);
// Populate views with offer data
if (mOfferItem != null) {
mTvValue.setText(mOfferItem.getValue());
// mTvSmallDescription.setText(mOfferItem.getDescription());
// Store the full description text
mFullDescriptionText = mOfferItem.getFullDescription();
mTvFullDescription.setText(mFullDescriptionText);
// Format and set the end date
String endDate = mOfferItem.getEndDate();
if (endDate != null && !endDate.isEmpty()) {
// Convert from DD/MM/YYYY to DD-MM-YYYY
String formattedDate = endDate.replace("/", "-");
if (mOfferItem.getExpiration() != null && !mOfferItem.getExpiration().isEmpty()) {
String formattedDate = formatValidityDate(mOfferItem.getExpiration());
mTvEndDate.setText(getString(R.string.demo_valid_until, formattedDate));
mTvEndDate.setVisibility(View.VISIBLE);
} else {
mTvEndDate.setVisibility(View.GONE);
}
// Load image (in a real app, you would use an image loading library)
// For demo purposes, we'll use a placeholder
int imageResId = getResources().getIdentifier(
mOfferItem.getImageUrl().replace(".png", ""),
"drawable",
getPackageName());
if (imageResId != 0) {
mIvImage.setImageResource(imageResId);
if (mOfferItem.getCouponsetDetails() != null && mOfferItem.getCouponsetDetails().getImg_preview() != null && !TextUtils.isEmpty(mOfferItem.getCouponsetDetails().getImg_preview())) {
Glide.with(this)
// .setDefaultRequestOptions(
// RequestOptions
// .placeholderOf(R.drawable.demo_logo)
// .error(R.drawable.demo_logo))
.load(mOfferItem.getCouponsetDetails().getImg_preview())
.diskCacheStrategy(DiskCacheStrategy.DATA)
.into(mIvImage);
}
if (mOfferItem.getCouponsetDetails() != null && mOfferItem.getCouponsetDetails().getName() != null && !TextUtils.isEmpty(mOfferItem.getCouponsetDetails().getName()))
mTvValue.setText(mOfferItem.getCouponsetDetails().getName());
if (mOfferItem.getCouponsetDetails() != null && mOfferItem.getCouponsetDetails().getShort_description() != null && !TextUtils.isEmpty(mOfferItem.getCouponsetDetails().getShort_description()))
mTvSmallDescription.setText(mOfferItem.getCouponsetDetails().getShort_description());
if (mOfferItem.getCouponsetDetails() != null && mOfferItem.getCouponsetDetails().getDescription() != null && !TextUtils.isEmpty(mOfferItem.getCouponsetDetails().getDescription()))
mTvFullDescription.setText(HtmlCompat.fromHtml(mOfferItem.getCouponsetDetails().getDescription(), HtmlCompat.FROM_HTML_MODE_COMPACT));
if (mOfferItem.getCouponsetDetails() != null && mOfferItem.getCouponsetDetails().getTerms() != null && !TextUtils.isEmpty(mOfferItem.getCouponsetDetails().getTerms()))
mTvTermsText.setText(HtmlCompat.fromHtml(mOfferItem.getCouponsetDetails().getTerms(), HtmlCompat.FROM_HTML_MODE_COMPACT));
// Setup the More button
setupMoreButton();
......@@ -193,18 +201,26 @@ public class SingleCouponActivity extends Activity implements View.OnClickListen
}
}
/**
* Sets up the coupon code expandable section
*/
private void setupCouponCodeSection() {
// Set coupon code - using a hardcoded value for demo purposes
// In a real app, this would come from the offer item
String couponCode = "coupons_ab";
if (mOfferItem != null && mOfferItem.getId() != null) {
// Use offer ID as part of the coupon code for demo purposes
couponCode = "coupon_" + mOfferItem.getId().toLowerCase();
private String formatValidityDate(String endDate) {
try {
SimpleDateFormat inputFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
Date date = inputFormat.parse(endDate);
SimpleDateFormat outputFormat = new SimpleDateFormat("dd-MM", Locale.getDefault());
return "έως " + outputFormat.format(date);
} catch (ParseException e) {
try {
SimpleDateFormat inputFormat2 = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.getDefault());
Date date = inputFormat2.parse(endDate);
SimpleDateFormat outputFormat = new SimpleDateFormat("dd-MM", Locale.getDefault());
return "έως " + outputFormat.format(date);
} catch (ParseException e2) {
return endDate;
}
}
mTvCouponCode.setText(couponCode);
}
private void setupCouponCodeSection() {
mTvCouponCode.setText(mOfferItem.getCoupon());
// Set click listener for the header to expand/collapse
mCouponCodeHeader.setOnClickListener(new View.OnClickListener() {
......@@ -231,9 +247,6 @@ public class SingleCouponActivity extends Activity implements View.OnClickListen
});
}
/**
* Toggles between expanded and collapsed states for the coupon code section
*/
private void toggleCouponCodeExpansion() {
if (mIsCouponCodeExpanded) {
// Collapse the content
......@@ -248,9 +261,6 @@ public class SingleCouponActivity extends Activity implements View.OnClickListen
}
}
/**
* Copies the coupon code to the clipboard
*/
private void copyCouponCodeToClipboard() {
String couponCode = mTvCouponCode.getText().toString();
......@@ -267,9 +277,6 @@ public class SingleCouponActivity extends Activity implements View.OnClickListen
Toast.makeText(this, R.string.demo_copy_success, Toast.LENGTH_SHORT).show();
}
/**
* Sets up the "More" button for expanding/collapsing the description text
*/
private void setupMoreButton() {
// Wait for layout to be ready to check if text is truncated
mTvFullDescription.post(new Runnable() {
......@@ -292,9 +299,6 @@ public class SingleCouponActivity extends Activity implements View.OnClickListen
});
}
/**
* Toggles between expanded and collapsed states for the description text
*/
private void toggleDescriptionExpansion() {
if (mIsDescriptionExpanded) {
// Collapse the text
......@@ -309,9 +313,6 @@ public class SingleCouponActivity extends Activity implements View.OnClickListen
}
}
/**
* Sets up the QR code expandable section
*/
private void setupQrCodeSection() {
// Set click listener for the header to expand/collapse
mQrCodeHeader.setOnClickListener(new View.OnClickListener() {
......@@ -330,9 +331,6 @@ public class SingleCouponActivity extends Activity implements View.OnClickListen
});
}
/**
* Toggles between expanded and collapsed states for the QR code section
*/
private void toggleQrCodeExpansion() {
if (mIsQrCodeExpanded) {
// Collapse the content
......@@ -347,9 +345,6 @@ public class SingleCouponActivity extends Activity implements View.OnClickListen
}
}
/**
* Sets up the Terms of Use expandable section
*/
private void setupTermsSection() {
// Set click listener for the header to expand/collapse
mTermsHeader.setOnClickListener(new View.OnClickListener() {
......@@ -368,9 +363,6 @@ public class SingleCouponActivity extends Activity implements View.OnClickListen
});
}
/**
* Toggles between expanded and collapsed states for the Terms of Use section
*/
private void toggleTermsExpansion() {
if (mIsTermsExpanded) {
// Collapse the content
......
package ly.warp.sdk.activities;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.core.text.HtmlCompat;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import ly.warp.sdk.R;
import ly.warp.sdk.io.models.Couponset;
import ly.warp.sdk.utils.WarpUtils;
public class SingleCouponsetActivity extends Activity implements View.OnClickListener {
// ===========================================================
// Constants
// ===========================================================
public static final String EXTRA_OFFER_ITEM = "offer_item";
// ===========================================================
// Fields
// ===========================================================
private ImageView mIvBack;
private Couponset mOfferItem;
private TextView mTvSmallDescription;
private TextView mTvFullDescription;
private TextView mTvEndDate;
private TextView mTvValue;
private TextView mTvMoreButton;
private ImageView mIvImage;
private boolean mIsDescriptionExpanded = false;
// Terms of Use section
private LinearLayout mTermsContainer;
private LinearLayout mTermsHeader;
private LinearLayout mTermsContent;
private ImageView mIvTermsArrow;
private TextView mTvTermsText;
private boolean mIsTermsExpanded = false;
private TextView mTvHeaderTitle, mTvTermsTitle, mTvShopsTitle, mTvWebsiteTitle, mTVMoreTitle;
// ===========================================================
// Methods for/from SuperClass/Interfaces
// ===========================================================
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_single_couponset);
Intent intent = getIntent();
if (intent != null && intent.hasExtra(EXTRA_OFFER_ITEM)) {
mOfferItem = (Couponset) intent.getSerializableExtra(EXTRA_OFFER_ITEM);
}
initViews();
WarpUtils.applyEdgeToEdge(this,
findViewById(R.id.header_layout),
null);
}
@Override
public void onResume() {
super.onResume();
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.iv_back) {
onBackPressed();
}
}
// ===========================================================
// Methods
// ===========================================================
private void initViews() {
mIvBack = findViewById(R.id.iv_back);
mIvBack.setOnClickListener(this);
// Initialize views
mTvSmallDescription = findViewById(R.id.tv_coupon_small_description);
mTvFullDescription = findViewById(R.id.tv_coupon_full_description);
mTvEndDate = findViewById(R.id.tv_coupon_end_date);
mTvValue = findViewById(R.id.tv_coupon_value);
mIvImage = findViewById(R.id.iv_coupon_image);
mTvMoreButton = findViewById(R.id.tv_more_button);
// Initialize Terms of Use section
mTermsContainer = findViewById(R.id.terms_container);
mTermsHeader = findViewById(R.id.terms_header);
mTermsContent = findViewById(R.id.terms_content);
mIvTermsArrow = findViewById(R.id.iv_terms_arrow);
mTvTermsText = findViewById(R.id.tv_terms_text);
mTvHeaderTitle = findViewById(R.id.tv_header_title);
mTvTermsTitle = findViewById(R.id.tv_terms_title);
mTvShopsTitle = findViewById(R.id.tv_shops_title);
mTvWebsiteTitle = findViewById(R.id.tv_website_title);
mTVMoreTitle = findViewById(R.id.tv_more_title);
WarpUtils.renderCustomFont(this, R.font.ping_lcg_bold, mTvHeaderTitle, mTvValue,
mTvTermsTitle, mTvShopsTitle, mTvWebsiteTitle);
WarpUtils.renderCustomFont(this, R.font.ping_lcg_regular, mTvSmallDescription,
mTvEndDate, mTvFullDescription, mTvTermsText,
mTVMoreTitle, mTvMoreButton);
if (mOfferItem != null) {
if (mOfferItem.getEndDate() != null && !mOfferItem.getEndDate().isEmpty()) {
String formattedDate = formatValidityDate(mOfferItem.getEndDate());
mTvEndDate.setText(getString(R.string.demo_valid_until, formattedDate));
mTvEndDate.setVisibility(View.VISIBLE);
} else {
mTvEndDate.setVisibility(View.GONE);
}
if (!TextUtils.isEmpty(mOfferItem.getImg_preview())) {
Glide.with(this)
// .setDefaultRequestOptions(
// RequestOptions
// .placeholderOf(R.drawable.demo_logo)
// .error(R.drawable.demo_logo))
.load(mOfferItem.getImg_preview())
.diskCacheStrategy(DiskCacheStrategy.DATA)
.into(mIvImage);
}
if (!TextUtils.isEmpty(mOfferItem.getName()))
mTvValue.setText(mOfferItem.getName());
if (!TextUtils.isEmpty(mOfferItem.getShort_description()))
mTvSmallDescription.setText(mOfferItem.getShort_description());
if (!TextUtils.isEmpty(mOfferItem.getDescription()))
mTvFullDescription.setText(HtmlCompat.fromHtml(mOfferItem.getDescription(), HtmlCompat.FROM_HTML_MODE_COMPACT));
if (!TextUtils.isEmpty(mOfferItem.getTerms()))
mTvTermsText.setText(HtmlCompat.fromHtml(mOfferItem.getTerms(), HtmlCompat.FROM_HTML_MODE_COMPACT));
// Setup the More button
setupMoreButton();
// Setup Terms of Use section
setupTermsSection();
}
}
private void setupMoreButton() {
// Wait for layout to be ready to check if text is truncated
mTvFullDescription.post(new Runnable() {
@Override
public void run() {
// Check if text is truncated (more than 4 lines)
if (mTvFullDescription.getLineCount() > 3) {
// Show the More button
mTvMoreButton.setVisibility(View.VISIBLE);
// Set click listener for the More button
mTvMoreButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
toggleDescriptionExpansion();
}
});
}
}
});
}
private void toggleDescriptionExpansion() {
if (mIsDescriptionExpanded) {
// Collapse the text
mTvFullDescription.setMaxLines(4);
mTvMoreButton.setText(R.string.demo_more);
mIsDescriptionExpanded = false;
} else {
// Expand the text
mTvFullDescription.setMaxLines(Integer.MAX_VALUE);
mTvMoreButton.setText(R.string.demo_less);
mIsDescriptionExpanded = true;
}
}
private void setupTermsSection() {
// Set click listener for the header to expand/collapse
mTermsHeader.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
toggleTermsExpansion();
}
});
// Set click listener for the entire container as well
mTermsContainer.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
toggleTermsExpansion();
}
});
}
private void toggleTermsExpansion() {
if (mIsTermsExpanded) {
// Collapse the content
mTermsContent.setVisibility(View.GONE);
mIvTermsArrow.setImageResource(R.drawable.ic_arrow_down);
mIsTermsExpanded = false;
} else {
// Expand the content
mTermsContent.setVisibility(View.VISIBLE);
mIvTermsArrow.setImageResource(R.drawable.ic_arrow_up);
mIsTermsExpanded = true;
}
}
private String formatValidityDate(String endDate) {
try {
SimpleDateFormat inputFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
Date date = inputFormat.parse(endDate);
SimpleDateFormat outputFormat = new SimpleDateFormat("dd-MM", Locale.getDefault());
return "έως " + outputFormat.format(date);
} catch (ParseException e) {
try {
SimpleDateFormat inputFormat2 = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.getDefault());
Date date = inputFormat2.parse(endDate);
SimpleDateFormat outputFormat = new SimpleDateFormat("dd-MM", Locale.getDefault());
return "έως " + outputFormat.format(date);
} catch (ParseException e2) {
return endDate;
}
}
}
// ===========================================================
// Inner and Anonymous Classes
// ===========================================================
}
package ly.warp.sdk.io.adapters;
import android.content.Context;
import android.text.TextUtils;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
......@@ -12,17 +13,17 @@ import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.resource.bitmap.CenterCrop;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import ly.warp.sdk.R;
import ly.warp.sdk.io.models.CouponItem;
import ly.warp.sdk.io.models.Coupon;
import ly.warp.sdk.utils.TopRoundedCornersTransformation;
import ly.warp.sdk.utils.WarpUtils;
......@@ -31,18 +32,19 @@ import ly.warp.sdk.utils.WarpUtils;
*/
public class CouponAdapter extends RecyclerView.Adapter<CouponAdapter.CouponViewHolder> {
private final List<CouponItem> allCouponItems;
private List<CouponItem> filteredCouponItems;
private final ArrayList<Coupon> allCouponItems;
private ArrayList<Coupon> filteredCouponItems;
private final Context context;
private OnCouponClickListener listener;
private String currentFilter = null;
private int currentFilter = 0;
/**
* Interface for handling coupon item clicks
*/
public interface OnCouponClickListener {
void onCouponClick(CouponItem couponItem, int position);
void onFavoriteClick(CouponItem couponItem, int position);
void onCouponClick(Coupon couponItem, int position);
void onFavoriteClick(Coupon couponItem, int position);
}
/**
......@@ -51,10 +53,10 @@ public class CouponAdapter extends RecyclerView.Adapter<CouponAdapter.CouponView
* @param context The context
* @param couponItems List of coupon items to display
*/
public CouponAdapter(Context context, List<CouponItem> couponItems) {
public CouponAdapter(Context context, ArrayList<Coupon> couponItems) {
this.context = context;
this.allCouponItems = couponItems;
this.filteredCouponItems = new ArrayList<>(couponItems);
this.filteredCouponItems = couponItems;
}
/**
......@@ -71,22 +73,20 @@ public class CouponAdapter extends RecyclerView.Adapter<CouponAdapter.CouponView
*
* @param status The status to filter by (active, favorite, redeemed) or null for all
*/
public void filterByStatus(String status) {
public void filterByStatus(int status) {
currentFilter = status;
filteredCouponItems.clear();
if (status == null) {
// Show all coupons
if (status == 0) {
filteredCouponItems.addAll(allCouponItems);
} else {
// Filter by status
for (CouponItem coupon : allCouponItems) {
if (status.equals(coupon.getStatus())) {
for (Coupon coupon : allCouponItems) {
if (status == coupon.getStatus()) {
filteredCouponItems.add(coupon);
}
}
}
notifyDataSetChanged();
}
......@@ -99,7 +99,7 @@ public class CouponAdapter extends RecyclerView.Adapter<CouponAdapter.CouponView
@Override
public void onBindViewHolder(@NonNull CouponViewHolder holder, int position) {
CouponItem couponItem = filteredCouponItems.get(position);
Coupon couponItem = filteredCouponItems.get(position);
holder.bind(couponItem, position);
}
......@@ -149,102 +149,71 @@ public class CouponAdapter extends RecyclerView.Adapter<CouponAdapter.CouponView
});
}
void bind(CouponItem couponItem, int position) {
// Set coupon data to views
tvTitle.setText(couponItem.getTitle());
tvDescription.setText(couponItem.getDescription());
tvPrice.setText(couponItem.getValue());
tvValidity.setText(formatValidityDate(couponItem.getEndDate()));
// Set heart icon based on favorite status
if (couponItem.isFavorite()) {
// Use pressed/filled heart for Favorites
ivFavorite.setImageResource(R.drawable.demo_heart_pressed);
void bind(Coupon couponItem, int position) {
tvTitle.setText(!TextUtils.isEmpty(couponItem.getCouponsetDetails().getName()) ? couponItem.getCouponsetDetails().getName() : "");
tvDescription.setText(!TextUtils.isEmpty(couponItem.getCouponsetDetails().getShort_description()) ? couponItem.getCouponsetDetails().getShort_description() : "");
tvPrice.setText(!TextUtils.isEmpty(couponItem.getDiscount()) ? couponItem.getDiscount() : "");
if (couponItem.getCouponsetDetails().getEndDate() != null && !couponItem.getCouponsetDetails().getEndDate().isEmpty()) {
tvValidity.setText(formatValidityDate(couponItem.getCouponsetDetails().getEndDate()));
tvValidity.setVisibility(View.VISIBLE);
} else {
// Use default/empty heart for other statuses
ivFavorite.setImageResource(R.drawable.demo_heart);
tvValidity.setVisibility(View.GONE);
}
// Load images from resources
loadOfferImage(couponItem.getImageUrl());
loadLogoImage(couponItem.getLogoUrl());
// Set heart icon based on favorite status
// if (couponItem.isFavorite()) {
// // Use pressed/filled heart for Favorites
// ivFavorite.setImageResource(R.drawable.demo_heart_pressed);
// } else {
// // Use default/empty heart for other statuses
// ivFavorite.setImageResource(R.drawable.demo_heart);
// }
loadCouponImage(couponItem.getCouponsetDetails().getImg_preview());
loadMerchantLogo(couponItem.getMerchantDetails().getImgPreview());
}
/**
* Format the end date to "έως dd-MM" format
*
* @param endDate The end date in "dd/MM/yyyy" format
* @return Formatted date string
*/
private String formatValidityDate(String endDate) {
try {
SimpleDateFormat inputFormat = new SimpleDateFormat("dd/MM/yyyy", Locale.getDefault());
SimpleDateFormat inputFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
Date date = inputFormat.parse(endDate);
SimpleDateFormat outputFormat = new SimpleDateFormat("dd-MM", Locale.getDefault());
return "έως " + outputFormat.format(date);
} catch (ParseException e) {
// Fallback to original if parsing fails
return endDate;
try {
SimpleDateFormat inputFormat2 = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.getDefault());
Date date = inputFormat2.parse(endDate);
SimpleDateFormat outputFormat = new SimpleDateFormat("dd-MM", Locale.getDefault());
return "έως " + outputFormat.format(date);
} catch (ParseException e2) {
return endDate;
}
}
}
/**
* Load offer image with rounded top corners using Glide
*
* @param imageName The image resource name
*/
private void loadOfferImage(String imageName) {
try {
// Remove file extension if present
if (imageName.contains(".")) {
imageName = imageName.substring(0, imageName.lastIndexOf('.'));
}
// Get resource ID by name
int resourceId = context.getResources().getIdentifier(
imageName, "drawable", context.getPackageName());
if (resourceId != 0) {
// Convert 9dp to pixels
int radiusInPixels = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 9,
context.getResources().getDisplayMetrics());
// Load with Glide and apply transformations
Glide.with(context)
.load(resourceId)
.transform(new CenterCrop(), new TopRoundedCornersTransformation(radiusInPixels))
.into(ivOfferImage);
}
} catch (Exception e) {
e.printStackTrace();
private void loadCouponImage(String imageUrl) {
if (imageUrl != null && !imageUrl.isEmpty()) {
int radiusInPixels = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 9,
context.getResources().getDisplayMetrics());
Glide.with(context)
.load(imageUrl)
.diskCacheStrategy(DiskCacheStrategy.DATA)
.transform(new CenterCrop(), new TopRoundedCornersTransformation(radiusInPixels))
.into(ivOfferImage);
}
}
/**
* Load logo image without transformations
*
* @param imageName The image resource name
*/
private void loadLogoImage(String imageName) {
try {
// Remove file extension if present
if (imageName.contains(".")) {
imageName = imageName.substring(0, imageName.lastIndexOf('.'));
}
// Get resource ID by name
int resourceId = context.getResources().getIdentifier(
imageName, "drawable", context.getPackageName());
if (resourceId != 0) {
// Load logo normally without transformations
ivLogo.setImageResource(resourceId);
}
} catch (Exception e) {
e.printStackTrace();
private void loadMerchantLogo(String logoUrl) {
if (logoUrl != null && !logoUrl.isEmpty()) {
ivLogo.setVisibility(View.VISIBLE);
Glide.with(context)
.load(logoUrl)
.diskCacheStrategy(DiskCacheStrategy.DATA)
.into(ivLogo);
} else {
ivLogo.setVisibility(View.GONE);
}
}
}
......
......@@ -5,7 +5,6 @@ import java.util.concurrent.TimeUnit;
import ly.warp.sdk.Warply;
import ly.warp.sdk.utils.WarplyProperty;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
......@@ -49,11 +48,11 @@ public class ApiClient {
private static OkHttpClient getClient() {
/* Logs Enabled */
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
// HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
// interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
return new OkHttpClient.Builder()
.addInterceptor(interceptor) // Logs Enabled
// .addInterceptor(interceptor) // Logs Enabled
.connectTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
......
......@@ -971,7 +971,7 @@ public class WarpUtils {
if (topView != null) {
topView.setPadding(
topView.getPaddingLeft(),
insets.top,
topView.getPaddingTop() + insets.top,
topView.getPaddingRight(),
topView.getPaddingBottom()
);
......@@ -983,7 +983,7 @@ public class WarpUtils {
bottomView.getPaddingLeft(),
bottomView.getPaddingTop(),
bottomView.getPaddingRight(),
insets.bottom
bottomView.getPaddingBottom() + insets.bottom
);
}
......
......@@ -35,6 +35,7 @@ import ly.warp.sdk.Warply;
import ly.warp.sdk.db.WarplyDBHelper;
import ly.warp.sdk.io.models.BannerItem;
import ly.warp.sdk.io.models.Campaign;
import ly.warp.sdk.io.models.Coupon;
import ly.warp.sdk.io.models.CouponList;
import ly.warp.sdk.io.models.Couponset;
import ly.warp.sdk.utils.managers.WarplyManager;
......@@ -54,6 +55,7 @@ public class WarplyManagerHelper {
// ===========================================================
private static CouponList mCouponRedeemedList = new CouponList();
private static ArrayList<Coupon> mCouponList = new ArrayList<Coupon>();
private static ArrayList<Campaign> mCampaignListAll = new ArrayList<Campaign>();
private static ArrayList<BannerItem> mBannerListAll = new ArrayList<BannerItem>();
private static LinkedHashMap<String, ArrayList<Couponset>> mCouponsetCategorizedMap = new LinkedHashMap<>();
......@@ -98,6 +100,15 @@ public class WarplyManagerHelper {
mCouponRedeemedList.addAll(couponRedeemedList);
}
public static void setCoupons(ArrayList<Coupon> couponList) {
mCouponList.clear();
mCouponList.addAll(couponList);
}
public static ArrayList<Coupon> getCoupons() {
return mCouponList;
}
public static String constructCampaignUrl(Campaign item) {
WarplyManager.getSingleCampaign(item.getSessionUUID());
String url = item.getIndexUrl();
......
......@@ -49,7 +49,6 @@ public class WarplyProperty {
public static final String KEY_LOGIN_TYPE = "LoginType";
public static final String KEY_DL_URL_SCHEME = "DL_URL_SCHEME";
public static final String KEY_BASE_URL = "BaseURL";
public static final String KEY_VERIFY_URL = "VerifyURL";
// ===========================================================
// Methods
......@@ -204,10 +203,6 @@ public class WarplyProperty {
return getWarplyProperty(context, KEY_BASE_URL);
}
public static String getVerifyUrl(Context context) {
return getWarplyProperty(context, KEY_VERIFY_URL);
}
public static boolean isSendPackages(Context context) {
return Boolean.parseBoolean(getWarplyProperty(context, KEY_SEND_PACKAGES));
}
......
......@@ -61,7 +61,6 @@ import ly.warp.sdk.io.models.BannerItem;
import ly.warp.sdk.io.models.Campaign;
import ly.warp.sdk.io.models.Content;
import ly.warp.sdk.io.models.Coupon;
import ly.warp.sdk.io.models.CouponList;
import ly.warp.sdk.io.models.Couponset;
import ly.warp.sdk.io.models.Merchant;
import ly.warp.sdk.io.models.User;
......@@ -371,7 +370,7 @@ public class WarplyManager {
});
}
public static void getUserCouponsWithCouponsets(final CallbackReceiver<CouponList> receiver) {
public static void getCoupons(final CallbackReceiver<ArrayList<Coupon>> receiver) {
WarpUtils.log("************* WARPLY User Coupons Request ********************");
WarpUtils.log("[WARP Trace] WARPLY User Coupons Request is active");
WarpUtils.log("**************************************************");
......@@ -379,18 +378,18 @@ public class WarplyManager {
ApiService service = ApiClient.getRetrofitInstance().create(ApiService.class);
ListeningExecutorService executorService = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(1));
SettableFuture<CouponList> futureUniversal = SettableFuture.create();
ListenableFuture<CouponList> futureCoupons = getCouponsUniversalRetro(service, 0, futureUniversal);
SettableFuture<ArrayList<Coupon>> futureUniversal = SettableFuture.create();
ListenableFuture<ArrayList<Coupon>> futureCoupons = getCouponsUniversalRetro(service, 0, futureUniversal);
ListenableFuture<List<Object>> allResultsFuture = Futures.allAsList(futureCoupons);
ListenableFuture<CouponList> mergedResultFuture = Futures.transformAsync(allResultsFuture, results -> {
CouponList resultCoupons = (CouponList) results.get(0);
ListenableFuture<ArrayList<Coupon>> mergedResultFuture = Futures.transformAsync(allResultsFuture, results -> {
ArrayList<Coupon> resultCoupons = (ArrayList<Coupon>) results.get(0);
return executorService.submit(() -> resultCoupons);
}, executorService);
Futures.addCallback(mergedResultFuture, new FutureCallback<CouponList>() {
Futures.addCallback(mergedResultFuture, new FutureCallback<ArrayList<Coupon>>() {
@Override
public void onSuccess(CouponList mergedResult) {
public void onSuccess(ArrayList<Coupon> mergedResult) {
executorService.shutdownNow();
new Handler(Looper.getMainLooper()).post(() -> receiver.onSuccess(mergedResult));
}
......@@ -463,7 +462,7 @@ public class WarplyManager {
ApiService service = ApiClient.getRetrofitInstance().create(ApiService.class);
ListeningExecutorService executorService = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(2));
ListenableFuture<ArrayList<Couponset>> futureCouponsets = getCouponsetsRetro(service);
ListenableFuture<ArrayList<Couponset>> futureCouponsets = getCouponsetsRetro(service, 0);
ListenableFuture<ArrayList<Merchant>> futureMerchants = getMerchantsRetro(service);
ListenableFuture<List<Object>> allResultsFuture = Futures.allAsList(futureCouponsets, futureMerchants);
......@@ -488,7 +487,7 @@ public class WarplyManager {
}, executorService);
}
private static ListenableFuture<ArrayList<Couponset>> getCouponsetsRetro(ApiService service/*, Callback<ResponseBody> callback*/) {
private static ListenableFuture<ArrayList<Couponset>> getCouponsetsRetro(ApiService service, int tries/*, Callback<ResponseBody> callback*/) {
SettableFuture<ArrayList<Couponset>> future = SettableFuture.create();
String timeStamp = DateFormat.format("yyyy-MM-dd hh:mm:ss", System.currentTimeMillis()).toString();
......@@ -550,6 +549,31 @@ public class WarplyManager {
} else {
future.set(new ArrayList<Couponset>());
}
} else if (response.code() == 401) {
refreshToken(new WarplyRefreshTokenRequest(), new CallbackReceiver<JSONObject>() {
@Override
public void onSuccess(JSONObject result) {
int status = result.optInt("status", 2);
if (status == 1)
getCouponsetsRetro(service, tries);
else {
if (tries < MAX_RETRIES) {
getCouponsetsRetro(service, (tries + 1));
} else {
future.setException(new Throwable());
}
}
}
@Override
public void onFailure(int errorCode) {
if (tries < MAX_RETRIES) {
getCouponsetsRetro(service, (tries + 1));
} else {
future.setException(new Throwable());
}
}
});
} else if (String.valueOf(response.code()).startsWith("5")) {
future.set(new ArrayList<Couponset>());
} else {
......@@ -985,7 +1009,7 @@ public class WarplyManager {
return future;
}
private static ListenableFuture<CouponList> getCouponsUniversalRetro(ApiService service, int tries, SettableFuture<CouponList> future) {
private static ListenableFuture<ArrayList<Coupon>> getCouponsUniversalRetro(ApiService service, int tries, SettableFuture<ArrayList<Coupon>> future) {
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());
......@@ -995,17 +1019,8 @@ public class WarplyManager {
jsonParams.put("action", "user_coupons");
JSONArray jArr = new JSONArray();
jArr.put("merchant");
jArr.put("redemption");
jsonParams.put("details", jArr);
jsonParams.put("language", WarpUtils.getApplicationLocale(Warply.getWarplyContext()));
// JSONObject jPagination= new JSONObject();
// try {
// jPagination.putOpt("page",1);
// jPagination.putOpt("per_page", 10);
// } catch (JSONException e) {
// throw new RuntimeException(e);
// }
// jsonParams.put("pagination", jPagination);
// jsonParams.put("language", WarpUtils.getApplicationLocale(Warply.getWarplyContext()));
jsonParamsCoupons.put("coupon", jsonParams);
RequestBody couponsRequest = RequestBody.create(MediaType.get("application/json; charset=utf-8"), (new JSONObject(jsonParamsCoupons)).toString());
......@@ -1032,32 +1047,29 @@ public class WarplyManager {
}
if (jCouponsBody != null) {
CouponList mCouponRedeemedList = new CouponList();
ArrayList<Coupon> mCouponList = new ArrayList<Coupon>();
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);
if (tempCoupon.getStatus() == 0) {
mCouponRedeemedList.add(tempCoupon);
}
mCouponList.add(tempCoupon);
}
WarplyManagerHelper.setCouponRedeemedList(mCouponRedeemedList);
WarplyManagerHelper.setCoupons(mCouponList);
Collections.sort(mCouponRedeemedList, (coupon1, coupon2) -> coupon1.getExpirationDate().compareTo(coupon2.getExpirationDate()));
Collections.sort(mCouponList, (coupon1, coupon2) -> coupon1.getExpirationDate().compareTo(coupon2.getExpirationDate()));
executorCoupons.shutdownNow();
future.set(mCouponRedeemedList);
future.set(mCouponList);
});
} else {
future.set(new CouponList());
future.set(new ArrayList<Coupon>());
}
} else {
future.set(new CouponList());
future.set(new ArrayList<Coupon>());
}
} else if (response.code() == 401) {
refreshToken(new WarplyRefreshTokenRequest(), new CallbackReceiver<JSONObject>() {
......@@ -1071,7 +1083,7 @@ public class WarplyManager {
if (tries < MAX_RETRIES) {
getCouponsUniversalRetro(service, (tries + 1), future);
} else {
// future.set(new CouponList());
// future.set(new ArrayList<Coupon>());
future.setException(new Throwable());
}
}
......@@ -1083,20 +1095,20 @@ public class WarplyManager {
if (tries < MAX_RETRIES) {
getCouponsUniversalRetro(service, (tries + 1), future);
} else {
// future.set(new CouponList());
// future.set(new ArrayList<Coupon>());
future.setException(new Throwable());
}
}
});
} else {
// future.set(new CouponList());
// future.set(new ArrayList<Coupon>());
future.setException(new Throwable());
}
}
@Override
public void onFailure(@NonNull Call<ResponseBody> call, @NonNull Throwable t) {
// future.set(new CouponList());
// future.set(new ArrayList<Coupon>());
future.setException(new Throwable());
}
});
......
......@@ -25,7 +25,8 @@
android:background="@color/custom_grey_light"
android:orientation="horizontal"
android:paddingHorizontal="16dp"
android:paddingVertical="16dp">
android:paddingBottom="16dp"
android:paddingTop="16dp">
<LinearLayout
android:layout_width="0dp"
......@@ -104,12 +105,19 @@
</RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<LinearLayout
android:id="@+id/ll_sections_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="48dp"
android:paddingBottom="16dp"
android:orientation="vertical" />
<RelativeLayout
android:id="@+id/rl_sections_loading"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:layout_marginTop="48dp"
android:translationZ="100dp"
android:visibility="gone"
tools:visibility="visible">
......@@ -122,13 +130,6 @@
android:indeterminateTint="@color/custom_light_blue"
android:indeterminateTintMode="src_atop" />
</RelativeLayout>
<LinearLayout
android:id="@+id/ll_sections_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="48dp"
android:orientation="vertical" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</RelativeLayout>
......
......@@ -223,6 +223,25 @@
android:clipToPadding="false"
android:nestedScrollingEnabled="false"
android:paddingHorizontal="16dp" />
<RelativeLayout
android:id="@+id/pb_loading"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:layout_marginTop="64dp"
android:translationZ="100dp"
android:visibility="gone"
tools:visibility="visible">
<ProgressBar
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_centerInParent="true"
android:indeterminate="true"
android:indeterminateTint="@color/custom_light_blue"
android:indeterminateTintMode="src_atop" />
</RelativeLayout>
</RelativeLayout>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
......
......@@ -59,8 +59,7 @@
android:id="@+id/iv_coupon_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY"
tools:src="@drawable/demo_home_banner1"
android:scaleType="centerCrop"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
......@@ -280,7 +279,7 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/demo_qr_code"
android:text="@string/demo_barcode_code"
android:textColor="@color/custom_black2"
android:textSize="15sp" />
......@@ -303,10 +302,10 @@
<ImageView
android:id="@+id/iv_qr_code"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_height="120dp"
android:layout_marginVertical="16dp"
android:scaleType="fitCenter"
android:src="@drawable/demo_qr" />
android:src="@drawable/demo_barcode" />
</LinearLayout>
</LinearLayout>
......
......@@ -87,7 +87,6 @@
app:layout_constraintBottom_toBottomOf="parent"
tools:text="έως 30-09" />
<!-- Brand Logo -->
<ImageView
android:id="@+id/iv_logo"
android:layout_width="80dp"
......
......@@ -16,7 +16,8 @@
android:layout_height="wrap_content"
android:background="@android:color/white"
android:paddingHorizontal="16dp"
android:paddingVertical="16dp">
android:paddingBottom="16dp"
android:paddingTop="16dp">
<ImageView
android:id="@+id/user_img"
......
......@@ -15,6 +15,7 @@
<string name="demo_valid_until">Η προσφορά ισχύει έως %1$s</string>
<string name="demo_coupon_code">Κωδικός Κουπονιού</string>
<string name="demo_qr_code">QR Κουπονιού</string>
<string name="demo_barcode_code">Barcode Κουπονιού</string>
<string name="demo_terms">Όροι Χρήσης</string>
<string name="demo_copy_success">Ο κωδικός αντιγράφηκε στο πρόχειρο</string>
<string name="demo_lorem_ipsum">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</string>
......