diff --git a/shared/src/commonMain/composeResources/values/strings.xml b/shared/src/commonMain/composeResources/values/strings.xml
index 5d46b590..f844b6e4 100644
--- a/shared/src/commonMain/composeResources/values/strings.xml
+++ b/shared/src/commonMain/composeResources/values/strings.xml
@@ -15,6 +15,11 @@
Sponsor
Spectacled is an open-source software for journals, notes, and tasks - built on open standards (iCalendar + CalDAV), synced to your own server, with no accounts, no proprietary backend, and no tracking. \n\nIt's maintained across Android, iOS, Web, and Desktop as one codebase, which is a lot of ongoing work for a small project. If Spectacled is useful to you, chip in whatever it's worth to you - any amount helps keep development going. \n\nThank you for supporting open source!
More donation options
+ Translations
+ Spectacled is translated by the community on Weblate, a libre translation platform. \n\nYou don't need a development environment or any Git knowledge - just sign in, pick your language and start translating right in your browser. Every translation is shared by all Spectacled apps on all platforms.
+ Translate on Weblate
+ Code
+ Spectacled is developed in the open on GitHub - one shared Kotlin Multiplatform codebase for Android, iOS, Web and Desktop. \n\nBug reports and feature ideas are just as welcome as pull requests. Have a look at the open issues to see what is currently being worked on, or where you could jump in.
Thank you!
PayPal
More on GitHub.com
diff --git a/shared/src/commonMain/kotlin/at/techbee/spectacled/screens/about/presentation/GitHubContributors.kt b/shared/src/commonMain/kotlin/at/techbee/spectacled/screens/about/presentation/GitHubContributors.kt
index c4e3e878..dcbc4aec 100644
--- a/shared/src/commonMain/kotlin/at/techbee/spectacled/screens/about/presentation/GitHubContributors.kt
+++ b/shared/src/commonMain/kotlin/at/techbee/spectacled/screens/about/presentation/GitHubContributors.kt
@@ -2,18 +2,22 @@ package at.techbee.spectacled.screens.about.presentation
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.FlowRow
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
-import androidx.compose.foundation.lazy.LazyColumn
-import androidx.compose.foundation.lazy.itemsIndexed
+import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.CircleShape
+import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.outlined.OpenInNew
+import androidx.compose.material.icons.outlined.Code
import androidx.compose.material.icons.outlined.Person
+import androidx.compose.material.icons.outlined.Translate
import androidx.compose.material3.Button
+import androidx.compose.material3.ElevatedCard
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
@@ -30,19 +34,22 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import at.techbee.spectacled.SpectacledVariant
import at.techbee.spectacled.screens.about.domain.GitHubContributor
-import at.techbee.spectacled.screens.core.presentation.components.SpecialRoundedCard
import at.techbee.spectacled.theme.AppTheme
import coil3.compose.AsyncImage
import io.github.aakira.napier.Napier
import org.jetbrains.compose.resources.stringResource
import spectacled.shared.generated.resources.Res
+import spectacled.shared.generated.resources.about_code_contributions
+import spectacled.shared.generated.resources.about_code_contributions_info
import spectacled.shared.generated.resources.about_contributors
+import spectacled.shared.generated.resources.about_translate_on_weblate
+import spectacled.shared.generated.resources.about_translations
+import spectacled.shared.generated.resources.about_translations_info
import spectacled.shared.generated.resources.more_on_github
-//TODO: Change for Release!!!
-private const val GITHUB_CONTRIBUTORS_URL = "https://github.com/TechbeeAT/jtxBoard/graphs/contributors"
-
+private const val GITHUB_CONTRIBUTORS_URL = "https://github.com/TechbeeAT/spectacled/graphs/contributors"
+private const val WEBLATE_URL = "https://hosted.weblate.org/engage/spectacled/"
@Composable
@@ -52,7 +59,7 @@ fun GitHubContributors(
val uriHandler = LocalUriHandler.current
Column(
- modifier = Modifier.fillMaxSize()
+ modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState())
) {
Text(
text = stringResource(Res.string.about_contributors),
@@ -61,50 +68,116 @@ fun GitHubContributors(
modifier = Modifier.fillMaxWidth().padding(top = 16.dp, bottom = 8.dp, start = 8.dp, end = 8.dp)
)
- LazyColumn(
- verticalArrangement = Arrangement.spacedBy(4.dp),
- horizontalAlignment = Alignment.CenterHorizontally,
- modifier = Modifier.fillMaxSize()
+ ElevatedCard(
+ modifier = Modifier.fillMaxWidth().padding(bottom = 16.dp)
) {
+ Column(
+ modifier = Modifier.padding(16.dp).fillMaxWidth(),
+ verticalArrangement = Arrangement.spacedBy(8.dp, Alignment.CenterVertically),
+ horizontalAlignment = Alignment.CenterHorizontally
+ ) {
+
+ Row(
+ verticalAlignment = Alignment.CenterVertically,
+ horizontalArrangement = Arrangement.spacedBy(8.dp)
+ ) {
+ Icon(
+ imageVector = Icons.Outlined.Translate,
+ contentDescription = null,
+ modifier = Modifier.size(32.dp)
+ )
+ Text(
+ text = stringResource(Res.string.about_translations),
+ style = MaterialTheme.typography.headlineSmall
+ )
+ }
- itemsIndexed(contributors) { index, contributor ->
- SpecialRoundedCard(
- isFirst = index == 0,
- isLast = index == contributors.lastIndex,
+ Text(
+ text = stringResource(Res.string.about_translations_info),
+ style = MaterialTheme.typography.bodyMedium,
+ textAlign = TextAlign.Center
+ )
+
+ Button(
onClick = {
try {
- contributor.url?.let { uriHandler.openUri(it) }
+ uriHandler.openUri(WEBLATE_URL)
} catch (e: Exception) {
Napier.w(e.stackTraceToString())
}
},
- modifier = Modifier.fillMaxWidth()
+ modifier = Modifier.padding(top = 8.dp)
) {
- Column(
- modifier = Modifier.padding(8.dp).fillMaxWidth(),
- verticalArrangement = Arrangement.spacedBy(4.dp, Alignment.CenterVertically),
- horizontalAlignment = Alignment.CenterHorizontally
+ Row(
+ horizontalArrangement = Arrangement.spacedBy(8.dp, Alignment.CenterHorizontally),
+ verticalAlignment = Alignment.CenterVertically
) {
+ Text(stringResource(Res.string.about_translate_on_weblate))
+ Icon(Icons.AutoMirrored.Outlined.OpenInNew, null)
+ }
+ }
+ }
+ }
+
+ ElevatedCard {
+
+ Column(
+ modifier = Modifier.padding(16.dp).fillMaxWidth(),
+ verticalArrangement = Arrangement.spacedBy(8.dp, Alignment.CenterVertically),
+ horizontalAlignment = Alignment.CenterHorizontally
+ ) {
+
+ Row(
+ verticalAlignment = Alignment.CenterVertically,
+ horizontalArrangement = Arrangement.spacedBy(8.dp)
+ ) {
+ Icon(
+ imageVector = Icons.Outlined.Code,
+ contentDescription = null,
+ modifier = Modifier.size(32.dp)
+ )
+ Text(
+ text = stringResource(Res.string.about_code_contributions),
+ style = MaterialTheme.typography.headlineSmall
+ )
+ }
- AsyncImage(
- model = contributor.avatarUrl,
- contentDescription = null,
- placeholder = rememberVectorPainter(Icons.Outlined.Person),
- error = rememberVectorPainter(Icons.Outlined.Person),
- fallback = rememberVectorPainter(Icons.Outlined.Person),
- modifier = Modifier.size(80.dp).clip(CircleShape).shadow(2.dp)
- )
+ Text(
+ text = stringResource(Res.string.about_code_contributions_info),
+ style = MaterialTheme.typography.bodyMedium,
+ textAlign = TextAlign.Center
+ )
- Text(
- text = contributor.login,
- style = MaterialTheme.typography.titleSmall
- )
+ FlowRow(
+ horizontalArrangement = Arrangement.Center
+ ) {
+
+ contributors.forEach { contributor ->
+
+ Column(
+ modifier = Modifier.padding(8.dp),
+ verticalArrangement = Arrangement.spacedBy(4.dp, Alignment.CenterVertically),
+ horizontalAlignment = Alignment.CenterHorizontally
+ ) {
+
+ AsyncImage(
+ model = contributor.avatarUrl,
+ contentDescription = null,
+ placeholder = rememberVectorPainter(Icons.Outlined.Person),
+ error = rememberVectorPainter(Icons.Outlined.Person),
+ fallback = rememberVectorPainter(Icons.Outlined.Person),
+ modifier = Modifier.size(80.dp).clip(CircleShape).shadow(2.dp)
+ )
+
+ Text(
+ text = contributor.login,
+ style = MaterialTheme.typography.titleSmall
+ )
+ }
}
}
- }
- item {
Button(
onClick = {
try {
@@ -124,7 +197,9 @@ fun GitHubContributors(
}
}
}
+
}
+
}
}