refactor(settings): draw the About card from floret-kit SettingsRecipes

Calendula's bespoke About card was the floret-kit components.AboutCard recipe in
disguise — logo + name/author, a row of equal-width outlined links, and a
full-width tonal highlight link. Replace the hand-rolled layout with the kit
recipe, supplying Calendula's logo (AppLogo, app-local) and its source
(ic_gitea, via vectorResource) / licence / support links as AboutLinks. Drop the
now-unused button/icon imports.

Calendula's language picker keeps its app-local form (it uses a custom header
the generic LanguagePickerRow recipe doesn't carry).

Compile + unit tests + lintDebug green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-28 21:05:01 +02:00
parent 78fe7676a2
commit f9bf9db141

View File

@@ -24,7 +24,6 @@ import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
@@ -51,10 +50,8 @@ import androidx.compose.material.icons.filled.Palette
import androidx.compose.material.icons.filled.Translate import androidx.compose.material.icons.filled.Translate
import androidx.compose.material.icons.filled.Tune import androidx.compose.material.icons.filled.Tune
import de.jeanlucmakiola.floret.locale.AppLanguage import de.jeanlucmakiola.floret.locale.AppLanguage
import androidx.compose.material3.FilledTonalButton
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.Surface import androidx.compose.material3.Surface
import androidx.compose.material3.Switch import androidx.compose.material3.Switch
import androidx.compose.material3.Text import androidx.compose.material3.Text
@@ -72,6 +69,7 @@ import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.colorResource import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.res.pluralStringResource import androidx.compose.ui.res.pluralStringResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
@@ -98,6 +96,8 @@ import de.jeanlucmakiola.floret.crash.submitCrashReport
import de.jeanlucmakiola.floret.identity.expandEnter import de.jeanlucmakiola.floret.identity.expandEnter
import de.jeanlucmakiola.calendula.ui.common.AgendaRangePicker import de.jeanlucmakiola.calendula.ui.common.AgendaRangePicker
import de.jeanlucmakiola.calendula.ui.common.agendaRangeLabel import de.jeanlucmakiola.calendula.ui.common.agendaRangeLabel
import de.jeanlucmakiola.floret.components.AboutCard
import de.jeanlucmakiola.floret.components.AboutLink
import de.jeanlucmakiola.floret.components.CollapsingScaffold import de.jeanlucmakiola.floret.components.CollapsingScaffold
import de.jeanlucmakiola.floret.components.GroupedRow import de.jeanlucmakiola.floret.components.GroupedRow
import de.jeanlucmakiola.calendula.ui.common.IMPLEMENTED_VIEWS import de.jeanlucmakiola.calendula.ui.common.IMPLEMENTED_VIEWS
@@ -339,83 +339,30 @@ private fun LanguageRow(position: Position) {
@Composable @Composable
private fun AboutCard() { private fun AboutCard() {
val context = LocalContext.current // The card layout lives in floret-kit (components.AboutCard); Calendula
val sourceUrl = stringResource(R.string.about_source_url) // supplies its own logo, author and the source / licence / support links.
val licenseUrl = stringResource(R.string.about_license_url) AboutCard(
val supportUrl = stringResource(R.string.about_support_url) logo = { AppLogo() },
appName = stringResource(R.string.app_name),
Surface( author = stringResource(R.string.settings_about_author),
color = MaterialTheme.colorScheme.surfaceContainerHigh, primaryLinks = listOf(
shape = RoundedCornerShape(24.dp), AboutLink(
modifier = Modifier.fillMaxWidth(), icon = ImageVector.vectorResource(R.drawable.ic_gitea),
) { label = stringResource(R.string.settings_about_source),
Column( url = stringResource(R.string.about_source_url),
modifier = Modifier ),
.fillMaxWidth() AboutLink(
.padding(16.dp), icon = Icons.Default.Gavel,
) { label = stringResource(R.string.settings_license),
Row(verticalAlignment = Alignment.CenterVertically) { url = stringResource(R.string.about_license_url),
AppLogo() ),
Spacer(Modifier.width(16.dp)) ),
Column(Modifier.weight(1f)) { highlightLink = AboutLink(
Text( icon = Icons.Default.Favorite,
text = stringResource(R.string.app_name), label = stringResource(R.string.settings_about_support),
style = MaterialTheme.typography.titleLarge, url = stringResource(R.string.about_support_url),
) ),
Text( )
text = stringResource(R.string.settings_about_author),
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant,
)
}
}
Spacer(Modifier.height(12.dp))
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(8.dp),
) {
OutlinedButton(
onClick = { openUrl(context, sourceUrl) },
contentPadding = PaddingValues(horizontal = 12.dp),
modifier = Modifier.weight(1f),
) {
Icon(
painter = painterResource(R.drawable.ic_gitea),
contentDescription = null,
modifier = Modifier.size(18.dp),
)
Spacer(Modifier.width(8.dp))
Text(stringResource(R.string.settings_about_source))
}
OutlinedButton(
onClick = { openUrl(context, licenseUrl) },
contentPadding = PaddingValues(horizontal = 12.dp),
modifier = Modifier.weight(1f),
) {
Icon(
Icons.Default.Gavel,
contentDescription = null,
modifier = Modifier.size(18.dp),
)
Spacer(Modifier.width(8.dp))
Text(stringResource(R.string.settings_license))
}
}
Spacer(Modifier.height(8.dp))
FilledTonalButton(
onClick = { openUrl(context, supportUrl) },
modifier = Modifier.fillMaxWidth(),
) {
Icon(
Icons.Default.Favorite,
contentDescription = null,
modifier = Modifier.size(18.dp),
)
Spacer(Modifier.width(8.dp))
Text(stringResource(R.string.settings_about_support))
}
}
}
} }
/** Plain centred version mark at the foot of the settings list (no card). */ /** Plain centred version mark at the foot of the settings list (no card). */