Show pending syncs in AccountActivity again

This commit is contained in:
Ricki Hirner 2024-03-15 12:01:46 +01:00
parent a43dbb5cff
commit 732d925b4c
4 changed files with 84 additions and 27 deletions

View file

@ -87,19 +87,23 @@ abstract class BaseSyncWorker(
* @param workStates list of states of workers to match
* @param account the account which the workers belong to
* @param authorities type of sync work, ie [CalendarContract.AUTHORITY]
* @param whichTag function to generate tag that should be observed for given account and authority
* @return *true* if at least one worker with matching query was found; *false* otherwise
*/
fun exists(
context: Context,
workStates: List<WorkInfo.State>,
account: Account? = null,
authorities: List<String>? = null
authorities: List<String>? = null,
whichTag: (account: Account, authority: String) -> String = { account, authority ->
commonTag(account, authority)
}
): LiveData<Boolean> {
val workQuery = WorkQuery.Builder
.fromStates(workStates)
if (account != null && authorities != null)
workQuery.addTags(
authorities.map { authority -> commonTag(account, authority) }
authorities.map { authority -> whichTag(account, authority) }
)
return WorkManager.getInstance(context)
.getWorkInfosLiveData(workQuery.build()).map { workInfoList ->

View file

@ -107,6 +107,13 @@ class AccountActivity : AppCompatActivity() {
}
}
/** Tri-state enum to represent active / pending / idle status */
enum class Progress {
Active, // syncing or refreshing
Pending, // sync pending
Idle
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -128,13 +135,25 @@ class AccountActivity : AppCompatActivity() {
val cardDavSvc by model.cardDavSvc.observeAsState()
val canCreateAddressBook by model.canCreateAddressBook.observeAsState(false)
val cardDavRefreshing by model.cardDavRefreshing.observeAsState(false)
val cardDavSyncPending by model.cardDavSyncPending.observeAsState(false)
val cardDavSyncing by model.cardDavSyncing.observeAsState(false)
val cardDavProgress: Progress = when {
cardDavRefreshing || cardDavSyncing -> Progress.Active
cardDavSyncPending -> Progress.Pending
else -> Progress.Idle
}
val addressBooks by model.addressBooksPager.observeAsState()
val calDavSvc by model.calDavSvc.observeAsState()
val canCreateCalendar by model.canCreateCalendar.observeAsState(false)
val calDavRefreshing by model.calDavRefreshing.observeAsState(false)
val calDavSyncPending by model.calDavSyncPending.observeAsState(false)
val calDavSyncing by model.calDavSyncing.observeAsState(false)
val calDavProgress: Progress = when {
calDavRefreshing || calDavSyncing -> Progress.Active
calDavSyncPending -> Progress.Pending
else -> Progress.Idle
}
val calendars by model.calendarsPager.observeAsState()
val subscriptions by model.webcalPager.observeAsState()
@ -151,12 +170,12 @@ class AccountActivity : AppCompatActivity() {
},
hasCardDav = cardDavSvc != null,
canCreateAddressBook = canCreateAddressBook,
cardDavSyncing = cardDavRefreshing || cardDavSyncing,
cardDavProgress = cardDavProgress,
cardDavRefreshing = cardDavRefreshing,
addressBooks = addressBooks?.flow?.collectAsLazyPagingItems(),
hasCalDav = calDavSvc != null,
canCreateCalendar = canCreateCalendar,
calDavSyncing = calDavRefreshing || calDavSyncing,
calDavProgress = calDavProgress,
calDavRefreshing = calDavRefreshing,
calendars = calendars?.flow?.collectAsLazyPagingItems(),
subscriptions = subscriptions?.flow?.collectAsLazyPagingItems(),
@ -234,12 +253,12 @@ fun AccountOverview(
onSetShowOnlyPersonal: (showOnlyPersonal: Boolean) -> Unit,
hasCardDav: Boolean,
canCreateAddressBook: Boolean,
cardDavSyncing: Boolean,
cardDavProgress: AccountActivity.Progress,
cardDavRefreshing: Boolean,
addressBooks: LazyPagingItems<Collection>?,
hasCalDav: Boolean,
canCreateCalendar: Boolean,
calDavSyncing: Boolean,
calDavProgress: AccountActivity.Progress,
calDavRefreshing: Boolean,
calendars: LazyPagingItems<Collection>?,
subscriptions: LazyPagingItems<Collection>?,
@ -406,7 +425,7 @@ fun AccountOverview(
idxCardDav ->
ServiceTab(
requiredPermissions = listOf(Manifest.permission.WRITE_CONTACTS),
refreshing = cardDavSyncing,
progress = cardDavProgress,
collections = addressBooks,
onUpdateCollectionSync = onUpdateCollectionSync,
onChangeForceReadOnly = onChangeForceReadOnly
@ -419,7 +438,7 @@ fun AccountOverview(
}
ServiceTab(
requiredPermissions = permissions,
refreshing = calDavSyncing,
progress = calDavProgress,
collections = calendars,
onUpdateCollectionSync = onUpdateCollectionSync,
onChangeForceReadOnly = onChangeForceReadOnly
@ -450,7 +469,7 @@ fun AccountOverview(
ServiceTab(
requiredPermissions = listOf(Manifest.permission.WRITE_CALENDAR),
refreshing = calDavSyncing,
progress = calDavProgress,
collections = subscriptions,
onSubscribe = onSubscribe
)
@ -479,12 +498,12 @@ fun AccountOverview_CardDAV_CalDAV() {
onSetShowOnlyPersonal = {},
hasCardDav = true,
canCreateAddressBook = false,
cardDavSyncing = true,
cardDavProgress = AccountActivity.Progress.Active,
cardDavRefreshing = false,
addressBooks = null,
hasCalDav = true,
canCreateCalendar = true,
calDavSyncing = false,
calDavProgress = AccountActivity.Progress.Pending,
calDavRefreshing = false,
calendars = null,
subscriptions = null
@ -674,7 +693,7 @@ fun DeleteAccountDialog(
@Composable
fun ServiceTab(
requiredPermissions: List<String>,
refreshing: Boolean,
progress: AccountActivity.Progress,
collections: LazyPagingItems<Collection>?,
onUpdateCollectionSync: (collectionId: Long, sync: Boolean) -> Unit = { _, _ -> },
onChangeForceReadOnly: (collectionId: Long, forceReadOnly: Boolean) -> Unit = { _, _ -> },
@ -685,19 +704,29 @@ fun ServiceTab(
Column {
// progress indicator
val progressAlpha by animateFloatAsState(
if (refreshing) 1f else 0f,
when (progress) {
AccountActivity.Progress.Active -> 1f
AccountActivity.Progress.Pending -> 0.5f
AccountActivity.Progress.Idle -> 0f
},
label = "progressAlpha"
)
if (refreshing)
// indeterminate
LinearProgressIndicator(
when (progress) {
AccountActivity.Progress.Active -> LinearProgressIndicator(
color = MaterialTheme.colors.secondary,
modifier = Modifier
.graphicsLayer(alpha = progressAlpha)
.fillMaxWidth()
)
else
Spacer(Modifier.height(ProgressIndicatorDefaults.StrokeWidth))
AccountActivity.Progress.Pending -> LinearProgressIndicator(
color = MaterialTheme.colors.secondary,
progress = 1f,
modifier = Modifier
.graphicsLayer(alpha = progressAlpha)
.fillMaxWidth()
)
AccountActivity.Progress.Idle -> Spacer(Modifier.height(ProgressIndicatorDefaults.StrokeWidth))
}
// permissions warning
val permissionsState = rememberMultiplePermissionsState(requiredPermissions)

View file

@ -100,14 +100,25 @@ class AccountModel @AssistedInject constructor(
return@switchMap null
RefreshCollectionsWorker.exists(application, RefreshCollectionsWorker.workerName(svc.id))
}
val cardDavSyncPending = BaseSyncWorker.exists(
getApplication(),
listOf(WorkInfo.State.ENQUEUED),
account,
listOf(context.getString(R.string.address_books_authority)),
whichTag = { account, authority ->
// we are only interested in pending OneTimeSyncWorkers because there's always a pending PeriodicSyncWorker
OneTimeSyncWorker.workerName(account, authority)
}
)
val cardDavSyncing = BaseSyncWorker.exists(
getApplication(),
listOf(WorkInfo.State.RUNNING),
account,
listOf(context.getString(R.string.address_books_authority), ContactsContract.AUTHORITY)
listOf(context.getString(R.string.address_books_authority))
)
val addressBooksPager = CollectionPager(db, cardDavSvc, Collection.TYPE_ADDRESSBOOK, showOnlyPersonal)
private val tasksProvider = TaskUtils.currentProviderLive(context)
val calDavSvc = db.serviceDao().getLiveByAccountAndType(account.name, Service.TYPE_CALDAV)
val canCreateCalendar = calDavSvc.switchMap { svc ->
if (svc != null)
@ -120,12 +131,26 @@ class AccountModel @AssistedInject constructor(
return@switchMap null
RefreshCollectionsWorker.exists(application, RefreshCollectionsWorker.workerName(svc.id))
}
val calDavSyncing = BaseSyncWorker.exists(
getApplication(),
listOf(WorkInfo.State.RUNNING),
account,
listOf(CalendarContract.AUTHORITY)
)
val calDavSyncPending = tasksProvider.switchMap { tasks ->
BaseSyncWorker.exists(
getApplication(),
listOf(WorkInfo.State.ENQUEUED),
account,
listOfNotNull(CalendarContract.AUTHORITY, tasks?.authority),
whichTag = { account, authority ->
// we are only interested in pending OneTimeSyncWorkers because there's always a pending PeriodicSyncWorker
OneTimeSyncWorker.workerName(account, authority)
}
)
}
val calDavSyncing = tasksProvider.switchMap { tasks ->
BaseSyncWorker.exists(
getApplication(),
listOf(WorkInfo.State.RUNNING),
account,
listOfNotNull(CalendarContract.AUTHORITY, tasks?.authority)
)
}
val calendarsPager = CollectionPager(db, calDavSvc, Collection.TYPE_CALENDAR, showOnlyPersonal)
val webcalPager = CollectionPager(db, calDavSvc, Collection.TYPE_WEBCAL, showOnlyPersonal)
@ -171,7 +196,7 @@ class AccountModel @AssistedInject constructor(
context.getString(R.string.address_books_authority),
CalendarContract.AUTHORITY
)
TaskUtils.currentProvider(context)?.authority?.let { authorities.add(it) }
tasksProvider.value?.authority?.let { authorities.add(it) }
val syncIntervals = authorities.map { Pair(it, oldSettings.getSyncInterval(it)) }
val accountManager = AccountManager.get(context)

View file

@ -672,7 +672,6 @@ class AccountSettingsActivity: AppCompatActivity() {
val syncIntervalContacts = MutableLiveData<Long>()
val syncIntervalCalendars = MutableLiveData<Long>()
// TODO tasksProvider LiveData
val tasksProvider = TaskUtils.currentProvider(context)
val syncIntervalTasks = MutableLiveData<Long>()