From a298cb75e2316a807971532a8b4127a8f52278dd Mon Sep 17 00:00:00 2001 From: acite <1498045907@qq.com> Date: Sat, 20 Sep 2025 14:16:46 +0800 Subject: [PATCH] [fix] Crash when page initialized before view model --- .../com/acitelight/aether/view/ComicScreen.kt | 2 +- .../com/acitelight/aether/view/VideoScreen.kt | 282 +++++++++--------- .../aether/viewModel/VideoScreenViewModel.kt | 6 +- 3 files changed, 153 insertions(+), 137 deletions(-) diff --git a/app/src/main/java/com/acitelight/aether/view/ComicScreen.kt b/app/src/main/java/com/acitelight/aether/view/ComicScreen.kt index 7c93dff..02203e9 100644 --- a/app/src/main/java/com/acitelight/aether/view/ComicScreen.kt +++ b/app/src/main/java/com/acitelight/aether/view/ComicScreen.kt @@ -187,7 +187,7 @@ fun ComicScreen( HorizontalDivider(thickness = 1.5.dp) LazyVerticalStaggeredGrid( - columns = StaggeredGridCells.Adaptive(128.dp), + columns = StaggeredGridCells.Adaptive(136.dp), contentPadding = PaddingValues(8.dp), verticalItemSpacing = 8.dp, horizontalArrangement = Arrangement.spacedBy(8.dp), diff --git a/app/src/main/java/com/acitelight/aether/view/VideoScreen.kt b/app/src/main/java/com/acitelight/aether/view/VideoScreen.kt index 4579003..cebcadf 100644 --- a/app/src/main/java/com/acitelight/aether/view/VideoScreen.kt +++ b/app/src/main/java/com/acitelight/aether/view/VideoScreen.kt @@ -118,156 +118,168 @@ fun VideoScreen( val tabIndex by videoScreenViewModel.tabIndex var menuVisibility by videoScreenViewModel.menuVisibility var searchFilter by videoScreenViewModel.searchFilter + var doneInit by videoScreenViewModel.doneInit - CardPage(title = "Videos") { - Box(Modifier.fillMaxSize()) - { - Column( - modifier = Modifier.fillMaxSize() - ) { - // TopRow(videoScreenViewModel); - Row(Modifier.padding(bottom = 4.dp)) - { - Card( - shape = RoundedCornerShape(8.dp), - colors = CardDefaults.cardColors(containerColor = colorScheme.primary), - modifier = Modifier - .align(Alignment.CenterVertically) - .padding(horizontal = 2.dp) - .size(36.dp), - onClick = { - menuVisibility = !menuVisibility - }) + if (doneInit) + CardPage(title = "Videos") { + Box(Modifier.fillMaxSize()) + { + Column( + modifier = Modifier.fillMaxSize() + ) { + // TopRow(videoScreenViewModel); + Row(Modifier.padding(bottom = 4.dp)) { - Box(Modifier.fillMaxSize()) + Card( + shape = RoundedCornerShape(8.dp), + colors = CardDefaults.cardColors(containerColor = colorScheme.primary), + modifier = Modifier + .align(Alignment.CenterVertically) + .padding(horizontal = 2.dp) + .size(36.dp), + onClick = { + menuVisibility = !menuVisibility + }) { + Box(Modifier.fillMaxSize()) + { + Icon( + modifier = Modifier + .size(30.dp) + .align(Alignment.Center), + imageVector = Icons.Default.Menu, + contentDescription = "Catalogue" + ) + } + } + + Card( + shape = RoundedCornerShape(8.dp), + colors = CardDefaults.cardColors(containerColor = colorScheme.primary), + modifier = Modifier + .align(Alignment.CenterVertically) + .padding(horizontal = 2.dp) + .height(36.dp), + onClick = { + menuVisibility = !menuVisibility + }) + { + Box(Modifier.fillMaxHeight()) + { + Text( + text = videoScreenViewModel.videoLibrary.classes.getOrNull( + tabIndex + ) + ?: "", + style = MaterialTheme.typography.bodyLarge, + fontWeight = FontWeight.Bold, + modifier = Modifier + .align(Alignment.CenterStart) + .padding(horizontal = 8.dp), + maxLines = 1 + ) + } + } + + Row( + modifier = Modifier + .height(36.dp) + .widthIn(max = 240.dp) + .background(colorScheme.primary, RoundedCornerShape(8.dp)) + .padding(horizontal = 6.dp) + ) { Icon( modifier = Modifier .size(30.dp) - .align(Alignment.Center), - imageVector = Icons.Default.Menu, + .align(Alignment.CenterVertically), + imageVector = Icons.Default.Search, contentDescription = "Catalogue" ) - } - } - - Card( - shape = RoundedCornerShape(8.dp), - colors = CardDefaults.cardColors(containerColor = colorScheme.primary), - modifier = Modifier - .align(Alignment.CenterVertically) - .padding(horizontal = 2.dp) - .height(36.dp), - onClick = { - menuVisibility = !menuVisibility - }) - { - Box(Modifier.fillMaxHeight()) - { - Text( - text = videoScreenViewModel.videoLibrary.classes.getOrNull(tabIndex) - ?: "", - style = MaterialTheme.typography.bodyLarge, - fontWeight = FontWeight.Bold, - modifier = Modifier - .align(Alignment.CenterStart) - .padding(horizontal = 8.dp), - maxLines = 1 - ) - } - } - - Row( - modifier = Modifier - .height(36.dp).widthIn(max = 240.dp) - .background(colorScheme.primary, RoundedCornerShape(8.dp)) - .padding(horizontal = 6.dp) - ) { - Icon( - modifier = Modifier - .size(30.dp).align(Alignment.CenterVertically), - imageVector = Icons.Default.Search, - contentDescription = "Catalogue" - ) - Spacer(Modifier.width(4.dp)) - BasicTextField( - value = searchFilter, - onValueChange = { searchFilter = it }, - textStyle = LocalTextStyle.current.copy( - fontSize = 18.sp, - color = Color.White, - textAlign = TextAlign.Start - ), - singleLine = true, - modifier = Modifier.align(Alignment.CenterVertically) - ) - } - } - HorizontalDivider(Modifier.padding(bottom = 8.dp), 1.5.dp, DividerDefaults.color) - LazyVerticalStaggeredGrid( - columns = StaggeredGridCells.Adaptive(160.dp), - contentPadding = PaddingValues(8.dp), - verticalItemSpacing = 8.dp, - horizontalArrangement = androidx.compose.foundation.layout.Arrangement.spacedBy(8.dp), - state = state, - modifier = Modifier.fillMaxSize() - ) { - items( - items = videoScreenViewModel.videoLibrary.classesMap.getOrDefault( - videoScreenViewModel.videoLibrary.classes.getOrNull( - tabIndex - ), listOf() - ).filter { it.video.name.contains(searchFilter) }, - key = { "${it.klass}/${it.id}" } - ) { video -> - androidx.compose.foundation.layout.Box( - modifier = Modifier - .fillMaxWidth() - .wrapContentHeight() - ) { - VideoCard(video, navController, videoScreenViewModel) - } - } - } - } - - AnimatedVisibility( - visible = menuVisibility, - enter = slideInHorizontally(initialOffsetX = { full -> full }), - exit = slideOutHorizontally(targetOffsetX = { full -> full }), - modifier = Modifier.align(Alignment.CenterEnd) - ) { - Card( - Modifier - .fillMaxHeight() - .width(200.dp) - .align(Alignment.CenterEnd), - shape = RoundedCornerShape(8.dp), - colors = CardDefaults.cardColors(containerColor = colorScheme.surface) - ) - { - LazyColumn { - items(videoScreenViewModel.videoLibrary.classes) { item -> - CatalogueItemRow( - item = Pair( - videoScreenViewModel.videoLibrary.classes.indexOf(item), - item + Spacer(Modifier.width(4.dp)) + BasicTextField( + value = searchFilter, + onValueChange = { searchFilter = it }, + textStyle = LocalTextStyle.current.copy( + fontSize = 18.sp, + color = Color.White, + textAlign = TextAlign.Start ), - onItemClick = { - menuVisibility = false - videoScreenViewModel.setTabIndex( - videoScreenViewModel.videoLibrary.classes.indexOf( - item - ) - ) - } + singleLine = true, + modifier = Modifier.align(Alignment.CenterVertically) ) } } + HorizontalDivider( + Modifier.padding(bottom = 8.dp), + 1.5.dp, + DividerDefaults.color + ) + LazyVerticalStaggeredGrid( + columns = StaggeredGridCells.Adaptive(160.dp), + contentPadding = PaddingValues(8.dp), + verticalItemSpacing = 8.dp, + horizontalArrangement = androidx.compose.foundation.layout.Arrangement.spacedBy( + 8.dp + ), + state = state, + modifier = Modifier.fillMaxSize() + ) { + items( + items = videoScreenViewModel.videoLibrary.classesMap.getOrDefault( + videoScreenViewModel.videoLibrary.classes.getOrNull( + tabIndex + ), listOf() + ).filter { it.video.name.contains(searchFilter) }, + key = { "${it.klass}/${it.id}" } + ) { video -> + androidx.compose.foundation.layout.Box( + modifier = Modifier + .fillMaxWidth() + .wrapContentHeight() + ) { + VideoCard(video, navController, videoScreenViewModel) + } + } + } + } + + AnimatedVisibility( + visible = menuVisibility, + enter = slideInHorizontally(initialOffsetX = { full -> full }), + exit = slideOutHorizontally(targetOffsetX = { full -> full }), + modifier = Modifier.align(Alignment.CenterEnd) + ) { + Card( + Modifier + .fillMaxHeight() + .width(200.dp) + .align(Alignment.CenterEnd), + shape = RoundedCornerShape(8.dp), + colors = CardDefaults.cardColors(containerColor = colorScheme.surface) + ) + { + LazyColumn { + items(videoScreenViewModel.videoLibrary.classes) { item -> + CatalogueItemRow( + item = Pair( + videoScreenViewModel.videoLibrary.classes.indexOf(item), + item + ), + onItemClick = { + menuVisibility = false + videoScreenViewModel.setTabIndex( + videoScreenViewModel.videoLibrary.classes.indexOf( + item + ) + ) + } + ) + } + } + } } } } - } } @Composable diff --git a/app/src/main/java/com/acitelight/aether/viewModel/VideoScreenViewModel.kt b/app/src/main/java/com/acitelight/aether/viewModel/VideoScreenViewModel.kt index 5af19f6..cc986ef 100644 --- a/app/src/main/java/com/acitelight/aether/viewModel/VideoScreenViewModel.kt +++ b/app/src/main/java/com/acitelight/aether/viewModel/VideoScreenViewModel.kt @@ -47,6 +47,7 @@ class VideoScreenViewModel @Inject constructor( var imageLoader: ImageLoader? = null; var menuVisibility = mutableStateOf(false) var searchFilter = mutableStateOf("") + var doneInit = mutableStateOf(false) suspend fun init() { fetchManager.configured.filter { it }.first() @@ -69,7 +70,8 @@ class VideoScreenViewModel @Inject constructor( val r = vl.sortedWith(compareBy(naturalOrder()) { it.video.name }) videoLibrary.classesMap[videoLibrary.classes[0]]?.addAll(r) } - } else { + } + else { videoLibrary.classes.add("Offline") videoLibrary.updatingMap[0] = true videoLibrary.classesMap["Offline"] = mutableStateListOf