Skip to content

Commit 81fef7e

Browse files
committed
Another version of the about screen
1 parent 332c0ed commit 81fef7e

File tree

3 files changed

+128
-173
lines changed

3 files changed

+128
-173
lines changed

app/src/main/kotlin/org/stypox/dicio/error/ErrorActivity.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ class ErrorActivity : BaseActivity() {
9999
val CURRENT_TIMESTAMP_FORMATTER: DateTimeFormatter =
100100
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")
101101

102-
private fun getOsInfo(): String {
102+
fun getOsInfo(): String {
103103
val osBase = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
104104
Build.VERSION.BASE_OS
105105
else

app/src/main/kotlin/org/stypox/dicio/ui/about/AboutScreen.kt

Lines changed: 112 additions & 152 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,47 @@
1+
@file:OptIn(ExperimentalMaterial3Api::class)
2+
13
package org.stypox.dicio.ui.about
24

3-
import android.os.Build
5+
import androidx.annotation.StringRes
6+
import androidx.compose.foundation.Image
47
import androidx.compose.foundation.clickable
8+
import androidx.compose.foundation.layout.Arrangement
9+
import androidx.compose.foundation.layout.Column
10+
import androidx.compose.foundation.layout.PaddingValues
11+
import androidx.compose.foundation.layout.Row
12+
import androidx.compose.foundation.layout.Spacer
513
import androidx.compose.foundation.layout.fillMaxSize
14+
import androidx.compose.foundation.layout.fillMaxWidth
15+
import androidx.compose.foundation.layout.height
616
import androidx.compose.foundation.layout.padding
17+
import androidx.compose.foundation.layout.size
18+
import androidx.compose.foundation.layout.wrapContentSize
719
import androidx.compose.foundation.lazy.LazyColumn
820
import androidx.compose.material.icons.Icons
921
import androidx.compose.material.icons.filled.BugReport
1022
import androidx.compose.material.icons.filled.Code
11-
import androidx.compose.material.icons.filled.Description
12-
import androidx.compose.material.icons.filled.Gavel
23+
import androidx.compose.material.icons.filled.ContentCopy
1324
import androidx.compose.material.icons.filled.Group
14-
import androidx.compose.material.icons.filled.Info
15-
import androidx.compose.material.icons.filled.LibraryBooks
1625
import androidx.compose.material.icons.filled.Policy
1726
import androidx.compose.material3.ExperimentalMaterial3Api
18-
import androidx.compose.material3.HorizontalDivider
27+
import androidx.compose.material3.Icon
28+
import androidx.compose.material3.MaterialTheme
1929
import androidx.compose.material3.Scaffold
20-
import androidx.compose.material3.SnackbarHost
21-
import androidx.compose.material3.SnackbarHostState
2230
import androidx.compose.material3.Text
2331
import androidx.compose.material3.TopAppBar
2432
import androidx.compose.runtime.Composable
25-
import androidx.compose.runtime.remember
26-
import androidx.compose.runtime.rememberCoroutineScope
33+
import androidx.compose.ui.Alignment
2734
import androidx.compose.ui.Modifier
35+
import androidx.compose.ui.graphics.vector.ImageVector
2836
import androidx.compose.ui.platform.LocalContext
2937
import androidx.compose.ui.res.stringResource
38+
import androidx.compose.ui.text.font.FontWeight
39+
import androidx.compose.ui.text.style.TextAlign
3040
import androidx.compose.ui.tooling.preview.Preview
3141
import androidx.compose.ui.unit.dp
32-
import kotlinx.coroutines.launch
3342
import org.stypox.dicio.BuildConfig
3443
import org.stypox.dicio.R
35-
import org.stypox.dicio.settings.ui.SettingsCategoryTitle
44+
import org.stypox.dicio.error.ErrorActivity
3645
import org.stypox.dicio.settings.ui.SettingsItem
3746
import org.stypox.dicio.ui.theme.AppTheme
3847
import org.stypox.dicio.util.ShareUtils
@@ -42,178 +51,129 @@ fun AboutScreen(
4251
navigationIcon: @Composable () -> Unit,
4352
) {
4453
val context = LocalContext.current
45-
val snackbarHostState = remember { SnackbarHostState() }
46-
val scope = rememberCoroutineScope()
4754

4855
Scaffold(
4956
topBar = {
50-
@OptIn(ExperimentalMaterial3Api::class)
5157
TopAppBar(
5258
title = { Text(stringResource(R.string.about)) },
5359
navigationIcon = navigationIcon,
5460
)
5561
},
56-
snackbarHost = { SnackbarHost(hostState = snackbarHostState) },
5762
) { paddingValues ->
5863
LazyColumn(
59-
modifier = Modifier
60-
.fillMaxSize()
61-
.padding(paddingValues)
64+
contentPadding = PaddingValues(bottom = 4.dp),
65+
modifier = Modifier.padding(paddingValues)
6266
) {
63-
// App Information Section
64-
item {
65-
SettingsCategoryTitle(title = stringResource(R.string.about_app_info))
66-
}
67-
68-
item {
69-
SettingsItem(
70-
title = stringResource(R.string.app_name),
71-
description = stringResource(R.string.about_description),
72-
)
73-
}
74-
75-
item {
76-
SettingsItem(
77-
title = stringResource(R.string.about_version),
78-
description = BuildConfig.VERSION_NAME,
79-
)
80-
}
81-
82-
item {
83-
SettingsItem(
84-
title = stringResource(R.string.about_application_id),
85-
description = BuildConfig.APPLICATION_ID,
86-
)
87-
}
88-
89-
// Build Information Section
9067
item {
91-
SettingsCategoryTitle(title = stringResource(R.string.about_build_info))
92-
}
93-
94-
item {
95-
SettingsItem(
96-
title = stringResource(R.string.about_version_code),
97-
description = BuildConfig.VERSION_CODE.toString(),
98-
)
99-
}
100-
101-
item {
102-
SettingsItem(
103-
title = stringResource(R.string.about_copy_version_info),
104-
icon = Icons.Default.Description,
105-
modifier = Modifier.clickable {
106-
val versionInfo = buildVersionInfo()
107-
ShareUtils.copyToClipboard(context, versionInfo)
108-
scope.launch {
109-
snackbarHostState.showSnackbar(
110-
context.getString(R.string.copied_to_clipboard)
111-
)
112-
}
113-
},
114-
)
115-
}
116-
117-
// Links Section
118-
item {
119-
SettingsCategoryTitle(title = stringResource(R.string.about_links))
68+
Column(
69+
modifier = Modifier
70+
.padding(start = 16.dp, end = 16.dp, bottom = 16.dp)
71+
.fillMaxWidth()
72+
.wrapContentSize(Alignment.Center),
73+
horizontalAlignment = Alignment.CenterHorizontally
74+
) {
75+
Image(
76+
imageVector = DicioSquircleIcon,
77+
contentDescription = stringResource(R.string.app_name),
78+
modifier = Modifier.size(64.dp)
79+
)
80+
Spacer(Modifier.height(4.dp))
81+
Text(
82+
text = stringResource(R.string.app_name),
83+
style = MaterialTheme.typography.titleLarge,
84+
textAlign = TextAlign.Center
85+
)
86+
val versionTextSizeUnit = MaterialTheme.typography.titleMedium.fontSize.value.dp
87+
Row(
88+
verticalAlignment = Alignment.CenterVertically,
89+
horizontalArrangement = Arrangement.spacedBy(versionTextSizeUnit * 0.25f),
90+
modifier = Modifier.clickable(
91+
onClickLabel = stringResource(R.string.about_version_copy)
92+
) { ShareUtils.copyToClipboard(context, getVersionInfoString()) }
93+
) {
94+
Text(
95+
text = stringResource(
96+
R.string.about_version,
97+
BuildConfig.VERSION_NAME,
98+
BuildConfig.VERSION_CODE
99+
),
100+
style = MaterialTheme.typography.titleMedium.copy(fontWeight = FontWeight.Light),
101+
textAlign = TextAlign.Center
102+
)
103+
Icon(
104+
imageVector = Icons.Default.ContentCopy,
105+
contentDescription = null,
106+
modifier = Modifier.size(versionTextSizeUnit * 0.8f)
107+
)
108+
}
109+
Text(
110+
modifier = Modifier.fillMaxWidth(),
111+
text = stringResource(R.string.about_description),
112+
textAlign = TextAlign.Center
113+
)
114+
}
120115
}
121-
116+
122117
item {
123-
SettingsItem(
124-
title = stringResource(R.string.about_source_code),
118+
AboutItem(
119+
title = R.string.about_repository_title,
125120
icon = Icons.Default.Code,
126-
description = "github.com/Stypox/dicio-android",
127-
modifier = Modifier.clickable {
128-
ShareUtils.openUrlInBrowser(
129-
context,
130-
"https://github.com/Stypox/dicio-android"
131-
)
132-
},
121+
description = R.string.about_repository_description,
122+
link = R.string.about_repository_link
133123
)
134124
}
135-
125+
136126
item {
137-
SettingsItem(
138-
title = stringResource(R.string.about_report_issue),
127+
AboutItem(
128+
title = R.string.about_issues_title,
139129
icon = Icons.Default.BugReport,
140-
description = "Report bugs and request features",
141-
modifier = Modifier.clickable {
142-
ShareUtils.openUrlInBrowser(
143-
context,
144-
"https://github.com/Stypox/dicio-android/issues"
145-
)
146-
},
130+
description = R.string.about_issues_description,
131+
link = R.string.about_issues_link
147132
)
148133
}
149-
150-
// Legal Section
151-
item {
152-
SettingsCategoryTitle(title = stringResource(R.string.about_legal))
153-
}
154-
134+
155135
item {
156-
SettingsItem(
157-
title = stringResource(R.string.about_license),
158-
icon = Icons.Default.Gavel,
159-
description = stringResource(R.string.about_license_gpl),
160-
modifier = Modifier.clickable {
161-
ShareUtils.openUrlInBrowser(
162-
context,
163-
"https://www.gnu.org/licenses/gpl-3.0.html"
164-
)
165-
},
136+
AboutItem(
137+
title = R.string.about_contributing_title,
138+
icon = Icons.Default.Group,
139+
description = R.string.about_contributing_description,
140+
link = R.string.about_contributing_link
166141
)
167142
}
168-
143+
169144
item {
170-
SettingsItem(
171-
title = stringResource(R.string.about_privacy_policy),
145+
AboutItem(
146+
title = R.string.about_privacy_title,
172147
icon = Icons.Default.Policy,
173-
description = stringResource(R.string.privacy_intro),
174-
modifier = Modifier.clickable {
175-
ShareUtils.openUrlInBrowser(
176-
context,
177-
"https://github.com/Stypox/dicio-android/blob/master/PRIVACY.md"
178-
)
179-
},
180-
)
181-
}
182-
183-
// Credits Section
184-
item {
185-
SettingsCategoryTitle(title = stringResource(R.string.about_credits))
186-
}
187-
188-
item {
189-
SettingsItem(
190-
title = stringResource(R.string.about_contributors),
191-
icon = Icons.Default.Group,
192-
description = stringResource(R.string.about_contributors_description),
193-
modifier = Modifier.clickable {
194-
ShareUtils.openUrlInBrowser(
195-
context,
196-
"https://github.com/Stypox/dicio-android/graphs/contributors"
197-
)
198-
},
148+
description = R.string.about_privacy_description,
149+
link = R.string.about_privacy_link
199150
)
200151
}
201-
202-
item {
203-
HorizontalDivider(modifier = Modifier.padding(vertical = 8.dp))
204-
}
205152
}
206153
}
207154
}
208155

209-
private fun buildVersionInfo(): String {
210-
return """
211-
${BuildConfig.APPLICATION_ID}
212-
Version ${BuildConfig.VERSION_NAME} (${BuildConfig.VERSION_CODE})
213-
214-
Device: ${Build.MANUFACTURER} ${Build.MODEL}
215-
Android: ${Build.VERSION.RELEASE} (API ${Build.VERSION.SDK_INT})
216-
""".trimIndent()
156+
@Composable
157+
fun AboutItem(
158+
@StringRes title: Int,
159+
icon: ImageVector,
160+
@StringRes description: Int,
161+
@StringRes link: Int
162+
) {
163+
val context = LocalContext.current
164+
SettingsItem(
165+
title = stringResource(title),
166+
icon = icon,
167+
description = stringResource(description),
168+
modifier = Modifier.clickable {
169+
ShareUtils.openUrlInBrowser(context, context.getString(link))
170+
},
171+
)
172+
}
173+
174+
private fun getVersionInfoString(): String {
175+
return "${BuildConfig.APPLICATION_ID} ${BuildConfig.VERSION_NAME} (" +
176+
"${BuildConfig.VERSION_CODE}) running on ${ErrorActivity.getOsInfo()}"
217177
}
218178

219179
@Preview

app/src/main/res/values/strings.xml

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -262,25 +262,20 @@
262262
<string name="skill_flashlight_turned_on">Flashlight turned on</string>
263263
<string name="skill_flashlight_turned_off">Flashlight turned off</string>
264264
<string name="skill_flashlight_error">Unable to control the flashlight</string>
265-
266-
<!-- About screen -->
267265
<string name="about">About</string>
268-
<string name="about_description">Free and open source voice assistant</string>
269-
<string name="about_version">Version</string>
270-
<string name="about_app_info">App information</string>
271-
<string name="about_application_id">Application ID</string>
272-
<string name="about_build_info">Build information</string>
273-
<string name="about_version_code">Version code</string>
274-
<string name="about_links">Links</string>
275-
<string name="about_source_code">Source code</string>
276-
<string name="about_report_issue">Report an issue</string>
277-
<string name="about_github" translatable="false">GitHub</string>
278-
<string name="about_legal">Legal</string>
279-
<string name="about_license">License</string>
280-
<string name="about_license_gpl" translatable="false">GNU General Public License v3.0</string>
281-
<string name="about_privacy_policy">Privacy policy</string>
282-
<string name="about_credits">Credits</string>
283-
<string name="about_contributors">Contributors</string>
284-
<string name="about_contributors_description">Dicio is made possible by contributors around the world</string>
285-
<string name="about_copy_version_info">Copy version info</string>
266+
<string name="about_version">%1$s (%2$d)</string>
267+
<string name="about_version_copy">Copy version info</string>
268+
<string name="about_description">Multilanguage, local and libre voice assistant</string>
269+
<string name="about_repository_title">Source code repository</string>
270+
<string name="about_repository_description">Dicio is free and open source, licensed under GPLv3</string>
271+
<string name="about_repository_link" translatable="false">https://github.com/Stypox/dicio-android</string>
272+
<string name="about_issues_title">Found a bug?</string>
273+
<string name="about_issues_description">Feel free to request new features or report broken things (remember to attach logs)</string>
274+
<string name="about_issues_link" translatable="false">https://github.com/Stypox/dicio-android/issues</string>
275+
<string name="about_contributing_title">Contributing</string>
276+
<string name="about_contributing_description">Dicio is developed by volunteers around the world. You can help out too by contributing code improvements, translations and even new skills!</string>
277+
<string name="about_contributing_link" translatable="false">https://github.com/Stypox/dicio-android#contributing</string>
278+
<string name="about_privacy_title">Privacy policy</string>
279+
<string name="about_privacy_description">Dicio connects to external services only when a skill is expected to do so, or to download machine learning models during setup. All speech processing is performed locally on-device, and most skills can be used offline.</string>
280+
<string name="about_privacy_link" translatable="false">https://stypox.org/dicio-privacy-policy.html</string>
286281
</resources>

0 commit comments

Comments
 (0)