diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 420fcfb5a..886e3da5a 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -310,6 +310,10 @@
android:name=".billing.PurchaseActivity"
android:theme="@style/Tasks" />
+
+
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 dc47895e6..f60ce93a8 100644
--- a/app/src/main/java/com/todoroo/astrid/activity/MainActivity.kt
+++ b/app/src/main/java/com/todoroo/astrid/activity/MainActivity.kt
@@ -86,7 +86,7 @@ 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.sync.AddAccountDialog
+import org.tasks.compose.accounts.Platform
import org.tasks.sync.SyncAdapters
import org.tasks.sync.microsoft.MicrosoftSignInViewModel
import org.tasks.themes.ColorProvider
@@ -277,30 +277,30 @@ class MainActivity : AppCompatActivity() {
signIn = { platform ->
firebase.logEvent(R.string.event_onboarding_sync, R.string.param_selection to platform)
when (platform) {
- AddAccountDialog.Platform.TASKS_ORG ->
+ Platform.TASKS_ORG ->
syncLauncher.launch(
Intent(this@MainActivity, SignInActivity::class.java)
)
- AddAccountDialog.Platform.GOOGLE_TASKS ->
+ Platform.GOOGLE_TASKS ->
syncLauncher.launch(
Intent(this@MainActivity, GtasksLoginActivity::class.java)
)
- AddAccountDialog.Platform.MICROSOFT ->
+ Platform.MICROSOFT ->
microsoftVM.signIn(this@MainActivity)
- AddAccountDialog.Platform.CALDAV ->
+ Platform.CALDAV ->
syncLauncher.launch(
Intent(this@MainActivity, CaldavAccountSettingsActivity::class.java)
)
- AddAccountDialog.Platform.ETESYNC ->
+ Platform.ETESYNC ->
syncLauncher.launch(
Intent(this@MainActivity, EtebaseAccountSettingsActivity::class.java)
)
- AddAccountDialog.Platform.LOCAL ->
+ Platform.LOCAL ->
addAccountViewModel.createLocalAccount()
else -> throw IllegalArgumentException()
diff --git a/app/src/main/java/org/tasks/compose/AddAccountDialog.kt b/app/src/main/java/org/tasks/compose/AddAccountDialog.kt
deleted file mode 100644
index de8c75250..000000000
--- a/app/src/main/java/org/tasks/compose/AddAccountDialog.kt
+++ /dev/null
@@ -1,95 +0,0 @@
-package org.tasks.compose
-
-import android.content.res.Configuration
-import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.rememberScrollState
-import androidx.compose.foundation.verticalScroll
-import androidx.compose.material3.MaterialTheme
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.tooling.preview.Preview
-import org.tasks.R
-import org.tasks.sync.AddAccountDialog.Platform
-import org.tasks.themes.TasksTheme
-
-@Composable
-fun AddAccountDialog(
- hasTasksAccount: Boolean,
- hasPro: Boolean,
- selected: (Platform) -> Unit,
-) {
- Column(modifier = Modifier.verticalScroll(rememberScrollState())) {
- if (!hasTasksAccount) {
- SyncAccount(
- title = R.string.tasks_org,
- cost = R.string.cost_more_money,
- description = R.string.tasks_org_description,
- icon = R.drawable.ic_round_icon,
- onClick = { selected(Platform.TASKS_ORG) }
- )
- }
- SyncAccount(
- title = R.string.gtasks_GPr_header,
- cost = if (hasPro) null else R.string.cost_free,
- description = R.string.google_tasks_selection_description,
- icon = R.drawable.ic_google,
- onClick = { selected(Platform.GOOGLE_TASKS) }
- )
- SyncAccount(
- title = R.string.microsoft,
- cost = if (hasPro) null else R.string.cost_free,
- description = R.string.microsoft_selection_description,
- icon = R.drawable.ic_microsoft_tasks,
- onClick = { selected(Platform.MICROSOFT) }
- )
- SyncAccount(
- title = R.string.davx5,
- cost = if (hasPro) null else R.string.cost_money,
- description = R.string.davx5_selection_description,
- icon = R.drawable.ic_davx5_icon_green_bg,
- onClick = { selected(Platform.DAVX5) }
- )
- SyncAccount(
- title = R.string.caldav,
- cost = if (hasPro) null else R.string.cost_money,
- description = R.string.caldav_selection_description,
- icon = R.drawable.ic_webdav_logo,
- tint = MaterialTheme.colorScheme.onSurface.copy(
- alpha = .8f
- ),
- onClick = { selected(Platform.CALDAV) }
- )
- SyncAccount(
- title = R.string.etesync,
- cost = if (hasPro) null else R.string.cost_money,
- description = R.string.etesync_selection_description,
- icon = R.drawable.ic_etesync,
- onClick = { selected(Platform.ETESYNC) }
- )
- SyncAccount(
- title = R.string.decsync,
- cost = if (hasPro) null else R.string.cost_money,
- description = R.string.decsync_selection_description,
- icon = R.drawable.ic_decsync,
- onClick = { selected(Platform.DECSYNC_CC) }
- )
- }
-}
-
-@Preview(showBackground = true, widthDp = 320)
-@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES, widthDp = 320)
-@Composable
-fun AddAccountDialogPreview() {
- TasksTheme {
- AddAccountDialog(hasTasksAccount = false, hasPro = false, selected = {})
- }
-}
-
-@Preview(showBackground = true, widthDp = 320)
-@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES, widthDp = 320)
-@Composable
-fun AddAccountDialogPreviewWithPro() {
- TasksTheme {
- AddAccountDialog(hasTasksAccount = false, hasPro = true, selected = {})
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/org/tasks/compose/accounts/AddAccountActivity.kt b/app/src/main/java/org/tasks/compose/accounts/AddAccountActivity.kt
new file mode 100644
index 000000000..cd87ec496
--- /dev/null
+++ b/app/src/main/java/org/tasks/compose/accounts/AddAccountActivity.kt
@@ -0,0 +1,122 @@
+package org.tasks.compose.accounts
+
+import android.app.Activity
+import android.content.Intent
+import android.os.Bundle
+import androidx.activity.ComponentActivity
+import androidx.activity.compose.setContent
+import androidx.activity.result.contract.ActivityResultContracts
+import androidx.activity.viewModels
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.lifecycle.compose.collectAsStateWithLifecycle
+import com.todoroo.astrid.gtasks.auth.GtasksLoginActivity
+import dagger.hilt.android.AndroidEntryPoint
+import org.tasks.R
+import org.tasks.analytics.Firebase
+import org.tasks.auth.SignInActivity
+import org.tasks.billing.Inventory
+import org.tasks.caldav.CaldavAccountSettingsActivity
+import org.tasks.data.dao.CaldavDao
+import org.tasks.etebase.EtebaseAccountSettingsActivity
+import org.tasks.sync.microsoft.MicrosoftSignInViewModel
+import org.tasks.themes.TasksTheme
+import org.tasks.themes.Theme
+import javax.inject.Inject
+
+@AndroidEntryPoint
+class AddAccountActivity : ComponentActivity() {
+ @Inject lateinit var theme: Theme
+ @Inject lateinit var inventory: Inventory
+ @Inject lateinit var firebase: Firebase
+ @Inject lateinit var caldavDao: CaldavDao
+
+ private val viewModel: AddAccountViewModel by viewModels()
+ private val microsoftVM: MicrosoftSignInViewModel by viewModels()
+
+ private val syncLauncher = registerForActivityResult(
+ ActivityResultContracts.StartActivityForResult()
+ ) { result ->
+ if (result.resultCode == Activity.RESULT_OK) {
+ setResult(Activity.RESULT_OK)
+ finish()
+ } else {
+ result.data
+ ?.getStringExtra(GtasksLoginActivity.EXTRA_ERROR)
+ ?.let { /* ignore error, user can try again */ }
+ }
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ theme.themeBase.set(this)
+
+ setContent {
+ val accounts by caldavDao
+ .watchAccounts()
+ .collectAsStateWithLifecycle(initialValue = emptyList())
+ var initialAccountCount by remember { mutableStateOf(null) }
+ var hasTasksAccount by remember { mutableStateOf(inventory.hasTasksAccount) }
+ LaunchedEffect(Unit) {
+ inventory.updateTasksAccount()
+ hasTasksAccount = inventory.hasTasksAccount
+ initialAccountCount = caldavDao.getAccounts().size
+ }
+ LaunchedEffect(accounts, initialAccountCount) {
+ if (initialAccountCount != null && accounts.size > initialAccountCount!!) {
+ setResult(Activity.RESULT_OK)
+ finish()
+ }
+ }
+ TasksTheme(
+ theme = theme.themeBase.index,
+ primary = theme.themeColor.primaryColor,
+ ) {
+ AddAccountScreen(
+ hasTasksAccount = hasTasksAccount,
+ hasPro = inventory.hasPro,
+ onBack = { finish() },
+ signIn = { platform ->
+ firebase.logEvent(
+ R.string.event_onboarding_sync,
+ R.string.param_selection to platform
+ )
+ when (platform) {
+ Platform.TASKS_ORG ->
+ syncLauncher.launch(
+ Intent(this, SignInActivity::class.java)
+ )
+ Platform.GOOGLE_TASKS ->
+ syncLauncher.launch(
+ Intent(this, GtasksLoginActivity::class.java)
+ )
+ Platform.MICROSOFT ->
+ microsoftVM.signIn(this)
+ Platform.CALDAV ->
+ syncLauncher.launch(
+ Intent(this, CaldavAccountSettingsActivity::class.java)
+ )
+ Platform.ETESYNC ->
+ syncLauncher.launch(
+ Intent(this, EtebaseAccountSettingsActivity::class.java)
+ )
+ Platform.LOCAL ->
+ viewModel.createLocalAccount()
+ else -> throw IllegalArgumentException()
+ }
+ },
+ openUrl = { platform ->
+ firebase.logEvent(
+ R.string.event_onboarding_sync,
+ R.string.param_selection to platform.name
+ )
+ viewModel.openUrl(this, platform)
+ },
+ )
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/org/tasks/compose/accounts/AddAccountScreen.kt b/app/src/main/java/org/tasks/compose/accounts/AddAccountScreen.kt
index 2ba267c73..f8b65477a 100644
--- a/app/src/main/java/org/tasks/compose/accounts/AddAccountScreen.kt
+++ b/app/src/main/java/org/tasks/compose/accounts/AddAccountScreen.kt
@@ -44,7 +44,6 @@ import androidx.compose.ui.tooling.preview.PreviewLightDark
import androidx.compose.ui.tooling.preview.PreviewScreenSizes
import androidx.compose.ui.unit.dp
import org.tasks.R
-import org.tasks.sync.AddAccountDialog.Platform
import org.tasks.themes.TasksTheme
@OptIn(ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class)
diff --git a/app/src/main/java/org/tasks/compose/accounts/AddAccountViewModel.kt b/app/src/main/java/org/tasks/compose/accounts/AddAccountViewModel.kt
index 9dc7ee676..9a20edea1 100644
--- a/app/src/main/java/org/tasks/compose/accounts/AddAccountViewModel.kt
+++ b/app/src/main/java/org/tasks/compose/accounts/AddAccountViewModel.kt
@@ -9,7 +9,6 @@ import org.tasks.R
import org.tasks.data.dao.CaldavDao
import org.tasks.data.newLocalAccount
import org.tasks.extensions.Context.openUri
-import org.tasks.sync.AddAccountDialog
import javax.inject.Inject
@HiltViewModel
@@ -20,11 +19,11 @@ class AddAccountViewModel @Inject constructor(
caldavDao.newLocalAccount()
}
- fun openUrl(context: Context, platform: AddAccountDialog.Platform) {
+ fun openUrl(context: Context, platform: Platform) {
val url = when (platform) {
- AddAccountDialog.Platform.DAVX5 -> R.string.url_davx5
- AddAccountDialog.Platform.DECSYNC_CC -> R.string.url_decsync
- AddAccountDialog.Platform.LOCAL -> R.string.help_url_sync
+ Platform.DAVX5 -> R.string.url_davx5
+ Platform.DECSYNC_CC -> R.string.url_decsync
+ Platform.LOCAL -> R.string.help_url_sync
else -> return
}
context.openUri(context.getString(url))
diff --git a/app/src/main/java/org/tasks/compose/accounts/Platform.kt b/app/src/main/java/org/tasks/compose/accounts/Platform.kt
new file mode 100644
index 000000000..52fca5ed1
--- /dev/null
+++ b/app/src/main/java/org/tasks/compose/accounts/Platform.kt
@@ -0,0 +1,12 @@
+package org.tasks.compose.accounts
+
+enum class Platform {
+ TASKS_ORG,
+ GOOGLE_TASKS,
+ MICROSOFT,
+ DAVX5,
+ CALDAV,
+ ETESYNC,
+ DECSYNC_CC,
+ LOCAL,
+}
diff --git a/app/src/main/java/org/tasks/preferences/fragments/MainSettingsFragment.kt b/app/src/main/java/org/tasks/preferences/fragments/MainSettingsFragment.kt
index b51998860..0a103bd1b 100644
--- a/app/src/main/java/org/tasks/preferences/fragments/MainSettingsFragment.kt
+++ b/app/src/main/java/org/tasks/preferences/fragments/MainSettingsFragment.kt
@@ -4,11 +4,9 @@ import android.content.Intent
import android.os.Bundle
import androidx.core.content.ContextCompat
import androidx.fragment.app.activityViewModels
-import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import androidx.preference.Preference
import androidx.preference.PreferenceScreen
-import com.todoroo.astrid.gtasks.auth.GtasksLoginActivity
import com.todoroo.astrid.service.TaskDeleter
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.launchIn
@@ -16,19 +14,15 @@ import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import org.tasks.BuildConfig
import org.tasks.R
-import org.tasks.auth.SignInActivity
import org.tasks.billing.BillingClient
import org.tasks.billing.Inventory
import org.tasks.billing.Purchase
import org.tasks.billing.PurchaseActivity
import org.tasks.caldav.BaseCaldavAccountSettingsActivity
-import org.tasks.caldav.CaldavAccountSettingsActivity
import org.tasks.data.accountSettingsClass
import org.tasks.data.entity.CaldavAccount
import org.tasks.data.prefIcon
import org.tasks.data.prefTitle
-import org.tasks.etebase.EtebaseAccountSettingsActivity
-import org.tasks.extensions.Context.openUri
import org.tasks.extensions.Context.toast
import org.tasks.injection.InjectingPreferenceFragment
import org.tasks.preferences.IconPreference
@@ -38,11 +32,7 @@ import org.tasks.preferences.PreferencesViewModel
import org.tasks.preferences.fragments.GoogleTasksAccount.Companion.newGoogleTasksAccountPreference
import org.tasks.preferences.fragments.MicrosoftAccount.Companion.newMicrosoftAccountPreference
import org.tasks.preferences.fragments.TasksAccount.Companion.newTasksAccountPreference
-import org.tasks.sync.AddAccountDialog
-import org.tasks.sync.AddAccountDialog.Companion.EXTRA_SELECTED
-import org.tasks.sync.AddAccountDialog.Companion.newAccountDialog
-import org.tasks.sync.AddAccountDialog.Platform
-import org.tasks.sync.microsoft.MicrosoftSignInViewModel
+import org.tasks.compose.accounts.AddAccountActivity
import org.tasks.widget.AppWidgetManager
import javax.inject.Inject
@@ -56,7 +46,6 @@ class MainSettingsFragment : InjectingPreferenceFragment() {
@Inject lateinit var billingClient: BillingClient
private val viewModel: PreferencesViewModel by activityViewModels()
- private val microsoftVM: MicrosoftSignInViewModel by viewModels()
override fun getPreferenceXml() = R.xml.preferences
@@ -101,45 +90,6 @@ class MainSettingsFragment : InjectingPreferenceFragment() {
} else {
inventory.subscription.observe(this) { refreshSubscription(it) }
}
-
- parentFragmentManager.setFragmentResultListener(
- AddAccountDialog.ADD_ACCOUNT,
- this
- ) { _, result ->
- val platform =
- result.getSerializable(EXTRA_SELECTED) as? Platform
- ?: return@setFragmentResultListener
- when (platform) {
- Platform.TASKS_ORG ->
- startActivityForResult(
- Intent(requireContext(), SignInActivity::class.java),
- REQUEST_TASKS_ORG
- )
- Platform.GOOGLE_TASKS ->
- startActivityForResult(
- Intent(requireContext(), GtasksLoginActivity::class.java),
- REQUEST_GOOGLE_TASKS
- )
- Platform.MICROSOFT ->
- microsoftVM.signIn(requireActivity())
- Platform.DAVX5 ->
- context?.openUri(R.string.url_davx5)
- Platform.CALDAV ->
- startActivityForResult(
- Intent(requireContext(), CaldavAccountSettingsActivity::class.java),
- REQUEST_CALDAV_SETTINGS
- )
- Platform.ETESYNC ->
- startActivityForResult(
- Intent(requireContext(), EtebaseAccountSettingsActivity::class.java),
- REQUEST_CALDAV_SETTINGS
- )
- Platform.DECSYNC_CC ->
- context?.openUri(R.string.url_decsync)
-
- Platform.LOCAL -> {}
- }
- }
}
override fun onResume() {
@@ -166,13 +116,10 @@ class MainSettingsFragment : InjectingPreferenceFragment() {
}
private fun addAccount(): Boolean {
- lifecycleScope.launch {
- newAccountDialog(
- hasTasksAccount = viewModel.tasksAccount() != null,
- hasPro = inventory.hasPro,
- )
- .show(parentFragmentManager, FRAG_TAG_ADD_ACCOUNT)
- }
+ startActivityForResult(
+ Intent(requireContext(), AddAccountActivity::class.java),
+ REQUEST_ADD_ACCOUNT
+ )
return false
}
@@ -294,10 +241,10 @@ class MainSettingsFragment : InjectingPreferenceFragment() {
}
companion object {
- private const val FRAG_TAG_ADD_ACCOUNT = "frag_tag_add_account"
const val REQUEST_CALDAV_SETTINGS = 10013
const val REQUEST_GOOGLE_TASKS = 10014
const val REQUEST_TASKS_ORG = 10016
+ private const val REQUEST_ADD_ACCOUNT = 10017
fun PreferenceScreen.removeAt(index: Int, count: Int = 1) {
repeat(count) {
diff --git a/app/src/main/java/org/tasks/sync/AddAccountDialog.kt b/app/src/main/java/org/tasks/sync/AddAccountDialog.kt
deleted file mode 100644
index 2f6b33d1d..000000000
--- a/app/src/main/java/org/tasks/sync/AddAccountDialog.kt
+++ /dev/null
@@ -1,85 +0,0 @@
-package org.tasks.sync
-
-import android.app.Dialog
-import android.os.Bundle
-import androidx.core.os.bundleOf
-import androidx.fragment.app.DialogFragment
-import androidx.fragment.app.setFragmentResult
-import dagger.hilt.android.AndroidEntryPoint
-import org.tasks.R
-import org.tasks.compose.AddAccountDialog
-import org.tasks.dialogs.DialogBuilder
-import org.tasks.extensions.Context.openUri
-import org.tasks.preferences.Preferences
-import org.tasks.themes.TasksTheme
-import org.tasks.themes.Theme
-import javax.inject.Inject
-
-@AndroidEntryPoint
-class AddAccountDialog : DialogFragment() {
-
- @Inject lateinit var dialogBuilder: DialogBuilder
- @Inject lateinit var theme: Theme
- @Inject lateinit var preferences: Preferences
-
- private val hasTasksAccount: Boolean
- get() = arguments?.getBoolean(EXTRA_HAS_TASKS_ACCOUNT) ?: false
-
- private val hasPro: Boolean
- get() = arguments?.getBoolean(EXTRA_HAS_PRO) ?: false
-
- enum class Platform {
- TASKS_ORG,
- GOOGLE_TASKS,
- MICROSOFT,
- DAVX5,
- CALDAV,
- ETESYNC,
- DECSYNC_CC,
- LOCAL,
- }
-
- override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
- return dialogBuilder
- .newDialog()
- .setTitle(R.string.choose_synchronization_service)
- .setContent {
- TasksTheme(
- theme = theme.themeBase.index,
- primary = theme.themeColor.primaryColor,
- ) {
- AddAccountDialog(
- hasTasksAccount = hasTasksAccount,
- hasPro = hasPro,
- selected = this::selected
- )
- }
- }
- .setNeutralButton(R.string.help) { _, _ -> activity?.openUri(R.string.help_url_sync) }
- .setNegativeButton(R.string.cancel, null)
- .show()
- }
-
- private fun selected(platform: Platform) {
- setFragmentResult(ADD_ACCOUNT, bundleOf(EXTRA_SELECTED to platform))
- dismiss()
- }
-
- companion object {
- const val ADD_ACCOUNT = "add_account"
- const val EXTRA_SELECTED = "selected"
- private const val EXTRA_HAS_TASKS_ACCOUNT = "extra_has_tasks_account"
- private const val EXTRA_HAS_PRO = "extra_has_pro"
-
- fun newAccountDialog(
- hasTasksAccount: Boolean,
- hasPro: Boolean,
- ) =
- AddAccountDialog().apply {
- arguments = bundleOf(
- EXTRA_HAS_TASKS_ACCOUNT to hasTasksAccount,
- EXTRA_HAS_PRO to hasPro,
- )
- }
- }
-}
\ No newline at end of file