diff --git a/app/src/main/java/com/todoroo/astrid/activity/MainActivity.kt b/app/src/main/java/com/todoroo/astrid/activity/MainActivity.kt index 595990265..27c5cc439 100644 --- a/app/src/main/java/com/todoroo/astrid/activity/MainActivity.kt +++ b/app/src/main/java/com/todoroo/astrid/activity/MainActivity.kt @@ -28,7 +28,6 @@ import androidx.compose.material3.adaptive.layout.calculatePaneScaffoldDirective import androidx.compose.material3.adaptive.navigation.rememberListDetailPaneScaffoldNavigator import androidx.compose.material3.rememberDrawerState import androidx.compose.runtime.LaunchedEffect -import androidx.lifecycle.compose.LifecycleResumeEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.rememberCoroutineScope @@ -39,6 +38,7 @@ import androidx.compose.ui.unit.dp import androidx.core.content.IntentCompat.getParcelableExtra import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen import androidx.hilt.navigation.compose.hiltViewModel +import androidx.lifecycle.compose.LifecycleResumeEffect import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.lifecycleScope import androidx.navigation.compose.NavHost @@ -65,6 +65,7 @@ import org.tasks.compose.WelcomeDestination import org.tasks.compose.WelcomeScreen import org.tasks.compose.accounts.AddAccountScreen import org.tasks.compose.accounts.AddAccountViewModel +import org.tasks.compose.accounts.Platform import org.tasks.compose.home.HomeScreen import org.tasks.data.dao.AlarmDao import org.tasks.data.dao.CaldavDao @@ -87,7 +88,6 @@ import org.tasks.preferences.DefaultFilterProvider import org.tasks.preferences.Preferences import org.tasks.preferences.TasksPreferences import org.tasks.preferences.fragments.FRAG_TAG_IMPORT_TASKS -import org.tasks.compose.accounts.Platform import org.tasks.sync.SyncAdapters import org.tasks.sync.microsoft.MicrosoftSignInViewModel import org.tasks.themes.ColorProvider diff --git a/app/src/main/java/org/tasks/TasksApplication.kt b/app/src/main/java/org/tasks/TasksApplication.kt index 41cfc492a..77b3dc423 100644 --- a/app/src/main/java/org/tasks/TasksApplication.kt +++ b/app/src/main/java/org/tasks/TasksApplication.kt @@ -162,9 +162,9 @@ class TasksApplication : Application(), Configuration.Provider { } companion object { - @Suppress("KotlinConstantConditions") + @Suppress("KotlinConstantConditions", "SimplifyBooleanWithConstants") const val IS_GOOGLE_PLAY = BuildConfig.FLAVOR == "googleplay" - @Suppress("KotlinConstantConditions") + @Suppress("KotlinConstantConditions", "SimplifyBooleanWithConstants") const val IS_GENERIC = BuildConfig.FLAVOR == "generic" } } diff --git a/app/src/main/java/org/tasks/auth/SignInActivity.kt b/app/src/main/java/org/tasks/auth/SignInActivity.kt index f83590451..e6f359568 100644 --- a/app/src/main/java/org/tasks/auth/SignInActivity.kt +++ b/app/src/main/java/org/tasks/auth/SignInActivity.kt @@ -21,6 +21,14 @@ import androidx.activity.viewModels import androidx.annotation.MainThread import androidx.annotation.WorkerThread import androidx.browser.customtabs.CustomTabsIntent +import androidx.compose.material3.AlertDialog +import androidx.compose.material3.Text +import androidx.compose.material3.TextButton +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue +import androidx.compose.ui.res.stringResource import androidx.compose.ui.window.Dialog import androidx.lifecycle.lifecycleScope import at.bitfire.dav4jvm.exception.HttpException @@ -36,6 +44,7 @@ import net.openid.appauth.RegistrationResponse import net.openid.appauth.ResponseTypeValues import org.tasks.R import org.tasks.TasksApplication.Companion.IS_GENERIC +import org.tasks.TasksApplication.Companion.IS_GOOGLE_PLAY import org.tasks.analytics.Firebase import org.tasks.billing.Inventory import org.tasks.billing.PurchaseActivity @@ -74,6 +83,7 @@ class SignInActivity : ComponentActivity() { private val mAuthIntent = AtomicReference() private var mAuthIntentLatch = CountDownLatch(1) private val mExecutor: ExecutorService = newSingleThreadExecutor() + private var showSubscriptionRequiredDialog by mutableStateOf(null) private val authService: AuthorizationService get() = viewModel.authService!! @@ -96,6 +106,19 @@ class SignInActivity : ComponentActivity() { val autoSelect = intent.getSerializableExtra(EXTRA_SELECT_SERVICE) as Platform? if (autoSelect != null) { + setContent { + TasksTheme( + theme = theme.themeBase.index, + primary = theme.themeColor.primaryColor, + ) { + showSubscriptionRequiredDialog?.let { isGitHub -> + SubscriptionRequiredDialog( + isGitHub = isGitHub, + onDismiss = { finish() }, + ) + } + } + } selectService(autoSelect) } else { setContent { @@ -103,21 +126,76 @@ class SignInActivity : ComponentActivity() { theme = theme.themeBase.index, primary = theme.themeColor.primaryColor, ) { - Dialog(onDismissRequest = { finish() }) { - SignInDialog( - selected = { selectService(it) }, - help = { - openUri(R.string.help_url_sync) - finish() - }, - cancel = { finish() } + if (showSubscriptionRequiredDialog != null) { + SubscriptionRequiredDialog( + isGitHub = showSubscriptionRequiredDialog!!, + onDismiss = { finish() }, ) + } else { + Dialog(onDismissRequest = { finish() }) { + SignInDialog( + selected = { selectService(it) }, + help = { + openUri(R.string.help_url_sync) + finish() + }, + cancel = { finish() } + ) + } } } } } } + @Composable + private fun SubscriptionRequiredDialog( + isGitHub: Boolean, + onDismiss: () -> Unit, + ) { + AlertDialog( + onDismissRequest = onDismiss, + title = { + Text( + stringResource( + if (isGitHub) R.string.github_sponsors else R.string.subscription + ) + ) + }, + text = { + Text( + stringResource( + if (isGitHub) + R.string.sponsorship_required_fdroid + else + R.string.subscription_required_fdroid + ) + ) + }, + dismissButton = if (isGitHub) { + { + TextButton(onClick = onDismiss) { + Text(stringResource(R.string.cancel)) + } + } + } else null, + confirmButton = { + TextButton(onClick = { + if (isGitHub) { + openUri(R.string.url_sponsor) + } + onDismiss() + }) { + Text( + stringResource( + if (isGitHub) R.string.github_sponsor else R.string.ok + ) + ) + } + }, + ) + } + private fun selectService(which: Platform) { viewModel.initializeAuthService(when (which) { Platform.GOOGLE -> AuthorizationService.ISS_GOOGLE @@ -147,12 +225,16 @@ class SignInActivity : ComponentActivity() { private fun handleError(e: Throwable) { if (e is HttpException && e.code == 402) { - startActivityForResult( - Intent(this, PurchaseActivity::class.java) - .putExtra(EXTRA_GITHUB, viewModel.authService?.isGitHub ?: IS_GENERIC) - .putExtra(EXTRA_NAME_YOUR_PRICE, false), - RC_PURCHASE - ) + if (IS_GOOGLE_PLAY) { + startActivityForResult( + Intent(this, PurchaseActivity::class.java) + .putExtra(EXTRA_GITHUB, viewModel.authService?.isGitHub ?: IS_GENERIC) + .putExtra(EXTRA_NAME_YOUR_PRICE, false), + RC_PURCHASE + ) + } else { + showSubscriptionRequiredDialog = viewModel.authService?.isGitHub ?: false + } } else { returnError(e) } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5f15b578c..ec1ab4db4 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -628,6 +628,8 @@ File %1$s contained %2$s.\n\n Insufficient subscription level. Please upgrade your subscription to resume service. No eligible GitHub sponsorship found No eligible Google Play subscription found + A subscription is required to use Tasks.org sync. Subscriptions must be initiated from the Google Play version of Tasks. + A GitHub sponsorship is required to use Tasks.org sync. Click below to become a sponsor. $%s/year $%s/month %s/month