diff --git a/app/src/main/java/com/hippo/ehviewer/ui/settings/AboutScreen.kt b/app/src/main/java/com/hippo/ehviewer/ui/settings/AboutScreen.kt index 660548acb..417603048 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/settings/AboutScreen.kt +++ b/app/src/main/java/com/hippo/ehviewer/ui/settings/AboutScreen.kt @@ -1,5 +1,8 @@ package com.hippo.ehviewer.ui.settings +import android.text.Html +import android.text.Spanned +import android.text.style.StrikethroughSpan import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.padding import androidx.compose.material.icons.Icons @@ -10,8 +13,14 @@ import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.AnnotatedString +import androidx.compose.ui.text.SpanStyle +import androidx.compose.ui.text.buildAnnotatedString +import androidx.compose.ui.text.style.TextDecoration +import com.hippo.ehviewer.BuildConfig import com.hippo.ehviewer.R import com.hippo.ehviewer.ui.login.LocalNavController @@ -31,6 +40,31 @@ fun AboutScreen() { }, ) { Column(modifier = Modifier.padding(it)) { + Preference(title = stringResource(id = R.string.settings_about_declaration), summary = stringResource(id = R.string.settings_about_declaration_summary)) + val author = stringResource(R.string.settings_about_author_summary).replace('$', '@').let { + fun Spanned.toAnnotatedString(): AnnotatedString = buildAnnotatedString { + val spanned = this@toAnnotatedString + append(spanned.toString()) + getSpans(0, spanned.length, Any::class.java).forEach { span -> + val start = getSpanStart(span) + val end = getSpanEnd(span) + when (span) { + is StrikethroughSpan -> addStyle(SpanStyle(textDecoration = TextDecoration.LineThrough), start, end) + } + } + } + remember { Html.fromHtml(it, Html.FROM_HTML_MODE_LEGACY).toAnnotatedString() } + } + HtmlPreference(title = stringResource(id = R.string.settings_about_author), summary = author) + val url = "https://github.com/Ehviewer-Overhauled/Ehviewer/releases" + UrlPreference(title = stringResource(id = R.string.settings_about_latest_release), url = url) + val url2 = "https://github.com/Ehviewer-Overhauled/Ehviewer" + UrlPreference(title = stringResource(id = R.string.settings_about_source), url = url2) + Preference(title = stringResource(id = R.string.license)) { + navController.navigate(LICENSE_SCREEN) + } + Preference(title = stringResource(id = R.string.settings_about_version), summary = "${BuildConfig.VERSION_NAME} (${BuildConfig.COMMIT_SHA})\n" + stringResource(R.string.settings_about_build_time, BuildConfig.BUILD_TIME)) + Preference(title = stringResource(id = R.string.settings_about_check_for_updates)) } } } diff --git a/app/src/main/java/com/hippo/ehviewer/ui/settings/BaseScreen.kt b/app/src/main/java/com/hippo/ehviewer/ui/settings/BaseScreen.kt index 6cdd09ded..c23dd850e 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/settings/BaseScreen.kt +++ b/app/src/main/java/com/hippo/ehviewer/ui/settings/BaseScreen.kt @@ -1,15 +1,8 @@ package com.hippo.ehviewer.ui.settings import android.app.Activity -import androidx.annotation.StringRes -import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Adb import androidx.compose.material.icons.filled.ArrowBack @@ -18,42 +11,15 @@ import androidx.compose.material.icons.filled.Info import androidx.compose.material.icons.filled.Security import androidx.compose.material3.Icon import androidx.compose.material3.IconButton -import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.painter.Painter -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.graphics.vector.rememberVectorPainter import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import com.hippo.ehviewer.R -import com.hippo.ehviewer.ui.login.LocalNavController -import com.hippo.ehviewer.ui.settings.PreferenceTokens.PreferenceHeaderHeight -import com.hippo.ehviewer.ui.settings.PreferenceTokens.PreferenceIconPadding -import com.hippo.ehviewer.ui.settings.PreferenceTokens.PreferenceIconSize -import com.hippo.ehviewer.ui.settings.PreferenceTokens.PreferenceTextPadding - -@Composable -fun PreferenceHeader(icon: Painter, @StringRes title: Int, childRouteName: String) { - val navController = LocalNavController.current - Row( - modifier = Modifier.clickable { navController.navigate(childRouteName) }.fillMaxWidth().height(PreferenceHeaderHeight), - verticalAlignment = Alignment.CenterVertically, - ) { - Spacer(modifier = Modifier.size(PreferenceIconPadding)) - Icon(painter = icon, contentDescription = null, modifier = Modifier.size(PreferenceIconSize), tint = MaterialTheme.colorScheme.primary) - Spacer(modifier = Modifier.size(PreferenceIconPadding)) - Text(text = stringResource(id = title), modifier = Modifier.padding(PreferenceTextPadding)) - } -} - -@Composable -fun PreferenceHeader(icon: ImageVector, @StringRes title: Int, childRouteName: String) = PreferenceHeader(icon = rememberVectorPainter(image = icon), title = title, childRouteName = childRouteName) @Composable fun BaseScreen() { diff --git a/app/src/main/java/com/hippo/ehviewer/ui/settings/LicenseScreen.kt b/app/src/main/java/com/hippo/ehviewer/ui/settings/LicenseScreen.kt new file mode 100644 index 000000000..10151d78d --- /dev/null +++ b/app/src/main/java/com/hippo/ehviewer/ui/settings/LicenseScreen.kt @@ -0,0 +1,36 @@ +package com.hippo.ehviewer.ui.settings + +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.ArrowBack +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import com.hippo.ehviewer.R +import com.hippo.ehviewer.ui.login.LocalNavController +import com.mikepenz.aboutlibraries.ui.compose.LibrariesContainer + +@Composable +fun LicenseScreen() { + val navController = LocalNavController.current + Scaffold( + topBar = { + TopAppBar( + title = { Text(text = stringResource(id = R.string.license)) }, + navigationIcon = { + IconButton(onClick = { navController.popBackStack() }) { + Icon(imageVector = Icons.Default.ArrowBack, contentDescription = null) + } + }, + ) + }, + ) { + LibrariesContainer(modifier = Modifier.fillMaxSize().padding(it)) + } +} diff --git a/app/src/main/java/com/hippo/ehviewer/ui/settings/PreferenceTokens.kt b/app/src/main/java/com/hippo/ehviewer/ui/settings/PreferenceTokens.kt index bbdd7ca98..e4a263f21 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/settings/PreferenceTokens.kt +++ b/app/src/main/java/com/hippo/ehviewer/ui/settings/PreferenceTokens.kt @@ -7,4 +7,7 @@ object PreferenceTokens { val PreferenceIconSize = 24.dp val PreferenceIconPadding = 16.dp val PreferenceTextPadding = 8.dp + + val PreferenceMinHeight = 56.dp + val PreferencePadding = 16.dp } diff --git a/app/src/main/java/com/hippo/ehviewer/ui/settings/PreferenceWidgets.kt b/app/src/main/java/com/hippo/ehviewer/ui/settings/PreferenceWidgets.kt new file mode 100644 index 000000000..242989a3c --- /dev/null +++ b/app/src/main/java/com/hippo/ehviewer/ui/settings/PreferenceWidgets.kt @@ -0,0 +1,83 @@ +package com.hippo.ehviewer.ui.settings + +import androidx.annotation.StringRes +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.defaultMinSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.painter.Painter +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.graphics.vector.rememberVectorPainter +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.AnnotatedString +import com.hippo.ehviewer.ui.login.LocalNavController +import com.hippo.ehviewer.ui.openBrowser +import com.hippo.ehviewer.ui.settings.PreferenceTokens.PreferenceMinHeight +import com.hippo.ehviewer.ui.settings.PreferenceTokens.PreferencePadding +import com.hippo.ehviewer.ui.settings.PreferenceTokens.PreferenceTextPadding + +@Composable +fun PreferenceHeader(icon: Painter, @StringRes title: Int, childRouteName: String) { + val navController = LocalNavController.current + Row( + modifier = Modifier.clickable { navController.navigate(childRouteName) }.fillMaxWidth().height( + PreferenceTokens.PreferenceHeaderHeight, + ), + verticalAlignment = Alignment.CenterVertically, + ) { + Spacer(modifier = Modifier.size(PreferenceTokens.PreferenceIconPadding)) + Icon(painter = icon, contentDescription = null, modifier = Modifier.size(PreferenceTokens.PreferenceIconSize), tint = MaterialTheme.colorScheme.primary) + Spacer(modifier = Modifier.size(PreferenceTokens.PreferenceIconPadding)) + Text(text = stringResource(id = title), modifier = Modifier.padding(PreferenceTextPadding), style = MaterialTheme.typography.bodyLarge) + } +} + +@Composable +fun PreferenceHeader(icon: ImageVector, @StringRes title: Int, childRouteName: String) = PreferenceHeader(icon = rememberVectorPainter(image = icon), title = title, childRouteName = childRouteName) + +@Composable +fun Preference(title: String, summary: String? = null, onClick: () -> Unit = {}) { + Column( + modifier = Modifier.defaultMinSize(minHeight = PreferenceMinHeight).fillMaxWidth().clickable(onClick = onClick).padding(PreferencePadding), + verticalArrangement = Arrangement.Center, + ) { + Text(text = title, style = MaterialTheme.typography.bodyLarge) + summary?.let { + Spacer(modifier = Modifier.size(PreferenceTextPadding)) + Text(text = summary, style = MaterialTheme.typography.bodyMedium) + } + } +} + +@Composable +fun UrlPreference(title: String, url: String) { + val context = LocalContext.current + Preference(title, url) { context.openBrowser(url) } +} + +@Composable +fun HtmlPreference(title: String, summary: AnnotatedString? = null, onClick: () -> Unit = {}) { + Column( + modifier = Modifier.defaultMinSize(minHeight = PreferenceMinHeight).fillMaxWidth().clickable(onClick = onClick).padding(PreferencePadding), + verticalArrangement = Arrangement.Center, + ) { + Text(text = title, style = MaterialTheme.typography.bodyLarge) + summary?.let { + Spacer(modifier = Modifier.size(PreferenceTextPadding)) + Text(text = summary, style = MaterialTheme.typography.bodyMedium) + } + } +} diff --git a/app/src/main/java/com/hippo/ehviewer/ui/settings/SettingsActivity.kt b/app/src/main/java/com/hippo/ehviewer/ui/settings/SettingsActivity.kt index d16ca7ab1..7b32e37bb 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/settings/SettingsActivity.kt +++ b/app/src/main/java/com/hippo/ehviewer/ui/settings/SettingsActivity.kt @@ -24,6 +24,9 @@ class SettingsActivity : EhActivity() { composable(ABOUT_SETTINGS_SCREEN) { AboutScreen() } + composable(LICENSE_SCREEN) { + LicenseScreen() + } } } } @@ -41,3 +44,4 @@ const val DOWNLOAD_SETTINGS_SCREEN = "Download" const val SECURITY_SETTINGS_SCREEN = "Security" const val ADVANCED_SETTINGS_SCREEN = "Advanced" const val ABOUT_SETTINGS_SCREEN = "About" +const val LICENSE_SCREEN = "License"