Load last backup times in PreferencesViewModel

pull/1136/head
Alex Baker 5 years ago
parent dd715c2b23
commit 5e472aabbe

@ -1,39 +0,0 @@
package org.tasks.backup
import android.content.ContentResolver
import android.content.Context
import androidx.documentfile.provider.DocumentFile
import com.todoroo.astrid.backup.BackupConstants
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.tasks.preferences.Preferences
import java.io.File
import javax.inject.Inject
class BackupHelper @Inject constructor(
@param:ApplicationContext private val context: Context,
private val preferences: Preferences
) {
suspend fun getLastBackup(): Long? {
val uri = preferences.backupDirectory
val timestamps: List<Long>? = withContext(Dispatchers.IO) {
when (uri?.scheme) {
ContentResolver.SCHEME_CONTENT -> {
DocumentFile.fromTreeUri(context, uri)
?.listFiles()
?.filter { BackupConstants.isBackupFile(it.name!!) }
?.map { BackupConstants.getTimestamp(it) }
}
ContentResolver.SCHEME_FILE -> {
File(uri.path!!)
.listFiles()
?.filter { BackupConstants.isBackupFile(it.name) }
?.map { BackupConstants.getTimestamp(it) }
}
else -> emptyList()
}
}
return timestamps?.maxOrNull()
}
}

@ -2,6 +2,8 @@ package org.tasks.preferences
import android.app.Activity
import android.content.Intent
import android.os.Bundle
import androidx.activity.viewModels
import com.todoroo.astrid.gtasks.auth.GtasksLoginActivity
import dagger.hilt.android.AndroidEntryPoint
import org.tasks.R
@ -13,6 +15,7 @@ import org.tasks.preferences.fragments.REQUEST_DRIVE_BACKUP
import org.tasks.preferences.fragments.REQUEST_GOOGLE_TASKS
import org.tasks.sync.SyncAdapters
import org.tasks.ui.Toaster
import timber.log.Timber
import javax.inject.Inject
@AndroidEntryPoint
@ -22,10 +25,18 @@ class MainPreferences : BasePreferences() {
@Inject lateinit var workManager: WorkManager
@Inject lateinit var toaster: Toaster
private val viewModel: PreferencesViewModel by viewModels()
override fun getRootTitle() = R.string.TLA_menu_settings
override fun getRootPreference() = MainSettingsFragment()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Timber.d("viewModel=$viewModel")
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == REQUEST_CALDAV_SETTINGS) {
if (resultCode == RESULT_OK) {

@ -0,0 +1,96 @@
package org.tasks.preferences
import android.content.ContentResolver
import android.content.Context
import androidx.documentfile.provider.DocumentFile
import androidx.hilt.lifecycle.ViewModelInject
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.google.api.client.googleapis.json.GoogleJsonResponseException
import com.google.api.services.drive.DriveScopes
import com.todoroo.astrid.backup.BackupConstants
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.tasks.R
import org.tasks.drive.DriveInvoker
import org.tasks.gtasks.GoogleAccountManager
import timber.log.Timber
import java.io.File
class PreferencesViewModel @ViewModelInject constructor(
@ApplicationContext private val context: Context,
private val preferences: Preferences,
private val driveInvoker: DriveInvoker,
private val googleAccountManager: GoogleAccountManager,
) : ViewModel() {
val lastBackup = MutableLiveData<Long?>()
val lastDriveBackup = MutableLiveData<Long?>()
val lastAndroidBackup = MutableLiveData<Long>()
val driveAccount: String?
get() {
val account = preferences.getStringValue(R.string.p_google_drive_backup_account)
val enabled = !account.isNullOrBlank()
&& preferences.getBoolean(R.string.p_google_drive_backup, false)
&& googleAccountManager.canAccessAccount(account)
&& !preferences.alreadyNotified(account, DriveScopes.DRIVE_FILE)
return if (enabled) account else null
}
private fun updateDriveBackup() = viewModelScope.launch {
if (driveAccount.isNullOrBlank()) {
lastDriveBackup.value = null
return@launch
}
val files = preferences.getStringValue(R.string.p_google_drive_backup_folder)
?.takeIf { it.isNotBlank() }
?.let {
try {
driveInvoker.getFilesByPrefix(it, "auto.", "user.")
} catch (e: GoogleJsonResponseException) {
Timber.e(e)
null
}
}
?: emptyList()
lastDriveBackup.value = files.firstOrNull()?.let { BackupConstants.getTimestamp(it) }
}
private fun updateLocalBackup() = viewModelScope.launch {
val uri = preferences.backupDirectory
val timestamps: List<Long>? = withContext(Dispatchers.IO) {
when (uri?.scheme) {
ContentResolver.SCHEME_CONTENT -> {
DocumentFile.fromTreeUri(context, uri)
?.listFiles()
?.filter { BackupConstants.isBackupFile(it.name!!) }
?.map { BackupConstants.getTimestamp(it) }
}
ContentResolver.SCHEME_FILE -> {
File(uri.path!!)
.listFiles()
?.filter { BackupConstants.isBackupFile(it.name) }
?.map { BackupConstants.getTimestamp(it) }
}
else -> emptyList()
}
}
lastBackup.value = timestamps?.maxOrNull()
}
private fun updateAndroidBackup() {
lastAndroidBackup.value = preferences
.getLong(R.string.p_backups_android_backup_last, -1L)
.takeIf { it >= 0 }
}
init {
updateLocalBackup()
updateDriveBackup()
updateAndroidBackup()
}
}

@ -3,30 +3,23 @@ package org.tasks.preferences.fragments
import android.app.Activity.RESULT_OK
import android.content.Intent
import android.os.Bundle
import androidx.lifecycle.lifecycleScope
import androidx.fragment.app.activityViewModels
import androidx.preference.Preference
import androidx.preference.SwitchPreferenceCompat
import com.google.api.client.googleapis.json.GoogleJsonResponseException
import com.google.api.services.drive.DriveScopes
import com.todoroo.andlib.utility.DateUtilities
import com.todoroo.astrid.backup.BackupConstants
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch
import org.tasks.PermissionUtil
import org.tasks.R
import org.tasks.backup.BackupHelper
import org.tasks.dialogs.ExportTasksDialog
import org.tasks.dialogs.ImportTasksDialog
import org.tasks.drive.DriveInvoker
import org.tasks.drive.DriveLoginActivity
import org.tasks.files.FileHelper
import org.tasks.gtasks.GoogleAccountManager
import org.tasks.injection.InjectingPreferenceFragment
import org.tasks.preferences.FragmentPermissionRequestor
import org.tasks.preferences.PermissionRequestor
import org.tasks.preferences.Preferences
import org.tasks.preferences.PreferencesViewModel
import org.tasks.ui.Toaster
import timber.log.Timber
import java.util.*
import javax.inject.Inject
@ -42,10 +35,9 @@ class Backups : InjectingPreferenceFragment() {
@Inject lateinit var preferences: Preferences
@Inject lateinit var permissionRequestor: FragmentPermissionRequestor
@Inject lateinit var toaster: Toaster
@Inject lateinit var googleAccountManager: GoogleAccountManager
@Inject lateinit var locale: Locale
@Inject lateinit var driveInvoker: DriveInvoker
@Inject lateinit var backupHelper: BackupHelper
private val viewModel: PreferencesViewModel by activityViewModels()
override fun getPreferenceXml() = R.xml.preferences_backups
@ -75,64 +67,52 @@ class Backups : InjectingPreferenceFragment() {
requestGoogleDriveLogin()
false
}
}
override fun onResume() {
super.onResume()
updateDriveAccount()
viewModel.lastBackup.observe(this, this::updateLastBackup)
viewModel.lastDriveBackup.observe(this, this::updateDriveBackup)
viewModel.lastAndroidBackup.observe(this, this::updateAndroidBackup)
}
val driveBackup = findPreference(R.string.google_drive_backup) as SwitchPreferenceCompat
driveBackup.isChecked = driveAccount != null
if (driveAccount != null) {
lifecycleScope.launch {
val files = preferences.getStringValue(R.string.p_google_drive_backup_folder)
?.takeIf { it.isNotBlank() }
?.let {
try {
driveInvoker.getFilesByPrefix(it, "auto.", "user.")
} catch (e: GoogleJsonResponseException) {
Timber.e(e)
null
}
}
?: emptyList()
driveBackup.summary = getString(
private fun updateLastBackup(timestamp: Long?) {
findPreference(R.string.backup_BAc_export).summary =
getString(
R.string.last_backup,
if (files.isEmpty()) {
getString(R.string.last_backup_never)
} else {
DateUtilities.getLongDateStringWithTime(
BackupConstants.getTimestamp(files[0]),
locale
)
})
}
}
timestamp
?.let { DateUtilities.getLongDateStringWithTime(it, locale) }
?: getString(R.string.last_backup_never)
)
}
lifecycleScope.launch {
findPreference(R.string.backup_BAc_export).summary =
getString(
R.string.last_backup,
backupHelper.getLastBackup()
?.takeIf { it > 0 }
?.let { DateUtilities.getLongDateStringWithTime(it, locale) }
?: getString(R.string.last_backup_never)
)
}
private fun updateDriveBackup(timestamp: Long?) {
findPreference(R.string.google_drive_backup).summary =
getString(
R.string.last_backup,
timestamp
?.let { DateUtilities.getLongDateStringWithTime(it, locale) }
?: getString(R.string.last_backup_never)
)
}
val lastAndroidBackup = preferences.getLong(R.string.p_backups_android_backup_last, 0L)
private fun updateAndroidBackup(timestamp: Long?) {
findPreference(R.string.p_backups_android_backup_enabled).summary =
getString(
R.string.last_backup,
if (lastAndroidBackup == 0L) {
getString(R.string.last_backup_never)
} else {
DateUtilities.getLongDateStringWithTime(lastAndroidBackup, locale)
}
timestamp
?.let { DateUtilities.getLongDateStringWithTime(it, locale) }
?: getString(R.string.last_backup_never)
)
}
override fun onResume() {
super.onResume()
updateDriveAccount()
val driveBackup = findPreference(R.string.google_drive_backup) as SwitchPreferenceCompat
val driveAccount = viewModel.driveAccount
driveBackup.isChecked = driveAccount != null
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
@ -179,16 +159,6 @@ class Backups : InjectingPreferenceFragment() {
}
}
private val driveAccount: String?
get() {
val account = preferences.getStringValue(R.string.p_google_drive_backup_account)
val enabled = !account.isNullOrBlank()
&& preferences.getBoolean(R.string.p_google_drive_backup, false)
&& googleAccountManager.canAccessAccount(account)
&& !preferences.alreadyNotified(account, DriveScopes.DRIVE_FILE)
return if (enabled) account else null
}
private fun onGoogleDriveCheckChanged(preference: Preference, newValue: Any?) = when {
newValue as Boolean -> {
requestGoogleDriveLogin()
@ -203,7 +173,7 @@ class Backups : InjectingPreferenceFragment() {
}
private fun updateDriveAccount() {
val account = driveAccount
val account = viewModel.driveAccount
val pref = findPreference(R.string.p_google_drive_backup_account)
pref.isEnabled = account != null
pref.summary =

Loading…
Cancel
Save