diff --git a/app/src/main/java/com/example/research/data/repository/LocalDictionaryRepository.kt b/app/src/main/java/com/example/research/data/repository/LocalDictionaryRepository.kt index 13ece3d..d367e42 100644 --- a/app/src/main/java/com/example/research/data/repository/LocalDictionaryRepository.kt +++ b/app/src/main/java/com/example/research/data/repository/LocalDictionaryRepository.kt @@ -195,6 +195,18 @@ class LocalDictionaryRepository( val lastEmittedPercent = AtomicInteger(-1) val lastProgressEmitMs = AtomicLong(0L) + val publishCurrentProgress = { + val tracker = progressTracker + if (tracker != null) { + val progress = tracker.progress() + lastEmittedPercent.set((progress * 100f).toInt().coerceIn(0, 100)) + lastProgressEmitMs.set(SystemClock.elapsedRealtime()) + mutableIndexingProgress.update { p -> + p.copy(progress = progress) + } + } + } + supervisorScope { filesToIndex.map { file -> async { @@ -228,6 +240,7 @@ class LocalDictionaryRepository( if (res is OperationResult.Success) { progressTracker?.updateFileProgress(file.name, 1.0f) + publishCurrentProgress() totalArticlesIndexed.addAndGet(res.data.articleCount) val dictionary = res.data addDictionary(dictionary) diff --git a/app/src/main/java/com/example/research/ui/settings/components/DictionaryProgressSection.kt b/app/src/main/java/com/example/research/ui/settings/components/DictionaryProgressSection.kt index cfe5d3c..0dfccec 100644 --- a/app/src/main/java/com/example/research/ui/settings/components/DictionaryProgressSection.kt +++ b/app/src/main/java/com/example/research/ui/settings/components/DictionaryProgressSection.kt @@ -1,8 +1,8 @@ package com.example.research.ui.settings.components import androidx.compose.animation.AnimatedVisibility -import androidx.compose.animation.core.FastOutSlowInEasing -import androidx.compose.animation.core.animateFloatAsState +import androidx.compose.animation.core.Animatable +import androidx.compose.animation.core.LinearEasing import androidx.compose.animation.core.tween import androidx.compose.animation.expandVertically import androidx.compose.animation.fadeIn @@ -19,6 +19,10 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import com.example.research.R +private const val MILLIS_PER_PROGRESS_UNIT = 10_000 +private const val MIN_PROGRESS_MOTION_MS = 50 +private const val MAX_PROGRESS_MOTION_MS = 650 + @Composable fun DictionaryProgressSection( visible: Boolean, @@ -58,11 +62,21 @@ fun DictionaryProgressSection( displayedTestTag = testTag } } - val animatedProgress by animateFloatAsState( - targetValue = monotonicTargetProgress, - animationSpec = tween(durationMillis = 650, easing = FastOutSlowInEasing), - label = "dictionary-progress" - ) + val animatedState = remember { Animatable(0f) } + LaunchedEffect(monotonicTargetProgress) { + val delta = monotonicTargetProgress - animatedState.value + if (delta > 0f) { + animatedState.animateTo( + targetValue = monotonicTargetProgress, + animationSpec = tween( + durationMillis = (delta * MILLIS_PER_PROGRESS_UNIT).toInt() + .coerceIn(MIN_PROGRESS_MOTION_MS, MAX_PROGRESS_MOTION_MS), + easing = LinearEasing, + ), + ) + } + } + val animatedProgress = animatedState.value Column(modifier = Modifier.testTag(displayedTestTag)) { Row(