Compose settings: about screen

This commit is contained in:
MM20 2021-09-26 21:31:30 +02:00
parent f1546d3d3e
commit 98e8769974
No known key found for this signature in database
GPG Key ID: 0B61A8F2DEAFA389
6 changed files with 400 additions and 2 deletions

View File

@ -58,7 +58,7 @@
<string name="preference_translucent_cards">Durchscheinende Karten</string>
<string name="preference_category_debug">Debug</string>
<string name="preference_export_debug">Debug-Informationen exportieren</string>
<string name="debug_export_information_file">Exportiere nach %1$s</string>
<string name="debug_export_information_file">Exportiert nach %1$s</string>
<string name="wikipedia_url">https://de.wikipedia.org</string>
<string name="wikipedia_source">Aus Wikipedia</string>
<string name="preference_category_icons">Symbole</string>

View File

@ -91,7 +91,7 @@
<string name="preference_translucent_cards">Translucent cards</string>
<string name="preference_category_debug">Debug</string>
<string name="preference_export_debug">Export debug information</string>
<string name="debug_export_information_file">Exporting to %1$s</string>
<string name="debug_export_information_file">Exported to %1$s</string>
<!-- Wikipedia url prefix -->
<string name="wikipedia_url">https://en.wikipedia.org</string>
<string name="wikipedia_source">From Wikipedia</string>

View File

@ -17,6 +17,7 @@ import androidx.lifecycle.lifecycleScope
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import androidx.navigation.navArgument
import com.google.accompanist.insets.ProvideWindowInsets
import de.mm20.launcher2.ui.LauncherTheme
import de.mm20.launcher2.ui.locals.LocalAppWidgetHost
@ -24,6 +25,8 @@ import de.mm20.launcher2.ui.locals.LocalColorScheme
import de.mm20.launcher2.ui.locals.LocalNavController
import de.mm20.launcher2.ui.locals.LocalWindowSize
import de.mm20.launcher2.ui.screens.LauncherMainScreen
import de.mm20.launcher2.ui.screens.settings.SettingsAboutScreen
import de.mm20.launcher2.ui.screens.settings.SettingsLicenseScreen
import de.mm20.launcher2.ui.screens.settings.SettingsMainScreen
import de.mm20.launcher2.ui.theme.WallpaperColors
import de.mm20.launcher2.ui.theme.colors.DefaultColorScheme
@ -100,6 +103,17 @@ class ComposeActivity : AppCompatActivity() {
composable("settings") {
SettingsMainScreen()
}
composable("settings/about") {
SettingsAboutScreen()
}
composable(
"settings/license?library={libraryName}",
arguments = listOf(navArgument("libraryName") {
nullable = true
})
) {
SettingsLicenseScreen(it.arguments?.getString("libraryName"))
}
}
}
}

View File

@ -645,4 +645,122 @@ val Icons.Rounded.NotificationBadge
arcTo(4f, 4f, 0f, false, false, 18f, 14f)
close()
}
}
val Icons.Rounded.GitHub
get() = materialIcon("Icons.Rounded.GitHub") {
materialPath {
moveTo(12f, 2f)
arcTo(10f, 10f, 0f, false, false, 2f, 12f)
curveTo(2f, 16.42f, 4.87f, 20.17f, 8.84f, 21.5f)
curveTo(9.34f, 21.58f, 9.5f, 21.27f, 9.5f, 21f)
curveTo(9.5f, 20.77f, 9.5f, 20.14f, 9.5f, 19.31f)
curveTo(6.73f, 19.91f, 6.14f, 17.97f, 6.14f, 17.97f)
curveTo(5.68f, 16.81f, 5.03f, 16.5f, 5.03f, 16.5f)
curveTo(4.12f, 15.88f, 5.1f, 15.9f, 5.1f, 15.9f)
curveTo(6.1f, 15.97f, 6.63f, 16.93f, 6.63f, 16.93f)
curveTo(7.5f, 18.45f, 8.97f, 18f, 9.54f, 17.76f)
curveTo(9.63f, 17.11f, 9.89f, 16.67f, 10.17f, 16.42f)
curveTo(7.95f, 16.17f, 5.62f, 15.31f, 5.62f, 11.5f)
curveTo(5.62f, 10.39f, 6f, 9.5f, 6.65f, 8.79f)
curveTo(6.55f, 8.54f, 6.2f, 7.5f, 6.75f, 6.15f)
curveTo(6.75f, 6.15f, 7.59f, 5.88f, 9.5f, 7.17f)
curveTo(10.29f, 6.95f, 11.15f, 6.84f, 12f, 6.84f)
curveTo(12.85f, 6.84f, 13.71f, 6.95f, 14.5f, 7.17f)
curveTo(16.41f, 5.88f, 17.25f, 6.15f, 17.25f, 6.15f)
curveTo(17.8f, 7.5f, 17.45f, 8.54f, 17.35f, 8.79f)
curveTo(18f, 9.5f, 18.38f, 10.39f, 18.38f, 11.5f)
curveTo(18.38f, 15.32f, 16.04f, 16.16f, 13.81f, 16.41f)
curveTo(14.17f, 16.72f, 14.5f, 17.33f, 14.5f, 18.26f)
curveTo(14.5f, 19.6f, 14.5f, 20.68f, 14.5f, 21f)
curveTo(14.5f, 21.27f, 14.66f, 21.59f, 15.17f, 21.5f)
curveTo(19.14f, 20.16f, 22f, 16.42f, 22f, 12f)
arcTo(10f, 10f, 0f, false, false, 12f, 2f)
close()
}
}
val Icons.Rounded.Telegram
get() = materialIcon("Icons.Rounded.Telegram") {
materialPath {
moveTo(9.78f, 18.65f)
lineTo(10.06f, 14.42f)
lineTo(17.74f, 7.5f)
curveTo(18.08f, 7.19f, 17.67f, 7.04f, 17.22f, 7.31f)
lineTo(7.74f, 13.3f)
lineTo(3.64f, 12f)
curveTo(2.76f, 11.75f, 2.75f, 11.14f, 3.84f, 10.7f)
lineTo(19.81f, 4.54f)
curveTo(20.54f, 4.21f, 21.24f, 4.72f, 20.96f, 5.84f)
lineTo(18.24f, 18.65f)
curveTo(18.05f, 19.56f, 17.5f, 19.78f, 16.74f, 19.36f)
lineTo(12.6f, 16.3f)
lineTo(10.61f, 18.23f)
curveTo(10.38f, 18.46f, 10.19f, 18.65f, 9.78f, 18.65f)
close()
}
}
val Icons.Rounded.Fdroid
get() = materialIcon("Icons.Rounded.Fdroid") {
materialPath {
moveTo(4.4570312f, 3.6269531f)
arcTo(0.44109249f, 0.44109249f, 0f, false, false, 4.1757812f, 3.71875f)
arcTo(0.44109249f, 0.44109249f, 0f, false, false, 4.0957031f, 4.3378906f)
lineTo(5.3691406f, 5.984375f)
curveTo(5.3240789f, 6.102208f, 5.2949219f, 6.2272726f, 5.2949219f, 6.3613281f)
lineTo(5.2949219f, 6.5507812f)
lineTo(5.2949219f, 7.4199219f)
lineTo(5.2949219f, 7.7714844f)
lineTo(5.2949219f, 8.640625f)
lineTo(5.2949219f, 8.8300781f)
curveTo(5.2949219f, 9.4165531f, 5.7670378f, 9.8886719f, 6.3535156f, 9.8886719f)
lineTo(17.646484f, 9.8886719f)
curveTo(18.232962f, 9.8886719f, 18.705078f, 9.4165531f, 18.705078f, 8.8300781f)
lineTo(18.705078f, 8.640625f)
lineTo(18.705078f, 6.5507812f)
lineTo(18.705078f, 6.3613281f)
curveTo(18.705078f, 6.2272726f, 18.675921f, 6.102208f, 18.630859f, 5.984375f)
lineTo(19.904297f, 4.3378906f)
arcTo(0.44109249f, 0.44109249f, 0f, false, false, 19.824219f, 3.71875f)
arcTo(0.44109249f, 0.44109249f, 0f, false, false, 19.566406f, 3.6269531f)
arcTo(0.44109249f, 0.44109249f, 0f, false, false, 19.207031f, 3.796875f)
lineTo(17.990234f, 5.3710938f)
curveTo(17.881129f, 5.3332803f, 17.768779f, 5.3027344f, 17.646484f, 5.3027344f)
lineTo(6.3535156f, 5.3027344f)
curveTo(6.2312214f, 5.3027344f, 6.1188708f, 5.3332803f, 6.0097656f, 5.3710938f)
lineTo(4.7929688f, 3.796875f)
arcTo(0.44109249f, 0.44109249f, 0f, false, false, 4.4570312f, 3.6269531f)
close()
moveTo(8.5664062f, 6.625f)
arcTo(1.1909523f, 1.1909465f, 0f, false, true, 8.6035156f, 6.625f)
arcTo(1.1909523f, 1.1909465f, 0f, false, true, 9.7949219f, 7.8164062f)
arcTo(1.1909523f, 1.1909465f, 0f, false, true, 8.6035156f, 9.0078125f)
arcTo(1.1909523f, 1.1909465f, 0f, false, true, 7.4121094f, 7.8164062f)
arcTo(1.1909523f, 1.1909465f, 0f, false, true, 8.5664062f, 6.625f)
close()
moveTo(15.447266f, 6.625f)
arcTo(1.1909523f, 1.1909465f, 0f, false, true, 15.484375f, 6.625f)
arcTo(1.1909523f, 1.1909465f, 0f, false, true, 16.675781f, 7.8164062f)
arcTo(1.1909523f, 1.1909465f, 0f, false, true, 15.484375f, 9.0078125f)
arcTo(1.1909523f, 1.1909465f, 0f, false, true, 14.292969f, 7.8164062f)
arcTo(1.1909523f, 1.1909465f, 0f, false, true, 15.447266f, 6.625f)
close()
moveTo(6.3535156f, 10.242188f)
curveTo(5.7670378f, 10.242188f, 5.2949219f, 10.714306f, 5.2949219f, 11.300781f)
lineTo(5.2949219f, 11.572266f)
lineTo(5.2949219f, 13.771484f)
lineTo(5.2949219f, 15.888672f)
lineTo(5.2949219f, 18.087891f)
lineTo(5.2949219f, 18.359375f)
curveTo(5.2949219f, 18.94585f, 5.7670378f, 19.417969f, 6.3535156f, 19.417969f)
lineTo(17.646484f, 19.417969f)
curveTo(18.232962f, 19.417969f, 18.705078f, 18.94585f, 18.705078f, 18.359375f)
lineTo(18.705078f, 18.087891f)
lineTo(18.705078f, 11.572266f)
lineTo(18.705078f, 11.300781f)
curveTo(18.705078f, 10.714306f, 18.232962f, 10.242187f, 17.646484f, 10.242188f)
lineTo(6.3535156f, 10.242188f)
close()
}
}

View File

@ -0,0 +1,173 @@
package de.mm20.launcher2.ui.screens.settings
import android.content.Intent
import android.net.Uri
import androidx.compose.material.SnackbarDuration
import androidx.compose.material.SnackbarResult
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.Info
import androidx.compose.material.rememberScaffoldState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.core.content.FileProvider
import de.mm20.launcher2.crashreporter.CrashReporter
import de.mm20.launcher2.debug.DebugInformationDumper
import de.mm20.launcher2.ktx.tryStartActivity
import de.mm20.launcher2.licenses.OpenSourceLicenses
import de.mm20.launcher2.ui.R
import de.mm20.launcher2.ui.component.preferences.Preference
import de.mm20.launcher2.ui.component.preferences.PreferenceCategory
import de.mm20.launcher2.ui.component.preferences.PreferenceScreen
import de.mm20.launcher2.ui.icons.Fdroid
import de.mm20.launcher2.ui.icons.GitHub
import de.mm20.launcher2.ui.icons.Telegram
import de.mm20.launcher2.ui.locals.LocalNavController
import kotlinx.coroutines.launch
import java.io.File
@Composable
fun SettingsAboutScreen() {
val context = LocalContext.current
val navController = LocalNavController.current
val scaffoldState = rememberScaffoldState()
val scope = rememberCoroutineScope()
PreferenceScreen(
title = stringResource(id = R.string.preference_screen_about),
scaffoldState = scaffoldState
) {
item {
PreferenceCategory {
val version = context.packageManager.getPackageInfo(
context.packageName,
0
).versionName
Preference(
title = stringResource(id = R.string.preference_version),
summary = version
)
}
}
item {
PreferenceCategory(title = stringResource(id = R.string.preference_category_license)) {
Preference(
icon = Icons.Rounded.Info,
title = stringResource(id = R.string.preference_about_license),
summary = stringResource(id = R.string.preference_about_license_summary),
onClick = {
navController?.navigate("settings/license")
}
)
}
}
item {
PreferenceCategory(title = stringResource(id = R.string.preference_category_links)) {
Preference(
icon = Icons.Rounded.Telegram,
title = stringResource(id = R.string.preference_about_telegram),
summary = "t.me/Kvaesitso",
onClick = {
context.startActivity(Intent(Intent.ACTION_VIEW).apply {
data = Uri.parse("https://t.me/Kvaesitso")
})
}
)
Preference(
icon = Icons.Rounded.Fdroid,
title = stringResource(id = R.string.preference_about_fdroid),
summary = "github.com/MM2-0/fdroid",
onClick = {
context.startActivity(Intent(Intent.ACTION_VIEW).apply {
data =
Uri.parse("https://raw.githubusercontent.com/MM2-0/fdroid/master/fdroid/repo")
})
}
)
Preference(
icon = Icons.Rounded.GitHub,
title = "GitHub",
summary = "github.com/MM2-0/Kvaesitso",
onClick = {
context.startActivity(Intent(Intent.ACTION_VIEW).apply {
data = Uri.parse("https://github.com/MM2-0/Kvaesitso")
})
}
)
}
}
item {
PreferenceCategory(title = stringResource(id = R.string.preference_category_debug)) {
Preference(
title = stringResource(id = R.string.preference_crash_reporter),
onClick = {
context.startActivity(CrashReporter.getLaunchIntent())
}
)
Preference(
title = stringResource(id = R.string.preference_export_debug),
onClick = {
scope.launch {
val path = DebugInformationDumper().dump(context)
val result = scaffoldState.snackbarHostState.showSnackbar(
context.getString(R.string.debug_export_information_file, path),
actionLabel = context.getString(R.string.menu_share),
duration = SnackbarDuration.Long
)
if (result == SnackbarResult.ActionPerformed) {
context.tryStartActivity(Intent(Intent.ACTION_SEND).apply {
type = "text/plain"
putExtra(
Intent.EXTRA_STREAM, FileProvider.getUriForFile(
context,
context.applicationContext.packageName + ".fileprovider",
File(path)
)
)
})
}
}
}
)
Preference(
title = stringResource(id = R.string.preference_export_databases),
onClick = {
scope.launch {
val path = DebugInformationDumper().exportDatabases(context)
val result = scaffoldState.snackbarHostState.showSnackbar(
context.getString(R.string.debug_export_information_file, path),
actionLabel = context.getString(R.string.menu_share),
duration = SnackbarDuration.Long
)
if (result == SnackbarResult.ActionPerformed) {
context.tryStartActivity(Intent(Intent.ACTION_SEND).apply {
type = "application/x-sqlite3"
putExtra(
Intent.EXTRA_STREAM, FileProvider.getUriForFile(
context,
context.applicationContext.packageName + ".fileprovider",
File(path)
)
)
})
}
}
}
)
}
}
item {
PreferenceCategory(title = stringResource(id = R.string.preference_category_licenses)) {
for (library in OpenSourceLicenses.sortedBy { it.name.lowercase() }) {
Preference(
title = library.name,
summary = library.description,
onClick = {
navController?.navigate("settings/license?library=${library.name}")
}
)
}
}
}
}
}

View File

@ -0,0 +1,93 @@
package de.mm20.launcher2.ui.screens.settings
import android.content.Intent
import android.net.Uri
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material.Icon
import androidx.compose.material.LocalContentColor
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.OpenInBrowser
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import de.mm20.launcher2.licenses.AppLicense
import de.mm20.launcher2.licenses.OpenSourceLicenses
import de.mm20.launcher2.ui.R
import de.mm20.launcher2.ui.component.preferences.PreferenceCategory
import de.mm20.launcher2.ui.component.preferences.PreferenceScreen
@Composable
fun SettingsLicenseScreen(libraryName: String? = null) {
val context = LocalContext.current
val library = if (libraryName == null) {
AppLicense.get(context)
} else {
OpenSourceLicenses.first { it.name == libraryName }
}
PreferenceScreen(title = stringResource(id = R.string.preference_screen_about)) {
item {
PreferenceCategory {
Column(
modifier = Modifier.padding(16.dp)
) {
Text(text = library.name, style = MaterialTheme.typography.subtitle1)
library.description?.let { Text(text = it) }
}
CompositionLocalProvider(
LocalContentColor provides MaterialTheme.colors.primary
) {
Row(
modifier = Modifier
.fillMaxWidth()
.clickable {
context.startActivity(Intent(Intent.ACTION_VIEW).apply {
data = Uri.parse(library.url)
})
}
.padding(all = 16.dp),
verticalAlignment = Alignment.CenterVertically,
) {
Icon(imageVector = Icons.Rounded.OpenInBrowser, contentDescription = null)
Text(
modifier = Modifier.padding(start = 8.dp),
text = stringResource(id = R.string.open_webpage),
style = MaterialTheme.typography.button
)
}
}
}
}
item {
PreferenceCategory {
Column(
modifier = Modifier.padding(16.dp)
) {
Text(
text = stringResource(id = library.licenseName),
style = MaterialTheme.typography.subtitle2
)
library.copyrightNote?.let {
Text(
text = it,
modifier = Modifier.padding(vertical = 4.dp)
)
}
Text(
text = context.resources.openRawResource(library.licenseText).reader()
.readText()
)
}
}
}
}
}