Show a screen while the app migrates after an update

This commit is contained in:
AntsyLich
2026-10-07 22:22:32 +06:00
parent a6ee4bc596
commit fd4f73c908
7 changed files with 114 additions and 5 deletions
@@ -0,0 +1,48 @@
package eu.kanade.presentation.more
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.safeDrawingPadding
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.stringResource
/**
* Shown instead of the app while migrations from the previous version run, so a slow first launch
* after an update doesn't look like the app hanging.
*/
@Composable
fun AppMigratingScreen() {
Surface(modifier = Modifier.fillMaxSize()) {
Column(
modifier = Modifier
.safeDrawingPadding()
.padding(horizontal = 32.dp),
verticalArrangement = Arrangement.spacedBy(16.dp, Alignment.CenterVertically),
horizontalAlignment = Alignment.CenterHorizontally,
) {
CircularProgressIndicator()
Text(
text = stringResource(MR.strings.app_migrating_title),
style = MaterialTheme.typography.titleLarge,
textAlign = TextAlign.Center,
)
Text(
text = stringResource(MR.strings.app_migrating_summary),
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant,
textAlign = TextAlign.Center,
)
}
}
}
@@ -72,6 +72,7 @@ import eu.kanade.presentation.components.AppStateBanners
import eu.kanade.presentation.components.DownloadedOnlyBannerBackgroundColor
import eu.kanade.presentation.components.IncognitoModeBannerBackgroundColor
import eu.kanade.presentation.components.IndexingBannerBackgroundColor
import eu.kanade.presentation.more.AppMigratingScreen
import eu.kanade.presentation.more.settings.screen.browse.ExtensionStoresScreen
import eu.kanade.presentation.more.settings.screen.data.RestoreBackupScreen
import eu.kanade.presentation.util.AssistContentScreen
@@ -95,6 +96,7 @@ import eu.kanade.tachiyomi.util.system.isNavigationBarNeedsScrim
import eu.kanade.tachiyomi.util.system.updaterEnabled
import eu.kanade.tachiyomi.util.view.setComposeContent
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.drop
@@ -107,6 +109,7 @@ import mihon.app.di.AppGraph
import mihon.app.di.appGraph
import mihon.core.metro.metroGraph
import mihon.core.migration.Migrator
import mihon.domain.database.repository.DatabaseRepository
import mihon.feature.support.SupportUsScreen
import mihon.icons.materialsymbols.MaterialSymbols
import mihon.icons.materialsymbols.automirroredrounded.OpenInNew
@@ -138,6 +141,10 @@ class MainActivity : BaseActivity() {
@Inject private lateinit var chapterCache: ChapterCache
@Inject private lateinit var databaseRepository: DatabaseRepository
private val isAppMigrating = MutableStateFlow(Migrator.isRunning)
@Inject private lateinit var getIncognitoState: GetIncognitoState
@Inject private lateinit var extensionManager: ExtensionManager
@@ -160,7 +167,10 @@ class MainActivity : BaseActivity() {
super.onCreate(savedInstanceState)
Migrator.awaitAndRelease()
lifecycleScope.launch {
Migrator.awaitAndRelease()
isAppMigrating.value = false
}
// Do not let the launcher create a new activity http://stackoverflow.com/questions/16283079
if (!isTaskRoot) {
@@ -169,6 +179,15 @@ class MainActivity : BaseActivity() {
}
setComposeContent {
val appMigrating by isAppMigrating.collectAsState()
val databaseMigrating by databaseRepository.isMigrating.collectAsState()
if (appMigrating || databaseMigrating) {
AppMigratingScreen()
// Release the splash screen so the reason for the wait shows
LaunchedEffect(Unit) { ready = true }
return@setComposeContent
}
val context = LocalContext.current
var incognito by remember { mutableStateOf(false) }