From a556f4cbdcce92a8a4dcf55f2233d86b4f32dda5 Mon Sep 17 00:00:00 2001 From: Gato Date: Sat, 6 Jun 2026 06:46:28 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20[#27]=20sync=20CalDAV=20en=20arri=C3=A8?= =?UTF-8?q?re-plan=20(WorkManager=20PeriodicWork,=20SyncScheduler,=20repri?= =?UTF-8?q?se=20au=20d=C3=A9marrage)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mobile/data/notification/BootReceiver.kt | 7 ++- .../mobile/data/sync/CalDavSyncWorker.kt | 37 ++++++++++++++ .../planify/mobile/data/sync/SyncScheduler.kt | 51 +++++++++++++++++++ 3 files changed, 93 insertions(+), 2 deletions(-) create mode 100644 app/src/main/java/com/planify/mobile/data/sync/CalDavSyncWorker.kt create mode 100644 app/src/main/java/com/planify/mobile/data/sync/SyncScheduler.kt diff --git a/app/src/main/java/com/planify/mobile/data/notification/BootReceiver.kt b/app/src/main/java/com/planify/mobile/data/notification/BootReceiver.kt index 9f94458..9ce83ae 100644 --- a/app/src/main/java/com/planify/mobile/data/notification/BootReceiver.kt +++ b/app/src/main/java/com/planify/mobile/data/notification/BootReceiver.kt @@ -3,14 +3,17 @@ package com.planify.mobile.data.notification import android.content.BroadcastReceiver import android.content.Context import android.content.Intent +import com.planify.mobile.data.sync.SyncScheduler import dagger.hilt.android.AndroidEntryPoint +import javax.inject.Inject @AndroidEntryPoint class BootReceiver : BroadcastReceiver() { + @Inject lateinit var syncScheduler: SyncScheduler + override fun onReceive(context: Context, intent: Intent) { if (intent.action != Intent.ACTION_BOOT_COMPLETED) return - // TODO #14 : replanifier toutes les alarmes depuis la base de données - // Inject ReminderScheduler + ReminderRepository et rejouer tous les rappels actifs + syncScheduler.schedule() } } diff --git a/app/src/main/java/com/planify/mobile/data/sync/CalDavSyncWorker.kt b/app/src/main/java/com/planify/mobile/data/sync/CalDavSyncWorker.kt new file mode 100644 index 0000000..1125e56 --- /dev/null +++ b/app/src/main/java/com/planify/mobile/data/sync/CalDavSyncWorker.kt @@ -0,0 +1,37 @@ +package com.planify.mobile.data.sync + +import android.content.Context +import androidx.hilt.work.HiltWorker +import androidx.work.CoroutineWorker +import androidx.work.WorkerParameters +import com.planify.mobile.data.caldav.CalDavSyncManager +import com.planify.mobile.data.caldav.SyncResult +import com.planify.mobile.domain.repository.SourceRepository +import dagger.assisted.Assisted +import dagger.assisted.AssistedInject + +@HiltWorker +class CalDavSyncWorker @AssistedInject constructor( + @Assisted context: Context, + @Assisted params: WorkerParameters, + private val sourceRepository: SourceRepository, + private val syncManager: CalDavSyncManager, +) : CoroutineWorker(context, params) { + + override suspend fun doWork(): Result { + val sources = sourceRepository.getCaldavSources() + if (sources.isEmpty()) return Result.success() + + var hasError = false + sources.forEach { source -> + val result = syncManager.incrementalSync(source) + if (result is SyncResult.Failure) hasError = true + } + + return if (hasError) Result.retry() else Result.success() + } + + companion object { + const val WORK_NAME = "caldav_periodic_sync" + } +} diff --git a/app/src/main/java/com/planify/mobile/data/sync/SyncScheduler.kt b/app/src/main/java/com/planify/mobile/data/sync/SyncScheduler.kt new file mode 100644 index 0000000..e7e0146 --- /dev/null +++ b/app/src/main/java/com/planify/mobile/data/sync/SyncScheduler.kt @@ -0,0 +1,51 @@ +package com.planify.mobile.data.sync + +import android.content.Context +import androidx.work.Constraints +import androidx.work.ExistingPeriodicWorkPolicy +import androidx.work.NetworkType +import androidx.work.PeriodicWorkRequestBuilder +import androidx.work.WorkManager +import dagger.hilt.android.qualifiers.ApplicationContext +import java.util.concurrent.TimeUnit +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class SyncScheduler @Inject constructor( + @ApplicationContext private val context: Context, +) { + private val workManager = WorkManager.getInstance(context) + + fun schedule(intervalMinutes: Long = 30) { + val constraints = Constraints.Builder() + .setRequiredNetworkType(NetworkType.CONNECTED) + .build() + + val request = PeriodicWorkRequestBuilder( + repeatInterval = intervalMinutes, + repeatIntervalTimeUnit = TimeUnit.MINUTES, + ) + .setConstraints(constraints) + .build() + + workManager.enqueueUniquePeriodicWork( + CalDavSyncWorker.WORK_NAME, + ExistingPeriodicWorkPolicy.UPDATE, + request, + ) + } + + fun cancel() { + workManager.cancelUniqueWork(CalDavSyncWorker.WORK_NAME) + } + + fun syncNow() { + val request = androidx.work.OneTimeWorkRequestBuilder() + .setConstraints( + Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build() + ) + .build() + workManager.enqueue(request) + } +}