mirror of https://github.com/tasks/tasks
Add GoogleTasksAccount preference fragment
parent
19bcd457e3
commit
eb2c7420d6
@ -0,0 +1,62 @@
|
|||||||
|
package org.tasks.preferences.fragments
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Bundle
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import kotlinx.coroutines.NonCancellable
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import org.tasks.R
|
||||||
|
import org.tasks.billing.BillingClient
|
||||||
|
import org.tasks.billing.PurchaseDialog
|
||||||
|
import org.tasks.injection.InjectingPreferenceFragment
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
abstract class BaseAccountPreference : InjectingPreferenceFragment() {
|
||||||
|
|
||||||
|
@Inject lateinit var billingClient: BillingClient
|
||||||
|
|
||||||
|
override suspend fun setupPreferences(savedInstanceState: Bundle?) {
|
||||||
|
findPreference(R.string.logout).setOnPreferenceClickListener {
|
||||||
|
dialogBuilder
|
||||||
|
.newDialog()
|
||||||
|
.setMessage(R.string.logout_warning)
|
||||||
|
.setPositiveButton(R.string.remove) { _, _ ->
|
||||||
|
lifecycleScope.launch {
|
||||||
|
withContext(NonCancellable) {
|
||||||
|
removeAccount()
|
||||||
|
}
|
||||||
|
activity?.onBackPressed()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.setNegativeButton(R.string.cancel, null)
|
||||||
|
.show()
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract suspend fun removeAccount()
|
||||||
|
|
||||||
|
protected fun showPurchaseDialog(tasksPayment: Boolean = false): Boolean {
|
||||||
|
PurchaseDialog
|
||||||
|
.newPurchaseDialog(this, REQUEST_PURCHASE, tasksPayment)
|
||||||
|
.show(parentFragmentManager, PurchaseDialog.FRAG_TAG_PURCHASE_DIALOG)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||||
|
if (requestCode == REQUEST_PURCHASE) {
|
||||||
|
if (resultCode == Activity.RESULT_OK) {
|
||||||
|
billingClient.queryPurchases()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
super.onActivityResult(requestCode, resultCode, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val REQUEST_PURCHASE = 10201
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,129 @@
|
|||||||
|
package org.tasks.preferences.fragments
|
||||||
|
|
||||||
|
import android.content.*
|
||||||
|
import android.os.Bundle
|
||||||
|
import androidx.lifecycle.LiveData
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import com.todoroo.astrid.gtasks.auth.GtasksLoginActivity
|
||||||
|
import com.todoroo.astrid.service.TaskDeleter
|
||||||
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import org.tasks.LocalBroadcastManager
|
||||||
|
import org.tasks.R
|
||||||
|
import org.tasks.billing.Inventory
|
||||||
|
import org.tasks.data.CaldavAccount.Companion.isPaymentRequired
|
||||||
|
import org.tasks.data.GoogleTaskAccount
|
||||||
|
import org.tasks.data.GoogleTaskListDao
|
||||||
|
import org.tasks.preferences.IconPreference
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@AndroidEntryPoint
|
||||||
|
class GoogleTasksAccount : BaseAccountPreference() {
|
||||||
|
|
||||||
|
@Inject lateinit var taskDeleter: TaskDeleter
|
||||||
|
@Inject lateinit var inventory: Inventory
|
||||||
|
@Inject lateinit var localBroadcastManager: LocalBroadcastManager
|
||||||
|
@Inject lateinit var googleTaskListDao: GoogleTaskListDao
|
||||||
|
|
||||||
|
private lateinit var googleTaskAccountLiveData: LiveData<GoogleTaskAccount>
|
||||||
|
|
||||||
|
val googleTaskAccount: GoogleTaskAccount
|
||||||
|
get() = googleTaskAccountLiveData.value ?: requireArguments().getParcelable(EXTRA_ACCOUNT)!!
|
||||||
|
|
||||||
|
private val purchaseReceiver = object : BroadcastReceiver() {
|
||||||
|
override fun onReceive(context: Context, intent: Intent) {
|
||||||
|
lifecycleScope.launch {
|
||||||
|
googleTaskAccount.let {
|
||||||
|
if (inventory.subscription != null && it.error.isPaymentRequired()) {
|
||||||
|
it.error = null
|
||||||
|
googleTaskListDao.update(it)
|
||||||
|
}
|
||||||
|
refreshUi(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getPreferenceXml() = R.xml.preferences_google_tasks
|
||||||
|
|
||||||
|
override suspend fun setupPreferences(savedInstanceState: Bundle?) {
|
||||||
|
super.setupPreferences(savedInstanceState)
|
||||||
|
|
||||||
|
googleTaskAccountLiveData = googleTaskListDao.watchAccount(
|
||||||
|
arguments?.getParcelable<GoogleTaskAccount>(EXTRA_ACCOUNT)?.id ?: 0
|
||||||
|
)
|
||||||
|
googleTaskAccountLiveData.observe(this) { refreshUi(it) }
|
||||||
|
|
||||||
|
findPreference(R.string.reinitialize_account)
|
||||||
|
.setOnPreferenceClickListener { requestLogin() }
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun removeAccount() {
|
||||||
|
taskDeleter.delete(googleTaskAccount)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
localBroadcastManager.registerPurchaseReceiver(purchaseReceiver)
|
||||||
|
localBroadcastManager.registerRefreshListReceiver(purchaseReceiver)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onPause() {
|
||||||
|
super.onPause()
|
||||||
|
|
||||||
|
localBroadcastManager.unregisterReceiver(purchaseReceiver)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun refreshUi(account: GoogleTaskAccount?) {
|
||||||
|
if (account == null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
(findPreference(R.string.sign_in_with_google) as IconPreference).apply {
|
||||||
|
if (account.error.isNullOrBlank()) {
|
||||||
|
isVisible = false
|
||||||
|
return@apply
|
||||||
|
}
|
||||||
|
isVisible = true
|
||||||
|
when {
|
||||||
|
account.error.isPaymentRequired() -> {
|
||||||
|
setOnPreferenceClickListener { showPurchaseDialog() }
|
||||||
|
setTitle(R.string.name_your_price)
|
||||||
|
setSummary(R.string.requires_pro_subscription)
|
||||||
|
}
|
||||||
|
account.error.isUnauthorized() -> {
|
||||||
|
setTitle(R.string.sign_in_with_google)
|
||||||
|
setSummary(R.string.authentication_required)
|
||||||
|
setOnPreferenceClickListener { requestLogin() }
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
this.title = null
|
||||||
|
this.summary = account.error
|
||||||
|
this.onPreferenceClickListener = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
iconVisible = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun requestLogin(): Boolean {
|
||||||
|
activity?.startActivityForResult(
|
||||||
|
Intent(activity, GtasksLoginActivity::class.java),
|
||||||
|
MainSettingsFragment.REQUEST_GOOGLE_TASKS
|
||||||
|
)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val EXTRA_ACCOUNT = "extra_account"
|
||||||
|
|
||||||
|
fun String?.isUnauthorized(): Boolean =
|
||||||
|
this?.startsWith("401 Unauthorized", ignoreCase = true) == true
|
||||||
|
|
||||||
|
fun newGoogleTasksAccountPreference(account: GoogleTaskAccount) =
|
||||||
|
GoogleTasksAccount().apply {
|
||||||
|
arguments = Bundle().apply {
|
||||||
|
putParcelable(EXTRA_ACCOUNT, account)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:key="@string/preference_screen">
|
||||||
|
|
||||||
|
<org.tasks.preferences.IconPreference
|
||||||
|
android:key="@string/sign_in_with_google"
|
||||||
|
android:layout="@layout/preference_icon"
|
||||||
|
android:title="@string/sign_in_with_google"
|
||||||
|
android:summary="@string/authentication_required"
|
||||||
|
app:isPreferenceVisible="false"
|
||||||
|
tools:isPreferenceVisible="true"/>
|
||||||
|
|
||||||
|
<Preference
|
||||||
|
android:key="@string/reinitialize_account"
|
||||||
|
android:title="@string/reinitialize_account" />
|
||||||
|
|
||||||
|
<Preference
|
||||||
|
android:key="@string/logout"
|
||||||
|
android:title="@string/logout"
|
||||||
|
app:allowDividerAbove="true"/>
|
||||||
|
|
||||||
|
</PreferenceScreen>
|
||||||
Loading…
Reference in New Issue