Make DialogState Screen-Local (#2097)

* Prepare to make DialogState per Screen

* Remove some LocalDialogState usage

* Make DialogState Screen-Local

---------

Co-authored-by: Dude so hot <djohn@fbi.gov>
This commit is contained in:
renovate[bot]andDude so hot authored and GitHub committed 2025-01-16 21:08:07 +08:00
1 parent 6ac512e749
commit a8c0a05c28
25 files changed
+93 -87

No files matched your search

@@ -2,16 +2,19 @@ package com.hippo.ehviewer.ui
import androidx.compose.animation.AnimatedVisibilityScope
import androidx.compose.animation.SharedTransitionScope
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.SnackbarHostState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import com.hippo.ehviewer.ui.i18n.LocalStrings
import com.hippo.ehviewer.ui.i18n.Strings
import com.hippo.ehviewer.ui.screen.implicit
import com.hippo.ehviewer.ui.tools.DialogState
import com.hippo.ehviewer.ui.tools.LocalDialogState
import com.hippo.ehviewer.ui.tools.LocalGlobalDialogState
import com.hippo.ehviewer.ui.tools.NoopTransitionsVisibilityScope
import com.hippo.ehviewer.ui.tools.TransitionsVisibilityScope
import com.hippo.ehviewer.ui.tools.togetherWith
@@ -20,21 +23,25 @@ import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import kotlinx.coroutines.CoroutineScope
@Composable
inline fun <R> AnimatedVisibilityScope.composing(
inline fun <R> AnimatedVisibilityScope.Screen(
navigator: DestinationsNavigator,
block: @Composable context(Strings, MainActivity, SnackbarHostState, DialogState, SharedTransitionScope, TransitionsVisibilityScope, DestinationsNavigator, CoroutineScope)
() -> R,
) = with(NoopTransitionsVisibilityScope) {
togetherWith(implicit<AnimatedVisibilityScope>()) {
block(
LocalStrings.current,
with(LocalContext.current) { remember { findActivity() } },
LocalSnackBarHostState.current,
LocalDialogState.current,
LocalSharedTransitionScope.current,
this,
navigator,
rememberCoroutineScope(),
)
) = Box(modifier = Modifier.fillMaxSize()) {
val dialogState = with(LocalGlobalDialogState.current) { rememberLocal() }
with(NoopTransitionsVisibilityScope) {
togetherWith(implicit<AnimatedVisibilityScope>()) {
block(
LocalStrings.current,
with(LocalContext.current) { remember { findActivity() } },
LocalSnackBarHostState.current,
dialogState,
LocalSharedTransitionScope.current,
this,
navigator,
rememberCoroutineScope(),
)
dialogState.Place()
}
}
}
@@ -136,7 +136,6 @@ import com.hippo.ehviewer.ui.screen.navWithUrl
import com.hippo.ehviewer.ui.settings.showNewVersion
import com.hippo.ehviewer.ui.tools.DialogState
import com.hippo.ehviewer.ui.tools.LabeledCheckbox
import com.hippo.ehviewer.ui.tools.LocalDialogState
import com.hippo.ehviewer.ui.tools.LocalWindowSizeClass
import com.hippo.ehviewer.updater.AppUpdater
import com.hippo.ehviewer.util.AppConfig
@@ -219,7 +218,6 @@ class MainActivity : EhActivity() {
super.onCreate(savedInstanceState)
setMD3Content {
val configuration = LocalConfiguration.current
val dialogState = LocalDialogState.current
val navDrawerState = rememberDrawerState(DrawerValue.Closed)
val sideSheetState = rememberDrawerState2(DrawerValue.Closed)
val snackbarState = remember { SnackbarHostState() }
@@ -252,13 +250,13 @@ class MainActivity : EhActivity() {
if (!AppConfig.isBenchmark) {
val noNetwork = stringResource(R.string.no_network)
LaunchedEffect(Unit) {
runCatching { dialogState.checkDownloadLocation() }
runCatching { dialogState.checkAppLinkVerify() }
runCatching { checkDownloadLocation() }
runCatching { checkAppLinkVerify() }
if (hasNetwork) {
runSuspendCatching {
withIOContext {
AppUpdater.checkForUpdate()?.let {
dialogState.showNewVersion(this@MainActivity, it)
showNewVersion(this@MainActivity, it)
}
}
}.onFailure {
@@ -284,7 +282,7 @@ class MainActivity : EhActivity() {
else -> {
val url = uri.toString()
if (!navigator.navWithUrl(url)) {
val new = dialogState.awaitInputText(initial = url, title = cannotParse)
val new = awaitInputText(initial = url, title = cannotParse)
addTextToClipboard(new)
}
}
@@ -16,24 +16,22 @@ import androidx.navigation.NavBackStackEntry
import com.hippo.ehviewer.ui.i18n.ProvideTranslations
import com.hippo.ehviewer.ui.theme.EhTheme
import com.hippo.ehviewer.ui.tools.DialogState
import com.hippo.ehviewer.ui.tools.LocalDialogState
import com.hippo.ehviewer.ui.tools.LocalGlobalDialogState
import com.hippo.ehviewer.ui.tools.ProvideVectorPainterCache
import com.ramcosta.composedestinations.animations.NavHostAnimatedDestinationStyle
import soup.compose.material.motion.animation.materialSharedAxisXIn
import soup.compose.material.motion.animation.materialSharedAxisXOut
import soup.compose.material.motion.animation.rememberSlideDistance
inline fun ComponentActivity.setMD3Content(crossinline content: @Composable () -> Unit) = setContent {
inline fun ComponentActivity.setMD3Content(crossinline content: @Composable DialogState.() -> Unit) = setContent {
EhTheme(useDarkTheme = isSystemInDarkTheme()) {
ProvideVectorPainterCache {
val dialogState = remember { DialogState() }
CompositionLocalProvider(
LocalDialogState provides dialogState,
) {
CompositionLocalProvider(LocalGlobalDialogState provides dialogState) {
Box(modifier = Modifier.fillMaxSize()) {
ProvideTranslations {
content()
dialogState.value?.invoke(this)
content(dialogState)
dialogState.Place()
}
}
}
@@ -1,5 +1,6 @@
package com.hippo.ehviewer.ui.login
import androidx.compose.animation.AnimatedVisibilityScope
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
@@ -38,13 +39,11 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.autofill.AutofillType
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.res.painterResource
@@ -62,9 +61,9 @@ import com.hippo.ehviewer.Settings
import com.hippo.ehviewer.client.EhEngine
import com.hippo.ehviewer.client.EhUrl
import com.hippo.ehviewer.client.EhUtils
import com.hippo.ehviewer.ui.Screen
import com.hippo.ehviewer.ui.destinations.WebViewSignInScreenDestination
import com.hippo.ehviewer.ui.openBrowser
import com.hippo.ehviewer.ui.tools.LocalDialogState
import com.hippo.ehviewer.ui.tools.LocalWindowSizeClass
import com.hippo.ehviewer.ui.tools.autofill
import com.hippo.ehviewer.util.displayString
@@ -77,9 +76,8 @@ import kotlinx.coroutines.Job
@Destination<RootGraph>(start = true)
@Composable
fun SignInScreen(navigator: DestinationsNavigator) {
fun AnimatedVisibilityScope.SignInScreen(navigator: DestinationsNavigator) = Screen(navigator) {
val windowSizeClass = LocalWindowSizeClass.current
val coroutineScope = rememberCoroutineScope()
val focusManager = LocalFocusManager.current
var isProgressIndicatorVisible by rememberSaveable { mutableStateOf(false) }
var showUsernameError by rememberSaveable { mutableStateOf(false) }
@@ -87,9 +85,7 @@ fun SignInScreen(navigator: DestinationsNavigator) {
val username = rememberTextFieldState()
val password = rememberTextFieldState()
var passwordHidden by rememberSaveable { mutableStateOf(true) }
val context = LocalContext.current
var signInJob by remember { mutableStateOf<Job?>(null) }
val dialogState = LocalDialogState.current
fun signIn() {
if (signInJob?.isActive == true) return
@@ -109,14 +105,14 @@ fun SignInScreen(navigator: DestinationsNavigator) {
isProgressIndicatorVisible = true
EhUtils.signOut()
signInJob = coroutineScope.launchIO {
signInJob = launchIO {
runCatching {
EhEngine.signIn(username.text.toString(), password.text.toString())
}.onFailure {
withUIContext {
focusManager.clearFocus()
isProgressIndicatorVisible = false
dialogState.awaitConfirmationOrCancel(
awaitConfirmationOrCancel(
confirmText = R.string.get_it,
title = R.string.sign_in_failed,
showCancelButton = false,
@@ -202,7 +198,7 @@ fun SignInScreen(navigator: DestinationsNavigator) {
Spacer(modifier = Modifier.height(dimensionResource(id = R.dimen.keyline_margin)))
Row(modifier = Modifier.padding(top = dimensionResource(R.dimen.keyline_margin))) {
FilledTonalButton(
onClick = { context.openBrowser(EhUrl.URL_REGISTER) },
onClick = { openBrowser(EhUrl.URL_REGISTER) },
modifier = Modifier.weight(1f).padding(horizontal = 4.dp),
) {
Text(text = stringResource(id = R.string.register))
@@ -289,7 +285,7 @@ fun SignInScreen(navigator: DestinationsNavigator) {
Text(text = stringResource(id = R.string.sign_in))
}
FilledTonalButton(
onClick = { context.openBrowser(EhUrl.URL_REGISTER) },
onClick = { openBrowser(EhUrl.URL_REGISTER) },
modifier = Modifier.padding(horizontal = 4.dp).width(128.dp),
) {
Text(text = stringResource(id = R.string.register))
@@ -13,7 +13,7 @@ import com.google.accompanist.web.rememberWebViewState
import com.hippo.ehviewer.client.EhCookieStore
import com.hippo.ehviewer.client.EhUrl
import com.hippo.ehviewer.client.EhUtils
import com.hippo.ehviewer.ui.composing
import com.hippo.ehviewer.ui.Screen
import com.hippo.ehviewer.util.bgWork
import com.hippo.ehviewer.util.setDefaultSettings
import com.ramcosta.composedestinations.annotation.Destination
@@ -24,7 +24,7 @@ import kotlinx.coroutines.launch
@Destination<RootGraph>
@Composable
fun AnimatedVisibilityScope.WebViewSignInScreen(navigator: DestinationsNavigator) = composing(navigator) {
fun AnimatedVisibilityScope.WebViewSignInScreen(navigator: DestinationsNavigator) = Screen(navigator) {
val state = rememberWebViewState(url = EhUrl.URL_SIGN_IN)
val client = remember {
object : AccompanistWebViewClient() {
@@ -40,8 +40,8 @@ import com.hippo.ehviewer.client.EhTagDatabase
import com.hippo.ehviewer.client.EhUtils
import com.hippo.ehviewer.client.data.GalleryInfo.Companion.S_LANG_TAGS
import com.hippo.ehviewer.collectAsState
import com.hippo.ehviewer.ui.tools.DialogState
import com.hippo.ehviewer.ui.tools.DropdownFilterChip
import com.hippo.ehviewer.ui.tools.LocalDialogState
import com.hippo.ehviewer.ui.tools.thenIf
import com.hippo.ehviewer.util.toIntOrDefault
import kotlinx.coroutines.launch
@@ -59,6 +59,7 @@ private val categoryTable = arrayOf(
EhUtils.MISC to R.string.misc,
)
context(DialogState)
@Composable
fun SearchFilter(
modifier: Modifier = Modifier,
@@ -71,7 +72,6 @@ fun SearchFilter(
) = Column(modifier) {
val scope = rememberCoroutineScope()
val context = LocalContext.current
val dialogState = LocalDialogState.current
val animateItems by Settings.animateItems.collectAsState()
fun isCategoryChecked(bit: Int) = category and bit != 0
val categories = remember(category) { categoryTable.sortedBy { !isCategoryChecked(it.first) } }
@@ -150,7 +150,7 @@ fun SearchFilter(
selected = advancedOption.fromPage != 0 || advancedOption.toPage != 0,
onClick = {
scope.launch {
val (from, to) = dialogState.awaitResult(
val (from, to) = awaitResult(
initial = advancedOption.fromPage to advancedOption.toPage,
title = R.string.key_pages,
invalidator = { (min, max) ->
@@ -27,6 +27,7 @@ import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.LocalTextStyle
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
@@ -69,7 +70,8 @@ import com.hippo.ehviewer.gallery.status
import com.hippo.ehviewer.gallery.unblock
import com.hippo.ehviewer.gallery.useArchivePageLoader
import com.hippo.ehviewer.gallery.useEhPageLoader
import com.hippo.ehviewer.ui.composing
import com.hippo.ehviewer.ui.MainActivity
import com.hippo.ehviewer.ui.Screen
import com.hippo.ehviewer.ui.theme.EhTheme
import com.hippo.ehviewer.ui.tools.Await
import com.hippo.ehviewer.ui.tools.DialogState
@@ -88,6 +90,7 @@ import eu.kanade.tachiyomi.ui.reader.ReaderPageSheetMeta
import eu.kanade.tachiyomi.ui.reader.setting.ReadingModeType
import eu.kanade.tachiyomi.util.lang.launchIO
import kotlin.coroutines.resume
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.awaitCancellation
import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.flow.onCompletion
@@ -115,7 +118,7 @@ private fun Background(
@Destination<RootGraph>
@Composable
fun AnimatedVisibilityScope.ReaderScreen(args: ReaderScreenArgs, navigator: DestinationsNavigator) = composing(navigator) {
fun AnimatedVisibilityScope.ReaderScreen(args: ReaderScreenArgs, navigator: DestinationsNavigator) = Screen(navigator) {
val bgColor by collectBackgroundColorAsState()
val uiController = rememberSystemUiController()
DisposableEffect(uiController) {
@@ -163,15 +166,16 @@ fun AnimatedVisibilityScope.ReaderScreen(args: ReaderScreenArgs, navigator: Dest
val loader = result.value
val info = (args as? ReaderScreenArgs.Gallery)?.info
key(loader) {
ReaderScreen(loader, info, navigator)
ReaderScreen(loader, info)
}
}
}
}
}
context(MainActivity, SnackbarHostState, DialogState, CoroutineScope)
@Composable
fun AnimatedVisibilityScope.ReaderScreen(pageLoader: PageLoader, info: BaseGalleryInfo?, navigator: DestinationsNavigator) = composing(navigator) {
fun AnimatedVisibilityScope.ReaderScreen(pageLoader: PageLoader, info: BaseGalleryInfo?) {
ConfigureKeepScreenOn()
LaunchedEffect(Unit) {
val orientation = requestedOrientation
@@ -96,7 +96,7 @@ import com.hippo.ehviewer.icons.EhIcons
import com.hippo.ehviewer.icons.big.Download
import com.hippo.ehviewer.ui.DrawerHandle
import com.hippo.ehviewer.ui.LocalSideSheetState
import com.hippo.ehviewer.ui.composing
import com.hippo.ehviewer.ui.Screen
import com.hippo.ehviewer.ui.confirmRemoveDownloadRange
import com.hippo.ehviewer.ui.main.DownloadCard
import com.hippo.ehviewer.ui.main.FAB_ANIMATE_TIME
@@ -132,7 +132,7 @@ import sh.calvin.reorderable.rememberReorderableLazyListState
@Destination<RootGraph>
@Composable
fun AnimatedVisibilityScope.DownloadsScreen(navigator: DestinationsNavigator) = composing(navigator) {
fun AnimatedVisibilityScope.DownloadsScreen(navigator: DestinationsNavigator) = Screen(navigator) {
var gridView by Settings.gridView.asMutableState()
var sortMode by Settings.downloadSortMode.asMutableState()
val filterMode by Settings.downloadFilterMode.collectAsState { DownloadsFilterMode.from(it) }
@@ -65,8 +65,8 @@ import com.hippo.ehviewer.icons.EhIcons
import com.hippo.ehviewer.icons.filled.GoTo
import com.hippo.ehviewer.ui.DrawerHandle
import com.hippo.ehviewer.ui.LocalSideSheetState
import com.hippo.ehviewer.ui.Screen
import com.hippo.ehviewer.ui.awaitSelectDate
import com.hippo.ehviewer.ui.composing
import com.hippo.ehviewer.ui.main.AvatarIcon
import com.hippo.ehviewer.ui.main.FAB_ANIMATE_TIME
import com.hippo.ehviewer.ui.main.FabLayout
@@ -96,7 +96,7 @@ import moe.tarsin.coroutines.runSwallowingWithUI
@Destination<RootGraph>
@Composable
fun AnimatedVisibilityScope.FavouritesScreen(navigator: DestinationsNavigator) = composing(navigator) {
fun AnimatedVisibilityScope.FavouritesScreen(navigator: DestinationsNavigator) = Screen(navigator) {
// Immutables
val animateItems by Settings.animateItems.collectAsState()
val hasSignedIn by Settings.hasSignedIn.collectAsState()
@@ -91,7 +91,7 @@ import com.hippo.ehviewer.client.data.ListUrlBuilder
import com.hippo.ehviewer.collectAsState
import com.hippo.ehviewer.dao.Filter
import com.hippo.ehviewer.dao.FilterMode
import com.hippo.ehviewer.ui.composing
import com.hippo.ehviewer.ui.Screen
import com.hippo.ehviewer.ui.jumpToReaderByPage
import com.hippo.ehviewer.ui.main.GalleryCommentCard
import com.hippo.ehviewer.ui.openBrowser
@@ -169,7 +169,7 @@ private val MinimumContentPaddingEditText = 88.dp
@Destination<RootGraph>
@Composable
fun AnimatedVisibilityScope.GalleryCommentsScreen(gid: Long, navigator: DestinationsNavigator) = composing(navigator) {
fun AnimatedVisibilityScope.GalleryCommentsScreen(gid: Long, navigator: DestinationsNavigator) = Screen(navigator) {
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior()
var commenting by rememberSaveable { mutableStateOf(false) }
val animationProgress by animateFloatMergePredictiveBackAsState(enable = commenting) { commenting = false }
@@ -53,7 +53,7 @@ import com.hippo.ehviewer.ktbuilder.executeIn
import com.hippo.ehviewer.ktbuilder.imageRequest
import com.hippo.ehviewer.spider.SpiderDen
import com.hippo.ehviewer.ui.MainActivity
import com.hippo.ehviewer.ui.composing
import com.hippo.ehviewer.ui.Screen
import com.hippo.ehviewer.ui.main.GalleryDetailErrorTip
import com.hippo.ehviewer.ui.navToReader
import com.hippo.ehviewer.ui.openBrowser
@@ -94,7 +94,7 @@ data class TokenArgs(
@Destination<RootGraph>
@Composable
fun AnimatedVisibilityScope.GalleryDetailScreen(args: GalleryDetailScreenArgs, navigator: DestinationsNavigator) = composing(navigator) {
fun AnimatedVisibilityScope.GalleryDetailScreen(args: GalleryDetailScreenArgs, navigator: DestinationsNavigator) = Screen(navigator) {
val (gid, token) = remember(args) {
when (args) {
is GalleryInfoArgs -> with(args.galleryInfo) { gid to token }
@@ -94,8 +94,8 @@ import com.hippo.ehviewer.icons.EhIcons
import com.hippo.ehviewer.icons.filled.GoTo
import com.hippo.ehviewer.ui.DrawerHandle
import com.hippo.ehviewer.ui.LocalSideSheetState
import com.hippo.ehviewer.ui.Screen
import com.hippo.ehviewer.ui.awaitSelectDate
import com.hippo.ehviewer.ui.composing
import com.hippo.ehviewer.ui.destinations.ProgressScreenDestination
import com.hippo.ehviewer.ui.doGalleryInfoAction
import com.hippo.ehviewer.ui.main.AdvancedSearchOption
@@ -151,7 +151,7 @@ fun AnimatedVisibilityScope.ToplistScreen(navigator: DestinationsNavigator) = Ga
@Destination<RootGraph>
@Composable
fun AnimatedVisibilityScope.GalleryListScreen(lub: ListUrlBuilder, navigator: DestinationsNavigator) = composing(navigator) {
fun AnimatedVisibilityScope.GalleryListScreen(lub: ListUrlBuilder, navigator: DestinationsNavigator) = Screen(navigator) {
val searchFieldState = rememberTextFieldState()
var urlBuilder by rememberSaveable(lub) { mutableStateOf(lub) }
var searchBarExpanded by rememberSaveable { mutableStateOf(false) }
@@ -51,7 +51,7 @@ import com.hippo.ehviewer.collectAsState
import com.hippo.ehviewer.icons.EhIcons
import com.hippo.ehviewer.icons.big.History
import com.hippo.ehviewer.ui.DrawerHandle
import com.hippo.ehviewer.ui.composing
import com.hippo.ehviewer.ui.Screen
import com.hippo.ehviewer.ui.doGalleryInfoAction
import com.hippo.ehviewer.ui.main.GalleryInfoListItem
import com.hippo.ehviewer.ui.main.plus
@@ -70,7 +70,7 @@ import kotlinx.coroutines.launch
@Destination<RootGraph>
@Composable
fun AnimatedVisibilityScope.HistoryScreen(navigator: DestinationsNavigator) = composing(navigator) {
fun AnimatedVisibilityScope.HistoryScreen(navigator: DestinationsNavigator) = Screen(navigator) {
val animateItems by Settings.animateItems.collectAsState()
var searchBarExpanded by rememberSaveable { mutableStateOf(false) }
@@ -29,7 +29,7 @@ import androidx.compose.ui.text.font.FontWeight
import com.hippo.ehviewer.R
import com.hippo.ehviewer.client.data.ListUrlBuilder
import com.hippo.ehviewer.client.data.ListUrlBuilder.Companion.MODE_IMAGE_SEARCH
import com.hippo.ehviewer.ui.composing
import com.hippo.ehviewer.ui.Screen
import com.hippo.ehviewer.ui.main.ImageSearch
import com.hippo.ehviewer.ui.main.plus
import com.hippo.ehviewer.ui.tools.snackBarPadding
@@ -45,7 +45,7 @@ import kotlinx.coroutines.launch
@Destination<RootGraph>
@Composable
fun AnimatedVisibilityScope.ImageSearchScreen(navigator: DestinationsNavigator) = composing(navigator) {
fun AnimatedVisibilityScope.ImageSearchScreen(navigator: DestinationsNavigator) = Screen(navigator) {
val marginH = dimensionResource(id = R.dimen.gallery_list_margin_h)
val marginV = dimensionResource(id = R.dimen.gallery_list_margin_v)
var imageUri by rememberSaveable { mutableStateOf<Uri?>(null) }
@@ -23,7 +23,7 @@ import androidx.compose.ui.unit.dp
import com.hippo.ehviewer.client.EhEngine
import com.hippo.ehviewer.icons.EhIcons
import com.hippo.ehviewer.icons.big.SadAndroid
import com.hippo.ehviewer.ui.composing
import com.hippo.ehviewer.ui.Screen
import com.hippo.ehviewer.util.displayString
import com.ramcosta.composedestinations.annotation.Destination
import com.ramcosta.composedestinations.annotation.RootGraph
@@ -33,7 +33,7 @@ import moe.tarsin.coroutines.runSuspendCatching
@Destination<RootGraph>
@Composable
fun AnimatedVisibilityScope.ProgressScreen(gid: Long, token: String, page: Int, navigator: DestinationsNavigator) = composing(navigator) {
fun AnimatedVisibilityScope.ProgressScreen(gid: Long, token: String, page: Int, navigator: DestinationsNavigator) = Screen(navigator) {
var error by rememberSaveable { mutableStateOf("") }
LaunchedEffect(error) {
if (error.isEmpty()) {
@@ -31,10 +31,9 @@ import com.hippo.ehviewer.EhDB
import com.hippo.ehviewer.R
import com.hippo.ehviewer.Settings
import com.hippo.ehviewer.download.downloadLocation
import com.hippo.ehviewer.ui.composing
import com.hippo.ehviewer.ui.Screen
import com.hippo.ehviewer.ui.destinations.LicenseScreenDestination
import com.hippo.ehviewer.ui.tools.DialogState
import com.hippo.ehviewer.ui.tools.LocalDialogState
import com.hippo.ehviewer.ui.tools.observed
import com.hippo.ehviewer.updater.AppUpdater
import com.hippo.ehviewer.updater.Release
@@ -56,12 +55,11 @@ private const val RELEASE_URL = "$REPO_URL/releases"
@Destination<RootGraph>
@Composable
fun AnimatedVisibilityScope.AboutScreen(navigator: DestinationsNavigator) = composing(navigator) {
fun AnimatedVisibilityScope.AboutScreen(navigator: DestinationsNavigator) = Screen(navigator) {
val context = LocalContext.current
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior()
val snackbarHostState = remember { SnackbarHostState() }
val coroutineScope = rememberCoroutineScope { Dispatchers.IO }
val dialogState = LocalDialogState.current
fun launchSnackBar(content: String) = coroutineScope.launch { snackbarHostState.showSnackbar(content) }
Scaffold(
topBar = {
@@ -118,7 +116,7 @@ fun AnimatedVisibilityScope.AboutScreen(navigator: DestinationsNavigator) = comp
WorkPreference(title = settingsAboutCheckForUpdates) {
runSuspendCatching {
AppUpdater.checkForUpdate(true)?.let {
dialogState.showNewVersion(context, it)
showNewVersion(context, it)
} ?: launchSnackBar(alreadyLatestVersion)
}.onFailure {
launchSnackBar(updateFailed(it.displayString()))
@@ -51,7 +51,7 @@ import com.hippo.ehviewer.spider.SpiderQueen.Companion.SPIDER_INFO_FILENAME
import com.hippo.ehviewer.spider.readComicInfo
import com.hippo.ehviewer.spider.readCompatFromPath
import com.hippo.ehviewer.spider.speedLevelToSpeed
import com.hippo.ehviewer.ui.composing
import com.hippo.ehviewer.ui.Screen
import com.hippo.ehviewer.ui.keepNoMediaFileStatus
import com.hippo.ehviewer.ui.tools.observed
import com.hippo.ehviewer.ui.tools.rememberedAccessor
@@ -81,7 +81,7 @@ import splitties.init.appCtx
@Destination<RootGraph>
@Composable
fun AnimatedVisibilityScope.DownloadScreen(navigator: DestinationsNavigator) = composing(navigator) {
fun AnimatedVisibilityScope.DownloadScreen(navigator: DestinationsNavigator) = Screen(navigator) {
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior()
fun launchSnackBar(content: String) = launch { showSnackbar(content) }
Scaffold(
@@ -41,7 +41,7 @@ import com.hippo.ehviewer.client.EhTagDatabase
import com.hippo.ehviewer.client.EhUrl
import com.hippo.ehviewer.client.EhUtils
import com.hippo.ehviewer.collectAsState
import com.hippo.ehviewer.ui.composing
import com.hippo.ehviewer.ui.Screen
import com.hippo.ehviewer.ui.destinations.FilterScreenDestination
import com.hippo.ehviewer.ui.destinations.MyTagsScreenDestination
import com.hippo.ehviewer.ui.destinations.UConfigScreenDestination
@@ -60,7 +60,7 @@ import kotlinx.datetime.LocalTime
@Destination<RootGraph>
@Composable
fun AnimatedVisibilityScope.EhScreen(navigator: DestinationsNavigator) = composing(navigator) {
fun AnimatedVisibilityScope.EhScreen(navigator: DestinationsNavigator) = Screen(navigator) {
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior()
val snackbarHostState = remember { SnackbarHostState() }
val coroutineScope = rememberCoroutineScope { Dispatchers.IO }
@@ -61,7 +61,7 @@ import com.hippo.ehviewer.client.EhFilter.trigger
import com.hippo.ehviewer.collectAsState
import com.hippo.ehviewer.dao.Filter
import com.hippo.ehviewer.dao.FilterMode
import com.hippo.ehviewer.ui.composing
import com.hippo.ehviewer.ui.Screen
import com.hippo.ehviewer.ui.tools.Await
import com.hippo.ehviewer.ui.tools.thenIf
import com.ramcosta.composedestinations.annotation.Destination
@@ -74,7 +74,7 @@ import moe.tarsin.coroutines.groupByToObserved
@Destination<RootGraph>
@Composable
fun AnimatedVisibilityScope.FilterScreen(navigator: DestinationsNavigator) = composing(navigator) {
fun AnimatedVisibilityScope.FilterScreen(navigator: DestinationsNavigator) = Screen(navigator) {
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior()
val allFilterMap = remember { async { EhFilter.filters.await().groupByToObserved { it.mode } } }
val animateItems by Settings.animateItems.collectAsState()
@@ -15,7 +15,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.unit.dp
import com.hippo.ehviewer.ui.composing
import com.hippo.ehviewer.ui.Screen
import com.hippo.ehviewer.ui.openBrowser
import com.mikepenz.aboutlibraries.ui.compose.m3.LibrariesContainer
import com.mikepenz.aboutlibraries.ui.compose.m3.LibraryDefaults
@@ -25,7 +25,7 @@ import com.ramcosta.composedestinations.navigation.DestinationsNavigator
@Destination<RootGraph>
@Composable
fun AnimatedVisibilityScope.LicenseScreen(navigator: DestinationsNavigator) = composing(navigator) {
fun AnimatedVisibilityScope.LicenseScreen(navigator: DestinationsNavigator) = Screen(navigator) {
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior()
Scaffold(
topBar = {
@@ -15,7 +15,7 @@ import androidx.compose.ui.Modifier
import com.google.accompanist.web.WebView
import com.google.accompanist.web.rememberWebViewState
import com.hippo.ehviewer.client.EhUrl
import com.hippo.ehviewer.ui.composing
import com.hippo.ehviewer.ui.Screen
import com.hippo.ehviewer.util.setDefaultSettings
import com.ramcosta.composedestinations.annotation.Destination
import com.ramcosta.composedestinations.annotation.RootGraph
@@ -23,7 +23,7 @@ import com.ramcosta.composedestinations.navigation.DestinationsNavigator
@Destination<RootGraph>
@Composable
fun AnimatedVisibilityScope.MyTagsScreen(navigator: DestinationsNavigator) = composing(navigator) {
fun AnimatedVisibilityScope.MyTagsScreen(navigator: DestinationsNavigator) = Screen(navigator) {
val url = EhUrl.myTagsUrl
Scaffold(
topBar = {
@@ -23,7 +23,7 @@ import com.hippo.ehviewer.EhApplication.Companion.searchDatabase
import com.hippo.ehviewer.R
import com.hippo.ehviewer.Settings
import com.hippo.ehviewer.asMutableState
import com.hippo.ehviewer.ui.composing
import com.hippo.ehviewer.ui.Screen
import com.hippo.ehviewer.ui.isAuthenticationSupported
import com.hippo.ehviewer.ui.tools.observed
import com.hippo.ehviewer.ui.tools.rememberedAccessor
@@ -34,7 +34,7 @@ import kotlinx.coroutines.launch
@Destination<RootGraph>
@Composable
fun AnimatedVisibilityScope.PrivacyScreen(navigator: DestinationsNavigator) = composing(navigator) {
fun AnimatedVisibilityScope.PrivacyScreen(navigator: DestinationsNavigator) = Screen(navigator) {
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior()
val snackbarHostState = remember { SnackbarHostState() }
fun launchSnackBar(content: String) = launch { snackbarHostState.showSnackbar(content) }
@@ -20,7 +20,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll
import com.hippo.ehviewer.icons.EhIcons
import com.hippo.ehviewer.icons.filled.SadPanda
import com.hippo.ehviewer.ui.composing
import com.hippo.ehviewer.ui.Screen
import com.hippo.ehviewer.ui.destinations.AboutScreenDestination
import com.hippo.ehviewer.ui.destinations.AdvancedScreenDestination
import com.hippo.ehviewer.ui.destinations.DownloadScreenDestination
@@ -32,7 +32,7 @@ import com.ramcosta.composedestinations.navigation.DestinationsNavigator
@Destination<RootGraph>
@Composable
fun AnimatedVisibilityScope.SettingsScreen(navigator: DestinationsNavigator) = composing(navigator) {
fun AnimatedVisibilityScope.SettingsScreen(navigator: DestinationsNavigator) = Screen(navigator) {
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior()
Scaffold(
topBar = {
@@ -25,7 +25,7 @@ import com.google.accompanist.web.WebView
import com.google.accompanist.web.rememberWebViewState
import com.hippo.ehviewer.client.EhCookieStore
import com.hippo.ehviewer.client.EhUrl
import com.hippo.ehviewer.ui.composing
import com.hippo.ehviewer.ui.Screen
import com.hippo.ehviewer.util.setDefaultSettings
import com.ramcosta.composedestinations.annotation.Destination
import com.ramcosta.composedestinations.annotation.RootGraph
@@ -35,7 +35,7 @@ private const val APPLY_JS = "javascript:(function(){var apply = document.getEle
@Destination<RootGraph>
@Composable
fun AnimatedVisibilityScope.UConfigScreen(navigator: DestinationsNavigator) = composing(navigator) {
fun AnimatedVisibilityScope.UConfigScreen(navigator: DestinationsNavigator) = Screen(navigator) {
val url = EhUrl.uConfigUrl
var webview by remember { Atomic<WebView?>(null)::value }
val snackbarHostState = remember { SnackbarHostState() }
@@ -117,8 +117,13 @@ interface DialogScope<R> {
typealias MutableComposable = MutableState<(@Composable BoxScope.() -> Unit)?>
class DialogState : MutableComposable by mutableStateOf(null) {
val mutex = MutatorMutex()
class DialogState(val mutex: MutatorMutex = MutatorMutex()) : MutableComposable by mutableStateOf(null) {
@Composable
fun rememberLocal() = remember { DialogState(mutex) }
context(BoxScope)
@Composable
fun Place() = value?.let { it() }
fun dismiss() {
value = null
@@ -753,4 +758,4 @@ private fun CheckableItem(text: String, checked: Boolean, modifier: Modifier = M
private val IconWithTextCorner = RoundedCornerShape(8.dp)
private val DatePickerTitlePadding = PaddingValues(start = 24.dp, end = 12.dp, top = 16.dp)
val LocalDialogState = compositionLocalOf<DialogState> { error("CompositionLocal LocalDialogState not present!") }
val LocalGlobalDialogState = compositionLocalOf<DialogState> { error("CompositionLocal LocalDialogState not present!") }