feat(about): 优化许可证页面显示效果
This commit is contained in:
parent
2fd528b5bd
commit
7231bbda47
5 changed files with 230 additions and 9 deletions
|
|
@ -0,0 +1,25 @@
|
|||
package cn.super12138.todo.ui.components
|
||||
|
||||
import androidx.compose.foundation.lazy.LazyListState
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import my.nanihadesuka.compose.LazyColumnScrollbar
|
||||
import my.nanihadesuka.compose.ScrollbarSettings
|
||||
|
||||
@Composable
|
||||
fun LazyColumnCustomScrollBar(
|
||||
state: LazyListState,
|
||||
modifier: Modifier = Modifier,
|
||||
content: @Composable () -> Unit
|
||||
) {
|
||||
LazyColumnScrollbar(
|
||||
state = state,
|
||||
modifier = modifier,
|
||||
settings = ScrollbarSettings(
|
||||
thumbUnselectedColor = MaterialTheme.colorScheme.secondary,
|
||||
thumbSelectedColor = MaterialTheme.colorScheme.primary
|
||||
),
|
||||
content = content
|
||||
)
|
||||
}
|
||||
|
|
@ -22,9 +22,8 @@ import cn.super12138.todo.logic.database.TodoEntity
|
|||
import cn.super12138.todo.logic.model.Priority
|
||||
import cn.super12138.todo.logic.model.Subjects
|
||||
import cn.super12138.todo.ui.TodoDefaults
|
||||
import cn.super12138.todo.ui.components.LazyColumnCustomScrollBar
|
||||
import cn.super12138.todo.ui.pages.main.components.TodoCard
|
||||
import my.nanihadesuka.compose.LazyColumnScrollbar
|
||||
import my.nanihadesuka.compose.ScrollbarSettings
|
||||
|
||||
@OptIn(ExperimentalSharedTransitionApi::class)
|
||||
@Composable
|
||||
|
|
@ -40,12 +39,8 @@ fun ManagerFragment(
|
|||
modifier: Modifier = Modifier
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
LazyColumnScrollbar(
|
||||
LazyColumnCustomScrollBar(
|
||||
state = state,
|
||||
settings = ScrollbarSettings(
|
||||
thumbUnselectedColor = MaterialTheme.colorScheme.secondary,
|
||||
thumbSelectedColor = MaterialTheme.colorScheme.primary
|
||||
),
|
||||
modifier = modifier
|
||||
) {
|
||||
LazyColumn(
|
||||
|
|
|
|||
|
|
@ -3,14 +3,21 @@ package cn.super12138.todo.ui.pages.settings
|
|||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.produceState
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import cn.super12138.todo.R
|
||||
import cn.super12138.todo.ui.components.LargeTopAppBarScaffold
|
||||
import com.mikepenz.aboutlibraries.ui.compose.m3.LibrariesContainer
|
||||
import cn.super12138.todo.ui.pages.settings.components.licence.LicenceList
|
||||
import com.mikepenz.aboutlibraries.Libs
|
||||
import com.mikepenz.aboutlibraries.util.withContext
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
|
|
@ -25,12 +32,23 @@ fun SettingsAboutLicence(
|
|||
onBack = onNavigateUp,
|
||||
modifier = modifier
|
||||
) { innerPadding ->
|
||||
val context = LocalContext.current
|
||||
|
||||
val libraries = produceState<Libs?>(null) {
|
||||
value = withContext(Dispatchers.IO) {
|
||||
Libs.Builder().withContext(context).build()
|
||||
}
|
||||
}
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(innerPadding)
|
||||
) {
|
||||
LibrariesContainer()
|
||||
val listState = rememberLazyListState()
|
||||
LicenceList(
|
||||
libraries = libraries.value,
|
||||
state = listState
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
package cn.super12138.todo.ui.pages.settings.components.licence
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.ExperimentalLayoutApi
|
||||
import androidx.compose.foundation.layout.FlowRow
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.Badge
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.Typography
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Shape
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import com.mikepenz.aboutlibraries.entity.Library
|
||||
import com.mikepenz.aboutlibraries.ui.compose.m3.LibraryColors
|
||||
import com.mikepenz.aboutlibraries.ui.compose.m3.LibraryDefaults
|
||||
import com.mikepenz.aboutlibraries.ui.compose.m3.LibraryPadding
|
||||
import com.mikepenz.aboutlibraries.ui.compose.m3.util.author
|
||||
|
||||
@OptIn(ExperimentalLayoutApi::class)
|
||||
@Composable
|
||||
fun LicenceItem(
|
||||
library: Library,
|
||||
showAuthor: Boolean = true,
|
||||
showVersion: Boolean = true,
|
||||
showLicenseBadges: Boolean = true,
|
||||
colors: LibraryColors = LibraryDefaults.libraryColors(),
|
||||
padding: LibraryPadding = LibraryDefaults.libraryPadding(),
|
||||
contentPadding: PaddingValues = LibraryDefaults.ContentPadding,
|
||||
typography: Typography = MaterialTheme.typography,
|
||||
shape: Shape = MaterialTheme.shapes.large,
|
||||
onClick: () -> Unit,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
Column(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.background(colors.backgroundColor)
|
||||
.clip(shape)
|
||||
.clickable { onClick.invoke() }
|
||||
.padding(contentPadding)
|
||||
) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.SpaceBetween
|
||||
) {
|
||||
Text(
|
||||
text = library.name,
|
||||
modifier = Modifier
|
||||
.padding(padding.namePadding)
|
||||
.weight(1f),
|
||||
style = typography.titleLarge,
|
||||
color = colors.contentColor,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
val version = library.artifactVersion
|
||||
if (version != null && showVersion) {
|
||||
Text(
|
||||
version,
|
||||
modifier = Modifier.padding(padding.versionPadding),
|
||||
style = typography.bodyMedium,
|
||||
color = colors.contentColor,
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
}
|
||||
}
|
||||
val author = library.author
|
||||
if (showAuthor && author.isNotBlank()) {
|
||||
Text(
|
||||
text = author,
|
||||
style = typography.bodyMedium,
|
||||
color = colors.contentColor
|
||||
)
|
||||
}
|
||||
if (showLicenseBadges && library.licenses.isNotEmpty()) {
|
||||
FlowRow {
|
||||
library.licenses.forEach {
|
||||
Badge(
|
||||
modifier = Modifier.padding(padding.badgePadding),
|
||||
contentColor = colors.badgeContentColor,
|
||||
containerColor = colors.badgeBackgroundColor
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier.padding(padding.badgeContentPadding),
|
||||
text = it.name
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
package cn.super12138.todo.ui.pages.settings.components.licence
|
||||
|
||||
import android.util.Log
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.LazyListState
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.foundation.text.selection.SelectionContainer
|
||||
import androidx.compose.material3.FilledTonalButton
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalUriHandler
|
||||
import androidx.compose.ui.platform.LocalView
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import cn.super12138.todo.R
|
||||
import cn.super12138.todo.ui.components.BasicDialog
|
||||
import cn.super12138.todo.ui.components.LazyColumnCustomScrollBar
|
||||
import cn.super12138.todo.utils.VibrationUtils
|
||||
import com.mikepenz.aboutlibraries.Libs
|
||||
import com.mikepenz.aboutlibraries.ui.compose.m3.util.htmlReadyLicenseContent
|
||||
|
||||
@Composable
|
||||
fun LicenceList(
|
||||
libraries: Libs?,
|
||||
state: LazyListState = rememberLazyListState(),
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
val uriHandler = LocalUriHandler.current
|
||||
val view = LocalView.current
|
||||
LazyColumnCustomScrollBar(state = state) {
|
||||
LazyColumn(state = state) {
|
||||
items(libraries?.libraries ?: listOf()) { library ->
|
||||
var openDialog by rememberSaveable { mutableStateOf(false) }
|
||||
|
||||
LicenceItem(
|
||||
library = library,
|
||||
onClick = {
|
||||
val license = library.licenses.firstOrNull()
|
||||
if (!license?.htmlReadyLicenseContent.isNullOrBlank()) {
|
||||
openDialog = true
|
||||
} else if (!license?.url.isNullOrBlank()) {
|
||||
license?.url?.also {
|
||||
try {
|
||||
uriHandler.openUri(it)
|
||||
} catch (t: Throwable) {
|
||||
Log.e("Licence", "Failed to open the URL: $it")
|
||||
}
|
||||
}
|
||||
}
|
||||
VibrationUtils.performHapticFeedback(view)
|
||||
},
|
||||
)
|
||||
|
||||
BasicDialog(
|
||||
visible = openDialog,
|
||||
title = { Text(library.name) },
|
||||
text = {
|
||||
library.licenses.firstOrNull()?.licenseContent?.let {
|
||||
SelectionContainer {
|
||||
Text(text = it)
|
||||
}
|
||||
}
|
||||
},
|
||||
confirmButton = {
|
||||
FilledTonalButton(onClick = {
|
||||
openDialog = false
|
||||
VibrationUtils.performHapticFeedback(view)
|
||||
}) { Text(stringResource(R.string.action_confirm)) }
|
||||
},
|
||||
onDismissRequest = { openDialog = false }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue