Convert GoogleTaskAccount to CaldavAccount

pull/2146/head
Alex Baker 1 year ago
parent 6c10466904
commit a04fbebd0f

File diff suppressed because it is too large Load Diff

@ -11,7 +11,8 @@ import org.junit.Assert.assertNull
import org.junit.Before
import org.junit.Test
import org.tasks.LocalBroadcastManager
import org.tasks.data.GoogleTaskAccount
import org.tasks.data.CaldavAccount
import org.tasks.data.CaldavDao
import org.tasks.data.GoogleTaskListDao
import org.tasks.injection.InjectingTestCase
import org.tasks.injection.ProductionModule
@ -29,6 +30,7 @@ class GtasksListServiceTest : InjectingTestCase() {
@Inject lateinit var taskDeleter: TaskDeleter
@Inject lateinit var localBroadcastManager: LocalBroadcastManager
@Inject lateinit var googleTaskListDao: GoogleTaskListDao
@Inject lateinit var caldavDao: CaldavDao
private lateinit var gtasksListService: GtasksListService
@ -87,8 +89,11 @@ class GtasksListServiceTest : InjectingTestCase() {
}
private suspend fun setLists(vararg list: TaskList) {
val account = GoogleTaskAccount("account")
googleTaskListDao.insert(account)
val account = CaldavAccount().apply {
username = "account"
uuid = "account"
}
caldavDao.insert(account)
gtasksListService.updateLists(account, listOf(*list))
}
}

@ -17,14 +17,17 @@ import javax.inject.Inject
@HiltAndroidTest
class GoogleTaskListDaoTest : InjectingTestCase() {
@Inject lateinit var googleTaskListDao: GoogleTaskListDao
@Inject lateinit var caldavDao: CaldavDao
@Test
fun noResultsForEmptyAccount() = runBlocking {
val account = GoogleTaskAccount()
account.account = "user@gmail.com"
googleTaskListDao.insert(account)
val account = CaldavAccount().apply {
uuid = "user@gmail.com"
username = "user@gmail.com"
}
caldavDao.insert(account)
assertTrue(googleTaskListDao.getGoogleTaskFilters(account.account!!).isEmpty())
assertTrue(googleTaskListDao.getGoogleTaskFilters(account.username!!).isEmpty())
}
@Test

@ -7,7 +7,6 @@ import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.launch
import org.tasks.LocalBroadcastManager
import org.tasks.data.CaldavDao
import org.tasks.data.GoogleTaskDao
import org.tasks.dialogs.NewFilterDialog
import org.tasks.filters.NavigationDrawerSubheader
import org.tasks.filters.NavigationDrawerSubheader.SubheaderType.*
@ -19,7 +18,6 @@ import javax.inject.Inject
class SubheaderClickHandler @Inject constructor(
private val activity: Activity,
private val preferences: Preferences,
private val googleTaskDao: GoogleTaskDao,
private val caldavDao: CaldavDao,
private val localBroadcastManager: LocalBroadcastManager,
): SubheaderViewHolder.ClickHandler {
@ -28,8 +26,10 @@ class SubheaderClickHandler @Inject constructor(
val collapsed = !subheader.isCollapsed
when (subheader.subheaderType) {
PREFERENCE -> preferences.setBoolean(subheader.id.toInt(), collapsed)
GOOGLE_TASKS -> googleTaskDao.setCollapsed(subheader.id, collapsed)
CALDAV, TASKS, ETESYNC -> caldavDao.setCollapsed(subheader.id, collapsed)
GOOGLE_TASKS,
CALDAV,
TASKS,
ETESYNC -> caldavDao.setCollapsed(subheader.id, collapsed)
}
localBroadcastManager.broadcastRefreshList()
}

@ -135,10 +135,9 @@ class BuiltInFilterExposer @Inject constructor(
.join(Join.left(CaldavTask.TABLE, and(CaldavTask.TASK.eq(Task.ID))))
.join(Join.left(GoogleTaskList.TABLE, GoogleTaskList.REMOTE_ID.eq(GoogleTask.LIST)))
.join(Join.left(CaldavCalendar.TABLE, CaldavCalendar.UUID.eq(CaldavTask.CALENDAR)))
.join(Join.left(GoogleTaskAccount.TABLE, GoogleTaskAccount.ACCOUNT.eq(GoogleTaskList.ACCOUNT)))
.join(Join.left(CaldavAccount.TABLE, CaldavAccount.UUID.eq(CaldavCalendar.ACCOUNT)))
.where(or(
and(GoogleTask.ID.gt(0), GoogleTaskAccount.ACCOUNT.eq(null)),
and(GoogleTask.ID.gt(0), CaldavAccount.UUID.eq(null)),
and(CaldavTask.ID.gt(0), CaldavAccount.UUID.eq(null))))
).apply {
icon = R.drawable.ic_outline_cloud_off_24px

@ -28,7 +28,6 @@ import org.tasks.notifications.NotificationDao
CaldavCalendar::class,
CaldavTask::class,
CaldavAccount::class,
GoogleTaskAccount::class,
Principal::class,
PrincipalAccess::class,
Attachment::class,
@ -36,7 +35,7 @@ import org.tasks.notifications.NotificationDao
autoMigrations = [
AutoMigration(from = 83, to = 84, spec = Migrations.AutoMigrate83to84::class),
],
version = 87
version = 88
)
abstract class Database : RoomDatabase() {
abstract fun notificationDao(): NotificationDao

@ -8,11 +8,10 @@ package com.todoroo.astrid.gtasks
import com.google.api.services.tasks.model.TaskList
import com.todoroo.astrid.service.TaskDeleter
import org.tasks.LocalBroadcastManager
import org.tasks.data.GoogleTaskAccount
import org.tasks.data.CaldavAccount
import org.tasks.data.GoogleTaskList
import org.tasks.data.GoogleTaskListDao
import timber.log.Timber
import java.util.*
import javax.inject.Inject
class GtasksListService @Inject constructor(
@ -25,8 +24,8 @@ class GtasksListService @Inject constructor(
*
* @param remoteLists remote information about your lists
*/
suspend fun updateLists(account: GoogleTaskAccount, remoteLists: List<TaskList>) {
val lists = googleTaskListDao.getLists(account.account!!)
suspend fun updateLists(account: CaldavAccount, remoteLists: List<TaskList>) {
val lists = googleTaskListDao.getLists(account.uuid!!)
val previousLists: MutableSet<Long> = HashSet()
for (list in lists) {
previousLists.add(list.id)
@ -45,12 +44,12 @@ class GtasksListService @Inject constructor(
if (local == null) {
val byRemoteId = googleTaskListDao.findExistingList(id)
if (byRemoteId != null) {
byRemoteId.account = account.account
byRemoteId.account = account.uuid
local = byRemoteId
} else {
Timber.d("Adding new gtask list %s", title)
local = GoogleTaskList()
local.account = account.account
local.account = account.uuid
local.remoteId = id
}
}

@ -20,7 +20,9 @@ import org.tasks.PermissionUtil.verifyPermissions
import org.tasks.R
import org.tasks.analytics.Constants
import org.tasks.analytics.Firebase
import org.tasks.data.GoogleTaskAccount
import org.tasks.data.CaldavAccount
import org.tasks.data.CaldavAccount.Companion.TYPE_GOOGLE_TASKS
import org.tasks.data.CaldavDao
import org.tasks.data.GoogleTaskListDao
import org.tasks.dialogs.DialogBuilder
import org.tasks.gtasks.GoogleAccountManager
@ -39,6 +41,7 @@ import javax.inject.Inject
class GtasksLoginActivity : InjectingAppCompatActivity() {
@Inject lateinit var dialogBuilder: DialogBuilder
@Inject lateinit var googleAccountManager: GoogleAccountManager
@Inject lateinit var caldavDao: CaldavDao
@Inject lateinit var googleTaskListDao: GoogleTaskListDao
@Inject lateinit var permissionRequestor: ActivityPermissionRequestor
@Inject lateinit var firebase: Firebase
@ -71,18 +74,21 @@ class GtasksLoginActivity : InjectingAppCompatActivity() {
startActivity(intent)
} else {
withContext(NonCancellable) {
var account = googleTaskListDao.getAccount(accountName)
var account = caldavDao.getAccount(TYPE_GOOGLE_TASKS, accountName)
if (account == null) {
account = GoogleTaskAccount()
account.account = accountName
googleTaskListDao.insert(account)
account = CaldavAccount()
account.accountType = TYPE_GOOGLE_TASKS
account.uuid = accountName
account.name = accountName
account.username = accountName
caldavDao.insert(account)
firebase.logEvent(
R.string.event_sync_add_account,
R.string.param_type to Constants.SYNC_TYPE_GOOGLE_TASKS
)
} else {
account.error = ""
googleTaskListDao.update(account)
caldavDao.update(account)
googleTaskListDao.resetLastSync(accountName)
}
}

@ -72,12 +72,6 @@ class TaskDeleter @Inject constructor(
localBroadcastManager.broadcastRefreshList()
}
suspend fun delete(list: GoogleTaskAccount) {
val tasks = deletionDao.delete(list)
delete(tasks)
localBroadcastManager.broadcastRefreshList()
}
suspend fun delete(list: CaldavCalendar) {
vtodoCache.delete(list)
val tasks = deletionDao.delete(list)

@ -250,9 +250,11 @@ class Upgrader @Inject constructor(
private suspend fun migrateGoogleTaskAccount() {
val account = preferences.getStringValue("gtasks_user")
if (!isNullOrEmpty(account)) {
val googleTaskAccount = GoogleTaskAccount()
googleTaskAccount.account = account
googleTaskListDao.insert(googleTaskAccount)
val caldavAccount = CaldavAccount()
caldavAccount.uuid = account
caldavAccount.name = account
caldavAccount.username = account
caldavDao.insert(caldavAccount)
for (list in googleTaskListDao.getAllLists()) {
list.account = account
googleTaskListDao.insertOrReplace(list)

@ -17,7 +17,7 @@ import com.todoroo.astrid.service.TaskDeleter
import dagger.hilt.android.AndroidEntryPoint
import org.tasks.R
import org.tasks.Strings.isNullOrEmpty
import org.tasks.data.GoogleTaskAccount
import org.tasks.data.CaldavAccount
import org.tasks.data.GoogleTaskList
import org.tasks.data.GoogleTaskListDao
import org.tasks.databinding.ActivityGoogleTaskListSettingsBinding
@ -43,7 +43,7 @@ class GoogleTaskListSettingsActivity : BaseListSettingsActivity() {
gtasksList = intent.getParcelableExtra(EXTRA_STORE_DATA)
?: GoogleTaskList().apply {
isNewList = true
account = intent.getParcelableExtra<GoogleTaskAccount>(EXTRA_ACCOUNT)!!.account
account = intent.getParcelableExtra<CaldavAccount>(EXTRA_ACCOUNT)!!.username
}
super.onCreate(savedInstanceState)
if (savedInstanceState == null) {

@ -9,7 +9,6 @@ class BackupContainer(
val places: List<Place>?,
val tags: List<TagData>?,
val filters: List<Filter>?,
val googleTaskAccounts: List<GoogleTaskAccount>?,
val googleTaskLists: List<GoogleTaskList>?,
val caldavAccounts: List<CaldavAccount>?,
val caldavCalendars: List<CaldavCalendar>?,
@ -20,6 +19,7 @@ class BackupContainer(
val stringPrefs: Map<String, String>?,
val boolPrefs: Map<String, java.lang.Boolean>?,
val setPrefs: Map<String, java.util.Set<*>>?,
val googleTaskAccounts: List<GoogleTaskAccount>? = emptyList(),
) {
class TaskBackup(
val task: Task,

@ -132,7 +132,6 @@ class TasksJsonExporter @Inject constructor(
locationDao.getPlaces(),
tagDataDao.getAll(),
filterDao.getFilters(),
googleTaskListDao.getAccounts(),
googleTaskListDao.getAllLists(),
caldavDao.getAccounts(),
caldavDao.getCalendars(),

@ -19,6 +19,7 @@ import org.tasks.LocalBroadcastManager
import org.tasks.R
import org.tasks.caldav.VtodoCache
import org.tasks.data.*
import org.tasks.data.CaldavAccount.Companion.TYPE_GOOGLE_TASKS
import org.tasks.data.Place.Companion.newPlace
import org.tasks.db.Migrations.repeatFrom
import org.tasks.db.Migrations.withoutFrom
@ -81,8 +82,15 @@ class TasksJsonImporter @Inject constructor(
tagDataDao.createNew(tagData)
}
backupContainer.googleTaskAccounts?.forEach { googleTaskAccount ->
if (googleTaskListDao.getAccount(googleTaskAccount.account!!) == null) {
googleTaskListDao.insert(googleTaskAccount)
if (caldavDao.getAccount(TYPE_GOOGLE_TASKS, googleTaskAccount.account!!) == null) {
caldavDao.insert(
CaldavAccount().apply {
accountType = TYPE_GOOGLE_TASKS
uuid = googleTaskAccount.account
name = googleTaskAccount.account
username = googleTaskAccount.account
}
)
}
}
backupContainer.places?.forEach { place ->

@ -103,6 +103,9 @@ class CaldavAccount : Parcelable {
val isMicrosoft: Boolean
get() = accountType == TYPE_MICROSOFT
val isGoogleTasks: Boolean
get() = accountType == TYPE_GOOGLE_TASKS
fun listSettingsClass(): Class<out Activity> = when(accountType) {
TYPE_LOCAL -> LocalListSettingsActivity::class.java
TYPE_ETESYNC, TYPE_OPENTASKS -> OpenTasksListSettingsActivity::class.java
@ -208,6 +211,7 @@ class CaldavAccount : Parcelable {
uuid.isDavx5() -> R.string.davx5
uuid.isDecSync() -> R.string.decsync
isMicrosoft -> R.string.microsoft
isGoogleTasks -> R.string.gtasks_GPr_header
else -> 0
}
@ -219,6 +223,7 @@ class CaldavAccount : Parcelable {
uuid.isDavx5() -> R.drawable.ic_davx5_icon_green_bg
uuid.isDecSync() -> R.drawable.ic_decsync
isMicrosoft -> R.drawable.ic_microsoft_tasks
isGoogleTasks -> R.drawable.ic_google
else -> 0
}
@ -233,6 +238,7 @@ class CaldavAccount : Parcelable {
const val TYPE_TASKS = 4
const val TYPE_ETEBASE = 5
const val TYPE_MICROSOFT = 6
const val TYPE_GOOGLE_TASKS = 7
const val SERVER_UNKNOWN = -1
const val SERVER_TASKS = 0

@ -69,22 +69,9 @@ WHERE recurring = 1
return tasks
}
@Delete
internal abstract suspend fun deleteGoogleTaskAccount(googleTaskAccount: GoogleTaskAccount)
@Query("SELECT * FROM google_task_lists WHERE gtl_account = :account ORDER BY gtl_title ASC")
abstract suspend fun getLists(account: String): List<GoogleTaskList>
@Transaction
open suspend fun delete(googleTaskAccount: GoogleTaskAccount): List<Long> {
val deleted = ArrayList<Long>()
for (list in getLists(googleTaskAccount.account!!)) {
deleted.addAll(delete(list))
}
deleteGoogleTaskAccount(googleTaskAccount)
return deleted
}
@Query("SELECT cd_task FROM caldav_tasks WHERE cd_calendar = :calendar AND cd_deleted = 0")
internal abstract suspend fun getActiveCaldavTasks(calendar: String): List<Long>
@ -111,8 +98,14 @@ WHERE recurring = 1
@Transaction
open suspend fun delete(caldavAccount: CaldavAccount): List<Long> {
val deleted = ArrayList<Long>()
for (calendar in getCalendars(caldavAccount.uuid!!)) {
deleted.addAll(delete(calendar))
if (caldavAccount.isGoogleTasks) {
for (list in getLists(caldavAccount.uuid!!)) {
deleted.addAll(delete(list))
}
} else {
for (calendar in getCalendars(caldavAccount.uuid!!)) {
deleted.addAll(delete(calendar))
}
}
deleteCaldavAccount(caldavAccount)
return deleted

@ -1,98 +1,8 @@
package org.tasks.data
import android.os.Parcel
import android.os.Parcelable
import androidx.core.os.ParcelCompat
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.Ignore
import androidx.room.PrimaryKey
import com.todoroo.andlib.data.Table
@Entity(tableName = "google_task_accounts")
class GoogleTaskAccount : Parcelable {
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "gta_id")
@Transient
var id: Long = 0
@ColumnInfo(name = "gta_account")
var account: String? = null
@ColumnInfo(name = "gta_error")
@Transient
var error: String? = ""
@ColumnInfo(name = "gta_etag")
var etag: String? = null
@ColumnInfo(name = "gta_collapsed")
var isCollapsed = false
constructor()
@Ignore
constructor(source: Parcel) {
id = source.readLong()
account = source.readString()
error = source.readString()
etag = source.readString()
isCollapsed = ParcelCompat.readBoolean(source)
}
@Ignore
constructor(account: String?) {
this.account = account
}
override fun describeContents() = 0
override fun writeToParcel(dest: Parcel, flags: Int) {
with(dest) {
writeLong(id)
writeString(account)
writeString(error)
writeString(etag)
ParcelCompat.writeBoolean(this, isCollapsed)
}
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is GoogleTaskAccount) return false
if (id != other.id) return false
if (account != other.account) return false
if (error != other.error) return false
if (etag != other.etag) return false
if (isCollapsed != other.isCollapsed) return false
return true
}
override fun hashCode(): Int {
var result = id.hashCode()
result = 31 * result + (account?.hashCode() ?: 0)
result = 31 * result + (error?.hashCode() ?: 0)
result = 31 * result + (etag?.hashCode() ?: 0)
result = 31 * result + isCollapsed.hashCode()
return result
}
override fun toString(): String =
"GoogleTaskAccount(id=$id, account=$account, error=$error, etag=$etag, isCollapsed=$isCollapsed)"
val hasError: Boolean
get() = !error.isNullOrBlank()
companion object {
val TABLE = Table("google_task_accounts")
val ACCOUNT = TABLE.column("gta_account")
@JvmField val CREATOR: Parcelable.Creator<GoogleTaskAccount> = object : Parcelable.Creator<GoogleTaskAccount> {
override fun createFromParcel(source: Parcel): GoogleTaskAccount = GoogleTaskAccount(source)
override fun newArray(size: Int): Array<GoogleTaskAccount?> = arrayOfNulls(size)
}
}
}
@Deprecated("Only used for backup migration")
data class GoogleTaskAccount(
var account: String? = null,
var etag: String? = null,
var isCollapsed: Boolean = false,
)

@ -56,9 +56,6 @@ abstract class GoogleTaskDao {
update(task)
}
@Query("UPDATE google_task_accounts SET gta_collapsed = :collapsed WHERE gta_id = :id")
abstract suspend fun setCollapsed(id: Long, collapsed: Boolean)
@Query("SELECT * FROM google_tasks WHERE gt_task = :taskId AND gt_deleted = 0 LIMIT 1")
abstract suspend fun getByTaskId(taskId: Long): GoogleTask?

@ -3,25 +3,14 @@ package org.tasks.data
import androidx.lifecycle.LiveData
import androidx.room.*
import com.todoroo.astrid.api.FilterListItem.NO_ORDER
import org.tasks.data.CaldavAccount.Companion.TYPE_GOOGLE_TASKS
import org.tasks.filters.GoogleTaskFilters
import org.tasks.time.DateTimeUtils.currentTimeMillis
@Dao
interface GoogleTaskListDao {
@Query("SELECT * FROM google_task_accounts WHERE gta_id = :id")
fun watchAccount(id: Long): LiveData<GoogleTaskAccount>
@Query("SELECT COUNT(*) FROM google_task_accounts")
suspend fun accountCount(): Int
@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?
@Query("SELECT * FROM caldav_accounts WHERE cda_account_type = $TYPE_GOOGLE_TASKS")
suspend fun getAccounts(): List<CaldavAccount>
@Query("SELECT * FROM google_task_lists WHERE gtl_id = :id")
suspend fun getById(id: Long): GoogleTaskList?
@ -53,12 +42,6 @@ interface GoogleTaskListDao {
@Insert
suspend fun insert(googleTaskList: GoogleTaskList): Long
@Insert
suspend fun insert(googleTaskAccount: GoogleTaskAccount)
@Update
suspend fun update(account: GoogleTaskAccount)
@Update
suspend fun update(list: GoogleTaskList)

@ -16,6 +16,7 @@ import org.tasks.data.Alarm.Companion.TYPE_REL_END
import org.tasks.data.Alarm.Companion.TYPE_REL_START
import org.tasks.data.Alarm.Companion.TYPE_SNOOZE
import org.tasks.data.CaldavAccount.Companion.SERVER_UNKNOWN
import org.tasks.data.CaldavAccount.Companion.TYPE_GOOGLE_TASKS
import org.tasks.data.CaldavCalendar.Companion.ACCESS_READ_ONLY
import org.tasks.data.OpenTaskDao.Companion.getLong
import org.tasks.extensions.getLongOrNull
@ -588,6 +589,13 @@ object Migrations {
}
}
private val MIGRATION_87_88 = object : Migration(87, 88) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("INSERT INTO `caldav_accounts` (`cda_account_type`, `cda_server_type`, `cda_uuid`, `cda_name`, `cda_username`, `cda_collapsed`) SELECT $TYPE_GOOGLE_TASKS, $SERVER_UNKNOWN, `gta_account`, `gta_account`, `gta_account`, `gta_collapsed` FROM `google_task_accounts`")
database.execSQL("DROP TABLE `google_task_accounts`")
}
}
fun migrations(fileStorage: FileStorage) = arrayOf(
MIGRATION_35_36,
MIGRATION_36_37,
@ -631,6 +639,7 @@ object Migrations {
MIGRATION_84_85,
MIGRATION_85_86,
MIGRATION_86_87,
MIGRATION_87_88,
)
private fun noop(from: Int, to: Int): Migration = object : Migration(from, to) {

@ -19,7 +19,6 @@ import org.tasks.LocalBroadcastManager
import org.tasks.R
import org.tasks.billing.Inventory
import org.tasks.data.CaldavDao
import org.tasks.data.GoogleTaskDao
import org.tasks.dialogs.FilterPicker.Companion.EXTRA_LISTS_ONLY
import org.tasks.filters.FilterProvider
import org.tasks.filters.NavigationDrawerSubheader
@ -37,7 +36,6 @@ class FilterPickerViewModel @Inject constructor(
private val inventory: Inventory,
private val colorProvider: ColorProvider,
private val preferences: Preferences,
private val googleTaskDao: GoogleTaskDao,
private val caldavDao: CaldavDao,
) : ViewModel() {
private val listsOnly = savedStateHandle[EXTRA_LISTS_ONLY] ?: false
@ -70,8 +68,7 @@ class FilterPickerViewModel @Inject constructor(
when (subheader.subheaderType) {
NavigationDrawerSubheader.SubheaderType.PREFERENCE ->
preferences.setBoolean(subheader.id.toInt(), collapsed)
NavigationDrawerSubheader.SubheaderType.GOOGLE_TASKS ->
googleTaskDao.setCollapsed(subheader.id, collapsed)
NavigationDrawerSubheader.SubheaderType.GOOGLE_TASKS,
NavigationDrawerSubheader.SubheaderType.CALDAV,
NavigationDrawerSubheader.SubheaderType.TASKS,
NavigationDrawerSubheader.SubheaderType.ETESYNC ->

@ -39,7 +39,7 @@ class FilterProvider @Inject constructor(
private val locationDao: LocationDao) {
suspend fun listPickerItems(): List<FilterListItem> =
googleTaskFilters(false).plus(caldavFilters(false))
caldavFilters(false)
suspend fun navDrawerItems(): List<FilterListItem> =
getAllFilters(hideUnused = true).plus(navDrawerFooter)
@ -166,7 +166,6 @@ class FilterProvider @Inject constructor(
.plus(addFilters(showCreate, showBuiltIn))
.plus(addTags(showCreate, hideUnused))
.plus(addPlaces(showCreate, hideUnused))
.plus(googleTaskFilters(showCreate))
.plus(caldavFilters(showCreate))
.toList()
.plusAllIf(BuildConfig.DEBUG) { getDebugFilters() }
@ -201,13 +200,10 @@ class FilterProvider @Inject constructor(
Intent(context, HelpAndFeedback::class.java),
0))
private suspend fun googleTaskFilters(showCreate: Boolean = true): List<FilterListItem> =
googleTaskListDao.getAccounts().flatMap { googleTaskFilter(it, showCreate) }
private suspend fun googleTaskFilter(account: GoogleTaskAccount, showCreate: Boolean): List<FilterListItem> =
private suspend fun googleTaskFilter(account: CaldavAccount, showCreate: Boolean): List<FilterListItem> =
listOf(
NavigationDrawerSubheader(
account.account,
account.username,
account.error?.isNotBlank() ?: false,
account.isCollapsed,
SubheaderType.GOOGLE_TASKS,
@ -221,7 +217,7 @@ class FilterProvider @Inject constructor(
}))
.apply { if (account.isCollapsed) return this }
.plus(googleTaskListDao
.getGoogleTaskFilters(account.account!!)
.getGoogleTaskFilters(account.username!!)
.map(GoogleTaskFilters::toGtasksFilter)
.sort())
@ -229,7 +225,16 @@ class FilterProvider @Inject constructor(
caldavDao.getAccounts()
.ifEmpty { listOf(caldavDao.setupLocalAccount(context)) }
.filter { it.accountType != TYPE_LOCAL || preferences.getBoolean(R.string.p_lists_enabled, true) }
.flatMap { caldavFilter(it, showCreate && it.accountType != TYPE_OPENTASKS && it.accountType != TYPE_ETESYNC) }
.flatMap {
if (it.isGoogleTasks) {
googleTaskFilter(it, showCreate)
} else {
caldavFilter(
it,
showCreate && it.accountType != TYPE_OPENTASKS && it.accountType != TYPE_ETESYNC
)
}
}
private suspend fun caldavFilter(account: CaldavAccount, showCreate: Boolean): List<FilterListItem> =
listOf(

@ -43,6 +43,7 @@ import kotlin.math.max
class GoogleTaskSynchronizer @Inject constructor(
@param:ApplicationContext private val context: Context,
private val googleTaskListDao: GoogleTaskListDao,
private val caldavDao: CaldavDao,
private val gtasksListService: GtasksListService,
private val preferences: Preferences,
private val taskDao: TaskDao,
@ -58,7 +59,7 @@ class GoogleTaskSynchronizer @Inject constructor(
private val invokers: InvokerFactory,
private val alarmDao: AlarmDao,
) {
suspend fun sync(account: GoogleTaskAccount, i: Int) {
suspend fun sync(account: CaldavAccount, i: Int) {
Timber.d("%s: start sync", account)
try {
if (i == 0 || inventory.hasPro) {
@ -94,20 +95,20 @@ class GoogleTaskSynchronizer @Inject constructor(
account.error = e.message
firebase.reportException(e)
} finally {
googleTaskListDao.update(account)
caldavDao.update(account)
localBroadcastManager.broadcastRefreshList()
Timber.d("%s: end sync", account)
}
}
@Throws(IOException::class)
private suspend fun synchronize(account: GoogleTaskAccount) {
private suspend fun synchronize(account: CaldavAccount) {
if (!permissionChecker.canAccessAccounts()
|| googleAccountManager.getAccount(account.account) == null) {
|| googleAccountManager.getAccount(account.username) == null) {
account.error = context.getString(R.string.cannot_access_account)
return
}
val gtasksInvoker = invokers.getGtasksInvoker(account.account!!)
val gtasksInvoker = invokers.getGtasksInvoker(account.username!!)
pushLocalChanges(account, gtasksInvoker)
val gtaskLists: MutableList<TaskList> = ArrayList()
var nextPageToken: String? = null
@ -148,7 +149,7 @@ class GoogleTaskSynchronizer @Inject constructor(
googleTaskDao.reposition(list.id)
}
}
account.etag = eTag
// account.etag = eTag
account.error = ""
}
@ -168,8 +169,8 @@ class GoogleTaskSynchronizer @Inject constructor(
}
@Throws(IOException::class)
private suspend fun pushLocalChanges(account: GoogleTaskAccount, gtasksInvoker: GtasksInvoker) {
val tasks = taskDao.getGoogleTasksToPush(account.account!!)
private suspend fun pushLocalChanges(account: CaldavAccount, gtasksInvoker: GtasksInvoker) {
val tasks = taskDao.getGoogleTasksToPush(account.username!!)
for (task in tasks) {
pushTask(task, gtasksInvoker)
}

@ -19,6 +19,7 @@ import org.tasks.R
import org.tasks.data.*
import org.tasks.data.CaldavAccount.Companion.TYPE_CALDAV
import org.tasks.data.CaldavAccount.Companion.TYPE_ETEBASE
import org.tasks.data.CaldavAccount.Companion.TYPE_GOOGLE_TASKS
import org.tasks.data.CaldavAccount.Companion.TYPE_TASKS
import org.tasks.date.DateTimeUtils.midnight
import org.tasks.date.DateTimeUtils.newDateTime
@ -122,8 +123,8 @@ class WorkManagerImpl constructor(
override fun updateBackgroundSync() {
throttle.run {
val enabled = googleTaskListDao.accountCount() > 0 ||
caldavDao.getAccounts(TYPE_CALDAV, TYPE_TASKS, TYPE_ETEBASE).isNotEmpty() ||
val enabled =
caldavDao.getAccounts(TYPE_GOOGLE_TASKS, TYPE_CALDAV, TYPE_TASKS, TYPE_ETEBASE).isNotEmpty() ||
openTaskDao.shouldSync()
if (enabled) {
Timber.d("Enabling background sync")

@ -14,7 +14,8 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.tasks.R
import org.tasks.backup.BackupConstants
import org.tasks.data.*
import org.tasks.data.CaldavAccount
import org.tasks.data.CaldavDao
import org.tasks.date.DateTimeUtils.newDateTime
import org.tasks.googleapis.InvokerFactory
import org.tasks.gtasks.GoogleAccountManager
@ -29,13 +30,11 @@ class PreferencesViewModel @Inject constructor(
invokers: InvokerFactory,
private val googleAccountManager: GoogleAccountManager,
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?) =

@ -1,6 +1,8 @@
package org.tasks.preferences.fragments
import android.content.*
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.os.Bundle
import androidx.lifecycle.LiveData
import androidx.lifecycle.lifecycleScope
@ -11,9 +13,9 @@ import kotlinx.coroutines.launch
import org.tasks.LocalBroadcastManager
import org.tasks.R
import org.tasks.billing.Inventory
import org.tasks.data.CaldavAccount
import org.tasks.data.CaldavAccount.Companion.isPaymentRequired
import org.tasks.data.GoogleTaskAccount
import org.tasks.data.GoogleTaskListDao
import org.tasks.data.CaldavDao
import org.tasks.preferences.IconPreference
import javax.inject.Inject
@ -23,11 +25,11 @@ class GoogleTasksAccount : BaseAccountPreference() {
@Inject lateinit var taskDeleter: TaskDeleter
@Inject lateinit var inventory: Inventory
@Inject lateinit var localBroadcastManager: LocalBroadcastManager
@Inject lateinit var googleTaskListDao: GoogleTaskListDao
@Inject lateinit var caldavDao: CaldavDao
private lateinit var googleTaskAccountLiveData: LiveData<GoogleTaskAccount>
private lateinit var googleTaskAccountLiveData: LiveData<CaldavAccount>
val googleTaskAccount: GoogleTaskAccount
val googleTaskAccount: CaldavAccount
get() = googleTaskAccountLiveData.value ?: requireArguments().getParcelable(EXTRA_ACCOUNT)!!
private val purchaseReceiver = object : BroadcastReceiver() {
@ -36,7 +38,7 @@ class GoogleTasksAccount : BaseAccountPreference() {
googleTaskAccount.let {
if (inventory.subscription.value != null && it.error.isPaymentRequired()) {
it.error = null
googleTaskListDao.update(it)
caldavDao.update(it)
}
refreshUi(it)
}
@ -49,8 +51,8 @@ class GoogleTasksAccount : BaseAccountPreference() {
override suspend fun setupPreferences(savedInstanceState: Bundle?) {
super.setupPreferences(savedInstanceState)
googleTaskAccountLiveData = googleTaskListDao.watchAccount(
arguments?.getParcelable<GoogleTaskAccount>(EXTRA_ACCOUNT)?.id ?: 0
googleTaskAccountLiveData = caldavDao.watchAccount(
arguments?.getParcelable<CaldavAccount>(EXTRA_ACCOUNT)?.id ?: 0
)
googleTaskAccountLiveData.observe(this) { refreshUi(it) }
@ -74,7 +76,7 @@ class GoogleTasksAccount : BaseAccountPreference() {
localBroadcastManager.unregisterReceiver(purchaseReceiver)
}
private fun refreshUi(account: GoogleTaskAccount?) {
private fun refreshUi(account: CaldavAccount?) {
if (account == null) {
return
}
@ -119,7 +121,7 @@ class GoogleTasksAccount : BaseAccountPreference() {
fun String?.isUnauthorized(): Boolean =
this?.startsWith("401 Unauthorized", ignoreCase = true) == true
fun newGoogleTasksAccountPreference(account: GoogleTaskAccount) =
fun newGoogleTasksAccountPreference(account: CaldavAccount) =
GoogleTasksAccount().apply {
arguments = Bundle().apply {
putParcelable(EXTRA_ACCOUNT, account)

@ -22,7 +22,6 @@ import org.tasks.billing.PurchaseActivity
import org.tasks.caldav.BaseCaldavAccountSettingsActivity
import org.tasks.caldav.CaldavAccountSettingsActivity
import org.tasks.data.CaldavAccount
import org.tasks.data.GoogleTaskAccount
import org.tasks.etebase.EtebaseAccountSettingsActivity
import org.tasks.extensions.Context.openUri
import org.tasks.extensions.Context.toast
@ -87,7 +86,6 @@ class MainSettingsFragment : InjectingPreferenceFragment() {
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() }
if (BuildConfig.FLAVOR == "generic") {
remove(R.string.upgrade_to_pro)
@ -142,7 +140,6 @@ class MainSettingsFragment : InjectingPreferenceFragment() {
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
@ -153,15 +150,8 @@ class MainSettingsFragment : InjectingPreferenceFragment() {
preferenceScreen.insertAt(current++)
})
}
googleTaskAccounts.forEach {
setup(it, if (current < index) {
preferenceScreen.getPreference(current++) as IconPreference
} else {
preferenceScreen.insertAt(current++)
})
}
preferenceScreen.removeAt(current, index - current)
if (caldavAccounts.isEmpty() && googleTaskAccounts.isEmpty()) {
if (caldavAccounts.isEmpty()) {
addAccount.setTitle(R.string.not_signed_in)
addAccount.setIcon(R.drawable.ic_outline_cloud_off_24px)
} else {
@ -216,6 +206,12 @@ class MainSettingsFragment : InjectingPreferenceFragment() {
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)
@ -239,21 +235,6 @@ class MainSettingsFragment : InjectingPreferenceFragment() {
setupErrorIcon(pref, account.hasError, account.isEteSyncAccount)
}
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.hasError)
pref.setOnPreferenceClickListener {
(activity as MainPreferences).startPreference(
this,
newGoogleTasksAccountPreference(account),
account.account!!
)
false
}
}
private fun setupErrorIcon(
pref: IconPreference,
hasError: Boolean,

Loading…
Cancel
Save