fix(backup-job): Fix disappearing backup job (#1250)

* fix(backup-job): Fix disappearing backup job

* optimize

* localization

* fix string resource

* try/catch exception on workinfo
This commit is contained in:
Cuong-Tran 2025-10-27 11:33:35 +07:00 committed by GitHub
parent 317a21adc0
commit 212e0d8a45
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 56 additions and 0 deletions

View file

@ -23,6 +23,7 @@ import eu.kanade.tachiyomi.util.system.cancelNotification
import eu.kanade.tachiyomi.util.system.isRunning import eu.kanade.tachiyomi.util.system.isRunning
import eu.kanade.tachiyomi.util.system.setForegroundSafely import eu.kanade.tachiyomi.util.system.setForegroundSafely
import eu.kanade.tachiyomi.util.system.workManager import eu.kanade.tachiyomi.util.system.workManager
import kotlinx.coroutines.guava.await
import logcat.LogPriority import logcat.LogPriority
import tachiyomi.core.common.util.system.logcat import tachiyomi.core.common.util.system.logcat
import tachiyomi.domain.backup.service.BackupPreferences import tachiyomi.domain.backup.service.BackupPreferences
@ -125,6 +126,24 @@ class BackupCreateJob(private val context: Context, workerParams: WorkerParamete
.build() .build()
context.workManager.enqueueUniqueWork(TAG_MANUAL, ExistingWorkPolicy.KEEP, request) context.workManager.enqueueUniqueWork(TAG_MANUAL, ExistingWorkPolicy.KEEP, request)
} }
// KMK -->
/**
* Returns true if a periodic backup job is currently scheduled.
* @param context The application context.
* @return True if a periodic backup job is scheduled, false otherwise.
* @throws Exception If there is an error retrieving the work info.
*/
suspend fun isPeriodicBackupScheduled(context: Context): Boolean {
val workInfos = context.workManager
.getWorkInfosForUniqueWork(TAG_AUTO)
.await()
return workInfos.any { workInfo ->
!workInfo.state.isFinished
}
}
// KMK <--
} }
} }

View file

@ -10,6 +10,7 @@ import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.os.Looper import android.os.Looper
import android.view.View import android.view.View
import android.widget.Toast
import androidx.activity.ComponentActivity import androidx.activity.ComponentActivity
import androidx.activity.SystemBarStyle import androidx.activity.SystemBarStyle
import androidx.activity.enableEdgeToEdge import androidx.activity.enableEdgeToEdge
@ -73,6 +74,7 @@ import eu.kanade.tachiyomi.BuildConfig
import eu.kanade.tachiyomi.data.BackupRestoreStatus import eu.kanade.tachiyomi.data.BackupRestoreStatus
import eu.kanade.tachiyomi.data.LibraryUpdateStatus import eu.kanade.tachiyomi.data.LibraryUpdateStatus
import eu.kanade.tachiyomi.data.SyncStatus import eu.kanade.tachiyomi.data.SyncStatus
import eu.kanade.tachiyomi.data.backup.create.BackupCreateJob
import eu.kanade.tachiyomi.data.cache.ChapterCache import eu.kanade.tachiyomi.data.cache.ChapterCache
import eu.kanade.tachiyomi.data.coil.MangaCoverMetadata import eu.kanade.tachiyomi.data.coil.MangaCoverMetadata
import eu.kanade.tachiyomi.data.connections.discord.DiscordRPCService import eu.kanade.tachiyomi.data.connections.discord.DiscordRPCService
@ -101,6 +103,7 @@ import eu.kanade.tachiyomi.util.view.setComposeContent
import exh.debug.DebugToggles import exh.debug.DebugToggles
import exh.eh.EHentaiUpdateWorker import exh.eh.EHentaiUpdateWorker
import exh.log.DebugModeOverlay import exh.log.DebugModeOverlay
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.callbackFlow import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.collectLatest
@ -109,10 +112,12 @@ import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import logcat.LogPriority import logcat.LogPriority
import mihon.core.migration.Migrator import mihon.core.migration.Migrator
import mihon.core.migration.Migrator.scope import mihon.core.migration.Migrator.scope
import tachiyomi.core.common.Constants import tachiyomi.core.common.Constants
import tachiyomi.core.common.i18n.stringResource
import tachiyomi.core.common.preference.Preference import tachiyomi.core.common.preference.Preference
import tachiyomi.core.common.preference.PreferenceStore import tachiyomi.core.common.preference.PreferenceStore
import tachiyomi.core.common.util.lang.launchIO import tachiyomi.core.common.util.lang.launchIO
@ -121,6 +126,8 @@ import tachiyomi.domain.UnsortedPreferences
import tachiyomi.domain.backup.service.BackupPreferences import tachiyomi.domain.backup.service.BackupPreferences
import tachiyomi.domain.library.service.LibraryPreferences import tachiyomi.domain.library.service.LibraryPreferences
import tachiyomi.domain.release.interactor.GetApplicationRelease import tachiyomi.domain.release.interactor.GetApplicationRelease
import tachiyomi.i18n.MR
import tachiyomi.i18n.kmk.KMR
import tachiyomi.presentation.core.components.material.Scaffold import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.util.collectAsState import tachiyomi.presentation.core.util.collectAsState
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
@ -376,6 +383,9 @@ class MainActivity : BaseActivity() {
HandleOnNewIntent(context = context, navigator = navigator) HandleOnNewIntent(context = context, navigator = navigator)
// KMK -->
RearmJobs()
// KMK <--
CheckForUpdates() CheckForUpdates()
ShowOnboarding() ShowOnboarding()
} }
@ -493,6 +503,32 @@ class MainActivity : BaseActivity() {
} }
} }
// KMK -->
@Composable
private fun RearmJobs() {
val context = LocalContext.current
LaunchedEffect(Unit) {
launchIO {
try {
if (!BackupCreateJob.isPeriodicBackupScheduled(context)) {
BackupCreateJob.setupTask(context)
}
} catch (e: Exception) {
logcat(LogPriority.ERROR, e)
withContext(Dispatchers.Main) {
Toast.makeText(
context,
stringResource(KMR.strings.job_failed_schedule_update_check, stringResource(MR.strings.unknown_error)),
Toast.LENGTH_LONG,
).show()
}
}
}
}
}
// KMK <--
@Composable @Composable
private fun CheckForUpdates() { private fun CheckForUpdates() {
val context = LocalContext.current val context = LocalContext.current

View file

@ -173,6 +173,7 @@
<string name="current_">Current: %1$s</string> <string name="current_">Current: %1$s</string>
<string name="migrating_all_entries">Migrating all entries from source</string> <string name="migrating_all_entries">Migrating all entries from source</string>
<!-- Misc --> <!-- Misc -->
<string name="job_failed_schedule_update_check">Failed to schedule automatic backup: %s</string>
<string name="label_to_be_updated">To be updated</string> <string name="label_to_be_updated">To be updated</string>
<string name="sponsor_me">Sponsor Me</string> <string name="sponsor_me">Sponsor Me</string>
<string name="batch_add_description">Support: MangaDex, E-H, ExH, nH, 8Muses, Tsumino</string> <string name="batch_add_description">Support: MangaDex, E-H, ExH, nH, 8Muses, Tsumino</string>