mirror of https://github.com/tasks/tasks
New purchase activity
parent
505ad779f2
commit
dc8f722589
@ -1,10 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string-array name="pro_description">
|
||||
<item>@string/themes</item>
|
||||
<item>@string/pro_caldav_sync</item>
|
||||
<item>@string/pro_multiple_google_task_accounts</item>
|
||||
<item>@string/pro_tasker_plugins</item>
|
||||
<item>@string/pro_dashclock_extension</item>
|
||||
</string-array>
|
||||
</resources>
|
||||
@ -1,4 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string-array name="pro_description"/>
|
||||
</resources>
|
||||
@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string-array name="pro_description">
|
||||
<item>@string/themes</item>
|
||||
<item>@string/pro_caldav_sync</item>
|
||||
<item>@string/pro_etesync</item>
|
||||
<item>@string/pro_multiple_google_task_accounts</item>
|
||||
<item>@string/pro_google_places_search</item>
|
||||
<item>@string/pro_tasker_plugins</item>
|
||||
<item>@string/pro_dashclock_extension</item>
|
||||
</string-array>
|
||||
</resources>
|
||||
@ -1,261 +0,0 @@
|
||||
package org.tasks.billing;
|
||||
|
||||
import static com.google.common.collect.Lists.newArrayList;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.app.Dialog;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.DialogInterface.OnDismissListener;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import com.google.android.material.button.MaterialButton;
|
||||
import com.google.android.material.button.MaterialButtonToggleGroup;
|
||||
import com.google.common.collect.ContiguousSet;
|
||||
import com.google.common.collect.DiscreteDomain;
|
||||
import com.google.common.collect.Range;
|
||||
import javax.inject.Inject;
|
||||
import org.tasks.LocalBroadcastManager;
|
||||
import org.tasks.R;
|
||||
import org.tasks.dialogs.DialogBuilder;
|
||||
import org.tasks.dialogs.IconLayoutManager;
|
||||
import org.tasks.injection.DialogFragmentComponent;
|
||||
import org.tasks.injection.ForActivity;
|
||||
import org.tasks.injection.InjectingDialogFragment;
|
||||
import org.tasks.locale.Locale;
|
||||
import org.tasks.themes.Theme;
|
||||
|
||||
public class NameYourPriceDialog extends InjectingDialogFragment implements OnPurchasesUpdated {
|
||||
|
||||
private static final String EXTRA_MONTHLY = "extra_monthly";
|
||||
private static final String EXTRA_PRICE = "extra_price";
|
||||
|
||||
@Inject DialogBuilder dialogBuilder;
|
||||
@Inject @ForActivity Context context;
|
||||
@Inject BillingClient billingClient;
|
||||
@Inject LocalBroadcastManager localBroadcastManager;
|
||||
@Inject Inventory inventory;
|
||||
@Inject Locale locale;
|
||||
@Inject Theme theme;
|
||||
|
||||
@BindView(R.id.recycler_view)
|
||||
RecyclerView recyclerView;
|
||||
|
||||
@BindView(R.id.screen_wait)
|
||||
View loadingView;
|
||||
|
||||
@BindView(R.id.buttons)
|
||||
MaterialButtonToggleGroup buttons;
|
||||
|
||||
@BindView(R.id.subscribe)
|
||||
MaterialButton subscribe;
|
||||
|
||||
@BindView(R.id.unsubscribe)
|
||||
MaterialButton unsubscribe;
|
||||
|
||||
private PurchaseAdapter adapter;
|
||||
private Purchase currentSubscription = null;
|
||||
private BroadcastReceiver purchaseReceiver =
|
||||
new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
setup();
|
||||
}
|
||||
};
|
||||
private OnDismissListener listener;
|
||||
|
||||
static NameYourPriceDialog newNameYourPriceDialog() {
|
||||
return new NameYourPriceDialog();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
|
||||
View view = theme.getLayoutInflater(context).inflate(R.layout.dialog_name_your_price, null);
|
||||
|
||||
ButterKnife.bind(this, view);
|
||||
|
||||
setWaitScreen(true);
|
||||
|
||||
adapter = new PurchaseAdapter(context, theme, locale, this::onPriceChanged);
|
||||
|
||||
buttons.addOnButtonCheckedListener(this::onButtonChecked);
|
||||
|
||||
if (savedInstanceState != null) {
|
||||
buttons.check(
|
||||
savedInstanceState.getBoolean(EXTRA_MONTHLY)
|
||||
? R.id.button_monthly
|
||||
: R.id.button_annually);
|
||||
adapter.setSelected(savedInstanceState.getInt(EXTRA_PRICE));
|
||||
}
|
||||
|
||||
return dialogBuilder.newDialog(R.string.name_your_price).setView(view).show();
|
||||
}
|
||||
|
||||
private void onButtonChecked(MaterialButtonToggleGroup group, int id, boolean checked) {
|
||||
if (id == R.id.button_monthly) {
|
||||
if (!checked && group.getCheckedButtonId() != R.id.button_annually) {
|
||||
group.check(R.id.button_monthly);
|
||||
}
|
||||
} else {
|
||||
if (!checked && group.getCheckedButtonId() != R.id.button_monthly) {
|
||||
group.check(R.id.button_annually);
|
||||
}
|
||||
}
|
||||
updateSubscribeButton();
|
||||
}
|
||||
|
||||
private boolean isMonthly() {
|
||||
return buttons.getCheckedButtonId() == R.id.button_monthly;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(@NonNull Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
|
||||
outState.putBoolean(EXTRA_MONTHLY, isMonthly());
|
||||
outState.putInt(EXTRA_PRICE, adapter.getSelected());
|
||||
}
|
||||
|
||||
@SuppressLint("DefaultLocale")
|
||||
@OnClick(R.id.subscribe)
|
||||
protected void subscribe() {
|
||||
if (currentSubscriptionSelected() && currentSubscription.isCanceled()) {
|
||||
billingClient.initiatePurchaseFlow(
|
||||
(Activity) context, currentSubscription.getSku(), SkuDetails.TYPE_SUBS, null);
|
||||
} else {
|
||||
billingClient.initiatePurchaseFlow(
|
||||
(Activity) context,
|
||||
String.format("%s_%02d", isMonthly() ? "monthly" : "annual", adapter.getSelected()),
|
||||
SkuDetails.TYPE_SUBS,
|
||||
currentSubscription == null ? null : currentSubscription.getSku());
|
||||
}
|
||||
billingClient.addPurchaseCallback(this);
|
||||
dismiss();
|
||||
}
|
||||
|
||||
private void setup() {
|
||||
currentSubscription = inventory.getSubscription();
|
||||
if (adapter.getSelected() == 0) {
|
||||
if (currentSubscription == null) {
|
||||
adapter.setSelected(1);
|
||||
} else {
|
||||
adapter.setSelected(currentSubscription.getSubscriptionPrice());
|
||||
buttons.check(currentSubscription.isMonthly() ? R.id.button_monthly : R.id.button_annually);
|
||||
}
|
||||
}
|
||||
unsubscribe.setVisibility(
|
||||
currentSubscription == null || currentSubscription.isCanceled() ? View.GONE : View.VISIBLE);
|
||||
updateSubscribeButton();
|
||||
setWaitScreen(false);
|
||||
adapter.submitList(
|
||||
newArrayList(ContiguousSet.create(Range.closed(1, 10), DiscreteDomain.integers())));
|
||||
recyclerView.setLayoutManager(new IconLayoutManager(context));
|
||||
recyclerView.setAdapter(adapter);
|
||||
}
|
||||
|
||||
@OnClick(R.id.unsubscribe)
|
||||
protected void manageSubscription() {
|
||||
startActivity(
|
||||
new Intent(
|
||||
Intent.ACTION_VIEW,
|
||||
Uri.parse(getString(R.string.manage_subscription_url, currentSubscription.getSku()))));
|
||||
dismiss();
|
||||
}
|
||||
|
||||
private void onPriceChanged(Integer price) {
|
||||
adapter.setSelected(price);
|
||||
updateSubscribeButton();
|
||||
}
|
||||
|
||||
private void updateSubscribeButton() {
|
||||
subscribe.setEnabled(true);
|
||||
if (currentSubscription == null) {
|
||||
subscribe.setText(R.string.button_subscribe);
|
||||
} else if (currentSubscriptionSelected()) {
|
||||
if (currentSubscription.isCanceled()) {
|
||||
subscribe.setText(R.string.button_restore_subscription);
|
||||
} else {
|
||||
subscribe.setText(R.string.button_current_subscription);
|
||||
subscribe.setEnabled(false);
|
||||
}
|
||||
} else {
|
||||
subscribe.setText(isUpgrade() ? R.string.button_upgrade : R.string.button_downgrade);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isUpgrade() {
|
||||
return isMonthly() == currentSubscription.isMonthly()
|
||||
? currentSubscription.getSubscriptionPrice() < adapter.getSelected()
|
||||
: isMonthly();
|
||||
}
|
||||
|
||||
private boolean currentSubscriptionSelected() {
|
||||
return currentSubscription != null
|
||||
&& isMonthly() == currentSubscription.isMonthly()
|
||||
&& adapter.getSelected() == currentSubscription.getSubscriptionPrice();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void inject(DialogFragmentComponent component) {
|
||||
component.inject(this);
|
||||
}
|
||||
|
||||
private void setWaitScreen(boolean isWaitScreen) {
|
||||
recyclerView.setVisibility(isWaitScreen ? View.GONE : View.VISIBLE);
|
||||
buttons.setVisibility(isWaitScreen ? View.GONE : View.VISIBLE);
|
||||
subscribe.setVisibility(isWaitScreen ? View.GONE : View.VISIBLE);
|
||||
loadingView.setVisibility(isWaitScreen ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
|
||||
localBroadcastManager.registerPurchaseReceiver(purchaseReceiver);
|
||||
billingClient.queryPurchases();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
|
||||
localBroadcastManager.unregisterReceiver(purchaseReceiver);
|
||||
}
|
||||
|
||||
NameYourPriceDialog setOnDismissListener(OnDismissListener listener) {
|
||||
this.listener = listener;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDismiss(@NonNull DialogInterface dialog) {
|
||||
super.onDismiss(dialog);
|
||||
|
||||
if (listener != null) {
|
||||
listener.onDismiss(dialog);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPurchasesUpdated() {
|
||||
dismiss();
|
||||
}
|
||||
|
||||
@OnClick(R.id.button_more_info)
|
||||
public void openDocumentation() {
|
||||
startActivity(
|
||||
new Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.subscription_help_url))));
|
||||
dismiss();
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
package org.tasks.billing;
|
||||
|
||||
public interface OnPurchasesUpdated {
|
||||
void onPurchasesUpdated();
|
||||
void onPurchasesUpdated(boolean success);
|
||||
}
|
||||
|
||||
@ -1,38 +0,0 @@
|
||||
package org.tasks.billing;
|
||||
|
||||
import static org.tasks.billing.PurchaseDialog.newPurchaseDialog;
|
||||
|
||||
import android.os.Bundle;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import javax.inject.Inject;
|
||||
import org.tasks.injection.ActivityComponent;
|
||||
import org.tasks.injection.InjectingAppCompatActivity;
|
||||
import org.tasks.themes.ThemeAccent;
|
||||
|
||||
public class PurchaseActivity extends InjectingAppCompatActivity {
|
||||
|
||||
private static final String FRAG_TAG_PURCHASE = "frag_tag_purchase";
|
||||
|
||||
@Inject Inventory inventory;
|
||||
@Inject ThemeAccent themeAccent;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
themeAccent.applyStyle(getTheme());
|
||||
|
||||
FragmentManager fragmentManager = getSupportFragmentManager();
|
||||
PurchaseDialog dialog = (PurchaseDialog) fragmentManager.findFragmentByTag(FRAG_TAG_PURCHASE);
|
||||
if (dialog == null) {
|
||||
dialog = newPurchaseDialog();
|
||||
dialog.show(fragmentManager, FRAG_TAG_PURCHASE);
|
||||
}
|
||||
dialog.setOnDismissListener(d -> finish());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void inject(ActivityComponent component) {
|
||||
component.inject(this);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,215 @@
|
||||
package org.tasks.billing
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import butterknife.ButterKnife
|
||||
import butterknife.OnClick
|
||||
import com.google.android.material.button.MaterialButtonToggleGroup
|
||||
import com.google.common.collect.ContiguousSet
|
||||
import com.google.common.collect.DiscreteDomain
|
||||
import com.google.common.collect.Lists
|
||||
import com.google.common.collect.Range
|
||||
import org.tasks.LocalBroadcastManager
|
||||
import org.tasks.R
|
||||
import org.tasks.databinding.ActivityPurchaseBinding
|
||||
import org.tasks.dialogs.DialogBuilder
|
||||
import org.tasks.dialogs.IconLayoutManager
|
||||
import org.tasks.injection.ActivityComponent
|
||||
import org.tasks.injection.ThemedInjectingAppCompatActivity
|
||||
import org.tasks.locale.Locale
|
||||
import org.tasks.themes.Theme
|
||||
import timber.log.Timber
|
||||
import java.lang.String
|
||||
import javax.inject.Inject
|
||||
|
||||
private const val EXTRA_MONTHLY = "extra_monthly"
|
||||
private const val EXTRA_PRICE = "extra_price"
|
||||
|
||||
class PurchaseActivity : ThemedInjectingAppCompatActivity(), OnPurchasesUpdated, Toolbar.OnMenuItemClickListener {
|
||||
|
||||
@Inject lateinit var inventory: Inventory
|
||||
@Inject lateinit var dialogBuilder: DialogBuilder
|
||||
@Inject lateinit var billingClient: BillingClient
|
||||
@Inject lateinit var localBroadcastManager: LocalBroadcastManager
|
||||
@Inject lateinit var locale: Locale
|
||||
@Inject lateinit var theme: Theme
|
||||
|
||||
private lateinit var binding: ActivityPurchaseBinding
|
||||
private lateinit var adapter: PurchaseAdapter
|
||||
|
||||
private var currentSubscription: Purchase? = null
|
||||
|
||||
private val purchaseReceiver: BroadcastReceiver = object : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
setup()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
binding = ActivityPurchaseBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
ButterKnife.bind(this)
|
||||
|
||||
adapter = PurchaseAdapter(this, theme, locale, ::onPriceChanged)
|
||||
|
||||
if (savedInstanceState != null) {
|
||||
binding.buttons.check(
|
||||
if (savedInstanceState.getBoolean(EXTRA_MONTHLY)) R.id.button_monthly else R.id.button_annually)
|
||||
adapter.selected = savedInstanceState.getInt(EXTRA_PRICE)
|
||||
|
||||
}
|
||||
|
||||
binding.buttons.addOnButtonCheckedListener { group: MaterialButtonToggleGroup?, id: Int, checked: Boolean -> this.onButtonChecked(group!!, id, checked) }
|
||||
|
||||
val toolbar = binding.toolbar.toolbar
|
||||
toolbar.setNavigationIcon(R.drawable.ic_outline_arrow_back_24px)
|
||||
toolbar.setNavigationContentDescription(R.string.back)
|
||||
toolbar.setNavigationOnClickListener { finish() }
|
||||
toolbar.setTitle(R.string.upgrade_to_pro)
|
||||
toolbar.inflateMenu(R.menu.menu_purchase_activity)
|
||||
toolbar.setOnMenuItemClickListener(this)
|
||||
|
||||
themeColor.apply(toolbar)
|
||||
|
||||
setWaitScreen(true)
|
||||
}
|
||||
|
||||
@SuppressLint("DefaultLocale")
|
||||
@OnClick(R.id.subscribe)
|
||||
fun subscribe() {
|
||||
if (currentSubscriptionSelected() && currentSubscription?.isCanceled == true) {
|
||||
billingClient.initiatePurchaseFlow(
|
||||
this, currentSubscription!!.sku, SkuDetails.TYPE_SUBS, null)
|
||||
} else {
|
||||
billingClient.initiatePurchaseFlow(this, String.format("%s_%02d", if (isMonthly()) "monthly" else "annual", adapter.selected),
|
||||
SkuDetails.TYPE_SUBS,
|
||||
currentSubscription?.sku)
|
||||
}
|
||||
billingClient.addPurchaseCallback(this)
|
||||
}
|
||||
|
||||
private fun onButtonChecked(group: MaterialButtonToggleGroup, id: Int, checked: Boolean) {
|
||||
if (id == R.id.button_monthly) {
|
||||
if (!checked && group.checkedButtonId != R.id.button_annually) {
|
||||
group.check(R.id.button_monthly)
|
||||
}
|
||||
} else {
|
||||
if (!checked && group.checkedButtonId != R.id.button_monthly) {
|
||||
group.check(R.id.button_annually)
|
||||
}
|
||||
}
|
||||
updateSubscribeButton()
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
outState.putBoolean(EXTRA_MONTHLY, isMonthly())
|
||||
outState.putInt(EXTRA_PRICE, adapter.selected)
|
||||
}
|
||||
|
||||
private fun isMonthly() = binding.buttons.checkedButtonId == R.id.button_monthly
|
||||
|
||||
private fun setWaitScreen(isWaitScreen: Boolean) {
|
||||
Timber.d("setWaitScreen(%s)", isWaitScreen)
|
||||
binding.recyclerView.visibility = if (isWaitScreen) View.GONE else View.VISIBLE
|
||||
binding.buttons.visibility = if (isWaitScreen) View.GONE else View.VISIBLE
|
||||
binding.subscribe.visibility = if (isWaitScreen) View.GONE else View.VISIBLE
|
||||
binding.screenWait.visibility = if (isWaitScreen) View.VISIBLE else View.GONE
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
localBroadcastManager.registerPurchaseReceiver(purchaseReceiver)
|
||||
billingClient.queryPurchases()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
localBroadcastManager.unregisterReceiver(purchaseReceiver)
|
||||
}
|
||||
|
||||
override fun inject(component: ActivityComponent) {
|
||||
component.inject(this)
|
||||
}
|
||||
|
||||
private fun setup() {
|
||||
currentSubscription = inventory.subscription
|
||||
if (adapter.selected == 0) {
|
||||
adapter.selected = currentSubscription?.subscriptionPrice ?: 3
|
||||
if (currentSubscription != null) {
|
||||
binding.buttons.check(if (currentSubscription?.isMonthly == true) R.id.button_monthly else R.id.button_annually)
|
||||
}
|
||||
}
|
||||
binding.unsubscribe.visibility = if (currentSubscription == null || currentSubscription?.isCanceled == true) View.GONE else View.VISIBLE
|
||||
updateSubscribeButton()
|
||||
setWaitScreen(false)
|
||||
adapter.submitList(
|
||||
Lists.newArrayList(ContiguousSet.create(Range.closed(1, 10), DiscreteDomain.integers())))
|
||||
binding.recyclerView.layoutManager = IconLayoutManager(this)
|
||||
binding.recyclerView.adapter = adapter
|
||||
}
|
||||
|
||||
private fun updateSubscribeButton() {
|
||||
binding.subscribe.isEnabled = true
|
||||
if (currentSubscription == null) {
|
||||
binding.subscribe.setText(R.string.button_subscribe)
|
||||
} else if (currentSubscriptionSelected()) {
|
||||
if (currentSubscription!!.isCanceled) {
|
||||
binding.subscribe.setText(R.string.button_restore_subscription)
|
||||
} else {
|
||||
binding.subscribe.setText(R.string.button_current_subscription)
|
||||
binding.subscribe.isEnabled = false
|
||||
}
|
||||
} else {
|
||||
binding.subscribe.setText(if (isUpgrade()) R.string.button_upgrade else R.string.button_downgrade)
|
||||
}
|
||||
}
|
||||
|
||||
private fun currentSubscriptionSelected() =
|
||||
currentSubscription != null
|
||||
&& isMonthly() == currentSubscription!!.isMonthly
|
||||
&& adapter.selected == currentSubscription!!.subscriptionPrice
|
||||
|
||||
private fun isUpgrade() = if (isMonthly() == currentSubscription!!.isMonthly) {
|
||||
currentSubscription!!.subscriptionPrice < adapter.selected
|
||||
} else {
|
||||
isMonthly()
|
||||
}
|
||||
|
||||
private fun onPriceChanged(price: Int) {
|
||||
adapter.selected = price
|
||||
updateSubscribeButton()
|
||||
}
|
||||
|
||||
@OnClick(R.id.unsubscribe)
|
||||
fun manageSubscription() {
|
||||
startActivity(
|
||||
Intent(
|
||||
Intent.ACTION_VIEW,
|
||||
Uri.parse(getString(R.string.manage_subscription_url, currentSubscription!!.sku))))
|
||||
}
|
||||
|
||||
override fun onPurchasesUpdated(success: Boolean) {
|
||||
if (success) {
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onMenuItemClick(item: MenuItem?): Boolean {
|
||||
return if (item?.itemId == R.id.menu_more_info) {
|
||||
startActivity(
|
||||
Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.subscription_help_url))))
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,77 +0,0 @@
|
||||
package org.tasks.billing;
|
||||
|
||||
import static com.google.common.collect.Lists.transform;
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.tasks.billing.NameYourPriceDialog.newNameYourPriceDialog;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.DialogInterface.OnDismissListener;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.common.base.Joiner;
|
||||
import javax.inject.Inject;
|
||||
import org.tasks.R;
|
||||
import org.tasks.dialogs.DialogBuilder;
|
||||
import org.tasks.injection.DialogFragmentComponent;
|
||||
import org.tasks.injection.ForActivity;
|
||||
import org.tasks.injection.InjectingDialogFragment;
|
||||
import org.tasks.themes.Theme;
|
||||
|
||||
public class PurchaseDialog extends InjectingDialogFragment {
|
||||
|
||||
private static final String FRAG_TAG_PRICE = "frag_tag_price";
|
||||
|
||||
@Inject DialogBuilder dialogBuilder;
|
||||
@Inject Theme theme;
|
||||
@Inject @ForActivity Context context;
|
||||
private OnDismissListener listener;
|
||||
|
||||
public static PurchaseDialog newPurchaseDialog() {
|
||||
return new PurchaseDialog();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
|
||||
View view = theme.getLayoutInflater(context).inflate(R.layout.dialog_purchase, null);
|
||||
TextView textView = view.findViewById(R.id.feature_list);
|
||||
String[] rows = context.getResources().getStringArray(R.array.pro_description);
|
||||
textView.setText(Joiner.on('\n').join(transform(asList(rows), item -> "\u2022 " + item)));
|
||||
return dialogBuilder
|
||||
.newDialog(R.string.pro_support_development)
|
||||
.setView(view)
|
||||
.setPositiveButton(
|
||||
R.string.name_your_price,
|
||||
(dialog, which) -> {
|
||||
newNameYourPriceDialog()
|
||||
.setOnDismissListener(listener)
|
||||
.show(getFragmentManager(), FRAG_TAG_PRICE);
|
||||
listener = null;
|
||||
dialog.dismiss();
|
||||
})
|
||||
.show();
|
||||
}
|
||||
|
||||
void setOnDismissListener(OnDismissListener listener) {
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDismiss(@NonNull DialogInterface dialog) {
|
||||
super.onDismiss(dialog);
|
||||
|
||||
if (listener != null) {
|
||||
listener.onDismiss(dialog);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void inject(DialogFragmentComponent component) {
|
||||
component.inject(this);
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:color="?attr/colorAccent" android:state_checked="true"/>
|
||||
<item android:alpha="0.12" android:color="?attr/colorOnSurface" android:state_checked="false"/>
|
||||
<item android:color="?attr/colorAccent" android:state_enabled="true"/>
|
||||
<item android:alpha="0.12" android:color="?attr/colorOnSurface" android:state_enabled="false"/>
|
||||
</selector>
|
||||
|
||||
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:color="?attr/colorAccent" android:state_checked="true"/>
|
||||
<item android:alpha="0.12" android:color="?attr/colorOnSurface" android:state_checked="false"/>
|
||||
</selector>
|
||||
@ -0,0 +1,131 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:orientation="vertical">
|
||||
|
||||
<include
|
||||
android:id="@+id/toolbar"
|
||||
layout="@layout/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
style="@style/TextAppearance.AppCompat.Medium"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAlignment="center"
|
||||
android:text="@string/upgrade_blurb_1"
|
||||
android:padding="@dimen/keyline_first"
|
||||
android:layout_gravity="center_horizontal" />
|
||||
|
||||
<TextView
|
||||
style="@style/TextAppearance.AppCompat.Medium"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAlignment="center"
|
||||
android:text="@string/upgrade_blurb_2"
|
||||
android:padding="@dimen/keyline_first"
|
||||
android:layout_gravity="center_horizontal" />
|
||||
|
||||
<TextView
|
||||
style="@style/TextAppearance.AppCompat.Medium"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAlignment="center"
|
||||
android:text="@string/upgrade_blurb_3"
|
||||
android:padding="@dimen/keyline_first"
|
||||
android:layout_gravity="center_horizontal" />
|
||||
|
||||
<TextView
|
||||
style="@style/TextAppearance.AppCompat.Medium"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAlignment="center"
|
||||
android:text="@string/upgrade_blurb_4"
|
||||
android:padding="@dimen/keyline_first"
|
||||
android:layout_gravity="center_horizontal" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/screen_wait"
|
||||
style="?android:attr/progressBarStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:indeterminate="true"
|
||||
android:visibility="gone" />
|
||||
|
||||
<com.google.android.material.button.MaterialButtonToggleGroup
|
||||
android:id="@+id/buttons"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_horizontal"
|
||||
android:visibility="gone"
|
||||
app:checkedButton="@id/button_monthly"
|
||||
app:singleSelection="true"
|
||||
android:paddingLeft="@dimen/keyline_content_inset"
|
||||
android:paddingStart="@dimen/keyline_content_inset"
|
||||
android:paddingEnd="@dimen/keyline_content_inset"
|
||||
android:paddingRight="@dimen/keyline_content_inset">
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/button_monthly"
|
||||
style="@style/OutlineButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/monthly" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/button_annually"
|
||||
style="@style/OutlineButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/annually" />
|
||||
|
||||
</com.google.android.material.button.MaterialButtonToggleGroup>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recycler_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:paddingLeft="@dimen/keyline_content_inset"
|
||||
android:paddingStart="@dimen/keyline_content_inset"
|
||||
android:paddingEnd="@dimen/keyline_content_inset"
|
||||
android:paddingRight="@dimen/keyline_content_inset" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/subscribe"
|
||||
style="@style/OutlineButton"
|
||||
android:padding="@dimen/keyline_first"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_margin="@dimen/keyline_first"
|
||||
android:layout_height="wrap_content"
|
||||
app:strokeColor="@color/button_accent_stroke"
|
||||
android:text="@string/button_subscribe" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/unsubscribe"
|
||||
style="@style/OutlineButton"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/keyline_first"
|
||||
android:padding="@dimen/keyline_first"
|
||||
app:strokeColor="?attr/colorSecondary"
|
||||
android:text="@string/button_unsubscribe"
|
||||
android:visibility="gone" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
||||
</LinearLayout>
|
||||
@ -1,83 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<ScrollView
|
||||
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">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="@dimen/keyline_first"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/screen_wait"
|
||||
style="?android:attr/progressBarStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:indeterminate="true"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<com.google.android.material.button.MaterialButtonToggleGroup
|
||||
android:id="@+id/buttons"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
android:visibility="gone"
|
||||
app:checkedButton="@id/button_monthly"
|
||||
app:singleSelection="true">
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/button_monthly"
|
||||
style="@style/OutlineButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/monthly"/>
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/button_annually"
|
||||
style="@style/OutlineButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/annually"/>
|
||||
|
||||
</com.google.android.material.button.MaterialButtonToggleGroup>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recycler_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"/>
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/subscribe"
|
||||
style="@style/TextButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end"
|
||||
android:text="@string/button_subscribe"/>
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/unsubscribe"
|
||||
style="@style/TextButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end"
|
||||
android:text="@string/button_unsubscribe"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/button_more_info"
|
||||
style="@style/TextButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end"
|
||||
android:text="@string/button_more_info"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
||||
@ -1,34 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="@dimen/keyline_first"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/pro_description"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Body1"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="@dimen/keyline_first"
|
||||
android:text="@string/pro_subscribe_now"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Body1"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/feature_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="16dp"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Body2"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
||||
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tasks="http://schemas.android.com/apk/res-auto">
|
||||
<item
|
||||
android:id="@+id/menu_more_info"
|
||||
android:title="@string/button_more_info"
|
||||
android:icon="@drawable/ic_outline_help_outline_24px"
|
||||
android:contentDescription="@string/button_more_info"
|
||||
tasks:showAsAction="ifRoom" />
|
||||
</menu>
|
||||
Loading…
Reference in New Issue