Some changes
This commit is contained in:
parent
761abc013f
commit
6d70bd758a
|
@ -12,3 +12,4 @@
|
||||||
/app/google_full/
|
/app/google_full/
|
||||||
/app/google_acad/
|
/app/google_acad/
|
||||||
/app/src/google_donation/res/values/data.xml
|
/app/src/google_donation/res/values/data.xml
|
||||||
|
/keystore.properties
|
||||||
|
|
|
@ -1,7 +1,21 @@
|
||||||
apply plugin: 'com.android.application'
|
apply plugin: 'com.android.application'
|
||||||
apply plugin: "androidx.navigation.safeargs"
|
apply plugin: "androidx.navigation.safeargs"
|
||||||
|
|
||||||
|
|
||||||
|
def keystorePropertiesFile = rootProject.file("keystore.properties")
|
||||||
|
def keystoreProperties = new Properties()
|
||||||
|
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
|
||||||
|
|
||||||
android {
|
android {
|
||||||
|
signingConfigs {
|
||||||
|
full_version {
|
||||||
|
storeFile file(keystoreProperties['storeFile'])
|
||||||
|
storePassword keystoreProperties['storePassword']
|
||||||
|
keyPassword keystoreProperties['keyPassword']
|
||||||
|
keyAlias keystoreProperties['keyAlias']
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
compileSdkVersion 30
|
compileSdkVersion 30
|
||||||
buildToolsVersion "30.0.2"
|
buildToolsVersion "30.0.2"
|
||||||
|
|
||||||
|
@ -22,6 +36,7 @@ android {
|
||||||
release {
|
release {
|
||||||
minifyEnabled false
|
minifyEnabled false
|
||||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||||
|
signingConfig signingConfigs.full_version
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
compileOptions {
|
compileOptions {
|
||||||
|
@ -200,7 +215,7 @@ dependencies {
|
||||||
implementation 'com.fasterxml.jackson.core:jackson-core:2.12.0'
|
implementation 'com.fasterxml.jackson.core:jackson-core:2.12.0'
|
||||||
implementation 'org.slf4j:slf4j-simple:1.7.30'
|
implementation 'org.slf4j:slf4j-simple:1.7.30'
|
||||||
|
|
||||||
google_fullImplementation 'com.anjlab.android.iab.v3:library:1.0.44'
|
google_fullImplementation "com.android.billingclient:billing:3.0.2"
|
||||||
|
|
||||||
fdroid_peertube_apps_educImplementation 'org.matomo.sdk:tracker:4.1.2'
|
fdroid_peertube_apps_educImplementation 'org.matomo.sdk:tracker:4.1.2'
|
||||||
google_peertube_apps_educImplementation 'org.matomo.sdk:tracker:4.1.2'
|
google_peertube_apps_educImplementation 'org.matomo.sdk:tracker:4.1.2'
|
||||||
|
|
|
@ -14,11 +14,12 @@ package app.fedilab.fedilabtube;
|
||||||
* You should have received a copy of the GNU General Public License along with TubeLab; if not,
|
* You should have received a copy of the GNU General Public License along with TubeLab; if not,
|
||||||
* see <http://www.gnu.org/licenses>. */
|
* see <http://www.gnu.org/licenses>. */
|
||||||
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.fragment.app.FragmentManager;
|
import androidx.fragment.app.FragmentManager;
|
||||||
|
@ -26,23 +27,39 @@ import androidx.fragment.app.FragmentStatePagerAdapter;
|
||||||
import androidx.viewpager.widget.PagerAdapter;
|
import androidx.viewpager.widget.PagerAdapter;
|
||||||
import androidx.viewpager.widget.ViewPager;
|
import androidx.viewpager.widget.ViewPager;
|
||||||
|
|
||||||
import com.anjlab.android.iab.v3.BillingProcessor;
|
import com.android.billingclient.api.BillingClient;
|
||||||
import com.anjlab.android.iab.v3.TransactionDetails;
|
import com.android.billingclient.api.BillingClientStateListener;
|
||||||
|
import com.android.billingclient.api.BillingResult;
|
||||||
|
import com.android.billingclient.api.ConsumeParams;
|
||||||
|
import com.android.billingclient.api.ConsumeResponseListener;
|
||||||
|
import com.android.billingclient.api.Purchase;
|
||||||
|
import com.android.billingclient.api.PurchasesUpdatedListener;
|
||||||
|
import com.android.billingclient.api.SkuDetailsParams;
|
||||||
|
import com.google.android.material.snackbar.Snackbar;
|
||||||
import com.google.android.material.tabs.TabLayout;
|
import com.google.android.material.tabs.TabLayout;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import app.fedilab.fedilabtube.databinding.ActivityDonationBinding;
|
import app.fedilab.fedilabtube.databinding.ActivityDonationBinding;
|
||||||
|
|
||||||
|
import app.fedilab.fedilabtube.fragment.MySubscriptionDonationsFragment;
|
||||||
import app.fedilab.fedilabtube.fragment.DonationsFragment;
|
import app.fedilab.fedilabtube.fragment.DonationsFragment;
|
||||||
import app.fedilab.fedilabtube.fragment.MyDonationsFragment;
|
|
||||||
|
|
||||||
|
|
||||||
public class DonationActivity extends AppCompatActivity implements BillingProcessor.IBillingHandler {
|
public class DonationActivity extends AppCompatActivity implements PurchasesUpdatedListener {
|
||||||
|
|
||||||
|
|
||||||
BillingProcessor bp;
|
|
||||||
DonationsFragment donationsFragment;
|
DonationsFragment donationsFragment;
|
||||||
MyDonationsFragment myDonationsFragment;
|
DonationsFragment subscriptionDonationsFragment;
|
||||||
|
MySubscriptionDonationsFragment mySubscriptionDonationsFragment;
|
||||||
private ActivityDonationBinding binding;
|
private ActivityDonationBinding binding;
|
||||||
|
private BillingClient billingClient;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
@ -50,16 +67,87 @@ public class DonationActivity extends AppCompatActivity implements BillingProces
|
||||||
binding = ActivityDonationBinding.inflate(getLayoutInflater());
|
binding = ActivityDonationBinding.inflate(getLayoutInflater());
|
||||||
View view = binding.getRoot();
|
View view = binding.getRoot();
|
||||||
setContentView(view);
|
setContentView(view);
|
||||||
bp = new BillingProcessor(this, getString(R.string.google_key), this);
|
billingClient = BillingClient.newBuilder(this)
|
||||||
bp.initialize();
|
.setListener(this)
|
||||||
|
.enablePendingPurchases()
|
||||||
|
.build();
|
||||||
|
billingClient.startConnection(new BillingClientStateListener() {
|
||||||
|
@Override
|
||||||
|
public void onBillingSetupFinished(@NotNull BillingResult billingResult) {
|
||||||
|
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
|
||||||
|
// The BillingClient is ready. You can query purchases here.
|
||||||
|
donationsFragment.initialized(billingClient);
|
||||||
|
subscriptionDonationsFragment.initialized(billingClient);
|
||||||
|
|
||||||
|
Purchase.PurchasesResult purchasesResult = billingClient.queryPurchases(BillingClient.SkuType.SUBS);
|
||||||
|
List<Purchase> purchases = purchasesResult.getPurchasesList();
|
||||||
|
List<String> isSubscriptions = new ArrayList<>();
|
||||||
|
if (purchases != null) {
|
||||||
|
for (Purchase purchase : purchases) {
|
||||||
|
try {
|
||||||
|
JSONObject purchaseJson = new JSONObject(purchase.getOriginalJson());
|
||||||
|
String productId = purchaseJson.getString("productId");
|
||||||
|
isSubscriptions.add(productId);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SkuDetailsParams.Builder paramsSub = SkuDetailsParams.newBuilder();
|
||||||
|
paramsSub.setSkusList(isSubscriptions).setType(BillingClient.SkuType.SUBS);
|
||||||
|
billingClient.querySkuDetailsAsync(paramsSub.build(),
|
||||||
|
(billingResult2, skuDetailsList) -> mySubscriptionDonationsFragment.initialized(skuDetailsList, billingClient));
|
||||||
|
} else {
|
||||||
|
mySubscriptionDonationsFragment.initialized(new ArrayList<>(), billingClient);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
purchasesResult = billingClient.queryPurchases(BillingClient.SkuType.INAPP);
|
||||||
|
purchases = purchasesResult.getPurchasesList();
|
||||||
|
if (purchases != null) {
|
||||||
|
for (Purchase purchase : purchases) {
|
||||||
|
if (!purchase.isAutoRenewing()) {
|
||||||
|
ConsumeParams consumeParams =
|
||||||
|
ConsumeParams.newBuilder()
|
||||||
|
.setPurchaseToken(purchase.getPurchaseToken())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
ConsumeResponseListener listener = (billingResult1, purchaseToken) -> {
|
||||||
|
if (billingResult1.getResponseCode() == BillingClient.BillingResponseCode.OK) {
|
||||||
|
// Handle the success of the consume operation.
|
||||||
|
}
|
||||||
|
};
|
||||||
|
billingClient.consumeAsync(consumeParams, listener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBillingServiceDisconnected() {
|
||||||
|
// Try to restart the connection on the next request to
|
||||||
|
// Google Play by calling the startConnection() method.
|
||||||
|
}
|
||||||
|
});
|
||||||
if (getSupportActionBar() != null)
|
if (getSupportActionBar() != null)
|
||||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||||
donationsFragment = new DonationsFragment();
|
donationsFragment = new DonationsFragment();
|
||||||
myDonationsFragment = new MyDonationsFragment();
|
Bundle bundle1 = new Bundle();
|
||||||
|
bundle1.putSerializable("isSubscriptions", false);
|
||||||
|
donationsFragment.setArguments(bundle1);
|
||||||
|
|
||||||
binding.tablayout.addTab(binding.tablayout.newTab().setText(getString(R.string.donate)));
|
|
||||||
binding.tablayout.addTab(binding.tablayout.newTab().setText(getString(R.string.my_donations)));
|
subscriptionDonationsFragment = new DonationsFragment();
|
||||||
binding.viewpager.setOffscreenPageLimit(2);
|
Bundle bundle2 = new Bundle();
|
||||||
|
bundle2.putSerializable("isSubscriptions", true);
|
||||||
|
subscriptionDonationsFragment.setArguments(bundle2);
|
||||||
|
|
||||||
|
mySubscriptionDonationsFragment = new MySubscriptionDonationsFragment();
|
||||||
|
|
||||||
|
binding.tablayout.addTab(binding.tablayout.newTab().setText(getString(R.string.one_time)));
|
||||||
|
binding.tablayout.addTab(binding.tablayout.newTab().setText(getString(R.string.subscriptions)));
|
||||||
|
binding.tablayout.addTab(binding.tablayout.newTab().setText(getString(R.string.my_subscriptions)));
|
||||||
|
binding.viewpager.setOffscreenPageLimit(3);
|
||||||
|
|
||||||
PagerAdapter mPagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager());
|
PagerAdapter mPagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager());
|
||||||
binding.viewpager.setAdapter(mPagerAdapter);
|
binding.viewpager.setAdapter(mPagerAdapter);
|
||||||
|
@ -110,33 +198,38 @@ public class DonationActivity extends AppCompatActivity implements BillingProces
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onProductPurchased(@NotNull String productId, TransactionDetails details) {
|
public void onPurchasesUpdated(@NonNull BillingResult billingResult, @Nullable List<Purchase> purchases) {
|
||||||
|
String message;
|
||||||
|
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK
|
||||||
|
&& purchases != null) {
|
||||||
|
for (Purchase purchase : purchases) {
|
||||||
|
if (!purchase.isAutoRenewing()) {
|
||||||
|
ConsumeParams consumeParams =
|
||||||
|
ConsumeParams.newBuilder()
|
||||||
|
.setPurchaseToken(purchase.getPurchaseToken())
|
||||||
|
.build();
|
||||||
|
|
||||||
}
|
ConsumeResponseListener listener = (billingResult1, purchaseToken) -> {
|
||||||
|
if (billingResult1.getResponseCode() == BillingClient.BillingResponseCode.OK) {
|
||||||
@Override
|
// Handle the success of the consume operation.
|
||||||
public void onPurchaseHistoryRestored() {
|
}
|
||||||
|
};
|
||||||
}
|
billingClient.consumeAsync(consumeParams, listener);
|
||||||
|
}
|
||||||
@Override
|
}
|
||||||
public void onBillingError(int errorCode, Throwable error) {
|
message = getString(R.string.donation_succeeded_null);
|
||||||
|
} else if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.USER_CANCELED) {
|
||||||
}
|
message = getString(R.string.donation_cancelled);
|
||||||
|
} else {
|
||||||
@Override
|
message = getString(R.string.toast_error);
|
||||||
public void onBillingInitialized() {
|
|
||||||
donationsFragment.initialized(bp);
|
|
||||||
myDonationsFragment.initialized(bp);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
|
||||||
if (!bp.handleActivityResult(requestCode, resultCode, data)) {
|
|
||||||
super.onActivityResult(requestCode, resultCode, data);
|
|
||||||
}
|
}
|
||||||
|
View parentLayout = findViewById(android.R.id.content);
|
||||||
|
Snackbar snackbar = Snackbar.make(parentLayout, message, Snackbar.LENGTH_INDEFINITE);
|
||||||
|
snackbar.setAction(R.string.close, view -> snackbar.dismiss());
|
||||||
|
snackbar.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pager adapter for the 2 fragments
|
* Pager adapter for the 2 fragments
|
||||||
*/
|
*/
|
||||||
|
@ -151,15 +244,17 @@ public class DonationActivity extends AppCompatActivity implements BillingProces
|
||||||
public Fragment getItem(int position) {
|
public Fragment getItem(int position) {
|
||||||
if (position == 0) {
|
if (position == 0) {
|
||||||
return donationsFragment;
|
return donationsFragment;
|
||||||
|
} else if (position == 1) {
|
||||||
|
return subscriptionDonationsFragment;
|
||||||
} else {
|
} else {
|
||||||
return myDonationsFragment;
|
return mySubscriptionDonationsFragment;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getCount() {
|
public int getCount() {
|
||||||
return 2;
|
return 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,26 +21,29 @@ import android.view.ViewGroup;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import com.anjlab.android.iab.v3.BillingProcessor;
|
import com.android.billingclient.api.BillingClient;
|
||||||
import com.anjlab.android.iab.v3.SkuDetails;
|
import com.android.billingclient.api.BillingFlowParams;
|
||||||
|
import com.android.billingclient.api.SkuDetails;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import app.fedilab.fedilabtube.DonationActivity;
|
import app.fedilab.fedilabtube.DonationActivity;
|
||||||
|
import app.fedilab.fedilabtube.R;
|
||||||
import app.fedilab.fedilabtube.databinding.DrawerDonationBinding;
|
import app.fedilab.fedilabtube.databinding.DrawerDonationBinding;
|
||||||
import app.fedilab.fedilabtube.helper.Helper;
|
|
||||||
|
|
||||||
|
|
||||||
public class DonationButtonAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
public class DonationButtonAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
||||||
|
|
||||||
private final List<String> items;
|
private final List<SkuDetails> skuDetails;
|
||||||
private final BillingProcessor billingProcessor;
|
private final BillingClient billingClient;
|
||||||
private Context context;
|
private Context context;
|
||||||
|
private final boolean isSubscription;
|
||||||
|
|
||||||
public DonationButtonAdapter(List<String> items, BillingProcessor billingProcessor) {
|
public DonationButtonAdapter(List<SkuDetails> skuDetails, BillingClient billingClient, boolean subscription) {
|
||||||
this.items = items;
|
this.isSubscription = subscription;
|
||||||
this.billingProcessor = billingProcessor;
|
this.skuDetails = skuDetails;
|
||||||
|
this.billingClient = billingClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
|
@ -54,19 +57,27 @@ public class DonationButtonAdapter extends RecyclerView.Adapter<RecyclerView.Vie
|
||||||
@Override
|
@Override
|
||||||
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
|
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
|
||||||
final ViewHolder holder = (ViewHolder) viewHolder;
|
final ViewHolder holder = (ViewHolder) viewHolder;
|
||||||
String item = items.get(position);
|
SkuDetails skuDetail = skuDetails.get(position);
|
||||||
String product_item = "tubelab_donation_" + item;
|
String currency = skuDetail.getPriceCurrencyCode();
|
||||||
SkuDetails skuDetails = billingProcessor.getPurchaseListingDetails(product_item);
|
String price = skuDetail.getPrice();
|
||||||
String currency = skuDetails.currency;
|
if (isSubscription) {
|
||||||
Double price = skuDetails.priceValue;
|
holder.binding.buttonDonation.setText(String.format(Locale.getDefault(), "%s %s / %s", price, currency, context.getString(R.string.month)));
|
||||||
holder.binding.buttonDonation.setText(String.format(Locale.getDefault(), "%.2f %s", price, currency));
|
} else {
|
||||||
holder.binding.buttonDonation.setOnClickListener(v -> billingProcessor.purchase((DonationActivity) context, product_item));
|
holder.binding.buttonDonation.setText(String.format(Locale.getDefault(), "%s %s", price, currency));
|
||||||
|
}
|
||||||
|
|
||||||
|
holder.binding.buttonDonation.setOnClickListener(v -> {
|
||||||
|
BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
|
||||||
|
.setSkuDetails(skuDetail)
|
||||||
|
.build();
|
||||||
|
billingClient.launchBillingFlow((DonationActivity) context, billingFlowParams);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getItemCount() {
|
public int getItemCount() {
|
||||||
return items.size();
|
return skuDetails.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
static class ViewHolder extends RecyclerView.ViewHolder {
|
static class ViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
|
|
@ -21,60 +21,61 @@ import android.view.ViewGroup;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import com.anjlab.android.iab.v3.BillingProcessor;
|
import com.android.billingclient.api.BillingClient;
|
||||||
import com.anjlab.android.iab.v3.SkuDetails;
|
import com.android.billingclient.api.SkuDetails;
|
||||||
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
import app.fedilab.fedilabtube.DonationActivity;
|
import app.fedilab.fedilabtube.databinding.DrawerMyDonationBinding;
|
||||||
import app.fedilab.fedilabtube.databinding.DrawerDonationBinding;
|
|
||||||
import app.fedilab.fedilabtube.helper.Helper;
|
|
||||||
|
|
||||||
|
|
||||||
public class DonationHistoryAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
public class DonationHistoryAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
||||||
|
|
||||||
private final List<SkuDetails> items;
|
private final List<SkuDetails> skuDetailsList;
|
||||||
private final BillingProcessor billingProcessor;
|
private final BillingClient billingClient;
|
||||||
private Context context;
|
private Context context;
|
||||||
|
|
||||||
public DonationHistoryAdapter(List<SkuDetails> items, BillingProcessor billingProcessor) {
|
public DonationHistoryAdapter(List<SkuDetails> SkuDetailsList, BillingClient billingClient) {
|
||||||
this.items = items;
|
this.skuDetailsList = SkuDetailsList;
|
||||||
this.billingProcessor = billingProcessor;
|
this.billingClient = billingClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||||
context = parent.getContext();
|
context = parent.getContext();
|
||||||
DrawerDonationBinding itemBinding = DrawerDonationBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
|
DrawerMyDonationBinding itemBinding = DrawerMyDonationBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
|
||||||
return new ViewHolder(itemBinding);
|
return new ViewHolder(itemBinding);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
|
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
|
||||||
final ViewHolder holder = (ViewHolder) viewHolder;
|
final ViewHolder holder = (ViewHolder) viewHolder;
|
||||||
SkuDetails item = items.get(position);
|
SkuDetails skuDetails = skuDetailsList.get(position);
|
||||||
String product_item = "tubelab_donation_" + item;
|
holder.binding.productTitle.setText(skuDetails.getTitle());
|
||||||
SkuDetails skuDetails = billingProcessor.getPurchaseListingDetails(product_item);
|
holder.binding.productName.setText(skuDetails.getDescription());
|
||||||
String currency = skuDetails.currency;
|
holder.binding.productInfo.setText(skuDetails.getOriginalPrice());
|
||||||
Double price = skuDetails.priceValue;
|
holder.binding.cancelDonation.setOnClickListener(v -> {
|
||||||
holder.binding.buttonDonation.setText(String.format(Locale.getDefault(), "%.2f %s", price, currency));
|
|
||||||
holder.binding.buttonDonation.setOnClickListener(v -> billingProcessor.purchase((DonationActivity) context, product_item));
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getItemCount() {
|
public int getItemCount() {
|
||||||
return items.size();
|
return skuDetailsList.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
static class ViewHolder extends RecyclerView.ViewHolder {
|
static class ViewHolder extends RecyclerView.ViewHolder {
|
||||||
DrawerDonationBinding binding;
|
DrawerMyDonationBinding binding;
|
||||||
|
|
||||||
ViewHolder(DrawerDonationBinding itemView) {
|
ViewHolder(DrawerMyDonationBinding itemView) {
|
||||||
super(itemView.getRoot());
|
super(itemView.getRoot());
|
||||||
binding = itemView;
|
binding = itemView;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,14 +24,17 @@ import androidx.annotation.NonNull;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
|
|
||||||
import com.anjlab.android.iab.v3.BillingProcessor;
|
import com.android.billingclient.api.BillingClient;
|
||||||
|
import com.android.billingclient.api.SkuDetailsParams;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import app.fedilab.fedilabtube.R;
|
||||||
import app.fedilab.fedilabtube.databinding.FragmentDonationsBinding;
|
import app.fedilab.fedilabtube.databinding.FragmentDonationsBinding;
|
||||||
import app.fedilab.fedilabtube.drawable.DonationButtonAdapter;
|
import app.fedilab.fedilabtube.drawable.DonationButtonAdapter;
|
||||||
|
import app.fedilab.fedilabtube.helper.Helper;
|
||||||
|
|
||||||
|
|
||||||
public class DonationsFragment extends Fragment {
|
public class DonationsFragment extends Fragment {
|
||||||
|
@ -40,25 +43,52 @@ public class DonationsFragment extends Fragment {
|
||||||
private FragmentDonationsBinding binding;
|
private FragmentDonationsBinding binding;
|
||||||
private View rootView;
|
private View rootView;
|
||||||
private Context context;
|
private Context context;
|
||||||
|
private boolean isSubscriptions;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||||
binding = FragmentDonationsBinding.inflate(LayoutInflater.from(context));
|
binding = FragmentDonationsBinding.inflate(LayoutInflater.from(context));
|
||||||
rootView = binding.getRoot();
|
rootView = binding.getRoot();
|
||||||
context = getContext();
|
context = getContext();
|
||||||
|
Bundle bundle = this.getArguments();
|
||||||
|
if (bundle != null) {
|
||||||
|
isSubscriptions = bundle.getBoolean("isSubscriptions", false);
|
||||||
|
}
|
||||||
|
int donationText;
|
||||||
|
if (isSubscriptions) {
|
||||||
|
donationText = R.string.recurrent_donation_text;
|
||||||
|
} else {
|
||||||
|
donationText = R.string.one_time_donation_text;
|
||||||
|
}
|
||||||
|
binding.donationText.setText(donationText);
|
||||||
binding.loader.setVisibility(View.VISIBLE);
|
binding.loader.setVisibility(View.VISIBLE);
|
||||||
binding.lvProducts.setVisibility(View.GONE);
|
binding.lvProducts.setVisibility(View.GONE);
|
||||||
return rootView;
|
return rootView;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initialized(BillingProcessor bp) {
|
public void initialized(BillingClient bc) {
|
||||||
binding.loader.setVisibility(View.GONE);
|
|
||||||
binding.lvProducts.setVisibility(View.VISIBLE);
|
|
||||||
List<String> donationsList = new ArrayList<>();
|
List<String> donationsList = new ArrayList<>();
|
||||||
Collections.addAll(donationsList, donations);
|
for (String val : donations) {
|
||||||
DonationButtonAdapter donationButtonAdapter = new DonationButtonAdapter(donationsList, bp);
|
donationsList.add("tubelab_donation_" + val + (isSubscriptions ? "_s" : ""));
|
||||||
binding.lvProducts.setAdapter(donationButtonAdapter);
|
}
|
||||||
binding.lvProducts.setLayoutManager(new LinearLayoutManager(context));
|
SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();
|
||||||
|
if (isSubscriptions) {
|
||||||
|
params.setSkusList(donationsList).setType(BillingClient.SkuType.SUBS);
|
||||||
|
} else {
|
||||||
|
params.setSkusList(donationsList).setType(BillingClient.SkuType.INAPP);
|
||||||
|
}
|
||||||
|
bc.querySkuDetailsAsync(params.build(),
|
||||||
|
(billingResult, skuDetailsList) -> {
|
||||||
|
binding.loader.setVisibility(View.GONE);
|
||||||
|
binding.lvProducts.setVisibility(View.VISIBLE);
|
||||||
|
DonationButtonAdapter donationButtonAdapter = new DonationButtonAdapter(skuDetailsList, bc, isSubscriptions);
|
||||||
|
binding.lvProducts.setAdapter(donationButtonAdapter);
|
||||||
|
binding.lvProducts.setLayoutManager(new LinearLayoutManager(context));
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -24,20 +24,21 @@ import androidx.annotation.NonNull;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
|
|
||||||
import com.anjlab.android.iab.v3.BillingProcessor;
|
import com.android.billingclient.api.BillingClient;
|
||||||
import com.anjlab.android.iab.v3.SkuDetails;
|
import com.android.billingclient.api.Purchase;
|
||||||
|
import com.android.billingclient.api.SkuDetails;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import app.fedilab.fedilabtube.databinding.FragmentMyDonationsBinding;
|
import app.fedilab.fedilabtube.databinding.FragmentMyDonationsBinding;
|
||||||
import app.fedilab.fedilabtube.drawable.DonationHistoryAdapter;
|
import app.fedilab.fedilabtube.drawable.DonationHistoryAdapter;
|
||||||
|
import app.fedilab.fedilabtube.helper.Helper;
|
||||||
|
|
||||||
import static app.fedilab.fedilabtube.fragment.DonationsFragment.donations;
|
import static app.fedilab.fedilabtube.fragment.DonationsFragment.donations;
|
||||||
|
|
||||||
|
|
||||||
public class MyDonationsFragment extends Fragment {
|
public class MySubscriptionDonationsFragment extends Fragment {
|
||||||
|
|
||||||
private FragmentMyDonationsBinding binding;
|
private FragmentMyDonationsBinding binding;
|
||||||
private View rootView;
|
private View rootView;
|
||||||
|
@ -54,15 +55,14 @@ public class MyDonationsFragment extends Fragment {
|
||||||
return rootView;
|
return rootView;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initialized(BillingProcessor bp) {
|
public void initialized(List<SkuDetails> skuDetailsList, BillingClient bc) {
|
||||||
binding.loader.setVisibility(View.GONE);
|
binding.loader.setVisibility(View.GONE);
|
||||||
binding.lvPurchases.setVisibility(View.VISIBLE);
|
binding.lvPurchases.setVisibility(View.VISIBLE);
|
||||||
ArrayList<String> donationsList = new ArrayList<>();
|
|
||||||
Collections.addAll(donationsList, donations);
|
DonationHistoryAdapter donationHistoryAdapter = new DonationHistoryAdapter(skuDetailsList, bc);
|
||||||
List<SkuDetails> skuDetailsList = bp.getPurchaseListingDetails(donationsList);
|
|
||||||
DonationHistoryAdapter donationHistoryAdapter = new DonationHistoryAdapter(skuDetailsList, bp);
|
|
||||||
binding.lvPurchases.setAdapter(donationHistoryAdapter);
|
binding.lvPurchases.setAdapter(donationHistoryAdapter);
|
||||||
binding.lvPurchases.setLayoutManager(new LinearLayoutManager(context));
|
binding.lvPurchases.setLayoutManager(new LinearLayoutManager(context));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
|
@ -0,0 +1,54 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
|
||||||
|
android:layout_margin="10dp">
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="10dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/product_title"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="16sp"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/cancel_donation"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/product_name"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/cancel_donation"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/product_title" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/product_info"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/cancel_donation"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/product_name" />
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/cancel_donation"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:contentDescription="@string/cancel"
|
||||||
|
android:src="@drawable/ic_baseline_delete_24"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
</androidx.cardview.widget.CardView>
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_margin="20dp"
|
android:layout_margin="20dp"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:text="@string/donation_text" />
|
android:id="@+id/donation_text" />
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/lv_products"
|
android:id="@+id/lv_products"
|
||||||
|
|
|
@ -457,9 +457,16 @@
|
||||||
<string name="remote_account_from"><b>%1$s</b> remote account connected with the app.\n\nYou can proceed to some limited actions.</string>
|
<string name="remote_account_from"><b>%1$s</b> remote account connected with the app.\n\nYou can proceed to some limited actions.</string>
|
||||||
<string name="donate">Donate</string>
|
<string name="donate">Donate</string>
|
||||||
<string name="my_donations">My donations</string>
|
<string name="my_donations">My donations</string>
|
||||||
<string name="donation_text">Here, you can make a donation for supporting the development of the app. This action will not bring extra features!</string>
|
<string name="one_time_donation_text">Here, you can make a one time donation for supporting the development of the app. This action will not bring extra features!</string>
|
||||||
|
<string name="recurrent_donation_text">Here, you can make a recurrent donation for supporting the development of the app. This action will not bring extra features!</string>
|
||||||
<string name="make_a_donation">Make a donation</string>
|
<string name="make_a_donation">Make a donation</string>
|
||||||
<string name="donations_description">Here you will find the list of donations made to the app! Thank you!</string>
|
<string name="donations_description">Here you will find the list of your recurrent donations made to support the development of the app! Thank you!</string>
|
||||||
<string name="support_the_app">Support the app</string>
|
<string name="support_the_app">Support the app</string>
|
||||||
|
<string name="donation_cancelled">Donation has been cancelled!</string>
|
||||||
|
<string name="donation_succeeded_null">Thank you for your donation!</string>
|
||||||
|
<string name="donation_succeeded">Thank you for your donation of %1$s!</string>
|
||||||
|
<string name="one_time">One time</string>
|
||||||
|
<string name="my_subscriptions">My subscription</string>
|
||||||
|
<string name="month">Month</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
|
@ -20,7 +20,19 @@ apply plugin: 'de.undercouch.download'
|
||||||
|
|
||||||
group='com.github.TorrentStream'
|
group='com.github.TorrentStream'
|
||||||
|
|
||||||
|
def keystorePropertiesFile = rootProject.file("keystore.properties")
|
||||||
|
def keystoreProperties = new Properties()
|
||||||
|
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
|
||||||
|
|
||||||
android {
|
android {
|
||||||
|
signingConfigs {
|
||||||
|
full_version {
|
||||||
|
storeFile file(keystoreProperties['storeFile'])
|
||||||
|
storePassword keystoreProperties['storePassword']
|
||||||
|
keyAlias keystoreProperties['keyAlias']
|
||||||
|
keyPassword keystoreProperties['keyPassword']
|
||||||
|
}
|
||||||
|
}
|
||||||
compileSdkVersion 30
|
compileSdkVersion 30
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
|
@ -32,6 +44,7 @@ android {
|
||||||
release {
|
release {
|
||||||
minifyEnabled false
|
minifyEnabled false
|
||||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
|
signingConfig signingConfigs.full_version
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue