From 20ddf04614c60f80be7a0c200cdf133dcadb66e9 Mon Sep 17 00:00:00 2001 From: tom5079 Date: Sun, 19 Dec 2021 12:33:47 +0900 Subject: [PATCH] Insets Nested navigation Hitomi main actions --- .idea/deploymentTargetDropDown.xml | 2 +- .../java/xyz/quaver/pupil/sources/Common.kt | 11 +-- .../sources/composable/FloatingSearchBar.kt | 26 ++--- .../sources/composable/ListSearchResult.kt | 4 +- .../MultipleFloatingActionButton.kt | 2 + .../pupil/sources/composable/ReaderBase.kt | 25 ++++- .../pupil/sources/composable/SearchBase.kt | 69 ++++++++----- .../xyz/quaver/pupil/sources/hitomi/Hitomi.kt | 97 ++++++++++++++++--- .../hitomi/HitomiSearchResultViewModel.kt | 8 +- .../java/xyz/quaver/pupil/ui/MainActivity.kt | 34 +++---- .../pupil/ui/viewmodel/MainViewModel.kt | 45 --------- 11 files changed, 192 insertions(+), 131 deletions(-) delete mode 100644 app/src/main/java/xyz/quaver/pupil/ui/viewmodel/MainViewModel.kt diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml index ec0d83c0..8ec0174f 100644 --- a/.idea/deploymentTargetDropDown.xml +++ b/.idea/deploymentTargetDropDown.xml @@ -12,6 +12,6 @@ - + \ No newline at end of file diff --git a/app/src/main/java/xyz/quaver/pupil/sources/Common.kt b/app/src/main/java/xyz/quaver/pupil/sources/Common.kt index 40c015f1..a747af3f 100644 --- a/app/src/main/java/xyz/quaver/pupil/sources/Common.kt +++ b/app/src/main/java/xyz/quaver/pupil/sources/Common.kt @@ -19,8 +19,8 @@ package xyz.quaver.pupil.sources import android.app.Application -import androidx.compose.runtime.Composable import androidx.navigation.NavController +import androidx.navigation.NavGraphBuilder import org.kodein.di.* import xyz.quaver.pupil.sources.hitomi.Hitomi @@ -28,14 +28,7 @@ abstract class Source { abstract val name: String abstract val iconResID: Int - @Composable - open fun MainScreen(navController: NavController) { } - - @Composable - open fun Search(navController: NavController) { } - - @Composable - open fun Reader(navController: NavController) { } + open fun NavGraphBuilder.navGraph(navController: NavController) { } } typealias SourceEntry = Pair diff --git a/app/src/main/java/xyz/quaver/pupil/sources/composable/FloatingSearchBar.kt b/app/src/main/java/xyz/quaver/pupil/sources/composable/FloatingSearchBar.kt index ded774bd..57a7f027 100644 --- a/app/src/main/java/xyz/quaver/pupil/sources/composable/FloatingSearchBar.kt +++ b/app/src/main/java/xyz/quaver/pupil/sources/composable/FloatingSearchBar.kt @@ -24,10 +24,7 @@ import androidx.compose.foundation.layout.* import androidx.compose.foundation.text.BasicTextField import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.material.Card -import androidx.compose.material.Icon -import androidx.compose.material.MaterialTheme -import androidx.compose.material.Text +import androidx.compose.material.* import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Close import androidx.compose.runtime.* @@ -80,7 +77,8 @@ fun FloatingSearchBar( elevation = 8.dp ) { Row( - modifier = Modifier.fillMaxSize().padding(16.dp, 0.dp), + modifier = Modifier + .fillMaxSize(), verticalAlignment = Alignment.CenterVertically ) { navigationIcon() @@ -91,14 +89,15 @@ fun FloatingSearchBar( .padding(16.dp, 0.dp) .onFocusChanged { if (it.isFocused) onTextFieldFocused() - else onTextFieldUnfocused() + else onTextFieldUnfocused() isFocused = it.isFocused }, value = query, onValueChange = onQueryChange, singleLine = true, - cursorBrush = SolidColor(MaterialTheme.colors.primary), + textStyle = LocalTextStyle.current.copy(color = MaterialTheme.colors.onSurface), + cursorBrush = SolidColor(MaterialTheme.colors.secondary), keyboardOptions = KeyboardOptions(imeAction = ImeAction.Search), keyboardActions = KeyboardActions( onSearch = { @@ -129,11 +128,14 @@ fun FloatingSearchBar( } ) - Row( - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(24.dp), - content = actions - ) + CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.medium) { + Row( + Modifier.fillMaxHeight(), + horizontalArrangement = Arrangement.End, + verticalAlignment = Alignment.CenterVertically, + content = actions + ) + } } } } \ No newline at end of file diff --git a/app/src/main/java/xyz/quaver/pupil/sources/composable/ListSearchResult.kt b/app/src/main/java/xyz/quaver/pupil/sources/composable/ListSearchResult.kt index 78af1e79..2c118053 100644 --- a/app/src/main/java/xyz/quaver/pupil/sources/composable/ListSearchResult.kt +++ b/app/src/main/java/xyz/quaver/pupil/sources/composable/ListSearchResult.kt @@ -28,10 +28,10 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp @Composable -fun ListSearchResult(searchResults: List, content: @Composable (T) -> Unit) { +fun ListSearchResult(searchResults: List, contentPadding: PaddingValues = PaddingValues(0.dp), content: @Composable (T) -> Unit) { LazyColumn( Modifier.fillMaxSize(), - contentPadding = PaddingValues(0.dp, 64.dp, 0.dp, 0.dp), + contentPadding = contentPadding, verticalArrangement = Arrangement.spacedBy(8.dp) ) { items(searchResults) { itemInfo -> diff --git a/app/src/main/java/xyz/quaver/pupil/sources/composable/MultipleFloatingActionButton.kt b/app/src/main/java/xyz/quaver/pupil/sources/composable/MultipleFloatingActionButton.kt index 203adf21..4407b93e 100644 --- a/app/src/main/java/xyz/quaver/pupil/sources/composable/MultipleFloatingActionButton.kt +++ b/app/src/main/java/xyz/quaver/pupil/sources/composable/MultipleFloatingActionButton.kt @@ -126,6 +126,7 @@ private class FloatingActionButtonItemProvider : PreviewParameterProvider, + modifier: Modifier = Modifier, fabIcon: ImageVector = Icons.Default.Add, visible: Boolean = true, targetState: FloatingActionButtonState = FloatingActionButtonState.COLLAPSED, @@ -150,6 +151,7 @@ fun MultipleFloatingActionButton( if (!visible) onStateChanged?.invoke(FloatingActionButtonState.COLLAPSED) Column( + modifier = modifier, horizontalAlignment = Alignment.End, verticalArrangement = Arrangement.spacedBy(12.dp) ) { diff --git a/app/src/main/java/xyz/quaver/pupil/sources/composable/ReaderBase.kt b/app/src/main/java/xyz/quaver/pupil/sources/composable/ReaderBase.kt index 9bd6227a..d358c808 100644 --- a/app/src/main/java/xyz/quaver/pupil/sources/composable/ReaderBase.kt +++ b/app/src/main/java/xyz/quaver/pupil/sources/composable/ReaderBase.kt @@ -41,6 +41,11 @@ import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.viewModelScope +import com.google.accompanist.insets.LocalWindowInsets +import com.google.accompanist.insets.rememberInsetsPaddingValues +import com.google.accompanist.insets.ui.Scaffold +import com.google.accompanist.insets.ui.TopAppBar +import com.google.accompanist.systemuicontroller.rememberSystemUiController import io.ktor.client.request.* import io.ktor.http.* import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -172,6 +177,16 @@ fun ReaderBase( } } + val systemUiController = rememberSystemUiController() + val useDarkIcons = MaterialTheme.colors.isLight + + SideEffect { + systemUiController.setSystemBarsColor( + color = Color.Transparent, + darkIcons = useDarkIcons + ) + } + Scaffold( topBar = { if (!model.isFullscreen) @@ -186,7 +201,11 @@ fun ReaderBase( }, actions = { //TODO - } + }, + contentPadding = rememberInsetsPaddingValues( + LocalWindowInsets.current.statusBars, + applyBottom = false + ) ) }, floatingActionButton = { @@ -208,8 +227,8 @@ fun ReaderBase( }, scaffoldState = scaffoldState, snackbarHost = { scaffoldState.snackbarHostState } - ) { - Box { + ) { contentPadding -> + Box(Modifier.padding(contentPadding)) { LazyColumn( Modifier.fillMaxSize(), verticalArrangement = Arrangement.spacedBy(4.dp) diff --git a/app/src/main/java/xyz/quaver/pupil/sources/composable/SearchBase.kt b/app/src/main/java/xyz/quaver/pupil/sources/composable/SearchBase.kt index e2a53cde..23aa3d36 100644 --- a/app/src/main/java/xyz/quaver/pupil/sources/composable/SearchBase.kt +++ b/app/src/main/java/xyz/quaver/pupil/sources/composable/SearchBase.kt @@ -24,20 +24,18 @@ import androidx.compose.animation.core.animateFloat import androidx.compose.animation.core.animateFloatAsState import androidx.compose.animation.core.updateTransition import androidx.compose.foundation.Canvas -import androidx.compose.foundation.clickable import androidx.compose.foundation.gestures.awaitFirstDown import androidx.compose.foundation.gestures.forEachGesture -import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.* import androidx.compose.material.* import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.NavigateBefore import androidx.compose.material.icons.filled.NavigateNext -import androidx.compose.material.ripple.rememberRipple import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.graphics.Color import androidx.compose.ui.hapticfeedback.HapticFeedbackType import androidx.compose.ui.input.nestedscroll.NestedScrollConnection import androidx.compose.ui.input.nestedscroll.NestedScrollSource @@ -55,6 +53,12 @@ import androidx.compose.ui.util.fastFirstOrNull import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.viewmodel.compose.viewModel import com.google.accompanist.drawablepainter.rememberDrawablePainter +import com.google.accompanist.insets.LocalWindowInsets +import com.google.accompanist.insets.navigationBarsPadding +import com.google.accompanist.insets.rememberInsetsPaddingValues +import com.google.accompanist.insets.systemBarsPadding +import com.google.accompanist.insets.ui.Scaffold +import com.google.accompanist.systemuicontroller.rememberSystemUiController import xyz.quaver.pupil.R import xyz.quaver.pupil.ui.theme.LightBlue300 import kotlin.math.* @@ -95,7 +99,7 @@ fun SearchBase( fabSubMenu: List = emptyList(), actions: @Composable RowScope.() -> Unit = { }, onSearch: () -> Unit = { }, - content: @Composable BoxScope.() -> Unit + content: @Composable BoxScope.(contentPadding: PaddingValues) -> Unit ) { val context = LocalContext.current val focusManager = LocalFocusManager.current @@ -115,11 +119,25 @@ fun SearchBase( } } + val systemBarsPaddingValues = rememberInsetsPaddingValues(insets = LocalWindowInsets.current.systemBars) + val pageTurnIndicatorHeight = LocalDensity.current.run { 64.dp.toPx() } - val searchBarHeight = LocalDensity.current.run { 64.dp.roundToPx() } + + val searchBarDefaultOffset = systemBarsPaddingValues.calculateTopPadding() + 64.dp + val searchBarDefaultOffsetPx = LocalDensity.current.run { searchBarDefaultOffset.roundToPx() } var overscroll: Float? by remember { mutableStateOf(null) } + val systemUiController = rememberSystemUiController() + val useDarkIcons = MaterialTheme.colors.isLight + + SideEffect { + systemUiController.setSystemBarsColor( + color = Color.Transparent, + darkIcons = useDarkIcons + ) + } + LaunchedEffect(navigationIconProgress) { navigationIcon.progress = navigationIconProgress } @@ -127,6 +145,7 @@ fun SearchBase( Scaffold( floatingActionButton = { MultipleFloatingActionButton( + modifier = Modifier.navigationBarsPadding(), items = fabSubMenu, visible = model.isFabVisible, targetState = isFabExpanded, @@ -135,8 +154,8 @@ fun SearchBase( } ) } - ) { - Box(Modifier.fillMaxSize()) { + ) { contentPadding -> + Box(Modifier.padding(contentPadding)) { val topCircleRadius by animateFloatAsState(if (overscroll?.let { it >= pageTurnIndicatorHeight } == true) 1000f else 0f) val bottomCircleRadius by animateFloatAsState(if (overscroll?.let { it <= -pageTurnIndicatorHeight } == true) 1000f else 0f) @@ -144,7 +163,7 @@ fun SearchBase( Canvas(modifier = Modifier.fillMaxSize()) { drawCircle( LightBlue300.copy(alpha = 0.6f), - center = Offset(this.center.x, searchBarHeight.toFloat()), + center = Offset(this.center.x, searchBarDefaultOffsetPx.toFloat()), radius = topCircleRadius ) drawCircle( @@ -195,7 +214,9 @@ fun SearchBase( modifier = Modifier .offset( 0.dp, - overscroll?.coerceIn(-pageTurnIndicatorHeight, pageTurnIndicatorHeight)?.let { overscroll -> LocalDensity.current.run { overscroll.toDp() } } + overscroll + ?.coerceIn(-pageTurnIndicatorHeight, pageTurnIndicatorHeight) + ?.let { overscroll -> LocalDensity.current.run { overscroll.toDp() } } ?: 0.dp) .nestedScroll(object : NestedScrollConnection { override fun onPreScroll( @@ -207,7 +228,7 @@ fun SearchBase( if (overscrollSnapshot == null || overscrollSnapshot == 0f) { model.searchBarOffset = (model.searchBarOffset + available.y.roundToInt()).coerceIn( - -searchBarHeight, + -searchBarDefaultOffsetPx, 0 ) @@ -275,29 +296,29 @@ fun SearchBase( } } }, - content = content + content = { + this.content( + PaddingValues(0.dp, searchBarDefaultOffset, 0.dp, 0.dp) + ) + } ) if (model.loading) CircularProgressIndicator(Modifier.align(Alignment.Center)) FloatingSearchBar( - modifier = Modifier.offset(0.dp, LocalDensity.current.run { model.searchBarOffset.toDp() }), + modifier = Modifier + .systemBarsPadding() + .offset(0.dp, LocalDensity.current.run { model.searchBarOffset.toDp() }), query = model.query, onQueryChange = { model.query = it }, navigationIcon = { - Icon( - painter = rememberDrawablePainter(navigationIcon), - contentDescription = null, - modifier = Modifier - .size(24.dp) - .clickable( - interactionSource = remember { MutableInteractionSource() }, - indication = rememberRipple(bounded = false) - ) { - focusManager.clearFocus() - } - ) + IconButton(onClick = { focusManager.clearFocus() }) { + Icon( + painter = rememberDrawablePainter(navigationIcon), + contentDescription = null + ) + } }, actions = actions, onTextFieldFocused = { navigationIconState = NavigationIconState.ARROW }, diff --git a/app/src/main/java/xyz/quaver/pupil/sources/hitomi/Hitomi.kt b/app/src/main/java/xyz/quaver/pupil/sources/hitomi/Hitomi.kt index dd09de31..908a1aae 100644 --- a/app/src/main/java/xyz/quaver/pupil/sources/hitomi/Hitomi.kt +++ b/app/src/main/java/xyz/quaver/pupil/sources/hitomi/Hitomi.kt @@ -19,14 +19,27 @@ package xyz.quaver.pupil.sources.hitomi import android.app.Application +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.size +import androidx.compose.material.* import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Settings import androidx.compose.material.icons.filled.Shuffle +import androidx.compose.material.icons.filled.Sort import androidx.compose.runtime.* import androidx.compose.runtime.livedata.observeAsState +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.NavController +import androidx.navigation.NavGraphBuilder +import androidx.navigation.compose.composable +import androidx.navigation.compose.navigation import io.ktor.client.* import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @@ -44,6 +57,7 @@ import xyz.quaver.pupil.sources.hitomi.composable.DetailedSearchResult import xyz.quaver.pupil.sources.hitomi.lib.getGalleryInfo import xyz.quaver.pupil.sources.hitomi.lib.getReferer import xyz.quaver.pupil.sources.hitomi.lib.imageUrlFromImage +import xyz.quaver.pupil.ui.dialog.SourceSelectDialog class Hitomi(app: Application) : Source(), DIAware { override val di by closestDI(app) @@ -58,16 +72,15 @@ class Hitomi(app: Application) : Source(), DIAware { override val name: String = "hitomi.la" override val iconResID: Int = R.drawable.hitomi - @Composable - override fun MainScreen(navController: NavController) { - navController.navigate("search/hitomi.la") { - launchSingleTop = true - navController.popBackStack() + override fun NavGraphBuilder.navGraph(navController: NavController) { + navigation(startDestination = "search", route = name) { + composable("search") { Search(navController) } + composable("reader/{itemID}") { Reader(navController) } } } @Composable - override fun Search(navController: NavController) { + fun Search(navController: NavController) { val model: HitomiSearchResultViewModel = viewModel() val database: AppDatabase by rememberInstance() val bookmarkDao = remember { database.bookmarkDao() } @@ -78,7 +91,21 @@ class Hitomi(app: Application) : Source(), DIAware { bookmarks?.toSet() ?: emptySet() } - LaunchedEffect(model.currentPage) { + var sourceSelectDialog by remember { mutableStateOf(false) } + + if (sourceSelectDialog) + SourceSelectDialog( + currentSource = name, + onDismissRequest = { sourceSelectDialog = false } + ) { + sourceSelectDialog = false + navController.navigate("main/${it.name}") { + launchSingleTop = true + popUpTo("main/{source}") { inclusive = true } + } + } + + LaunchedEffect(model.currentPage, model.sortByPopularity) { model.search() } @@ -99,11 +126,58 @@ class Hitomi(app: Application) : Source(), DIAware { ) ), actions = { + var expanded by remember { mutableStateOf(false) } + IconButton(onClick = { sourceSelectDialog = true }) { + Image( + painter = painterResource(id = R.drawable.hitomi), + contentDescription = null, + modifier = Modifier.size(24.dp) + ) + } + + IconButton(onClick = { expanded = true }) { + Icon(Icons.Default.Sort, contentDescription = null) + } + + IconButton(onClick = { navController.navigate("settings") }) { + Icon(Icons.Default.Settings, contentDescription = null) + } + + val onClick: (Boolean?) -> Unit = { + expanded = false + + it?.let { + model.sortByPopularity = it + } + } + DropdownMenu(expanded, onDismissRequest = { onClick(null) }) { + DropdownMenuItem(onClick = { onClick(false) }) { + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(16.dp) + ) { + Text(stringResource(R.string.main_menu_sort_newest)) + RadioButton(selected = !model.sortByPopularity, onClick = { onClick(false) }) + } + } + + Divider() + + DropdownMenuItem(onClick = { onClick(true) }){ + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(16.dp) + ) { + Text(stringResource(R.string.main_menu_sort_popular)) + RadioButton(selected = model.sortByPopularity, onClick = { onClick(true) }) + } + } + } }, onSearch = { model.search() } - ) { - ListSearchResult(model.searchResults) { + ) { contentPadding -> + ListSearchResult(model.searchResults, contentPadding = contentPadding) { DetailedSearchResult( it, bookmarks = bookmarkSet, @@ -114,14 +188,14 @@ class Hitomi(app: Application) : Source(), DIAware { } } ) { result -> - navController.navigate("reader/$name/${result.itemID}") + navController.navigate("reader/${result.itemID}") } } } } @Composable - override fun Reader(navController: NavController) { + fun Reader(navController: NavController) { val model: ReaderBaseViewModel = viewModel() val database: AppDatabase by rememberInstance() @@ -148,7 +222,6 @@ class Hitomi(app: Application) : Source(), DIAware { append("Referer", getReferer(galleryID)) } }.onFailure { - logger.warning(it) model.error = true } } diff --git a/app/src/main/java/xyz/quaver/pupil/sources/hitomi/HitomiSearchResultViewModel.kt b/app/src/main/java/xyz/quaver/pupil/sources/hitomi/HitomiSearchResultViewModel.kt index 15df10f5..0212ad7f 100644 --- a/app/src/main/java/xyz/quaver/pupil/sources/hitomi/HitomiSearchResultViewModel.kt +++ b/app/src/main/java/xyz/quaver/pupil/sources/hitomi/HitomiSearchResultViewModel.kt @@ -31,6 +31,8 @@ import kotlinx.coroutines.yield import org.kodein.di.DIAware import org.kodein.di.android.closestDI import org.kodein.di.instance +import org.kodein.log.LoggerFactory +import org.kodein.log.newLogger import xyz.quaver.pupil.db.AppDatabase import xyz.quaver.pupil.sources.composable.SearchBaseViewModel import xyz.quaver.pupil.sources.hitomi.lib.GalleryBlock @@ -41,6 +43,8 @@ import kotlin.math.ceil class HitomiSearchResultViewModel(app: Application) : SearchBaseViewModel(app), DIAware { override val di by closestDI(app) + private val logger = newLogger(LoggerFactory.default) + private val client: HttpClient by instance() private val database: AppDatabase by instance() @@ -80,9 +84,9 @@ class HitomiSearchResultViewModel(app: Application) : SearchBaseViewModel + yield() + loading = false searchResults.add(transform(getGalleryBlock(client, galleryID))) } } 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 9a4c3384..4f6ef99f 100644 --- a/app/src/main/java/xyz/quaver/pupil/ui/MainActivity.kt +++ b/app/src/main/java/xyz/quaver/pupil/ui/MainActivity.kt @@ -21,25 +21,24 @@ package xyz.quaver.pupil.ui import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent -import androidx.activity.viewModels import androidx.compose.animation.ExperimentalAnimationApi +import androidx.core.view.WindowCompat import androidx.navigation.compose.NavHost -import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController +import com.google.accompanist.insets.ProvideWindowInsets import org.kodein.di.DIAware import org.kodein.di.android.closestDI -import org.kodein.di.direct +import org.kodein.di.instance import org.kodein.log.LoggerFactory import org.kodein.log.newLogger +import xyz.quaver.pupil.sources.SourceEntries import xyz.quaver.pupil.ui.theme.PupilTheme -import xyz.quaver.pupil.ui.viewmodel.MainViewModel -import xyz.quaver.pupil.util.source class MainActivity : ComponentActivity(), DIAware { override val di by closestDI() - private val model: MainViewModel by viewModels() + private val sources: SourceEntries by instance() private val logger = newLogger(LoggerFactory.default) @@ -47,24 +46,17 @@ class MainActivity : ComponentActivity(), DIAware { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + WindowCompat.setDecorFitsSystemWindows(window, false) + setContent { PupilTheme { - val navController = rememberNavController() + ProvideWindowInsets { + val navController = rememberNavController() - NavHost(navController, startDestination = "main/{source}") { - composable("main/{source}") { - direct.source(it.arguments?.getString("source") ?: "hitomi.la") - .MainScreen(navController) - } - - composable("search/{source}") { - direct.source(it.arguments?.getString("source") ?: "hitomi.la") - .Search(navController) - } - - composable("reader/{source}/{itemID}") { - direct.source(it.arguments?.getString("source") ?: "hitomi.la") - .Reader(navController) + NavHost(navController, startDestination = "hitomi.la") { + sources.forEach { + it.second.run { navGraph(navController) } + } } } } 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 deleted file mode 100644 index 6a0fd9bb..00000000 --- a/app/src/main/java/xyz/quaver/pupil/ui/viewmodel/MainViewModel.kt +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Pupil, Hitomi.la viewer for Android - * Copyright (C) 2021 tom5079 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package xyz.quaver.pupil.ui.viewmodel - -import android.app.Application -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.setValue -import androidx.lifecycle.AndroidViewModel -import org.kodein.di.DIAware -import org.kodein.di.android.x.closestDI -import org.kodein.di.direct -import org.kodein.log.LoggerFactory -import org.kodein.log.newLogger -import xyz.quaver.pupil.sources.Source -import xyz.quaver.pupil.util.source - -@Suppress("UNCHECKED_CAST") -class MainViewModel(app: Application) : AndroidViewModel(app), DIAware { - override val di by closestDI() - - private val logger = newLogger(LoggerFactory.default) - - private val defaultSourceFactory: (String) -> Source = { - direct.source(it) - } - private var sourceFactory: (String) -> Source = defaultSourceFactory - var source by mutableStateOf(sourceFactory("hitomi.la")) -} \ No newline at end of file