diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index a26be727..d2a01ae9 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -31,4 +31,5 @@ -keepclasseswithmembers class xyz.quaver.pupil.** { # <-- change package name to your app's kotlinx.serialization.KSerializer serializer(...); } --keep class xyz.quaver.pupil.** { *; } \ No newline at end of file +-keep class xyz.quaver.pupil.** { *; } +-dontwarn org.slf4j.impl.StaticLoggerBinder \ No newline at end of file diff --git a/app/release/output-metadata.json b/app/release/output-metadata.json index 87e610c3..86cb7fcd 100644 --- a/app/release/output-metadata.json +++ b/app/release/output-metadata.json @@ -12,7 +12,7 @@ "filters": [], "attributes": [], "versionCode": 69, - "versionName": "5.3.10", + "versionName": "6.0.0", "outputFile": "app-release.apk" } ], diff --git a/app/src/main/java/xyz/quaver/pupil/ui/MainActivity.kt b/app/src/main/java/xyz/quaver/pupil/ui/MainActivity.kt index 1141524a..37dc5a25 100644 --- a/app/src/main/java/xyz/quaver/pupil/ui/MainActivity.kt +++ b/app/src/main/java/xyz/quaver/pupil/ui/MainActivity.kt @@ -27,10 +27,10 @@ import androidx.compose.material3.windowsizeclass.calculateWindowSizeClass import androidx.compose.runtime.getValue import androidx.core.view.WindowCompat import androidx.lifecycle.compose.collectAsStateWithLifecycle +import androidx.navigation.compose.rememberNavController import com.google.accompanist.adaptive.calculateDisplayFeatures import xyz.quaver.pupil.ui.composable.MainApp import xyz.quaver.pupil.ui.theme.AppTheme -import xyz.quaver.pupil.ui.viewmodel.MainUIState import xyz.quaver.pupil.ui.viewmodel.MainViewModel class MainActivity : BaseActivity() { @@ -48,13 +48,15 @@ class MainActivity : BaseActivity() { val windowSize = calculateWindowSizeClass(this) val displayFeatures = calculateDisplayFeatures(this) - val uiState by viewModel.uiState.collectAsStateWithLifecycle() + val uiState by viewModel.searchState.collectAsStateWithLifecycle() + + val navController = rememberNavController() MainApp( windowSize = windowSize, displayFeatures = displayFeatures, uiState = uiState, - navigateToDestination = viewModel::navigateToDestination, + navController = navController, closeDetailScreen = viewModel::closeDetailScreen, onQueryChange = viewModel::onQueryChange, loadSearchResult = viewModel::loadSearchResult diff --git a/app/src/main/java/xyz/quaver/pupil/ui/composable/MainApp.kt b/app/src/main/java/xyz/quaver/pupil/ui/composable/MainApp.kt index c0603545..2d752c99 100644 --- a/app/src/main/java/xyz/quaver/pupil/ui/composable/MainApp.kt +++ b/app/src/main/java/xyz/quaver/pupil/ui/composable/MainApp.kt @@ -1,7 +1,11 @@ package xyz.quaver.pupil.ui.composable +import android.util.Log import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.fadeIn +import androidx.compose.animation.fadeOut import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row @@ -14,25 +18,39 @@ import androidx.compose.material3.DrawerValue import androidx.compose.material3.MaterialTheme import androidx.compose.material3.ModalNavigationDrawer import androidx.compose.material3.PermanentNavigationDrawer +import androidx.compose.material3.Text import androidx.compose.material3.rememberDrawerState import androidx.compose.material3.windowsizeclass.WindowHeightSizeClass import androidx.compose.material3.windowsizeclass.WindowSizeClass import androidx.compose.material3.windowsizeclass.WindowWidthSizeClass import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import androidx.navigation.NavHostController +import androidx.navigation.activity +import androidx.navigation.compose.NavHost +import androidx.navigation.compose.composable +import androidx.navigation.compose.currentBackStackEntryAsState import androidx.window.layout.DisplayFeature import androidx.window.layout.FoldingFeature import kotlinx.coroutines.launch +import xyz.quaver.pupil.R import xyz.quaver.pupil.networking.SearchQuery -import xyz.quaver.pupil.ui.viewmodel.MainUIState +import xyz.quaver.pupil.ui.ReaderActivity +import xyz.quaver.pupil.ui.SettingsActivity +import xyz.quaver.pupil.ui.viewmodel.SearchState @Composable fun MainApp( windowSize: WindowSizeClass, displayFeatures: List, - uiState: MainUIState, - navigateToDestination: (MainDestination) -> Unit, + uiState: SearchState, + navController: NavHostController, closeDetailScreen: () -> Unit, onQueryChange: (SearchQuery?) -> Unit, loadSearchResult: (IntRange) -> Unit @@ -87,7 +105,7 @@ fun MainApp( displayFeatures, navigationContentPosition, uiState, - navigateToDestination, + navController, closeDetailScreen = closeDetailScreen, onQueryChange = onQueryChange, loadSearchResult = loadSearchResult @@ -100,8 +118,8 @@ private fun MainNavigationWrapper( contentType: ContentType, displayFeatures: List, navigationContentPosition: NavigationContentPosition, - uiState: MainUIState, - navigateToDestination: (MainDestination) -> Unit, + uiState: SearchState, + navController: NavHostController, closeDetailScreen: () -> Unit, onQueryChange: (SearchQuery?) -> Unit, loadSearchResult: (IntRange) -> Unit @@ -109,6 +127,9 @@ private fun MainNavigationWrapper( val drawerState = rememberDrawerState(initialValue = DrawerValue.Closed) val coroutineScope = rememberCoroutineScope() + val navBackStackEntry by navController.currentBackStackEntryAsState() + val currentRoute = navBackStackEntry?.destination?.route + val openDrawer: () -> Unit = { coroutineScope.launch { drawerState.open() @@ -119,9 +140,12 @@ private fun MainNavigationWrapper( PermanentNavigationDrawer( drawerContent = { PermanentNavigationDrawerContent( - selectedDestination = uiState.currentDestination, + selectedDestination = currentRoute, + navigateToDestination = { navController.navigate(it.route) { + popUpTo(MainDestination.Search.route) + launchSingleTop = true + } }, navigationContentPosition = navigationContentPosition, - navigateToDestination = navigateToDestination ) } ) { @@ -129,9 +153,8 @@ private fun MainNavigationWrapper( navigationType = navigationType, contentType = contentType, displayFeatures = displayFeatures, - navigationContentPosition = navigationContentPosition, uiState = uiState, - navigateToDestination = navigateToDestination, + navController = navController, onDrawerClicked = openDrawer, closeDetailScreen = closeDetailScreen, onQueryChange = onQueryChange, @@ -142,9 +165,12 @@ private fun MainNavigationWrapper( ModalNavigationDrawer( drawerContent = { ModalNavigationDrawerContent( - selectedDestination = uiState.currentDestination, + selectedDestination = currentRoute, + navigateToDestination = { navController.navigate(it.route) { + popUpTo(MainDestination.Search.route) + launchSingleTop = true + } }, navigationContentPosition = navigationContentPosition, - navigateToDestination = navigateToDestination, onDrawerClicked = { coroutineScope.launch { drawerState.close() @@ -158,9 +184,8 @@ private fun MainNavigationWrapper( navigationType = navigationType, contentType = contentType, displayFeatures = displayFeatures, - navigationContentPosition = navigationContentPosition, uiState = uiState, - navigateToDestination = navigateToDestination, + navController = navController, onDrawerClicked = openDrawer, closeDetailScreen = closeDetailScreen, onQueryChange = onQueryChange, @@ -170,25 +195,43 @@ private fun MainNavigationWrapper( } } +@Composable +fun NotImplemented() { + Box(Modifier.fillMaxSize()) { + Column( + Modifier.align(Alignment.Center), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(16.dp) + ) { + Text("(⁄ ⁄•⁄ω⁄•⁄ ⁄)", style = MaterialTheme.typography.headlineMedium, color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.5f)) + Text(stringResource(R.string.not_implemented), textAlign = TextAlign.Center) + } + } +} + @Composable fun MainContent( navigationType: NavigationType, contentType: ContentType, displayFeatures: List, - navigationContentPosition: NavigationContentPosition, - uiState: MainUIState, - navigateToDestination: (MainDestination) -> Unit, + uiState: SearchState, + navController: NavHostController, onDrawerClicked: () -> Unit, closeDetailScreen: () -> Unit, onQueryChange: (SearchQuery?) -> Unit, loadSearchResult: (IntRange) -> Unit ) { + val navBackStackEntry by navController.currentBackStackEntryAsState() + val currentRoute = navBackStackEntry?.destination?.route + Row(modifier = Modifier.fillMaxSize()) { AnimatedVisibility(visible = navigationType == NavigationType.NAVIGATION_RAIL) { MainNavigationRail( - selectedDestination = uiState.currentDestination, - navigationContentPosition = navigationContentPosition, - navigateToDestination = navigateToDestination, + selectedDestination = currentRoute, + navigateToDestination = { navController.navigate(it.route) { + popUpTo(MainDestination.Search.route) + launchSingleTop = true + } }, onDrawerClicked = onDrawerClicked ) } @@ -198,27 +241,55 @@ fun MainContent( .background(MaterialTheme.colorScheme.inverseOnSurface) ) { Box( - modifier = Modifier.weight(1f) + modifier = Modifier + .weight(1f) .run { if (navigationType == NavigationType.BOTTOM_NAVIGATION) { - this.consumeWindowInsets(WindowInsets.ime) + this + .consumeWindowInsets(WindowInsets.ime) .consumeWindowInsets(WindowInsets.navigationBars) } else this } ) { - MainScreen( - contentType = contentType, - displayFeatures = displayFeatures, - uiState = uiState, - closeDetailScreen = closeDetailScreen, - onQueryChange = onQueryChange, - loadSearchResult = loadSearchResult - ) + NavHost( + modifier = Modifier.fillMaxSize(), + navController = navController, + startDestination = MainDestination.Search.route + ) { + composable(MainDestination.Search.route) { + SearchScreen( + contentType = contentType, + displayFeatures = displayFeatures, + uiState = uiState, + closeDetailScreen = closeDetailScreen, + onQueryChange = onQueryChange, + loadSearchResult = loadSearchResult + ) + } + composable(MainDestination.History.route) { + NotImplemented() + } + composable(MainDestination.Downloads.route) { + NotImplemented() + } + composable(MainDestination.Favorites.route) { + NotImplemented() + } + activity(MainDestination.Settings.route) { + activityClass = SettingsActivity::class + } + activity(MainDestination.ImageViewer.route) { + activityClass = ReaderActivity::class + } + } } AnimatedVisibility(visible = navigationType == NavigationType.BOTTOM_NAVIGATION) { BottomNavigationBar( - selectedDestination = uiState.currentDestination, - navigateToDestination = navigateToDestination + selectedDestination = currentRoute, + navigateToDestination = { navController.navigate(it.route) { + popUpTo(MainDestination.Search.route) + launchSingleTop = true + } } ) } } diff --git a/app/src/main/java/xyz/quaver/pupil/ui/composable/MainNavigationActions.kt b/app/src/main/java/xyz/quaver/pupil/ui/composable/MainNavigationActions.kt index 4eae9d17..1446d0da 100644 --- a/app/src/main/java/xyz/quaver/pupil/ui/composable/MainNavigationActions.kt +++ b/app/src/main/java/xyz/quaver/pupil/ui/composable/MainNavigationActions.kt @@ -1,10 +1,13 @@ package xyz.quaver.pupil.ui.composable import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.automirrored.filled.MenuBook import androidx.compose.material.icons.filled.Download import androidx.compose.material.icons.filled.Favorite import androidx.compose.material.icons.filled.History +import androidx.compose.material.icons.filled.MenuBook import androidx.compose.material.icons.filled.Search +import androidx.compose.material.icons.filled.Settings import androidx.compose.material.icons.filled.Star import androidx.compose.ui.graphics.vector.ImageVector import xyz.quaver.pupil.R @@ -14,34 +17,48 @@ sealed interface MainDestination { val icon: ImageVector val textId: Int - object Search: MainDestination { + data object Search: MainDestination { override val route = "search" override val icon = Icons.Default.Search override val textId = R.string.main_destination_search } - object History: MainDestination { + data object History: MainDestination { override val route = "history" override val icon = Icons.Default.History override val textId = R.string.main_destination_history } - object Downloads: MainDestination { + data object Downloads: MainDestination { override val route = "downloads" override val icon = Icons.Default.Download override val textId = R.string.main_destination_downloads } - object Favorites: MainDestination { + data object Favorites: MainDestination { override val route = "favorites" override val icon = Icons.Default.Favorite override val textId = R.string.main_destination_favorites } + + data object Settings: MainDestination { + override val route = "settings" + override val icon = Icons.Default.Settings + override val textId = R.string.main_destination_settings + } + + data object ImageViewer: MainDestination { + override val route = "image_viewer" + override val icon = Icons.AutoMirrored.Filled.MenuBook + override val textId = R.string.main_destination_image_viewer + + } } val mainDestinations = listOf( MainDestination.Search, MainDestination.History, MainDestination.Downloads, - MainDestination.Favorites + MainDestination.Favorites, + MainDestination.Settings ) \ No newline at end of file diff --git a/app/src/main/java/xyz/quaver/pupil/ui/composable/NavigationDrawerContent.kt b/app/src/main/java/xyz/quaver/pupil/ui/composable/NavigationDrawerContent.kt index 8aa9fa15..2c4547c1 100644 --- a/app/src/main/java/xyz/quaver/pupil/ui/composable/NavigationDrawerContent.kt +++ b/app/src/main/java/xyz/quaver/pupil/ui/composable/NavigationDrawerContent.kt @@ -43,13 +43,14 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.offset +import androidx.navigation.NavDestination import xyz.quaver.pupil.R @Composable fun PermanentNavigationDrawerContent( - selectedDestination: MainDestination, + selectedDestination: String?, + navigateToDestination: (MainDestination) -> Unit, navigationContentPosition: NavigationContentPosition, - navigateToDestination: (MainDestination) -> Unit ) { PermanentDrawerSheet( modifier = Modifier.sizeIn(minWidth = 200.dp, maxWidth = 300.dp), @@ -97,7 +98,7 @@ fun PermanentNavigationDrawerContent( contentDescription = stringResource(destination.textId) ) }, - selected = selectedDestination.route == destination.route, + selected = selectedDestination == destination.route, colors = NavigationDrawerItemDefaults.colors( unselectedContainerColor = Color.Transparent ), @@ -113,7 +114,7 @@ fun PermanentNavigationDrawerContent( @Composable fun ModalNavigationDrawerContent( - selectedDestination: MainDestination, + selectedDestination: String?, navigationContentPosition: NavigationContentPosition, navigateToDestination: (MainDestination) -> Unit, onDrawerClicked: () -> Unit @@ -177,7 +178,7 @@ fun ModalNavigationDrawerContent( contentDescription = stringResource(destination.textId) ) }, - selected = selectedDestination.route == destination.route, + selected = selectedDestination == destination.route, colors = NavigationDrawerItemDefaults.colors( unselectedContainerColor = Color.Transparent ), @@ -193,8 +194,7 @@ fun ModalNavigationDrawerContent( @Composable fun MainNavigationRail( - selectedDestination: MainDestination, - navigationContentPosition: NavigationContentPosition, + selectedDestination: String?, navigateToDestination: (MainDestination) -> Unit, onDrawerClicked: () -> Unit ) { @@ -220,7 +220,7 @@ fun MainNavigationRail( ) { mainDestinations.forEach { destination -> NavigationRailItem( - selected = selectedDestination.route == destination.route, + selected = selectedDestination == destination.route, onClick = { navigateToDestination(destination) }, icon = { Icon( @@ -236,13 +236,13 @@ fun MainNavigationRail( @Composable fun BottomNavigationBar( - selectedDestination: MainDestination, + selectedDestination: String?, navigateToDestination: (MainDestination) -> Unit ) { NavigationBar(modifier = Modifier.fillMaxWidth(), windowInsets = WindowInsets.ime.union(WindowInsets.navigationBars)) { mainDestinations.forEach { destination -> NavigationBarItem( - selected = selectedDestination.route == destination.route, + selected = selectedDestination == destination.route, onClick = { navigateToDestination(destination) }, icon = { Icon( diff --git a/app/src/main/java/xyz/quaver/pupil/ui/composable/MainScreen.kt b/app/src/main/java/xyz/quaver/pupil/ui/composable/SearchScreen.kt similarity index 96% rename from app/src/main/java/xyz/quaver/pupil/ui/composable/MainScreen.kt rename to app/src/main/java/xyz/quaver/pupil/ui/composable/SearchScreen.kt index 16cc0805..cc1cc583 100644 --- a/app/src/main/java/xyz/quaver/pupil/ui/composable/MainScreen.kt +++ b/app/src/main/java/xyz/quaver/pupil/ui/composable/SearchScreen.kt @@ -96,7 +96,7 @@ import xyz.quaver.pupil.networking.SearchQuery import xyz.quaver.pupil.ui.theme.Blue600 import xyz.quaver.pupil.ui.theme.Pink600 import xyz.quaver.pupil.ui.theme.Yellow400 -import xyz.quaver.pupil.ui.viewmodel.MainUIState +import xyz.quaver.pupil.ui.viewmodel.SearchState import kotlin.math.roundToInt private val iconMap = mapOf( @@ -304,7 +304,6 @@ fun SearchBar( query: SearchQuery?, onQueryChange: (SearchQuery?) -> Unit, onSearchBarPositioned: (Int) -> Unit, - onSearch: () -> Unit, topOffset: Int, onTopOffsetChange: (Int) -> Unit, content: @Composable () -> Unit @@ -404,85 +403,6 @@ fun SearchBar( } } -@Composable -fun MainScreen( - contentType: ContentType, - displayFeatures: List, - uiState: MainUIState, - closeDetailScreen: () -> Unit, - onQueryChange: (SearchQuery?) -> Unit, - loadSearchResult: (IntRange) -> Unit -) { - LaunchedEffect(contentType) { - if (contentType == ContentType.SINGLE_PANE && !uiState.isDetailOnlyOpen) { - closeDetailScreen() - } - } - - val galleryLazyListState = rememberLazyListState() - - val itemsPerPage by remember { mutableIntStateOf(20) } - - val pageToRange: (Int) -> IntRange = remember(itemsPerPage) {{ page -> - page * itemsPerPage ..< (page+1) * itemsPerPage - }} - - val currentPage = remember(uiState) { - if (uiState.currentRange != IntRange.EMPTY) { - uiState.currentRange.first / itemsPerPage - } else 0 - } - - val maxPage = remember(itemsPerPage, uiState) { - if (uiState.galleryCount != null) { - uiState.galleryCount / itemsPerPage + if (uiState.galleryCount % itemsPerPage != 0) 1 else 0 - } else 0 - } - - val loadResult: (Int) -> Unit = remember(loadSearchResult) {{ page -> - loadSearchResult(pageToRange(page)) - }} - - LaunchedEffect(uiState.query, uiState.currentDestination) { loadSearchResult(pageToRange(0)) } - - if (contentType == ContentType.DUAL_PANE) { - TwoPane( - first = { - GalleryList( - contentType = contentType, - galleries = uiState.galleries, - query = uiState.query, - currentPage = currentPage, - maxPage = maxPage, - loading = uiState.loading, - error = uiState.error, - galleryLazyListState = galleryLazyListState, - onQueryChange = onQueryChange, - onPageChange = loadResult - ) - }, - second = { - - }, - strategy = HorizontalTwoPaneStrategy(splitFraction = 0.5f, gapWidth = 16.dp), - displayFeatures = displayFeatures - ) - } else { - GalleryList( - contentType = contentType, - galleries = uiState.galleries, - query = uiState.query, - currentPage = currentPage, - maxPage = maxPage, - loading = uiState.loading, - error = uiState.error, - galleryLazyListState = galleryLazyListState, - onQueryChange = onQueryChange, - onPageChange = loadResult - ) - } -} - @Composable fun GalleryList( contentType: ContentType, @@ -492,14 +412,8 @@ fun GalleryList( maxPage: Int, loading: Boolean = false, error: Boolean = false, - openedGallery: GalleryInfo? = null, onPageChange: (Int) -> Unit, onQueryChange: (SearchQuery?) -> Unit = {}, - search: () -> Unit = {}, - selectedGalleryIds: Set = emptySet(), - toggleGallerySelection: (Int) -> Unit = {}, - galleryLazyListState: LazyListState, - navigateToDetails: (GalleryInfo, ContentType) -> Unit = { gi, ct -> } ) { val listState = rememberLazyListState() var topOffset by remember { mutableIntStateOf(0) } @@ -522,7 +436,6 @@ fun GalleryList( query = query, onQueryChange = onQueryChange, onSearchBarPositioned = { searchBarPosition = it }, - onSearch = search, topOffset = topOffset, onTopOffsetChange = { topOffset = it }, ) { @@ -563,7 +476,7 @@ fun GalleryList( verticalArrangement = Arrangement.spacedBy(8.dp), state = listState ) { - items(galleries) {galleryInfo -> + items(galleries, key = { it.id }) {galleryInfo -> DetailedGalleryInfo( modifier = Modifier .fillMaxWidth() @@ -575,4 +488,80 @@ fun GalleryList( } } } -} \ No newline at end of file +} + +@Composable +fun SearchScreen( + contentType: ContentType, + displayFeatures: List, + uiState: SearchState, + closeDetailScreen: () -> Unit, + onQueryChange: (SearchQuery?) -> Unit, + loadSearchResult: (IntRange) -> Unit +) { + LaunchedEffect(contentType) { + if (contentType == ContentType.SINGLE_PANE && !uiState.isDetailOnlyOpen) { + closeDetailScreen() + } + } + + val itemsPerPage by remember { mutableIntStateOf(20) } + + val pageToRange: (Int) -> IntRange = remember(itemsPerPage) {{ page -> + page * itemsPerPage ..< (page+1) * itemsPerPage + }} + + val currentPage = remember(uiState) { + if (uiState.currentRange != IntRange.EMPTY) { + uiState.currentRange.first / itemsPerPage + } else 0 + } + + val maxPage = remember(itemsPerPage, uiState) { + if (uiState.galleryCount != null) { + uiState.galleryCount / itemsPerPage + if (uiState.galleryCount % itemsPerPage != 0) 1 else 0 + } else 0 + } + + val loadResult: (Int) -> Unit = remember(loadSearchResult) {{ page -> + loadSearchResult(pageToRange(page)) + }} + + LaunchedEffect(uiState.query, currentPage) { loadSearchResult(pageToRange(currentPage)) } + + if (contentType == ContentType.DUAL_PANE) { + TwoPane( + first = { + GalleryList( + contentType = contentType, + galleries = uiState.galleries, + query = uiState.query, + currentPage = currentPage, + maxPage = maxPage, + loading = uiState.loading, + error = uiState.error, + onQueryChange = onQueryChange, + onPageChange = loadResult + ) + }, + second = { + + }, + strategy = HorizontalTwoPaneStrategy(splitFraction = 0.5f, gapWidth = 16.dp), + displayFeatures = displayFeatures + ) + } else { + GalleryList( + contentType = contentType, + galleries = uiState.galleries, + query = uiState.query, + currentPage = currentPage, + maxPage = maxPage, + loading = uiState.loading, + error = uiState.error, + onQueryChange = onQueryChange, + onPageChange = loadResult + ) + } +} + diff --git a/app/src/main/java/xyz/quaver/pupil/ui/viewmodel/MainViewModel.kt b/app/src/main/java/xyz/quaver/pupil/ui/viewmodel/MainViewModel.kt index 1eff43c7..af277092 100644 --- a/app/src/main/java/xyz/quaver/pupil/ui/viewmodel/MainViewModel.kt +++ b/app/src/main/java/xyz/quaver/pupil/ui/viewmodel/MainViewModel.kt @@ -9,23 +9,15 @@ import kotlinx.coroutines.launch import xyz.quaver.pupil.networking.GalleryInfo import xyz.quaver.pupil.networking.GallerySearchSource import xyz.quaver.pupil.networking.SearchQuery -import xyz.quaver.pupil.ui.composable.MainDestination -import xyz.quaver.pupil.ui.composable.mainDestinations import kotlin.math.max import kotlin.math.min class MainViewModel : ViewModel() { - private val _uiState = MutableStateFlow(MainUIState()) - val uiState: StateFlow = _uiState + private val _uiState = MutableStateFlow(SearchState()) + val searchState: StateFlow = _uiState private var searchSource: GallerySearchSource = GallerySearchSource(null) private var job: Job? = null - fun navigateToDestination(destination: MainDestination) { - _uiState.value = MainUIState( - currentDestination = destination - ) - } - fun closeDetailScreen() { _uiState.value = _uiState.value.copy( isDetailOnlyOpen = false @@ -45,7 +37,7 @@ class MainViewModel : ViewModel() { fun loadSearchResult(range: IntRange) { job?.cancel() job = viewModelScope.launch { - val sanitizedRange = max(range.first, 0) .. min(range.last, uiState.value.galleryCount ?: Int.MAX_VALUE) + val sanitizedRange = max(range.first, 0) .. min(range.last, searchState.value.galleryCount ?: Int.MAX_VALUE) _uiState.value = _uiState.value.copy( loading = true, currentRange = sanitizedRange @@ -72,8 +64,7 @@ class MainViewModel : ViewModel() { } } -data class MainUIState( - val currentDestination: MainDestination = mainDestinations.first(), +data class SearchState( val query: SearchQuery? = null, val galleries: List = emptyList(), val loading: Boolean = false, diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index ff46ca27..1ef173db 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -33,6 +33,7 @@ グロフィルター "言語: " デフォルトキーワード設定 + 設定 メニューを開く お問い合わせ先 ホームページ @@ -166,4 +167,6 @@ タグ %1$d ページへ移動 タッチして編集 + イメージビューア + この機能はまだ実装されていません \ No newline at end of file diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index d0c0518e..c97a0323 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -36,6 +36,8 @@ Github 도움말 홈페이지 + 설정 + 뷰어 메뉴 열기 문의 전체 화면 @@ -166,4 +168,5 @@ 태그 %1$d 페이지로 이동 터치하여 수정 + 이 기능은 아직 개발 중입니다 \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1ecd2b75..fb70ccb8 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -32,6 +32,8 @@ Unlimited + This feature is not implemented yet + Copied to clipboard Download @@ -57,6 +59,8 @@ History Downloads Favorites + Settings + Reader Open Navigation Drawer Close Navigation Drawer Contact