From e1abf80f1174d57af599aa1bccfe9e9f03596dab Mon Sep 17 00:00:00 2001 From: Friday Date: Fri, 5 Jun 2026 21:08:42 +0000 Subject: [PATCH] v1.0.66: fix scheduled background sync never registering on pair creation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Creating an interval/daily/weekly sync pair saved it enabled but never enqueued the periodic WorkManager job — it only scheduled on the enable-toggle or a reboot, so a freshly-created scheduled backup silently never ran in the background. AddPairViewModel.save now registers the work (periodic / watcher) on save, mirroring toggleEnabled + BootReceiver. Verified on-device: the JobScheduler periodic job appears on save and a forced run performs the sync. --- .../syncflow/ui/addpair/AddPairViewModel.kt | 36 +++++++++++++++++-- version.properties | 4 +-- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/app/src/main/kotlin/com/syncflow/ui/addpair/AddPairViewModel.kt b/app/src/main/kotlin/com/syncflow/ui/addpair/AddPairViewModel.kt index e87485f..349b6a6 100644 --- a/app/src/main/kotlin/com/syncflow/ui/addpair/AddPairViewModel.kt +++ b/app/src/main/kotlin/com/syncflow/ui/addpair/AddPairViewModel.kt @@ -10,7 +10,10 @@ import com.syncflow.data.db.SyncPairDao import com.syncflow.data.db.entities.CloudAccountEntity import com.syncflow.data.db.entities.SyncPairEntity import com.syncflow.domain.model.* +import androidx.work.ExistingPeriodicWorkPolicy +import androidx.work.WorkManager import com.syncflow.worker.FileWatchService +import com.syncflow.worker.SyncWorker import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.qualifiers.ApplicationContext import kotlinx.coroutines.flow.* @@ -176,7 +179,7 @@ class AddPairViewModel @Inject constructor( notifyOnComplete = s.notifyOnComplete, notifyOnError = s.notifyOnError, isEnabled = true, lastSyncAt = null, lastSyncResult = SyncStatus.IDLE, pendingConflicts = 0, ) - if (editPairId == null) { + val pairId = if (editPairId == null) { syncPairDao.insert(entity) } else { val existing = syncPairDao.getById(editPairId) @@ -189,13 +192,40 @@ class AddPairViewModel @Inject constructor( ) { fileStateDao.deleteForPair(editPairId) } + editPairId } + entity.copy(id = pairId) } - .onSuccess { - if (s.scheduleType == ScheduleType.ON_CHANGE) FileWatchService.start(context) + .onSuccess { saved -> + applySchedule(saved) _state.update { it.copy(done = true) } } .onFailure { e -> _state.update { it.copy(isSaving = false, error = e.message) } } } } + + /** + * Register the pair's background work the moment it's saved. Previously this only happened on + * the enable-toggle or a reboot, so a freshly-created scheduled pair never actually ran in the + * background. Mirrors HomeViewModel.toggleEnabled / BootReceiver. + */ + private fun applySchedule(pair: SyncPairEntity) { + val wm = WorkManager.getInstance(context) + when (pair.scheduleType) { + ScheduleType.ON_CHANGE -> { + wm.cancelUniqueWork("periodic_${pair.id}") + FileWatchService.start(context) + } + ScheduleType.MANUAL -> wm.cancelUniqueWork("periodic_${pair.id}") + else -> { + val req = SyncWorker.buildPeriodicRequest( + pair.id, + pair.scheduleIntervalMinutes.toLong().coerceAtLeast(15), + pair.wifiOnly, + pair.chargingOnly, + ) + wm.enqueueUniquePeriodicWork("periodic_${pair.id}", ExistingPeriodicWorkPolicy.UPDATE, req) + } + } + } } diff --git a/version.properties b/version.properties index 14a273e..72d9ec7 100644 --- a/version.properties +++ b/version.properties @@ -1,2 +1,2 @@ -VERSION_NAME=1.0.65 -VERSION_CODE=66 +VERSION_NAME=1.0.66 +VERSION_CODE=67