NekoX/TMessagesProj/src/main/java/org/telegram/ui/Components/Premium/GiftPremiumBottomSheet.java

559 lines
26 KiB
Java

package org.telegram.ui.Components.Premium;
import android.annotation.SuppressLint;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.net.Uri;
import android.os.Bundle;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.TextPaint;
import android.text.style.ClickableSpan;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.android.billingclient.api.BillingClient;
import com.android.billingclient.api.BillingFlowParams;
import com.android.billingclient.api.ProductDetails;
import com.android.billingclient.api.QueryProductDetailsParams;
import org.telegram.messenger.AccountInstance;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.BillingController;
import org.telegram.messenger.BuildVars;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MessagesController;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R;
import org.telegram.messenger.browser.Browser;
import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.ActionBarLayout;
import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Cells.TextInfoPrivacyCell;
import org.telegram.ui.ChatActivity;
import org.telegram.ui.Components.AlertsCreator;
import org.telegram.ui.Components.BottomSheetWithRecyclerListView;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.RecyclerListView;
import org.telegram.ui.LaunchActivity;
import org.telegram.ui.PremiumPreviewFragment;
import org.telegram.ui.ProfileActivity;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
public class GiftPremiumBottomSheet extends BottomSheetWithRecyclerListView {
private PremiumGradient.GradientTools gradientTools;
private PremiumGradient.GradientTools outlineGradient;
private PremiumButtonView premiumButtonView;
private PremiumGiftTierCell dummyCell;
private List<GiftTier> giftTiers = new ArrayList<>();
private int selectedTierIndex = 0;
private int totalGradientHeight;
private int rowsCount;
private int headerRow;
private int tiersStartRow;
private int tiersEndRow;
private int footerRow;
private int buttonRow;
private TLRPC.User user;
@SuppressLint("NotifyDataSetChanged")
public GiftPremiumBottomSheet(BaseFragment fragment, TLRPC.User user) {
super(fragment, false, true);
this.user = user;
gradientTools = new PremiumGradient.GradientTools(Theme.key_premiumGradient1, Theme.key_premiumGradient2, null, null);
gradientTools.exactly = true;
gradientTools.x1 = 0;
gradientTools.y1 = 0f;
gradientTools.x2 = 0;
gradientTools.y2 = 1f;
gradientTools.cx = 0;
gradientTools.cy = 0;
outlineGradient = new PremiumGradient.GradientTools(Theme.key_premiumGradient1, Theme.key_premiumGradient2, Theme.key_premiumGradient3, Theme.key_premiumGradient4);
outlineGradient.paint.setStyle(Paint.Style.STROKE);
outlineGradient.paint.setStrokeWidth(AndroidUtilities.dp(1.5f));
dummyCell = new PremiumGiftTierCell(getContext());
TLRPC.UserFull userFull = MessagesController.getInstance(currentAccount).getUserFull(user.id);
if (userFull != null) {
List<QueryProductDetailsParams.Product> products = new ArrayList<>();
long pricePerMonthMax = 0;
for (TLRPC.TL_premiumGiftOption option : userFull.premium_gifts) {
GiftTier giftTier = new GiftTier(option);
giftTiers.add(giftTier);
if (BuildVars.useInvoiceBilling()) {
if (giftTier.getPricePerMonth() > pricePerMonthMax) {
pricePerMonthMax = giftTier.getPricePerMonth();
}
} else if (giftTier.giftOption.store_product != null && BillingController.getInstance().isReady()) {
products.add(QueryProductDetailsParams.Product.newBuilder()
.setProductType(BillingClient.ProductType.INAPP)
.setProductId(giftTier.giftOption.store_product)
.build());
}
}
if (BuildVars.useInvoiceBilling()) {
for (GiftTier tier : giftTiers) {
tier.setPricePerMonthRegular(pricePerMonthMax);
}
} else if (!products.isEmpty()) {
long startMs = System.currentTimeMillis();
BillingController.getInstance().queryProductDetails(products, (billingResult, list) -> {
long pricePerMonthMaxStore = 0;
for (ProductDetails details : list) {
for (GiftTier giftTier : giftTiers) {
if (giftTier.giftOption.store_product != null && giftTier.giftOption.store_product.equals(details.getProductId())) {
giftTier.setGooglePlayProductDetails(details);
if (giftTier.getPricePerMonth() > pricePerMonthMaxStore) {
pricePerMonthMaxStore = giftTier.getPricePerMonth();
}
break;
}
}
}
for (GiftTier giftTier : giftTiers) {
giftTier.setPricePerMonthRegular(pricePerMonthMaxStore);
}
AndroidUtilities.runOnUIThread(()-> {
recyclerListView.getAdapter().notifyDataSetChanged();
updateButtonText(System.currentTimeMillis() - startMs > 1000);
});
});
}
}
if (!giftTiers.isEmpty()) {
selectedTierIndex = 0;
updateButtonText(false);
}
headerRow = rowsCount++;
tiersStartRow = rowsCount;
rowsCount += giftTiers.size();
tiersEndRow = rowsCount;
footerRow = rowsCount++;
buttonRow = rowsCount++;
recyclerListView.setOnItemClickListener((view, position) -> {
if (view instanceof PremiumGiftTierCell) {
PremiumGiftTierCell giftTierCell = (PremiumGiftTierCell) view;
selectedTierIndex = giftTiers.indexOf(giftTierCell.tier);
updateButtonText(true);
giftTierCell.setChecked(true, true);
for (int i = 0; i < recyclerListView.getChildCount(); i++) {
View ch = recyclerListView.getChildAt(i);
if (ch instanceof PremiumGiftTierCell) {
PremiumGiftTierCell otherCell = (PremiumGiftTierCell) ch;
if (otherCell.tier != giftTierCell.tier) {
otherCell.setChecked(false, true);
}
}
}
for (int i = 0; i < recyclerListView.getHiddenChildCount(); i++) {
View ch = recyclerListView.getHiddenChildAt(i);
if (ch instanceof PremiumGiftTierCell) {
PremiumGiftTierCell otherCell = (PremiumGiftTierCell) ch;
if (otherCell.tier != giftTierCell.tier) {
otherCell.setChecked(false, true);
}
}
}
for (int i = 0; i < recyclerListView.getCachedChildCount(); i++) {
View ch = recyclerListView.getCachedChildAt(i);
if (ch instanceof PremiumGiftTierCell) {
PremiumGiftTierCell otherCell = (PremiumGiftTierCell) ch;
if (otherCell.tier != giftTierCell.tier) {
otherCell.setChecked(false, true);
}
}
}
for (int i = 0; i < recyclerListView.getAttachedScrapChildCount(); i++) {
View ch = recyclerListView.getAttachedScrapChildAt(i);
if (ch instanceof PremiumGiftTierCell) {
PremiumGiftTierCell otherCell = (PremiumGiftTierCell) ch;
if (otherCell.tier != giftTierCell.tier) {
otherCell.setChecked(false, true);
}
}
}
}
});
recyclerListView.setOverScrollMode(View.OVER_SCROLL_NEVER);
Path path = new Path();
recyclerListView.setSelectorTransformer(canvas -> {
path.rewind();
Rect selectorRect = recyclerListView.getSelectorRect();
AndroidUtilities.rectTmp.set(selectorRect.left + AndroidUtilities.dp(20), selectorRect.top + AndroidUtilities.dp(3), selectorRect.right - AndroidUtilities.dp(20), selectorRect.bottom - AndroidUtilities.dp(3));
path.addRoundRect(AndroidUtilities.rectTmp, AndroidUtilities.dp(12), AndroidUtilities.dp(12), Path.Direction.CW);
canvas.clipPath(path);
});
}
private void updateButtonText(boolean animated) {
if (!BuildVars.useInvoiceBilling() && (!BillingController.getInstance().isReady() || giftTiers.get(selectedTierIndex).googlePlayProductDetails == null)) {
premiumButtonView.setButton(LocaleController.getString(R.string.Loading), v -> {}, true);
premiumButtonView.setFlickerDisabled(true);
return;
}
premiumButtonView.setButton(LocaleController.formatString(R.string.GiftSubscriptionFor, giftTiers.get(selectedTierIndex).getFormattedPrice()), v -> onGiftPremium(), animated);
premiumButtonView.setFlickerDisabled(false);
}
private void onGiftSuccess(boolean fromGooglePlay) {
TLRPC.UserFull full = MessagesController.getInstance(currentAccount).getUserFull(user.id);
if (full != null) {
user.premium = true;
MessagesController.getInstance(currentAccount).putUser(user, true);
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.userInfoDidLoad, user.id, full);
}
if (getBaseFragment() != null) {
List<BaseFragment> fragments = new ArrayList<>(((LaunchActivity) getBaseFragment().getParentActivity()).getActionBarLayout().fragmentsStack);
ActionBarLayout layout = getBaseFragment().getParentLayout();
ChatActivity lastChatActivity = null;
for (BaseFragment fragment : fragments) {
if (fragment instanceof ChatActivity) {
lastChatActivity = (ChatActivity) fragment;
if (lastChatActivity.getDialogId() != user.id) {
fragment.removeSelfFromStack();
}
} else if (fragment instanceof ProfileActivity) {
if (fromGooglePlay && layout.getLastFragment() == fragment) {
fragment.finishFragment();
} else {
fragment.removeSelfFromStack();
}
}
}
if (lastChatActivity == null || lastChatActivity.getDialogId() != user.id) {
Bundle args = new Bundle();
args.putLong("user_id", user.id);
layout.presentFragment(new ChatActivity(args), true);
}
}
}
private void onGiftPremium() {
GiftTier tier = giftTiers.get(selectedTierIndex);
if (BuildVars.useInvoiceBilling()) {
if (getBaseFragment().getParentActivity() instanceof LaunchActivity) {
Uri uri = Uri.parse(tier.giftOption.bot_url);
if (uri.getHost().equals("t.me")) {
if (!uri.getPath().startsWith("/$") && !uri.getPath().startsWith("/invoice/")) {
((LaunchActivity) getBaseFragment().getParentActivity()).setNavigateToPremiumBot(true);
} else {
((LaunchActivity) getBaseFragment().getParentActivity()).setNavigateToPremiumGiftCallback(()-> onGiftSuccess(false));
}
}
Browser.openUrl(getBaseFragment().getParentActivity(), tier.giftOption.bot_url);
}
} else {
if (BillingController.getInstance().isReady() && tier.googlePlayProductDetails != null) {
TLRPC.TL_inputStorePaymentGiftPremium giftPremium = new TLRPC.TL_inputStorePaymentGiftPremium();
giftPremium.user_id = MessagesController.getInstance(currentAccount).getInputUser(user);
ProductDetails.OneTimePurchaseOfferDetails offerDetails = tier.googlePlayProductDetails.getOneTimePurchaseOfferDetails();
giftPremium.currency = offerDetails.getPriceCurrencyCode();
giftPremium.amount = (long) ((offerDetails.getPriceAmountMicros() / Math.pow(10, 6)) * Math.pow(10, BillingController.getInstance().getCurrencyExp(giftPremium.currency)));
BillingController.getInstance().addResultListener(tier.giftOption.store_product, billingResult -> {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
AndroidUtilities.runOnUIThread(()-> onGiftSuccess(true));
}
});
TLRPC.TL_payments_canPurchasePremium req = new TLRPC.TL_payments_canPurchasePremium();
req.purpose = giftPremium;
ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(()->{
if (response instanceof TLRPC.TL_boolTrue) {
BillingController.getInstance().launchBillingFlow(getBaseFragment().getParentActivity(), AccountInstance.getInstance(currentAccount), giftPremium, Collections.singletonList(BillingFlowParams.ProductDetailsParams.newBuilder()
.setProductDetails(tier.googlePlayProductDetails)
.build()));
} else if (error != null) {
AlertsCreator.processError(currentAccount, error, getBaseFragment(), req);
}
}));
}
}
}
@Override
public void onViewCreated(FrameLayout containerView) {
super.onViewCreated(containerView);
premiumButtonView = new PremiumButtonView(getContext(), true);
FrameLayout buttonContainer = new FrameLayout(getContext());
buttonContainer.addView(premiumButtonView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 48, Gravity.CENTER_VERTICAL, 16, 0, 16, 0));
buttonContainer.setBackgroundColor(getThemedColor(Theme.key_dialogBackground));
containerView.addView(buttonContainer, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 68, Gravity.BOTTOM));
}
@Override
protected void onPreMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onPreMeasure(widthMeasureSpec, heightMeasureSpec);
measureGradient(View.MeasureSpec.getSize(widthMeasureSpec), View.MeasureSpec.getSize(heightMeasureSpec));
}
private void measureGradient(int w, int h) {
int yOffset = 0;
for (int i = 0; i < giftTiers.size(); i++) {
dummyCell.bind(giftTiers.get(i));
dummyCell.measure(View.MeasureSpec.makeMeasureSpec(w, View.MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec(h, View.MeasureSpec.AT_MOST));
giftTiers.get(i).yOffset = yOffset;
yOffset += dummyCell.getMeasuredHeight();
}
totalGradientHeight = yOffset;
}
@Override
protected CharSequence getTitle() {
return LocaleController.getString(R.string.GiftTelegramPremiumTitle);
}
@Override
protected RecyclerListView.SelectionAdapter createAdapter() {
return new RecyclerListView.SelectionAdapter() {
private final static int VIEW_TYPE_HEADER = 0,
VIEW_TYPE_TIER = 1,
VIEW_TYPE_FOOTER = 2,
VIEW_TYPE_BUTTON = 3;
@Override
public boolean isEnabled(RecyclerView.ViewHolder holder) {
return holder.getItemViewType() == VIEW_TYPE_TIER;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view;
switch (viewType) {
default:
case VIEW_TYPE_HEADER:
view = new PremiumGiftHeaderCell(getContext());
break;
case VIEW_TYPE_TIER:
AtomicReference<Float> progressRef = new AtomicReference<>(0f);
PremiumGiftTierCell premiumGiftTierCell = new PremiumGiftTierCell(getContext()) {
@Override
protected void dispatchDraw(Canvas canvas) {
if (discountView.getVisibility() == VISIBLE) {
AndroidUtilities.rectTmp.set(discountView.getLeft(), discountView.getTop(), discountView.getRight(), discountView.getBottom());
gradientTools.gradientMatrix(0, 0, getMeasuredWidth(), totalGradientHeight, 0, -tier.yOffset);
canvas.drawRoundRect(AndroidUtilities.rectTmp, AndroidUtilities.dp(6), AndroidUtilities.dp(6), gradientTools.paint);
}
float progress = progressRef.get();
int alpha = outlineGradient.paint.getAlpha();
outlineGradient.paint.setAlpha((int) (progress * alpha));
AndroidUtilities.rectTmp.set(AndroidUtilities.dp(20), AndroidUtilities.dp(3), getWidth() - AndroidUtilities.dp(20), getHeight() - AndroidUtilities.dp(3));
outlineGradient.gradientMatrix(0, 0, getMeasuredWidth(), getMeasuredHeight(), 0, 0);
canvas.drawRoundRect(AndroidUtilities.rectTmp, AndroidUtilities.dp(12), AndroidUtilities.dp(12), outlineGradient.paint);
outlineGradient.paint.setAlpha(alpha);
super.dispatchDraw(canvas);
}
};
premiumGiftTierCell.setCirclePaintProvider(obj -> {
gradientTools.gradientMatrix(0, 0, premiumGiftTierCell.getMeasuredWidth(), totalGradientHeight, 0, -premiumGiftTierCell.tier.yOffset);
return gradientTools.paint;
});
premiumGiftTierCell.setProgressDelegate(progress -> {
progressRef.set(progress);
premiumGiftTierCell.invalidate();
});
view = premiumGiftTierCell;
break;
case VIEW_TYPE_FOOTER:
TextInfoPrivacyCell privacyCell = new TextInfoPrivacyCell(getContext());
privacyCell.setTopPadding(28);
privacyCell.getTextView().setGravity(Gravity.CENTER_HORIZONTAL);
String str = LocaleController.getString(R.string.GiftPremiumListFeaturesAndTerms);
int startIndex = str.indexOf('*'), lastIndex = str.lastIndexOf('*');
if (startIndex != -1 && lastIndex != -1) {
str = str.substring(0, startIndex) + str.substring(startIndex + 1, lastIndex) + str.substring(lastIndex + 1);
SpannableString span = new SpannableString(str);
span.setSpan(new LinkSpan(), startIndex, lastIndex - 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
privacyCell.setText(span);
} else {
privacyCell.setText(str);
}
privacyCell.setPadding(AndroidUtilities.dp(21), 0, AndroidUtilities.dp(21), 0);
view = privacyCell;
break;
case VIEW_TYPE_BUTTON:
view = new View(getContext()) {
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(68), MeasureSpec.EXACTLY));
}
};
break;
}
return new RecyclerListView.Holder(view);
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
if (position == headerRow) {
((PremiumGiftHeaderCell) holder.itemView).bind(user);
} else if (position >= tiersStartRow && position < tiersEndRow) {
PremiumGiftTierCell giftTierCell = (PremiumGiftTierCell) holder.itemView;
giftTierCell.bind(giftTiers.get(position - tiersStartRow));
giftTierCell.setChecked(position - tiersStartRow == selectedTierIndex, false);
}
}
@Override
public int getItemViewType(int position) {
if (position == headerRow) {
return VIEW_TYPE_HEADER;
} else if (position >= tiersStartRow && position < tiersEndRow) {
return VIEW_TYPE_TIER;
} else if (position == footerRow) {
return VIEW_TYPE_FOOTER;
} else if (position == buttonRow) {
return VIEW_TYPE_BUTTON;
}
return VIEW_TYPE_HEADER;
}
@Override
public int getItemCount() {
return rowsCount;
}
};
}
private final class LinkSpan extends ClickableSpan {
@Override
public void onClick(View widget) {
getBaseFragment().presentFragment(new PremiumPreviewFragment("profile"));
dismiss();
}
@Override
public void updateDrawState(TextPaint p) {
super.updateDrawState(p);
p.setUnderlineText(false);
}
}
public final static class GiftTier {
public final TLRPC.TL_premiumGiftOption giftOption;
private int discount;
private long pricePerMonth;
private long pricePerMonthRegular;
private ProductDetails googlePlayProductDetails;
public int yOffset;
public GiftTier(TLRPC.TL_premiumGiftOption giftOption) {
this.giftOption = giftOption;
}
public ProductDetails getGooglePlayProductDetails() {
return googlePlayProductDetails;
}
public void setGooglePlayProductDetails(ProductDetails googlePlayProductDetails) {
this.googlePlayProductDetails = googlePlayProductDetails;
}
public void setPricePerMonthRegular(long pricePerMonthRegular) {
this.pricePerMonthRegular = pricePerMonthRegular;
}
public int getMonths() {
return giftOption.months;
}
public int getDiscount() {
if (discount == 0) {
if (getPricePerMonth() == 0) {
return 0;
}
if (pricePerMonthRegular != 0) {
discount = (int) ((1.0 - getPricePerMonth() / (double) pricePerMonthRegular) * 100);
if (discount == 0) {
discount = -1;
}
}
}
return discount;
}
public long getPricePerMonth() {
if (pricePerMonth == 0) {
long price = getPrice();
if (price != 0) {
pricePerMonth = price / giftOption.months;
}
}
return pricePerMonth;
}
public String getFormattedPricePerMonth() {
if (BuildVars.useInvoiceBilling() || giftOption.store_product == null) {
return BillingController.getInstance().formatCurrency(getPricePerMonth(), getCurrency());
}
return googlePlayProductDetails == null ? "" : BillingController.getInstance().formatCurrency(getPricePerMonth(), getCurrency(), 6);
}
public String getFormattedPrice() {
if (BuildVars.useInvoiceBilling() || giftOption.store_product == null) {
return BillingController.getInstance().formatCurrency(getPrice(), getCurrency());
}
return googlePlayProductDetails == null ? "" : BillingController.getInstance().formatCurrency(getPrice(), getCurrency(), 6);
}
public long getPrice() {
if (BuildVars.useInvoiceBilling() || giftOption.store_product == null) {
return giftOption.amount;
}
return googlePlayProductDetails == null ? 0 : googlePlayProductDetails.getOneTimePurchaseOfferDetails().getPriceAmountMicros();
}
public String getCurrency() {
if (BuildVars.useInvoiceBilling() || giftOption.store_product == null) {
return giftOption.currency;
}
return googlePlayProductDetails == null ? "" : googlePlayProductDetails.getOneTimePurchaseOfferDetails().getPriceCurrencyCode();
}
}
}