Feat(ToolView): Add preview tooltip

This commit is contained in:
2024-08-12 17:39:32 +08:00
parent a3800bfad6
commit 60ffc569a5
8 changed files with 48 additions and 11 deletions

View File

@@ -145,7 +145,9 @@ fun OxygenApp(appState: OxygenAppState) {
if (destination != null) { if (destination != null) {
OxygenTopAppBar( OxygenTopAppBar(
scrollBehavior = topAppBarScrollBehavior, scrollBehavior = topAppBarScrollBehavior,
titleRes = destination.titleTextId, title = {
Text(text = stringResource(id = destination.titleTextId))
},
navigationIcon = OxygenIcons.Search, navigationIcon = OxygenIcons.Search,
navigationIconContentDescription = stringResource(R.string.feature_settings_top_app_bar_navigation_icon_description), navigationIconContentDescription = stringResource(R.string.feature_settings_top_app_bar_navigation_icon_description),
actionIcon = OxygenIcons.MoreVert, actionIcon = OxygenIcons.MoreVert,

View File

@@ -84,7 +84,9 @@ internal fun AboutScreen(
) { ) {
OxygenTopAppBar( OxygenTopAppBar(
scrollBehavior = topAppBarScrollBehavior, scrollBehavior = topAppBarScrollBehavior,
titleRes = R.string.feature_settings_more_about, title = {
Text(text = stringResource(id = R.string.feature_settings_more_about))
},
navigationIcon = OxygenIcons.Back, navigationIcon = OxygenIcons.Back,
navigationIconContentDescription = stringResource(R.string.core_back), navigationIconContentDescription = stringResource(R.string.core_back),
colors = TopAppBarDefaults.centerAlignedTopAppBarColors( colors = TopAppBarDefaults.centerAlignedTopAppBarColors(

View File

@@ -134,7 +134,9 @@ internal fun LibrariesScreen(
) { ) {
OxygenTopAppBar( OxygenTopAppBar(
scrollBehavior = topAppBarScrollBehavior, scrollBehavior = topAppBarScrollBehavior,
titleRes = R.string.feature_settings_open_source_license, title = {
Text(text = stringResource(id = R.string.feature_settings_open_source_license))
},
navigationIcon = OxygenIcons.Back, navigationIcon = OxygenIcons.Back,
navigationIconContentDescription = stringResource(R.string.core_back), navigationIconContentDescription = stringResource(R.string.core_back),
actionIcon = OxygenIcons.Search, actionIcon = OxygenIcons.Search,

View File

@@ -1,6 +1,5 @@
package top.fatweb.oxygen.toolbox.ui.component package top.fatweb.oxygen.toolbox.ui.component
import androidx.annotation.StringRes
import androidx.compose.animation.core.animateIntAsState import androidx.compose.animation.core.animateIntAsState
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.WindowInsets
@@ -46,7 +45,7 @@ import android.R as androidR
fun OxygenTopAppBar( fun OxygenTopAppBar(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
scrollBehavior: TopAppBarScrollBehavior? = null, scrollBehavior: TopAppBarScrollBehavior? = null,
@StringRes titleRes: Int? = null, title: @Composable () -> Unit = {},
navigationIcon: ImageVector? = null, navigationIcon: ImageVector? = null,
navigationIconContentDescription: String? = null, navigationIconContentDescription: String? = null,
actionIcon: ImageVector? = null, actionIcon: ImageVector? = null,
@@ -120,7 +119,7 @@ fun OxygenTopAppBar(
if ("\n" !in it) onQueryChange(it) if ("\n" !in it) onQueryChange(it)
} }
) )
else if (titleRes != null) Text(stringResource(titleRes)) else title()
}, },
navigationIcon = { navigationIcon = {
navigationIcon?.let { navigationIcon?.let {
@@ -161,7 +160,7 @@ fun OxygenTopAppBar(
private fun OxygenTopAppBarPreview() { private fun OxygenTopAppBarPreview() {
OxygenTheme { OxygenTheme {
OxygenTopAppBar( OxygenTopAppBar(
titleRes = androidR.string.untitled, title = { Text(text = stringResource(androidR.string.untitled)) },
navigationIcon = OxygenIcons.Search, navigationIcon = OxygenIcons.Search,
navigationIconContentDescription = "Navigation icon", navigationIconContentDescription = "Navigation icon",
actionIcon = OxygenIcons.MoreVert, actionIcon = OxygenIcons.MoreVert,

View File

@@ -47,10 +47,12 @@ internal fun ToolViewRoute(
viewModel: ToolViewScreenViewModel = hiltViewModel(), viewModel: ToolViewScreenViewModel = hiltViewModel(),
onBackClick: () -> Unit onBackClick: () -> Unit
) { ) {
val isPreview by viewModel.isPreview.collectAsStateWithLifecycle()
val toolViewUiState by viewModel.toolViewUiState.collectAsStateWithLifecycle() val toolViewUiState by viewModel.toolViewUiState.collectAsStateWithLifecycle()
ToolViewScreen( ToolViewScreen(
modifier = modifier, modifier = modifier,
isPreview = isPreview,
onBackClick = onBackClick, onBackClick = onBackClick,
toolViewUiState = toolViewUiState toolViewUiState = toolViewUiState
) )
@@ -61,6 +63,7 @@ internal fun ToolViewRoute(
@Composable @Composable
internal fun ToolViewScreen( internal fun ToolViewScreen(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
isPreview: Boolean,
onBackClick: () -> Unit, onBackClick: () -> Unit,
toolViewUiState: ToolViewUiState toolViewUiState: ToolViewUiState
) { ) {
@@ -70,7 +73,7 @@ internal fun ToolViewScreen(
Scaffold( Scaffold(
modifier = Modifier, modifier = Modifier,
containerColor = Color.Transparent, containerColor = Color.Transparent,
contentWindowInsets = WindowInsets(0, 0, 0, 0), contentWindowInsets = WindowInsets(0, 0, 0, 0)
) { padding -> ) { padding ->
Column( Column(
modifier modifier
@@ -85,6 +88,18 @@ internal fun ToolViewScreen(
) { ) {
OxygenTopAppBar( OxygenTopAppBar(
modifier = Modifier.zIndex(100f), modifier = Modifier.zIndex(100f),
title = {
Text(
text = when (toolViewUiState) {
ToolViewUiState.Loading -> stringResource(R.string.core_loading)
ToolViewUiState.Error -> stringResource(R.string.feature_tools_can_not_open)
is ToolViewUiState.Success -> if (isPreview) stringResource(
R.string.feature_tool_view_preview_suffix,
toolViewUiState.toolName
) else toolViewUiState.toolName
}
)
},
navigationIcon = OxygenIcons.Back, navigationIcon = OxygenIcons.Back,
navigationIconContentDescription = stringResource(R.string.core_back), navigationIconContentDescription = stringResource(R.string.core_back),
colors = TopAppBarDefaults.centerAlignedTopAppBarColors( colors = TopAppBarDefaults.centerAlignedTopAppBarColors(

View File

@@ -27,11 +27,14 @@ class ToolViewScreenViewModel @Inject constructor(
toolRepository: ToolRepository, toolRepository: ToolRepository,
savedStateHandle: SavedStateHandle savedStateHandle: SavedStateHandle
) : ViewModel() { ) : ViewModel() {
val isPreview = savedStateHandle.getStateFlow(IS_PREVIEW, false)
private val toolViewArgs = ToolViewArgs(savedStateHandle) private val toolViewArgs = ToolViewArgs(savedStateHandle)
val username = toolViewArgs.username private val username = toolViewArgs.username
val toolId = toolViewArgs.toolId private val toolId = toolViewArgs.toolId
val toolViewUiState: StateFlow<ToolViewUiState> = toolViewUiState( val toolViewUiState: StateFlow<ToolViewUiState> = toolViewUiState(
savedStateHandle = savedStateHandle,
username = username, username = username,
toolId = toolId, toolId = toolId,
storeRepository = storeRepository, storeRepository = storeRepository,
@@ -45,6 +48,7 @@ class ToolViewScreenViewModel @Inject constructor(
} }
private fun toolViewUiState( private fun toolViewUiState(
savedStateHandle: SavedStateHandle,
username: String, username: String,
toolId: String, toolId: String,
storeRepository: StoreRepository, storeRepository: StoreRepository,
@@ -56,6 +60,7 @@ private fun toolViewUiState(
return flow { return flow {
combine(entityFlow, toolViewTemplate, ::Pair).collect { (entityFlow, toolViewTemplate) -> combine(entityFlow, toolViewTemplate, ::Pair).collect { (entityFlow, toolViewTemplate) ->
if (entityFlow == null) { if (entityFlow == null) {
savedStateHandle[IS_PREVIEW] = true
storeRepository.detail(username, toolId).collect { storeRepository.detail(username, toolId).collect {
emit( emit(
when (it) { when (it) {
@@ -63,6 +68,7 @@ private fun toolViewUiState(
val dist = it.data.dist!! val dist = it.data.dist!!
val base = it.data.base!! val base = it.data.base!!
ToolViewUiState.Success( ToolViewUiState.Success(
it.data.name,
processHtml( processHtml(
toolViewTemplate = toolViewTemplate, toolViewTemplate = toolViewTemplate,
distBase64 = dist, distBase64 = dist,
@@ -83,8 +89,10 @@ private fun toolViewUiState(
) )
} }
} else { } else {
savedStateHandle[IS_PREVIEW] = false
emit( emit(
ToolViewUiState.Success( ToolViewUiState.Success(
entityFlow.name,
processHtml( processHtml(
toolViewTemplate = toolViewTemplate, toolViewTemplate = toolViewTemplate,
distBase64 = entityFlow.dist!!, distBase64 = entityFlow.dist!!,
@@ -98,7 +106,10 @@ private fun toolViewUiState(
} }
sealed interface ToolViewUiState { sealed interface ToolViewUiState {
data class Success(val htmlData: String) : ToolViewUiState data class Success(
val toolName: String,
val htmlData: String
) : ToolViewUiState
data object Error : ToolViewUiState data object Error : ToolViewUiState
@@ -112,3 +123,5 @@ private fun processHtml(toolViewTemplate: String, distBase64: String, baseBase64
return toolViewTemplate.replace("{{replace_code}}", "$dist\n$base") return toolViewTemplate.replace("{{replace_code}}", "$dist\n$base")
} }
private const val IS_PREVIEW = "IS_PREVIEW"

View File

@@ -33,6 +33,8 @@
<string name="feature_tools_no_tools_installed">暂无工具已安装</string> <string name="feature_tools_no_tools_installed">暂无工具已安装</string>
<string name="feature_tools_go_to_store">前往商店…</string> <string name="feature_tools_go_to_store">前往商店…</string>
<string name="feature_tool_view_preview_suffix">%1$s (预览)</string>
<string name="feature_star_title">收藏</string> <string name="feature_star_title">收藏</string>
<string name="feature_settings_title">设置</string> <string name="feature_settings_title">设置</string>

View File

@@ -32,6 +32,8 @@
<string name="feature_tools_no_tools_installed">No tools installed yet</string> <string name="feature_tools_no_tools_installed">No tools installed yet</string>
<string name="feature_tools_go_to_store">Go to store…</string> <string name="feature_tools_go_to_store">Go to store…</string>
<string name="feature_tool_view_preview_suffix">%1$s (Preview)</string>
<string name="feature_star_title">Star</string> <string name="feature_star_title">Star</string>
<string name="feature_settings_title">Settings</string> <string name="feature_settings_title">Settings</string>