mirror of https://github.com/tasks/tasks
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
309 lines
12 KiB
Kotlin
309 lines
12 KiB
Kotlin
package org.tasks.preferences.fragments
|
|
|
|
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.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.CaldavAccount
|
|
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
|
|
import org.tasks.preferences.MainPreferences
|
|
import org.tasks.preferences.Preferences
|
|
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.widget.AppWidgetManager
|
|
import javax.inject.Inject
|
|
|
|
@AndroidEntryPoint
|
|
class MainSettingsFragment : InjectingPreferenceFragment() {
|
|
|
|
@Inject lateinit var appWidgetManager: AppWidgetManager
|
|
@Inject lateinit var preferences: Preferences
|
|
@Inject lateinit var taskDeleter: TaskDeleter
|
|
@Inject lateinit var inventory: Inventory
|
|
@Inject lateinit var billingClient: BillingClient
|
|
|
|
private val viewModel: PreferencesViewModel by activityViewModels()
|
|
private val microsoftVM: MicrosoftSignInViewModel by viewModels()
|
|
|
|
override fun getPreferenceXml() = R.xml.preferences
|
|
|
|
override fun onCreate(savedInstanceState: Bundle?) {
|
|
super.onCreate(savedInstanceState)
|
|
|
|
findPreference(R.string.add_account).setOnPreferenceClickListener { addAccount() }
|
|
|
|
findPreference(R.string.name_your_price).setOnPreferenceClickListener {
|
|
startActivity(Intent(context, PurchaseActivity::class.java))
|
|
false
|
|
}
|
|
|
|
findPreference(R.string.button_unsubscribe).setOnPreferenceClickListener {
|
|
inventory.unsubscribe(requireActivity())
|
|
}
|
|
|
|
findPreference(R.string.refresh_purchases).setOnPreferenceClickListener {
|
|
lifecycleScope.launch {
|
|
try {
|
|
billingClient.queryPurchases(throwError = true)
|
|
if (inventory.subscription.value == null) {
|
|
activity?.toast(R.string.no_google_play_subscription)
|
|
}
|
|
} catch (e: Exception) {
|
|
activity?.toast(e.message)
|
|
}
|
|
}
|
|
false
|
|
}
|
|
|
|
viewModel.lastBackup.observe(this) { updateBackupWarning() }
|
|
viewModel.lastAndroidBackup.observe(this) { updateBackupWarning() }
|
|
viewModel.lastDriveBackup.observe(this) { updateBackupWarning() }
|
|
viewModel.caldavAccounts.observe(this) { refreshAccounts() }
|
|
if (BuildConfig.FLAVOR == "generic") {
|
|
remove(R.string.upgrade_to_pro)
|
|
} 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)
|
|
}
|
|
}
|
|
}
|
|
|
|
override fun onResume() {
|
|
super.onResume()
|
|
|
|
updateBackupWarning()
|
|
updateWidgetVisibility()
|
|
}
|
|
|
|
private fun refreshAccounts() {
|
|
val caldavAccounts = viewModel.caldavAccounts.value ?: emptyList()
|
|
val addAccount = findPreference(R.string.add_account)
|
|
val index = preferenceScreen.indexOf(addAccount)
|
|
var current = 0
|
|
caldavAccounts.forEach {
|
|
setup(it, if (current < index) {
|
|
preferenceScreen.getPreference(current++) as IconPreference
|
|
} else {
|
|
preferenceScreen.insertAt(current++)
|
|
})
|
|
}
|
|
preferenceScreen.removeAt(current, index - current)
|
|
if (caldavAccounts.isEmpty()) {
|
|
addAccount.setTitle(R.string.not_signed_in)
|
|
addAccount.setIcon(R.drawable.ic_outline_cloud_off_24px)
|
|
} else {
|
|
addAccount.setTitle(R.string.add_account)
|
|
addAccount.setIcon(R.drawable.ic_outline_add_24px)
|
|
}
|
|
tintIcons(addAccount, requireContext().getColor(R.color.icon_tint_with_alpha))
|
|
}
|
|
|
|
private fun addAccount(): Boolean {
|
|
newAccountDialog(hasTasksAccount = viewModel.tasksAccount() != null)
|
|
.show(parentFragmentManager, FRAG_TAG_ADD_ACCOUNT)
|
|
return false
|
|
}
|
|
|
|
private fun updateWidgetVisibility() {
|
|
findPreference(R.string.widget_settings).isVisible = appWidgetManager.widgetIds.isNotEmpty()
|
|
}
|
|
|
|
override suspend fun setupPreferences(savedInstanceState: Bundle?) {
|
|
requires(BuildConfig.DEBUG, R.string.debug)
|
|
|
|
updateWidgetVisibility()
|
|
}
|
|
|
|
private fun updateBackupWarning() {
|
|
val backupWarning =
|
|
preferences.showBackupWarnings()
|
|
&& (viewModel.usingPrivateStorage
|
|
|| viewModel.staleLocalBackup
|
|
|| viewModel.staleRemoteBackup)
|
|
(findPreference(R.string.backup_BPr_header) as IconPreference).iconVisible = backupWarning
|
|
}
|
|
|
|
private fun setup(account: CaldavAccount, pref: IconPreference) {
|
|
pref.setTitle(account.prefTitle)
|
|
pref.summary = account.name
|
|
pref.setIcon(account.prefIcon)
|
|
if (account.isCaldavAccount) {
|
|
tintIcons(pref, requireContext().getColor(R.color.icon_tint_with_alpha))
|
|
}
|
|
pref.setOnPreferenceClickListener {
|
|
if (account.isTasksOrg) {
|
|
(activity as MainPreferences).startPreference(
|
|
this,
|
|
newTasksAccountPreference(account),
|
|
getString(R.string.tasks_org)
|
|
)
|
|
} else if (account.isMicrosoft) {
|
|
(activity as MainPreferences).startPreference(
|
|
this,
|
|
newMicrosoftAccountPreference(account),
|
|
getString(R.string.microsoft)
|
|
)
|
|
} else if (account.isGoogleTasks) {
|
|
(activity as MainPreferences).startPreference(
|
|
this,
|
|
newGoogleTasksAccountPreference(account),
|
|
getString(R.string.gtasks_GPr_header)
|
|
)
|
|
} else {
|
|
val intent = Intent(context, account.accountSettingsClass).apply {
|
|
putExtra(BaseCaldavAccountSettingsActivity.EXTRA_CALDAV_DATA, account)
|
|
}
|
|
startActivityForResult(intent, REQUEST_CALDAV_SETTINGS)
|
|
}
|
|
false
|
|
}
|
|
when {
|
|
account.isTasksOrg -> {
|
|
pref.setOnPreferenceClickListener {
|
|
(activity as MainPreferences).startPreference(
|
|
this,
|
|
newTasksAccountPreference(account),
|
|
getString(R.string.tasks_org)
|
|
)
|
|
false
|
|
}
|
|
}
|
|
}
|
|
setupErrorIcon(pref, account.hasError, account.isEteSyncAccount)
|
|
}
|
|
|
|
private fun setupErrorIcon(
|
|
pref: IconPreference,
|
|
hasError: Boolean,
|
|
hasWarning: Boolean = false
|
|
) {
|
|
pref.drawable = ContextCompat
|
|
.getDrawable(requireContext(), when {
|
|
hasError -> R.drawable.ic_outline_error_outline_24px
|
|
hasWarning -> R.drawable.ic_outline_error_outline_24px
|
|
else -> R.drawable.ic_keyboard_arrow_right_24px
|
|
})
|
|
?.mutate()
|
|
pref.tint = context?.getColor(when {
|
|
hasError -> R.color.overdue
|
|
hasWarning -> R.color.orange_500
|
|
else -> R.color.icon_tint_with_alpha
|
|
})
|
|
}
|
|
|
|
private fun refreshSubscription(subscription: Purchase?) {
|
|
findPreference(R.string.upgrade_to_pro).setTitle(if (subscription == null) {
|
|
R.string.upgrade_to_pro
|
|
} else {
|
|
R.string.subscription
|
|
})
|
|
findPreference(R.string.name_your_price).apply {
|
|
if (subscription == null) {
|
|
title = getString(R.string.name_your_price)
|
|
summary = null
|
|
} else {
|
|
val interval = if (subscription.isMonthly) {
|
|
R.string.price_per_month
|
|
} else {
|
|
R.string.price_per_year
|
|
}
|
|
val price = (subscription.subscriptionPrice!! - .01).toString()
|
|
title = getString(R.string.manage_subscription)
|
|
summary = getString(R.string.current_subscription, getString(interval, price))
|
|
}
|
|
}
|
|
findPreference(R.string.button_unsubscribe).isVisible = subscription != null
|
|
}
|
|
|
|
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
|
|
|
|
fun PreferenceScreen.removeAt(index: Int, count: Int = 1) {
|
|
repeat(count) {
|
|
removePreference(getPreference(index))
|
|
}
|
|
}
|
|
|
|
fun PreferenceScreen.indexOf(pref: Preference): Int =
|
|
0.until(preferenceCount).first { pref == getPreference(it) }
|
|
|
|
fun PreferenceScreen.insertAt(index: Int): IconPreference {
|
|
index.until(preferenceCount).forEach {
|
|
getPreference(it).apply { order += 1 }
|
|
}
|
|
return IconPreference(context).apply {
|
|
layoutResource = R.layout.preference_icon
|
|
order = index
|
|
iconVisible = true
|
|
addPreference(this)
|
|
}
|
|
}
|
|
}
|
|
}
|