Move sync accounts to top level prefs menu

Remove synchronization submenu
pull/1305/head
Alex Baker 3 years ago
parent b8005daa80
commit 64e845a6fe

@ -19,7 +19,6 @@ import org.tasks.filters.NavigationDrawerSubheader
import org.tasks.filters.NavigationDrawerSubheader.SubheaderType
import org.tasks.preferences.MainPreferences
import org.tasks.preferences.Preferences
import org.tasks.preferences.SyncPreferences
import org.tasks.themes.DrawableUtil
internal class SubheaderViewHolder(
@ -66,12 +65,7 @@ internal class SubheaderViewHolder(
init {
ButterKnife.bind(this, itemView)
errorIcon.setOnClickListener {
val preferenceClass = if (subheader.subheaderType == SubheaderType.TASKS) {
MainPreferences::class.java
} else {
SyncPreferences::class.java
}
activity.startActivity(Intent(activity, preferenceClass))
activity.startActivity(Intent(activity, MainPreferences::class.java))
}
}
}

@ -12,10 +12,18 @@ import com.todoroo.andlib.data.Table
import com.todoroo.astrid.data.Task
import org.tasks.R
import org.tasks.activities.BaseListSettingsActivity
import org.tasks.caldav.BaseCaldavAccountSettingsActivity
import org.tasks.caldav.CaldavAccountSettingsActivity
import org.tasks.caldav.CaldavCalendarSettingsActivity
import org.tasks.caldav.LocalListSettingsActivity
import org.tasks.data.OpenTaskDao.Companion.isDavx5
import org.tasks.data.OpenTaskDao.Companion.isDecSync
import org.tasks.data.OpenTaskDao.Companion.isEteSync
import org.tasks.etebase.EtebaseAccountSettingsActivity
import org.tasks.etebase.EtebaseCalendarSettingsActivity
import org.tasks.etesync.EteSyncAccountSettingsActivity
import org.tasks.etesync.EteSyncCalendarSettingsActivity
import org.tasks.opentasks.OpenTaskAccountSettingsActivity
import org.tasks.opentasks.OpenTasksListSettingsActivity
import org.tasks.security.KeyStoreEncryption
import java.net.HttpURLConnection
@ -111,6 +119,15 @@ class CaldavAccount : Parcelable {
else -> CaldavCalendarSettingsActivity::class.java
}
val accountSettingsClass: Class<out BaseCaldavAccountSettingsActivity>
get() = when {
isCaldavAccount -> CaldavAccountSettingsActivity::class.java
isEteSyncAccount -> EteSyncAccountSettingsActivity::class.java
isEtebaseAccount -> EtebaseAccountSettingsActivity::class.java
isOpenTasks -> OpenTaskAccountSettingsActivity::class.java
else -> throw IllegalArgumentException("Unexpected account type: $this")
}
override fun describeContents() = 0
override fun writeToParcel(dest: Parcel, flags: Int) {
@ -178,6 +195,27 @@ class CaldavAccount : Parcelable {
fun isPaymentRequired() = error?.startsWith(EROR_PAYMENT_REQUIRED) == true
val prefTitle: Int
get() = when {
isTasksOrg -> R.string.tasks_org
isCaldavAccount -> R.string.caldav
isEtebaseAccount || uuid.isEteSync() -> R.string.etesync
isEteSyncAccount -> R.string.etesync_v1
uuid.isDavx5() -> R.string.davx5
uuid.isDecSync() -> R.string.decsync
else -> 0
}
val prefIcon: Int
get() = when {
isTasksOrg -> R.drawable.ic_round_icon
isCaldavAccount -> R.drawable.ic_webdav_logo
isEtebaseAccount || isEteSyncAccount || uuid.isEteSync() -> R.drawable.ic_etesync
uuid.isDavx5() -> R.drawable.ic_davx5_icon_green_bg
uuid.isDecSync() -> R.drawable.ic_decsync
else -> 0
}
companion object {
val TABLE = Table("caldav_accounts")
val UUID = TABLE.column("cda_uuid")

@ -51,6 +51,17 @@ abstract class CaldavDao {
@Query("""
SELECT *
FROM caldav_accounts
WHERE cda_account_type != $TYPE_LOCAL
ORDER BY CASE cda_account_type
WHEN $TYPE_TASKS THEN 0
ELSE 1
END, UPPER(cda_name)
""")
abstract fun watchAccounts(): LiveData<List<CaldavAccount>>
@Query("""
SELECT *
FROM caldav_accounts
ORDER BY CASE cda_account_type
WHEN $TYPE_TASKS THEN 0
WHEN $TYPE_LOCAL THEN 2

@ -14,6 +14,9 @@ interface GoogleTaskListDao {
@Query("SELECT * FROM google_task_accounts")
suspend fun getAccounts(): List<GoogleTaskAccount>
@Query("SELECT * FROM google_task_accounts")
fun watchAccounts(): LiveData<List<GoogleTaskAccount>>
@Query("SELECT * FROM google_task_accounts WHERE gta_account = :account COLLATE NOCASE LIMIT 1")
suspend fun getAccount(account: String): GoogleTaskAccount?

@ -15,9 +15,9 @@ import org.tasks.R
import org.tasks.auth.SignInActivity
import org.tasks.jobs.WorkManager
import org.tasks.preferences.fragments.MainSettingsFragment
import org.tasks.preferences.fragments.Synchronization.Companion.REQUEST_CALDAV_SETTINGS
import org.tasks.preferences.fragments.Synchronization.Companion.REQUEST_GOOGLE_TASKS
import org.tasks.preferences.fragments.Synchronization.Companion.REQUEST_TASKS_ORG
import org.tasks.preferences.fragments.MainSettingsFragment.Companion.REQUEST_CALDAV_SETTINGS
import org.tasks.preferences.fragments.MainSettingsFragment.Companion.REQUEST_GOOGLE_TASKS
import org.tasks.preferences.fragments.MainSettingsFragment.Companion.REQUEST_TASKS_ORG
import org.tasks.preferences.fragments.TasksAccount
import org.tasks.sync.SyncAdapters
import org.tasks.ui.Toaster

@ -171,7 +171,6 @@ class Preferences @JvmOverloads constructor(
PreferenceManager.setDefaultValues(context, R.xml.preferences, true)
PreferenceManager.setDefaultValues(context, R.xml.preferences_look_and_feel, true)
PreferenceManager.setDefaultValues(context, R.xml.preferences_notifications, true)
PreferenceManager.setDefaultValues(context, R.xml.preferences_synchronization, true)
PreferenceManager.setDefaultValues(context, R.xml.preferences_task_defaults, true)
PreferenceManager.setDefaultValues(context, R.xml.preferences_date_and_time, true)
PreferenceManager.setDefaultValues(context, R.xml.preferences_navigation_drawer, true)

@ -14,8 +14,7 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.tasks.R
import org.tasks.backup.BackupConstants
import org.tasks.data.CaldavAccount
import org.tasks.data.CaldavDao
import org.tasks.data.*
import org.tasks.date.DateTimeUtils.newDateTime
import org.tasks.googleapis.InvokerFactory
import org.tasks.gtasks.GoogleAccountManager
@ -27,12 +26,15 @@ class PreferencesViewModel @ViewModelInject constructor(
private val preferences: Preferences,
invokers: InvokerFactory,
private val googleAccountManager: GoogleAccountManager,
private val caldavDao: CaldavDao,
caldavDao: CaldavDao,
googleTaskListDao: GoogleTaskListDao,
) : ViewModel() {
private val driveInvoker = invokers.getDriveInvoker()
val lastBackup = MutableLiveData<Long?>()
val lastDriveBackup = MutableLiveData<Long?>()
val lastAndroidBackup = MutableLiveData<Long>()
var googleTaskAccounts = googleTaskListDao.watchAccounts()
var caldavAccounts = caldavDao.watchAccounts()
private fun isStale(timestamp: Long?) =
timestamp != null
@ -60,8 +62,7 @@ class PreferencesViewModel @ViewModelInject constructor(
return if (enabled) account else null
}
suspend fun tasksAccount(): CaldavAccount? =
caldavDao.getAccounts(CaldavAccount.TYPE_TASKS).firstOrNull()
fun tasksAccount(): CaldavAccount? = caldavAccounts.value?.firstOrNull { it.isTasksOrg }
fun updateDriveBackup() = viewModelScope.launch {
if (driveAccount.isNullOrBlank()) {

@ -1,13 +0,0 @@
package org.tasks.preferences
import dagger.hilt.android.AndroidEntryPoint
import org.tasks.R
import org.tasks.preferences.fragments.Synchronization
@AndroidEntryPoint
class SyncPreferences : BasePreferences() {
override fun getRootTitle() = R.string.synchronization
override fun getRootPreference() = Synchronization()
}

@ -5,17 +5,26 @@ import android.os.Bundle
import androidx.core.content.ContextCompat
import androidx.fragment.app.activityViewModels
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.NonCancellable
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.tasks.BuildConfig
import org.tasks.R
import org.tasks.auth.SignInActivity
import org.tasks.caldav.BaseCaldavAccountSettingsActivity
import org.tasks.data.CaldavAccount
import org.tasks.data.GoogleTaskAccount
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.TasksAccount.Companion.newTasksAccountPreference
import org.tasks.sync.AddAccountDialog.Companion.newAccountDialog
import org.tasks.widget.AppWidgetManager
import javax.inject.Inject
@ -24,6 +33,7 @@ class MainSettingsFragment : InjectingPreferenceFragment() {
@Inject lateinit var appWidgetManager: AppWidgetManager
@Inject lateinit var preferences: Preferences
@Inject lateinit var taskDeleter: TaskDeleter
private val viewModel: PreferencesViewModel by activityViewModels()
@ -32,64 +42,59 @@ class MainSettingsFragment : InjectingPreferenceFragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val pref = findPreference(R.string.tasks_org) as IconPreference
pref.setIcon(R.drawable.ic_round_icon_36dp)
pref.iconVisible = true
findPreference(R.string.synchronization).summary =
resources
.getStringArray(R.array.synchronization_services)
.joinToString(getString(R.string.list_separator_with_space))
findPreference(R.string.add_account).setOnPreferenceClickListener { addAccount() }
viewModel.lastBackup.observe(this) { updateBackupWarning() }
viewModel.lastAndroidBackup.observe(this) { updateBackupWarning() }
viewModel.lastDriveBackup.observe(this) { updateBackupWarning() }
viewModel.googleTaskAccounts.observe(this) { refreshAccounts() }
viewModel.caldavAccounts.observe(this) { refreshAccounts() }
}
override fun onResume() {
super.onResume()
lifecycleScope.launch {
updateAccount()
}
updateBackupWarning()
updateWidgetVisibility()
}
private suspend fun updateAccount() {
val pref = findPreference(R.string.tasks_org) as IconPreference
pref.drawable = ContextCompat
.getDrawable(requireContext(), R.drawable.ic_keyboard_arrow_right_24px)
?.mutate()
pref.tint = context?.getColor(R.color.icon_tint_with_alpha)
val account = viewModel.tasksAccount()
if (account == null) {
pref.setOnPreferenceClickListener { signIn() }
pref.summary = getString(R.string.not_signed_in)
return
private fun refreshAccounts() {
val caldavAccounts = viewModel.caldavAccounts.value ?: emptyList()
val googleTaskAccounts = viewModel.googleTaskAccounts.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++)
})
}
pref.summary = account.name
if (!account.error.isNullOrBlank()) {
pref.drawable = ContextCompat
.getDrawable(requireContext(), R.drawable.ic_outline_error_outline_24px)
?.mutate()
pref.tint = context?.getColor(R.color.overdue)
googleTaskAccounts.forEach {
setup(it, if (current < index) {
preferenceScreen.getPreference(current++) as IconPreference
} else {
preferenceScreen.insertAt(current++)
})
}
pref.setOnPreferenceClickListener {
(activity as MainPreferences).startPreference(
this,
newTasksAccountPreference(account),
getString(R.string.tasks_org)
)
false
repeat(current.until(index).count()) {
preferenceScreen.removePreference(preferenceScreen.getPreference(current))
}
if (caldavAccounts.isEmpty() && googleTaskAccounts.isEmpty()) {
addAccount.setTitle(R.string.not_signed_in)
addAccount.setIcon(R.drawable.ic_outline_cloud_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 signIn(): Boolean {
activity?.startActivityForResult(
Intent(activity, SignInActivity::class.java),
Synchronization.REQUEST_TASKS_ORG)
private fun addAccount(): Boolean {
val hasTasksAccount = viewModel.tasksAccount() != null
newAccountDialog(this@MainSettingsFragment, REQUEST_ADD_ACCOUNT, hasTasksAccount)
.show(parentFragmentManager, FRAG_TAG_ADD_ACCOUNT)
return false
}
@ -111,4 +116,129 @@ class MainSettingsFragment : InjectingPreferenceFragment() {
|| 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 {
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.error)
}
private fun setup(account: GoogleTaskAccount, pref: IconPreference) {
pref.setTitle(R.string.gtasks_GPr_header)
pref.setIcon(R.drawable.ic_google)
pref.summary = account.account
setupErrorIcon(pref, account.error)
pref.setOnPreferenceClickListener {
dialogBuilder
.newDialog(account.account)
.setItems(
listOf(
getString(R.string.reinitialize_account),
getString(R.string.logout)
)
) { _, which ->
if (which == 0) {
startActivityForResult(
Intent(context, GtasksLoginActivity::class.java),
REQUEST_GOOGLE_TASKS
)
} else {
logoutConfirmation(account)
}
}
.setNegativeButton(R.string.cancel, null)
.show()
false
}
}
private fun logoutConfirmation(account: GoogleTaskAccount) {
val name = account.account
val alertDialog = dialogBuilder
.newDialog()
.setMessage(R.string.logout_warning, name)
.setPositiveButton(R.string.logout) { _, _ ->
lifecycleScope.launch {
withContext(NonCancellable) {
taskDeleter.delete(account)
}
}
}
.setNegativeButton(R.string.cancel, null)
.create()
alertDialog.setCanceledOnTouchOutside(false)
alertDialog.setCancelable(false)
alertDialog.show()
}
private fun setupErrorIcon(pref: IconPreference, error: String?) {
val hasError = !error.isNullOrBlank()
pref.drawable = ContextCompat
.getDrawable(requireContext(), if (hasError) {
R.drawable.ic_outline_error_outline_24px
} else {
R.drawable.ic_keyboard_arrow_right_24px
})
?.mutate()
pref.tint = context?.getColor(if (hasError) {
R.color.overdue
} else {
R.color.icon_tint_with_alpha
})
}
companion object {
private const val REQUEST_ADD_ACCOUNT = 10015
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.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)
}
}
}
}

@ -1,190 +0,0 @@
package org.tasks.preferences.fragments
import android.content.Intent
import android.os.Bundle
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.lifecycleScope
import androidx.preference.Preference
import androidx.preference.PreferenceCategory
import com.todoroo.astrid.gtasks.auth.GtasksLoginActivity
import com.todoroo.astrid.service.TaskDeleter
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.NonCancellable
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.tasks.R
import org.tasks.Strings.isNullOrEmpty
import org.tasks.caldav.BaseCaldavAccountSettingsActivity
import org.tasks.caldav.CaldavAccountSettingsActivity
import org.tasks.data.CaldavAccount.Companion.TYPE_LOCAL
import org.tasks.data.CaldavAccount.Companion.TYPE_TASKS
import org.tasks.data.CaldavDao
import org.tasks.data.GoogleTaskAccount
import org.tasks.data.GoogleTaskListDao
import org.tasks.data.OpenTaskDao.Companion.isDavx5
import org.tasks.data.OpenTaskDao.Companion.isDecSync
import org.tasks.data.OpenTaskDao.Companion.isEteSync
import org.tasks.etebase.EtebaseAccountSettingsActivity
import org.tasks.etesync.EteSyncAccountSettingsActivity
import org.tasks.injection.InjectingPreferenceFragment
import org.tasks.opentasks.OpenTaskAccountSettingsActivity
import org.tasks.preferences.Preferences
import org.tasks.preferences.PreferencesViewModel
import org.tasks.sync.AddAccountDialog.Companion.newAccountDialog
import org.tasks.sync.SyncAdapters
import javax.inject.Inject
@AndroidEntryPoint
class Synchronization : InjectingPreferenceFragment() {
@Inject lateinit var preferences: Preferences
@Inject lateinit var caldavDao: CaldavDao
@Inject lateinit var googleTaskListDao: GoogleTaskListDao
@Inject lateinit var taskDeleter: TaskDeleter
@Inject lateinit var syncAdapters: SyncAdapters
private val viewModel: PreferencesViewModel by activityViewModels()
override fun getPreferenceXml() = R.xml.preferences_synchronization
override suspend fun setupPreferences(savedInstanceState: Bundle?) {
findPreference(R.string.add_account)
.setOnPreferenceClickListener {
lifecycleScope.launch {
val hasTasksAccount = viewModel.tasksAccount() != null
newAccountDialog(this@Synchronization, REQUEST_ADD_ACCOUNT, hasTasksAccount)
.show(parentFragmentManager, FRAG_TAG_ADD_ACCOUNT)
}
false
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == REQUEST_ADD_ACCOUNT) {
refresh()
} else {
super.onActivityResult(requestCode, resultCode, data)
}
}
override fun onResume() {
super.onResume()
refresh()
}
private suspend fun addGoogleTasksAccounts(category: PreferenceCategory): Boolean {
val accounts: List<GoogleTaskAccount> = googleTaskListDao.getAccounts()
for (googleTaskAccount in accounts) {
val account = googleTaskAccount.account
val preference = Preference(context)
preference.title = account
val error = googleTaskAccount.error
if (isNullOrEmpty(error)) {
preference.setSummary(R.string.gtasks_GPr_header)
} else {
preference.summary = error
}
preference.setOnPreferenceClickListener {
dialogBuilder
.newDialog(account)
.setItems(
listOf(
getString(R.string.reinitialize_account),
getString(R.string.logout)
)
) { _, which ->
if (which == 0) {
startActivityForResult(
Intent(context, GtasksLoginActivity::class.java),
REQUEST_GOOGLE_TASKS
)
} else {
logoutConfirmation(googleTaskAccount)
}
}
.setNegativeButton(R.string.cancel, null)
.show()
false
}
category.addPreference(preference)
}
return accounts.isNotEmpty()
}
private suspend fun addCaldavAccounts(category: PreferenceCategory): Boolean {
val accounts = caldavDao.getAccounts().filter {
it.accountType != TYPE_LOCAL && it.accountType != TYPE_TASKS
}
for (account in accounts) {
val preference = Preference(context)
preference.title = account.name
val error = account.error
if (isNullOrEmpty(error)) {
preference.setSummary(when {
account.isCaldavAccount -> R.string.caldav
account.isEteSyncAccount -> R.string.etesync_v1
account.isEtebaseAccount -> R.string.etesync
account.isOpenTasks && account.uuid.isEteSync() -> R.string.etesync
account.isOpenTasks && account.uuid.isDavx5() -> R.string.davx5
account.isOpenTasks && account.uuid.isDecSync() -> R.string.decsync
else -> 0
})
} else {
preference.summary = error
}
preference.onPreferenceClickListener = Preference.OnPreferenceClickListener {
val intent = Intent(context, when {
account.isCaldavAccount -> CaldavAccountSettingsActivity::class.java
account.isEteSyncAccount -> EteSyncAccountSettingsActivity::class.java
account.isEtebaseAccount -> EtebaseAccountSettingsActivity::class.java
account.isOpenTasks -> OpenTaskAccountSettingsActivity::class.java
else -> throw IllegalArgumentException("Unexpected account type: $account")
})
intent.putExtra(BaseCaldavAccountSettingsActivity.EXTRA_CALDAV_DATA, account)
startActivityForResult(intent, REQUEST_CALDAV_SETTINGS)
false
}
category.addPreference(preference)
}
return accounts.isNotEmpty()
}
private fun logoutConfirmation(account: GoogleTaskAccount) {
val name = account.account
val alertDialog = dialogBuilder
.newDialog()
.setMessage(R.string.logout_warning, name)
.setPositiveButton(R.string.logout) { _, _ ->
lifecycleScope.launch {
withContext(NonCancellable) {
taskDeleter.delete(account)
}
refresh()
}
}
.setNegativeButton(R.string.cancel, null)
.create()
alertDialog.setCanceledOnTouchOutside(false)
alertDialog.setCancelable(false)
alertDialog.show()
}
private fun refresh() {
lifecycleScope.launch {
val synchronizationPreferences = findPreference(R.string.accounts) as PreferenceCategory
synchronizationPreferences.removeAll()
val hasGoogleAccounts: Boolean = addGoogleTasksAccounts(synchronizationPreferences)
val hasCaldavAccounts = addCaldavAccounts(synchronizationPreferences)
findPreference(R.string.accounts).isVisible = hasGoogleAccounts || hasCaldavAccounts
}
}
companion object {
const val REQUEST_CALDAV_SETTINGS = 10013
const val REQUEST_GOOGLE_TASKS = 10014
private const val REQUEST_ADD_ACCOUNT = 10015
const val REQUEST_TASKS_ORG = 10016
private const val FRAG_TAG_ADD_ACCOUNT = "frag_tag_add_account"
}
}

@ -31,6 +31,7 @@ import org.tasks.injection.InjectingPreferenceFragment
import org.tasks.jobs.WorkManager
import org.tasks.locale.Locale
import org.tasks.preferences.IconPreference
import org.tasks.preferences.fragments.MainSettingsFragment.Companion.REQUEST_TASKS_ORG
import org.tasks.ui.Toaster
import java.time.format.FormatStyle
import javax.inject.Inject
@ -237,7 +238,7 @@ class TasksAccount : InjectingPreferenceFragment() {
SignInActivity.EXTRA_SELECT_SERVICE,
if (isGitHubAccount) 1 else 0
),
Synchronization.REQUEST_TASKS_ORG)
REQUEST_TASKS_ORG)
false
}
}

@ -21,9 +21,9 @@ import org.tasks.dialogs.DialogBuilder
import org.tasks.etebase.EtebaseAccountSettingsActivity
import org.tasks.extensions.getMutableIntList
import org.tasks.extensions.getMutableStringList
import org.tasks.preferences.fragments.Synchronization.Companion.REQUEST_CALDAV_SETTINGS
import org.tasks.preferences.fragments.Synchronization.Companion.REQUEST_GOOGLE_TASKS
import org.tasks.preferences.fragments.Synchronization.Companion.REQUEST_TASKS_ORG
import org.tasks.preferences.fragments.MainSettingsFragment.Companion.REQUEST_CALDAV_SETTINGS
import org.tasks.preferences.fragments.MainSettingsFragment.Companion.REQUEST_GOOGLE_TASKS
import org.tasks.preferences.fragments.MainSettingsFragment.Companion.REQUEST_TASKS_ORG
import org.tasks.themes.DrawableUtil
import javax.inject.Inject

@ -1,5 +1,5 @@
<vector android:height="24dp" android:viewportHeight="1024"
android:viewportWidth="1024" android:width="24dp"
<vector android:height="36dp" android:viewportHeight="1024"
android:viewportWidth="1024" android:width="36dp"
xmlns:aapt="http://schemas.android.com/aapt" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#77A646" android:pathData="M887.67,957.05L140.08,957.05c-39.35,0 -71.25,-31.9 -71.25,-71.25L68.82,138.2c0,-39.35 31.9,-71.25 71.25,-71.25l747.6,0c39.35,0 71.25,31.9 71.25,71.25l0,747.6c0,39.35 -31.9,71.25 -71.25,71.25z"/>
<path android:fillColor="#A2CF6E" android:pathData="M887.67,918.68L140.08,918.68c-39.35,0 -71.25,-31.9 -71.25,-71.25L68.82,138.2c0,-39.35 31.9,-71.25 71.25,-71.25l747.6,0c39.35,0 71.25,31.9 71.25,71.25l0,709.23c0,39.35 -31.9,71.25 -71.25,71.25z"/>

@ -1,6 +1,6 @@
<vector android:autoMirrored="true" android:height="24dp"
<vector android:autoMirrored="true" android:height="36dp"
android:viewportHeight="512" android:viewportWidth="512"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
android:width="36dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#ffffff" android:pathData="M0.647,-0.537l512.237,0l0,514.106l-512.237,0z"/>
<path android:fillColor="#0277BB" android:fillType="nonZero" android:pathData="M0,-0L0,512L512,512L512,-0L0,-0ZM292.5,49.5C343.3,58.5 388.2,84.8 419.7,123.9C429.4,136.1 438.9,150.9 440.4,156.1C442.2,162.8 436.4,170.7 428.1,173C420.5,175 417.1,172.6 408.3,159C389.7,130.5 368.2,111 339,96.1C277.7,65 206.5,71 150.5,112.2C140.4,119.6 120.6,140 112.8,151C104,163.4 93.1,184.8 88.7,198.6C85.4,208.7 81,227.6 81,231.4C81,232.8 82.5,233 91,233C96.5,233 101,233.3 101,233.7C101,234.6 64.8,297.1 64.5,296.8C63.8,296.2 28,234 28,233.5C28,233.2 33.1,233 39.3,233L50.7,233L52,224.2C62.1,156 106.4,96.2 169,66.7C193.8,55 222.7,47.8 249.5,46.7C259.9,46.3 283.1,47.8 292.5,49.5ZM206,127L206,152L306,152L306,127L331,127L331,152L339.8,152C346.8,152 349.5,152.5 353.5,154.4C359.3,157.1 363.4,160.9 366.4,166.5L368.5,170.5L368.5,359.5L366.3,363.5C363.8,368.2 358.9,373 354,375.6C350.7,377.4 346.2,377.5 256,377.5L161.5,377.5L157.5,375.3C152.8,372.8 148,367.9 145.4,363C143.6,359.7 143.5,355.2 143.5,265L143.5,170.5L145.6,166.5C148.6,160.9 152.7,157.1 158.5,154.4C162.5,152.5 165.2,152 172.3,152L181,152L181,127L206,127ZM469.4,243.9C479.1,260.6 487,274.7 487,275.1C487,275.6 481.8,276 475.5,276L464,276L464,279.1C464,284.2 459.2,306.2 455.9,316.8C448.1,341.3 435.1,365.4 419.3,385C405.9,401.6 385.3,419.7 367.1,431C319.6,460.4 260.7,469.6 206.6,455.9C152.4,442.2 105.6,407.1 77.7,358.9C74.1,352.7 74,346.3 77.5,342.2C81.1,337.9 88.3,334.6 92.3,335.4C97.5,336.5 99.7,338.6 107.3,350.3C119.3,368.7 131.3,381.8 147.3,394.3C188.8,426.8 240.3,439 292.5,429C353.5,417.2 405.1,372.3 425.8,312.9C429,303.7 434,282.9 434,278.7C434,276.1 434,276.1 424.5,275.8C419.3,275.6 414.9,275.1 414.9,274.7C414.7,273.1 450.4,212 451.1,212.8C451.5,213.2 459.8,227.2 469.4,243.9Z"/>
<path android:fillColor="#0277BB" android:fillType="nonZero" android:pathData="M247.6,191C241.3,192.6 232.1,198.1 228.4,202.4C226.5,204.6 223.7,208.9 222.2,212C219.8,216.9 219.5,218.6 219.5,227.5C219.5,236.4 219.8,238.1 222.2,243.1C229.6,258.2 246.3,266.9 262.2,264C274.3,261.8 284.3,254.2 289.7,243.2C292.2,238.1 292.5,236.4 292.5,227.5C292.5,218.6 292.2,216.9 289.8,212C285.6,203.4 280.8,198.5 272.7,194.5C264.7,190.6 254.9,189.2 247.6,191Z"/>

@ -1,6 +1,6 @@
<vector android:autoMirrored="true" android:height="24dp"
<vector android:autoMirrored="true" android:height="36dp"
android:viewportHeight="192" android:viewportWidth="192"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
android:width="36dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillAlpha="1" android:fillColor="#ffc107"
android:pathData="M160,67.52V30H122.48L96,3.52 69.52,30H32V67.52L5.52,94 32,120.48V158H69.52L96,184.48 122.48,158H160V120.48L186.48,94Z" android:strokeWidth="8"/>
<path android:fillAlpha="1" android:fillColor="#ffd740"

@ -1,6 +1,6 @@
<vector android:autoMirrored="true" android:height="24dp"
<vector android:autoMirrored="true" android:height="36dp"
android:viewportHeight="544.3" android:viewportWidth="533.5"
android:width="23.523792dp" xmlns:android="http://schemas.android.com/apk/res/android">
android:width="35.285688dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#4285F4" android:pathData="M533.5,278.4c0,-18.5 -1.5,-37.1 -4.7,-55.3H272.1v104.8h147c-6.1,33.8 -25.7,63.7 -54.4,82.7v68h87.7C503.9,431.2 533.5,361.2 533.5,278.4z"/>
<path android:fillColor="#34A853" android:pathData="M272.1,544.3c73.4,0 135.3,-24.1 180.4,-65.7l-87.7,-68c-24.4,16.6 -55.9,26 -92.6,26c-71,0 -131.2,-47.9 -152.8,-112.3H28.9v70.1C75.1,486.3 169.2,544.3 272.1,544.3z"/>
<path android:fillColor="#FBBC04" android:pathData="M119.3,324.3c-11.4,-33.8 -11.4,-70.4 0,-104.2V150H28.9c-38.6,76.9 -38.6,167.5 0,244.4L119.3,324.3z"/>

@ -1,6 +1,6 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="1146dp"
android:height="1146dp"
android:width="36dp"
android:height="36dp"
android:viewportWidth="1146"
android:viewportHeight="1146">
<group>

@ -1,14 +0,0 @@
<vector android:autoMirrored="true" android:height="36dp"
android:viewportHeight="1146" android:viewportWidth="1146"
android:width="36dp" xmlns:android="http://schemas.android.com/apk/res/android">
<group>
<clip-path android:pathData="M0,0l1145.72,0l0,1145.72l-1145.72,0z"/>
<path android:fillColor="#2196F3" android:pathData="M572.65,571.88m-572.51,0a572.51,572.51 0,1 1,1145.02 0a572.51,572.51 45,1 1,-1145.02 0"/>
<group>
<clip-path android:pathData="M572.65,571.88m-572.51,0a572.51,572.51 0,1 1,1145.02 0a572.51,572.51 45,1 1,-1145.02 0"/>
<path android:fillAlpha="0.15" android:fillColor="#FF000000"
android:fillType="nonZero" android:pathData="M429.5,771.89L230.23,572.61L162.61,640.23L1146.31,1623.94L1719.76,1050.49L935.33,266.06L429.5,771.89Z"/>
</group>
</group>
<path android:fillColor="#ffffff" android:fillType="nonZero" android:pathData="M429.5,771.88L230.22,572.61L162.61,640.23L429.5,907.12L1002.95,333.67L935.33,266.05L429.5,771.88Z"/>
</vector>

@ -120,7 +120,6 @@
<string name="sound">صوت</string>
<string name="vibrations">إهتزازات</string>
<string name="quiet_hours">الساعات الهادئة</string>
<string name="synchronization">التزامن</string>
<string name="enabled">تفعيل</string>
<string name="font_size">حجم الخط</string>
<string name="customize_edit_screen">تعديل الشاشه</string>

@ -280,7 +280,6 @@
<string name="backup_directory">Директория за резервни копия</string>
<string name="google_drive_backup">Копирай в Google Drive</string>
<string name="miscellaneous">Разни</string>
<string name="synchronization">Синхронизация</string>
<string name="enabled">Активирано</string>
<string name="font_size">Размер на шрифта</string>
<string name="row_spacing">Разстояние между редовете</string>

@ -177,7 +177,6 @@
<string name="quiet_hours">Nerušit od</string>
<string name="backup_directory">Složka pro zálohy</string>
<string name="miscellaneous">Jiné</string>
<string name="synchronization">Synchronizace</string>
<string name="enabled">Povoleno</string>
<string name="font_size">Velikost písma</string>
<string name="source_code">Zdrojový kód</string>

@ -373,7 +373,6 @@
<string name="font_size">Skriftstørrelse</string>
<string name="enabled">Aktiveret</string>
<string name="subtasks">Underopgaver</string>
<string name="synchronization">Synkronisering</string>
<string name="miscellaneous">Diverse</string>
<string name="google_drive_backup">Kopiér til Google Drive</string>
<string name="backup_directory">Mappe til sikkerhedskopi</string>

@ -280,7 +280,6 @@
<string name="backup_directory">Sicherungsordner</string>
<string name="google_drive_backup">Google Drive-Sicherung</string>
<string name="miscellaneous">Verschiedenes</string>
<string name="synchronization">Synchronisierung</string>
<string name="enabled">Aktiviert</string>
<string name="font_size">Schriftgröße</string>
<string name="row_spacing">Zeilenabstand</string>

@ -281,7 +281,6 @@
<string name="backup_directory">Carpeta de copia de seguridad</string>
<string name="google_drive_backup">Copia de seguridad de Google Drive</string>
<string name="miscellaneous">Miscelánea</string>
<string name="synchronization">Sincronización</string>
<string name="enabled">Habilitado</string>
<string name="font_size">Tamaño de la fuente</string>
<string name="row_spacing">Espaciado de fila</string>

@ -159,7 +159,6 @@
<string name="backup_directory">Varukoopia kaust</string>
<string name="google_drive_backup">Kopeeri Google Drive-i</string>
<string name="miscellaneous">Varia</string>
<string name="synchronization">Sünkroonimine</string>
<string name="enabled">Sisse lülitatud</string>
<string name="font_size">Teksti suurus</string>
<string name="row_spacing">Reavahed</string>

@ -283,7 +283,6 @@
<string name="backup_directory">Babes-kopien karpeta</string>
<string name="google_drive_backup">Google Drive babeskopia</string>
<string name="miscellaneous">Denetarik</string>
<string name="synchronization">Sinkronizazioa</string>
<string name="enabled">Gaituta</string>
<string name="font_size">Letraren tamaina</string>
<string name="row_spacing">Errenkaden banatze espazioa</string>

@ -271,7 +271,6 @@
<string name="attachment_directory">Liitehakemisto</string>
<string name="backup_directory">Varmuuskopioiden hakemisto</string>
<string name="miscellaneous">Sekalaista</string>
<string name="synchronization">Synkronointi</string>
<string name="enabled">Sallittu</string>
<string name="font_size">Kirjasimen koko</string>
<string name="row_spacing">Rivinväli</string>

@ -264,7 +264,6 @@
<string name="backup_directory">Dossier de sauvegarde</string>
<string name="google_drive_backup">Sauvegarde de Google Drive</string>
<string name="miscellaneous">Divers</string>
<string name="synchronization">Synchronisation</string>
<string name="enabled">Activé</string>
<string name="font_size">Taille de police</string>
<string name="row_spacing">Écartement de la ligne</string>

@ -193,7 +193,6 @@
<string name="attachment_directory">Directorio de archivos adjuntos</string>
<string name="backup_directory">Directorio de copia de seguridad</string>
<string name="miscellaneous">Miscelánea</string>
<string name="synchronization">Sincronización</string>
<string name="enabled">Habilitado</string>
<string name="font_size">Tamaño de la fuente</string>
<string name="row_spacing">Espaciado de fila</string>

@ -280,7 +280,6 @@
<string name="backup_directory">Mentési mappa</string>
<string name="google_drive_backup">Mentés Google Drive-ba</string>
<string name="miscellaneous">Egyéb</string>
<string name="synchronization">Szinkronizáció</string>
<string name="enabled">Engedélyezve</string>
<string name="font_size">Karakter méret</string>
<string name="row_spacing">Sorköz</string>

@ -203,7 +203,6 @@
<string name="backup_directory">Direktori cadangan</string>
<string name="google_drive_backup">Salin ke Google Drive</string>
<string name="miscellaneous">Lain-lain</string>
<string name="synchronization">Sinkronisasi</string>
<string name="subtasks">Subtugas</string>
<string name="enabled">Aktif</string>
<string name="font_size">Ukuran fon</string>

@ -282,7 +282,6 @@
<string name="backup_directory">Cartella di backup</string>
<string name="google_drive_backup">Backup su Google Drive</string>
<string name="miscellaneous">Varie</string>
<string name="synchronization">Sincronizzazione</string>
<string name="enabled">Attiva</string>
<string name="font_size">Dimensione carattere</string>
<string name="row_spacing">Interlinea</string>

@ -313,7 +313,6 @@
<string name="backup_directory">תיקיית גיבוי</string>
<string name="google_drive_backup">גיבוי Google Drive</string>
<string name="miscellaneous">שונות</string>
<string name="synchronization">סינכרון</string>
<string name="enabled">אפשר</string>
<string name="font_size">גודל גופן</string>
<string name="row_spacing">מרווח שורה</string>

@ -278,7 +278,6 @@
<string name="backup_directory">ディレクトリをバックアップ</string>
<string name="google_drive_backup">Google ドライブにコピー</string>
<string name="miscellaneous">その他</string>
<string name="synchronization">同期</string>
<string name="enabled">有効</string>
<string name="font_size">フォントサイズ</string>
<string name="row_spacing">行間隔</string>

@ -279,7 +279,6 @@
<string name="attachment_directory">첨부파일 위치</string>
<string name="backup_directory">백업 위치</string>
<string name="miscellaneous">기타</string>
<string name="synchronization">동기화</string>
<string name="enabled">활성화됨</string>
<string name="font_size">글자 크기</string>
<string name="row_spacing">줄 간격</string>

@ -277,7 +277,6 @@
<string name="backup_directory">Atsarginių kopijų direktorija</string>
<string name="google_drive_backup">Kopijuoti į Google Drive</string>
<string name="miscellaneous">Įvairūs</string>
<string name="synchronization">Sinchronizacija</string>
<string name="enabled">Įjungta</string>
<string name="font_size">Šrifto dydis</string>
<string name="row_spacing">Eilutės plotis</string>

@ -317,7 +317,6 @@
<string name="backup_directory">Sikkerhetskopimappe</string>
<string name="google_drive_backup">Google Drive-sikkerhetskopi</string>
<string name="miscellaneous">Ymse</string>
<string name="synchronization">Synkronisering</string>
<string name="enabled">Påskrudd</string>
<string name="font_size">Skriftstørrelse</string>
<string name="customize_edit_screen">Tilpass redigeringsskjerm</string>

@ -275,7 +275,6 @@
<string name="attachment_directory">Bijlage map</string>
<string name="google_drive_backup">Back-up naar Google Drive</string>
<string name="miscellaneous">Diversen</string>
<string name="synchronization">Synchronisatie</string>
<string name="enabled">Actief</string>
<string name="font_size">Font grootte</string>
<string name="row_spacing">Regelruimte</string>

@ -292,7 +292,6 @@
<string name="backup_directory">Katalog kopii zapasowych</string>
<string name="google_drive_backup">Kopia zapasowa na Dysku Google</string>
<string name="miscellaneous">Różne</string>
<string name="synchronization">Synchronizacja</string>
<string name="enabled">Włączone</string>
<string name="font_size">Rozmiar czcionki</string>
<string name="row_spacing">Odstęp wierszy</string>

@ -278,7 +278,6 @@
<string name="backup_directory">Pasta de backup</string>
<string name="google_drive_backup">Copiar para o Google Drive</string>
<string name="miscellaneous">Miscelânea</string>
<string name="synchronization">Sincronização</string>
<string name="enabled">Ativado</string>
<string name="font_size">Tamanho do texto</string>
<string name="row_spacing">Espaçamento da linha</string>

@ -268,7 +268,6 @@
<string name="attachment_directory">Diretório do anexo</string>
<string name="backup_directory">Diretório de cópia de segurança</string>
<string name="miscellaneous">Outras</string>
<string name="synchronization">Sincronização</string>
<string name="enabled">Ativo</string>
<string name="font_size">Tamanho da letra</string>
<string name="row_spacing">Espaçamento entre linhas</string>

@ -297,7 +297,6 @@
<string name="backup_directory">Папка резервных копий</string>
<string name="google_drive_backup">Резервное копирование в Google Drive</string>
<string name="miscellaneous">Прочие настройки</string>
<string name="synchronization">Синхронизация</string>
<string name="enabled">Включить режим</string>
<string name="font_size">Размер шрифта</string>
<string name="row_spacing">Межстрочный интервал</string>

@ -278,7 +278,6 @@
<string name="backup_directory">Zalóhovať adresár</string>
<string name="google_drive_backup">Kopírovať na Disk Google</string>
<string name="miscellaneous">Rôzne</string>
<string name="synchronization">Synchronizácia</string>
<string name="enabled">Povolené</string>
<string name="font_size">Veľkosť písma</string>
<string name="row_spacing">Šírka riadkov</string>

@ -193,7 +193,6 @@
<string name="attachment_directory">Lagringsplats för bilagor</string>
<string name="backup_directory">Lagringsplats för säkerhetskopior</string>
<string name="miscellaneous">Övrigt</string>
<string name="synchronization">Synkronisering</string>
<string name="enabled">Aktiverad</string>
<string name="font_size">Teckenstorlek</string>
<string name="customize_edit_screen">Anpassa redigeringsvyn</string>

@ -451,7 +451,6 @@
<string name="font_size">எழுத்துரு அளவு</string>
<string name="enabled">இயக்கப்பட்டது</string>
<string name="subtasks">துணை பணிகள்</string>
<string name="synchronization">ஒத்திசைவு</string>
<string name="miscellaneous">இதர</string>
<string name="google_drive_backup">Google இயக்கத்தில் நகலெடுக்கவும்</string>
<string name="backup_directory">காப்பு கோப்புறை</string>

@ -283,7 +283,6 @@
<string name="backup_directory">Yedekleme klasörü</string>
<string name="google_drive_backup">Google Drive yedeği</string>
<string name="miscellaneous">Türlü</string>
<string name="synchronization">Eşzamanlama</string>
<string name="enabled">Etkin</string>
<string name="font_size">Yazı tipi boyutu</string>
<string name="row_spacing">Satır aralığı</string>

@ -298,7 +298,6 @@
<string name="backup_directory">Папка з резервними копіями</string>
<string name="google_drive_backup">Резервне копіювання до Google Drive</string>
<string name="miscellaneous">Різне</string>
<string name="synchronization">Синхронізація</string>
<string name="enabled">Увімкнено</string>
<string name="font_size">Розмір шрифту</string>
<string name="row_spacing">Відстань між рядками</string>

@ -265,7 +265,6 @@
<string name="attachment_directory">附件文件夹</string>
<string name="backup_directory">备份文件夹</string>
<string name="miscellaneous">杂项</string>
<string name="synchronization">同步</string>
<string name="enabled">启用</string>
<string name="font_size">字体大小</string>
<string name="row_spacing">行间距</string>

@ -167,7 +167,6 @@
<string name="vibrations">震動</string>
<string name="backup_directory">備份資料夾</string>
<string name="miscellaneous">雜項設定</string>
<string name="synchronization">同步</string>
<string name="enabled">啟用</string>
<string name="row_spacing">行距</string>
<string name="translations">貢獻翻譯</string>

@ -323,7 +323,6 @@ File %1$s contained %2$s.\n\n
<string name="backup_directory">Backup folder</string>
<string name="google_drive_backup">Google Drive backup</string>
<string name="miscellaneous">Miscellaneous</string>
<string name="synchronization">Synchronization</string>
<string name="subtasks">Subtasks</string>
<string name="enabled">Enabled</string>
<string name="font_size">Font size</string>

@ -1,14 +1,10 @@
<?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">
xmlns:app="http://schemas.android.com/apk/res-auto">
<org.tasks.preferences.IconPreference
android:key="@string/tasks_org"
android:layout="@layout/preference_icon"
android:title="@string/tasks_org"
android:summary=" "
tools:summary="@string/sign_in_with_google" />
<Preference
android:key="@string/add_account"
android:title="@string/not_signed_in" />
<Preference
app:fragment="org.tasks.preferences.fragments.LookAndFeel"
@ -21,12 +17,6 @@
app:icon="@drawable/ic_outline_notifications_24px"
app:title="@string/notifications" />
<Preference
android:key="@string/synchronization"
app:fragment="org.tasks.preferences.fragments.Synchronization"
app:icon="@drawable/ic_outline_cloud_24px"
app:title="@string/synchronization" />
<Preference
app:fragment="org.tasks.preferences.fragments.TaskDefaults"
app:icon="@drawable/ic_outline_edit_24px"

@ -1,16 +0,0 @@
<?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"
android:key="@string/preference_screen">
<PreferenceCategory
android:key="@string/accounts"
android:title="@string/accounts"
app:isPreferenceVisible="false" />
<Preference
android:key="@string/add_account"
android:title="@string/add_account"
app:icon="@drawable/ic_outline_add_24px" />
</PreferenceScreen>
Loading…
Cancel
Save