diff --git a/app/src/main/java/org/tasks/Tasks.kt b/app/src/main/java/org/tasks/Tasks.kt index f1ea96169..e0b860a17 100644 --- a/app/src/main/java/org/tasks/Tasks.kt +++ b/app/src/main/java/org/tasks/Tasks.kt @@ -75,6 +75,7 @@ class Tasks : Application(), Configuration.Provider { } private fun backgroundWork() = CoroutineScope(Dispatchers.Default).launch { + inventory.updateTasksSubscription() NotificationSchedulerIntentService.enqueueWork(context, false) CalendarNotificationIntentService.enqueueWork(context) refreshScheduler.get().scheduleAll() diff --git a/app/src/main/java/org/tasks/auth/SignInActivity.kt b/app/src/main/java/org/tasks/auth/SignInActivity.kt index 188839717..06405a588 100644 --- a/app/src/main/java/org/tasks/auth/SignInActivity.kt +++ b/app/src/main/java/org/tasks/auth/SignInActivity.kt @@ -306,7 +306,7 @@ class SignInActivity : InjectingAppCompatActivity(), PurchaseDialog.PurchaseHand } override fun onPurchaseDialogDismissed() { - if (inventory.hasTasksSubscription) { + if (inventory.subscription?.isTasksSubscription == true) { lifecycleScope.launch { val account = viewModel.setupAccount(authStateManager.current) if (account != null) { diff --git a/app/src/main/java/org/tasks/billing/Inventory.kt b/app/src/main/java/org/tasks/billing/Inventory.kt index 6ed15962d..1375494d7 100644 --- a/app/src/main/java/org/tasks/billing/Inventory.kt +++ b/app/src/main/java/org/tasks/billing/Inventory.kt @@ -3,9 +3,12 @@ package org.tasks.billing import android.content.Context import android.content.Intent import android.net.Uri +import dagger.hilt.android.qualifiers.ApplicationContext import org.tasks.BuildConfig import org.tasks.LocalBroadcastManager import org.tasks.R +import org.tasks.data.CaldavAccount.Companion.TYPE_TASKS +import org.tasks.data.CaldavDao import org.tasks.preferences.Preferences import timber.log.Timber import java.util.* @@ -14,11 +17,15 @@ import javax.inject.Singleton @Singleton class Inventory @Inject constructor( + @ApplicationContext private val context: Context, private val preferences: Preferences, private val signatureVerifier: SignatureVerifier, - private val localBroadcastManager: LocalBroadcastManager + private val localBroadcastManager: LocalBroadcastManager, + private val caldavDao: CaldavDao ) { private val purchases: MutableMap = HashMap() + var hasTasksSubscription = false + private set fun clear() { Timber.d("clear()") @@ -49,10 +56,17 @@ class Inventory @Inject constructor( get() { return BuildConfig.FLAVOR == "generic" || (BuildConfig.DEBUG && preferences.getBoolean(R.string.p_debug_pro, false)) + || hasTasksSubscription || field } private set + suspend fun updateTasksSubscription() { + hasTasksSubscription = caldavDao.getAccounts(TYPE_TASKS).any { + it.isTasksSubscription(context) + } + } + fun purchased(sku: String) = purchases.containsKey(sku) fun getPurchase(sku: String) = purchases[sku] @@ -70,9 +84,6 @@ class Inventory @Inject constructor( } .firstOrNull() - val hasTasksSubscription: Boolean - get() = subscription?.isTasksSubscription ?: false - fun unsubscribe(context: Context): Boolean { subscription?.let { context.startActivity( diff --git a/app/src/main/java/org/tasks/data/CaldavAccount.kt b/app/src/main/java/org/tasks/data/CaldavAccount.kt index 1d7ef0200..39932d60e 100644 --- a/app/src/main/java/org/tasks/data/CaldavAccount.kt +++ b/app/src/main/java/org/tasks/data/CaldavAccount.kt @@ -1,5 +1,6 @@ package org.tasks.data +import android.content.Context import android.os.Parcel import android.os.Parcelable import androidx.core.os.ParcelCompat @@ -8,6 +9,7 @@ import androidx.room.Entity import androidx.room.Ignore import androidx.room.PrimaryKey import com.todoroo.astrid.data.Task +import org.tasks.R import org.tasks.activities.BaseListSettingsActivity import org.tasks.caldav.CaldavCalendarSettingsActivity import org.tasks.caldav.LocalListSettingsActivity @@ -16,6 +18,7 @@ import org.tasks.etebase.EtebaseCalendarSettingsActivity import org.tasks.etesync.EteSyncCalendarSettingsActivity import org.tasks.opentasks.OpenTasksListSettingsActivity import org.tasks.security.KeyStoreEncryption +import java.net.HttpURLConnection @Entity(tableName = "caldav_accounts") class CaldavAccount : Parcelable { @@ -165,6 +168,19 @@ class CaldavAccount : Parcelable { return "CaldavAccount(id=$id, uuid=$uuid, name=$name, url=$url, username=$username, password=$password, error=$error, isSuppressRepeatingTasks=$isSuppressRepeatingTasks, encryptionKey=$encryptionKey, accountType=$accountType, isCollapsed=$isCollapsed)" } + fun isTasksSubscription(context: Context): Boolean { + val caldavUrl = context.getString(R.string.tasks_caldav_url) + return url?.startsWith("https://${caldavUrl}/calendars/") == true && + !isPaymentRequired() && + !isLoggedOut() + } + + fun isLoggedOut(): Boolean = + error?.startsWith("HTTP ${HttpURLConnection.HTTP_UNAUTHORIZED}") == true + + fun isPaymentRequired(): Boolean = + error?.startsWith("HTTP ${HttpURLConnection.HTTP_PAYMENT_REQUIRED}") == true + companion object { const val TYPE_CALDAV = 0 @Deprecated("use etebase") const val TYPE_ETESYNC = 1 diff --git a/app/src/main/java/org/tasks/filters/FilterProvider.kt b/app/src/main/java/org/tasks/filters/FilterProvider.kt index e339061a7..f519d9af5 100644 --- a/app/src/main/java/org/tasks/filters/FilterProvider.kt +++ b/app/src/main/java/org/tasks/filters/FilterProvider.kt @@ -169,7 +169,7 @@ class FilterProvider @Inject constructor( private val navDrawerFooter: List get() = listOf(NavigationDrawerSeparator()) - .plusIf(BuildConfig.FLAVOR == "generic") { + .plusIf(BuildConfig.FLAVOR == "generic" && !inventory.hasTasksSubscription) { NavigationDrawerAction( context.getString(R.string.TLA_menu_donate), R.drawable.ic_outline_attach_money_24px, diff --git a/app/src/main/java/org/tasks/jobs/SyncCaldavWork.kt b/app/src/main/java/org/tasks/jobs/SyncCaldavWork.kt index 3f57a86e2..f82fbc602 100644 --- a/app/src/main/java/org/tasks/jobs/SyncCaldavWork.kt +++ b/app/src/main/java/org/tasks/jobs/SyncCaldavWork.kt @@ -8,6 +8,7 @@ import kotlinx.coroutines.* import org.tasks.LocalBroadcastManager import org.tasks.R import org.tasks.analytics.Firebase +import org.tasks.billing.Inventory import org.tasks.caldav.CaldavSynchronizer import org.tasks.data.CaldavAccount.Companion.TYPE_CALDAV import org.tasks.data.CaldavAccount.Companion.TYPE_TASKS @@ -21,7 +22,8 @@ class SyncCaldavWork @WorkerInject constructor( localBroadcastManager: LocalBroadcastManager, preferences: Preferences, private val caldavDao: CaldavDao, - private val caldavSynchronizer: CaldavSynchronizer + private val caldavSynchronizer: CaldavSynchronizer, + private val inventory: Inventory ) : SyncWork(context, workerParams, firebase, localBroadcastManager, preferences) { override suspend fun enabled() = getAccounts().isNotEmpty() @@ -30,6 +32,7 @@ class SyncCaldavWork @WorkerInject constructor( override suspend fun doSync() { caldavJobs().awaitAll() + inventory.updateTasksSubscription() } private suspend fun caldavJobs(): List> = coroutineScope { diff --git a/app/src/main/java/org/tasks/preferences/fragments/TasksAccount.kt b/app/src/main/java/org/tasks/preferences/fragments/TasksAccount.kt index 9f1b19389..85ba602f2 100644 --- a/app/src/main/java/org/tasks/preferences/fragments/TasksAccount.kt +++ b/app/src/main/java/org/tasks/preferences/fragments/TasksAccount.kt @@ -24,8 +24,6 @@ import org.tasks.injection.InjectingPreferenceFragment import org.tasks.jobs.WorkManager import org.tasks.preferences.IconPreference import org.tasks.ui.Toaster -import java.net.HttpURLConnection.HTTP_PAYMENT_REQUIRED -import java.net.HttpURLConnection.HTTP_UNAUTHORIZED import javax.inject.Inject @AndroidEntryPoint @@ -46,7 +44,7 @@ class TasksAccount : InjectingPreferenceFragment() { override fun onReceive(context: Context, intent: Intent) { lifecycleScope.launch { if (inventory.subscription?.isTasksSubscription == true - && caldavAccount.error.isPaymentRequired()) { + && caldavAccount.isPaymentRequired()) { caldavAccount.error = null caldavDao.update(caldavAccount) } @@ -125,7 +123,7 @@ class TasksAccount : InjectingPreferenceFragment() { private fun refreshUi() { (findPreference(R.string.sign_in_with_google) as IconPreference).apply { - isVisible = caldavAccount.error.isLoggedOut() + isVisible = caldavAccount.isLoggedOut() iconVisible = true } @@ -142,7 +140,7 @@ class TasksAccount : InjectingPreferenceFragment() { } val subscription = inventory.subscription findPreference(R.string.upgrade_to_pro).apply { - if (caldavAccount.error.isPaymentRequired()) { + if (caldavAccount.isPaymentRequired()) { if (subscription == null) { setTitle(R.string.upgrade_to_pro) setSummary(R.string.your_subscription_expired) @@ -192,11 +190,5 @@ class TasksAccount : InjectingPreferenceFragment() { } return fragment } - - private fun String?.isLoggedOut(): Boolean = - this?.startsWith("HTTP $HTTP_UNAUTHORIZED") == true - - private fun String?.isPaymentRequired(): Boolean = - this?.startsWith("HTTP $HTTP_PAYMENT_REQUIRED") == true } } \ No newline at end of file