@@ -41,13 +41,24 @@ import kotlinx.coroutines.Dispatchers
4141import kotlinx.coroutines.isActive
4242import kotlinx.coroutines.launch
4343import kotlinx.coroutines.withContext
44+ import com.bytecats.metanoia.ui.effects.cyberpunkHudBackground
45+ import com.bytecats.metanoia.ui.effects.cyberpunkGlowAura
46+ import androidx.compose.animation.core.withInfiniteAnimationFrameMillis
4447
4548@OptIn(ExperimentalMaterial3Api ::class , ExperimentalLayoutApi ::class , ExperimentalFoundationApi ::class )
4649@Composable
4750fun BibleScreen (viewModel : MainViewModel , onNavigateToSettings : () -> Unit = {}) {
4851 val bibleManager = viewModel.bibleManager
4952 val settings = viewModel.settingsManager
5053 val narration by viewModel.narrationState
54+
55+ val time by produceState(initialValue = 0f ) {
56+ while (true ) {
57+ withInfiniteAnimationFrameMillis {
58+ value = it / 1000f
59+ }
60+ }
61+ }
5162
5263 var step by remember { mutableStateOf(" book" ) }
5364 var selectedBook by remember { mutableStateOf<BibleBook ?>(null ) }
@@ -126,6 +137,7 @@ fun BibleScreen(viewModel: MainViewModel, onNavigateToSettings: () -> Unit = {})
126137 }
127138
128139 Scaffold (
140+ modifier = Modifier .cyberpunkHudBackground(time),
129141 topBar = {
130142 Column {
131143 TopAppBar (
@@ -214,7 +226,9 @@ fun BibleScreen(viewModel: MainViewModel, onNavigateToSettings: () -> Unit = {})
214226 val lerpedColorInt = ReadingStats .lerpColor(baseColor, readGreen, progress)
215227 val containerColor = if (progress > 0f ) Color (lerpedColorInt).copy(alpha = if (progress >= 1f ) 0.35f else 0.2f ) else MaterialTheme .colorScheme.surfaceVariant.copy(alpha = 0.4f )
216228 Card (
217- modifier = Modifier .padding(4 .dp).height(68 .dp).combinedClickable(
229+ modifier = Modifier .padding(4 .dp).height(68 .dp).let {
230+ if (progress >= 1f ) it.cyberpunkGlowAura(time, Color (0xFF9ece6a ).copy(alpha = 0.3f )) else it
231+ }.combinedClickable(
218232 onClick = { selectedBook = book; step = " chapter" ; isSearchVisible = false },
219233 onLongClick = { haptic.performHapticFeedback(HapticFeedbackType .LongPress ); modalBook = book }
220234 ),
@@ -282,7 +296,9 @@ fun BibleScreen(viewModel: MainViewModel, onNavigateToSettings: () -> Unit = {})
282296 val wordCount = chapterWordCounts[ch] ? : 0
283297 val isDownloaded = downloadedChapters.contains(ch)
284298 Card (
285- modifier = Modifier .padding(4 .dp).aspectRatio(1f ).clickable {
299+ modifier = Modifier .padding(4 .dp).aspectRatio(1f ).let {
300+ if (isDownloaded) it.cyberpunkGlowAura(time, Color (0xFF9ece6a ).copy(alpha = 0.2f )) else it
301+ }.clickable {
286302 selectedChapter = ch;
287303 currentChapterContent = bibleManager.getChapter(selectedBook!! .name, ch);
288304 highlights = bibleManager.getHighlights(selectedBook!! .name, ch);
@@ -425,7 +441,14 @@ fun BibleScreen(viewModel: MainViewModel, onNavigateToSettings: () -> Unit = {})
425441 scope.launch {
426442 isDownloadingBook = true
427443 try {
428- for (ch in 1 .. targetBook.chapters) {
444+ val existing = withContext(Dispatchers .IO ) { bibleManager.getDownloadedChapters(targetBook.name) }
445+ val maxExisting = existing.maxOrNull() ? : 0
446+ // Start from maxExisting (re-download last chapter just in case) or 1
447+ val startCh = if (maxExisting > 0 ) maxExisting else 1
448+ for (ch in startCh.. targetBook.chapters) {
449+ if (existing.contains(ch) && ch < maxExisting) {
450+ continue // Skip already completed chapters
451+ }
429452 downloadStatusText = " Downloading Chapter $ch / ${targetBook.chapters} ..."
430453 withContext(Dispatchers .IO ) {
431454 bibleManager.scrapeChapter(targetBook.name, ch, settings.bibleGatewayVersion)
0 commit comments