Feat(App): Support full screen
This commit is contained in:
@@ -10,6 +10,8 @@ import androidx.compose.material.icons.filled.Close
|
||||
import androidx.compose.material.icons.filled.Code
|
||||
import androidx.compose.material.icons.filled.Delete
|
||||
import androidx.compose.material.icons.filled.Download
|
||||
import androidx.compose.material.icons.filled.Fullscreen
|
||||
import androidx.compose.material.icons.filled.FullscreenExit
|
||||
import androidx.compose.material.icons.filled.Inbox
|
||||
import androidx.compose.material.icons.filled.MoreVert
|
||||
import androidx.compose.material.icons.filled.Reorder
|
||||
@@ -43,6 +45,8 @@ object OxygenIcons {
|
||||
val Delete = Icons.Default.Delete
|
||||
val Download = Icons.Default.Download
|
||||
val Error = Icons.Default.Cancel
|
||||
val FullScreen = Icons.Default.Fullscreen
|
||||
val FullScreenExit = Icons.Default.FullscreenExit
|
||||
val Home = Icons.Rounded.Home
|
||||
val HomeBorder = Icons.Outlined.Home
|
||||
val Info = Icons.Outlined.Info
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
package top.fatweb.oxygen.toolbox.navigation
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.navigation.NavController
|
||||
import androidx.navigation.NavDestination
|
||||
import androidx.navigation.compose.NavHost
|
||||
import top.fatweb.oxygen.toolbox.ui.OxygenAppState
|
||||
import top.fatweb.oxygen.toolbox.ui.util.LocalFullScreen
|
||||
|
||||
@Composable
|
||||
fun OxygenNavHost(
|
||||
@@ -16,6 +21,21 @@ fun OxygenNavHost(
|
||||
onShowSnackbar: suspend (message: String, action: String?) -> Boolean
|
||||
) {
|
||||
val navController = appState.navController
|
||||
val fullScreen = LocalFullScreen.current
|
||||
|
||||
LaunchedEffect(navController) {
|
||||
navController.addOnDestinationChangedListener(object :
|
||||
NavController.OnDestinationChangedListener {
|
||||
override fun onDestinationChanged(
|
||||
controller: NavController,
|
||||
destination: NavDestination,
|
||||
arguments: Bundle?
|
||||
) {
|
||||
fullScreen.onStateChange.invoke(false)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
NavHost(
|
||||
modifier = modifier,
|
||||
navController = navController,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package top.fatweb.oxygen.toolbox.ui
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
@@ -7,7 +8,6 @@ import androidx.compose.foundation.layout.WindowInsets
|
||||
import androidx.compose.foundation.layout.WindowInsetsSides
|
||||
import androidx.compose.foundation.layout.consumeWindowInsets
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.only
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.safeDrawing
|
||||
@@ -24,6 +24,7 @@ import androidx.compose.material3.SnackbarResult
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableIntStateOf
|
||||
@@ -34,9 +35,11 @@ import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.core.view.WindowInsetsControllerCompat
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import androidx.navigation.NavDestination
|
||||
import androidx.navigation.NavDestination.Companion.hierarchy
|
||||
@@ -59,6 +62,8 @@ import top.fatweb.oxygen.toolbox.ui.component.SearchButtonPosition
|
||||
import top.fatweb.oxygen.toolbox.ui.settings.SettingsDialog
|
||||
import top.fatweb.oxygen.toolbox.ui.theme.GradientColors
|
||||
import top.fatweb.oxygen.toolbox.ui.theme.LocalGradientColors
|
||||
import top.fatweb.oxygen.toolbox.ui.util.FullScreen
|
||||
import top.fatweb.oxygen.toolbox.ui.util.LocalFullScreen
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
@@ -69,6 +74,32 @@ fun OxygenApp(appState: OxygenAppState) {
|
||||
mutableStateOf(false)
|
||||
}
|
||||
|
||||
val context = LocalContext.current
|
||||
val window = (context as ComponentActivity).window
|
||||
val windowInsetsController = WindowInsetsControllerCompat(window, window.decorView)
|
||||
var isFullScreen by remember { mutableStateOf(false) }
|
||||
|
||||
val fullScreen = FullScreen(
|
||||
enable = isFullScreen,
|
||||
onStateChange = {
|
||||
isFullScreen = it
|
||||
}
|
||||
)
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
windowInsetsController.systemBarsBehavior =
|
||||
WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
|
||||
}
|
||||
|
||||
LaunchedEffect(isFullScreen) {
|
||||
if (isFullScreen) {
|
||||
windowInsetsController.hide(WindowInsetsCompat.Type.systemBars())
|
||||
} else {
|
||||
windowInsetsController.show(WindowInsetsCompat.Type.systemBars())
|
||||
}
|
||||
}
|
||||
|
||||
CompositionLocalProvider(LocalFullScreen provides fullScreen) {
|
||||
OxygenBackground {
|
||||
OxygenGradientBackground(
|
||||
gradientColors = if (shouldShowGradientBackground) LocalGradientColors.current else GradientColors()
|
||||
@@ -228,6 +259,7 @@ fun OxygenApp(appState: OxygenAppState) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun OxygenBottomBar(
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package top.fatweb.oxygen.toolbox.ui.util
|
||||
|
||||
import androidx.compose.runtime.compositionLocalOf
|
||||
|
||||
data class FullScreen(
|
||||
val enable: Boolean = false,
|
||||
val onStateChange: (Boolean) -> Unit = {}
|
||||
)
|
||||
|
||||
val LocalFullScreen = compositionLocalOf { FullScreen() }
|
||||
@@ -64,6 +64,7 @@ import top.fatweb.oxygen.toolbox.R
|
||||
import top.fatweb.oxygen.toolbox.icon.OxygenIcons
|
||||
import top.fatweb.oxygen.toolbox.ui.component.Indicator
|
||||
import top.fatweb.oxygen.toolbox.ui.component.OxygenTopAppBar
|
||||
import top.fatweb.oxygen.toolbox.ui.util.LocalFullScreen
|
||||
import top.fatweb.oxygen.toolbox.ui.util.ResourcesUtils
|
||||
import top.fatweb.oxygen.toolbox.util.NativeWebApi
|
||||
import top.fatweb.oxygen.toolbox.util.Permissions
|
||||
@@ -98,6 +99,7 @@ internal fun ToolViewScreen(
|
||||
isPreview: Boolean,
|
||||
onBackClick: () -> Unit
|
||||
) {
|
||||
val (isFullScreen, onFullScreenStateChange) = LocalFullScreen.current
|
||||
|
||||
Column(
|
||||
modifier
|
||||
@@ -111,7 +113,9 @@ internal fun ToolViewScreen(
|
||||
TopBar(
|
||||
toolViewUiState = toolViewUiState,
|
||||
isPreview = isPreview,
|
||||
onBackClick = onBackClick
|
||||
isFullScreen = isFullScreen,
|
||||
onBackClick = onBackClick,
|
||||
onFullScreenChange = onFullScreenStateChange
|
||||
)
|
||||
Content(
|
||||
toolViewUiState = toolViewUiState,
|
||||
@@ -125,7 +129,9 @@ internal fun ToolViewScreen(
|
||||
private fun TopBar(
|
||||
toolViewUiState: ToolViewUiState,
|
||||
isPreview: Boolean,
|
||||
onBackClick: () -> Unit
|
||||
isFullScreen: Boolean,
|
||||
onBackClick: () -> Unit,
|
||||
onFullScreenChange: (Boolean) -> Unit
|
||||
) = OxygenTopAppBar(
|
||||
title = {
|
||||
Text(
|
||||
@@ -143,11 +149,16 @@ private fun TopBar(
|
||||
},
|
||||
navigationIcon = OxygenIcons.Back,
|
||||
navigationIconContentDescription = stringResource(R.string.core_back),
|
||||
actionIcon = if (isFullScreen) OxygenIcons.FullScreenExit else OxygenIcons.FullScreen,
|
||||
actionIconContentDescription = stringResource(if (isFullScreen) R.string.core_exit_full_screen else R.string.core_full_screen),
|
||||
colors = TopAppBarDefaults.centerAlignedTopAppBarColors(
|
||||
containerColor = Color.Transparent,
|
||||
scrolledContainerColor = Color.Transparent
|
||||
),
|
||||
onNavigationClick = onBackClick
|
||||
onNavigationClick = onBackClick,
|
||||
onActionClick = {
|
||||
onFullScreenChange(!isFullScreen)
|
||||
}
|
||||
)
|
||||
|
||||
@Composable
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
<string name="core_search">搜索</string>
|
||||
<string name="core_loading">加载中…</string>
|
||||
<string name="core_no_connect">⚠️ 无法连接至互联网</string>
|
||||
<string name="core_full_screen">全屏</string>
|
||||
<string name="core_exit_full_screen">退出全屏</string>
|
||||
<string name="core_install">安装</string>
|
||||
<string name="core_installing">安装中……</string>
|
||||
<string name="core_upgrade">更新</string>
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
<string name="core_search">Search</string>
|
||||
<string name="core_loading">Loading…</string>
|
||||
<string name="core_no_connect">⚠️ Unable to connect to the internet</string>
|
||||
<string name="core_full_screen">Full Screen</string>
|
||||
<string name="core_exit_full_screen">Exit Full Screen</string>
|
||||
<string name="core_install">Install</string>
|
||||
<string name="core_installing">Installing…</string>
|
||||
<string name="core_upgrade">Upgrade</string>
|
||||
|
||||
Reference in New Issue
Block a user