feat(about): redesign screen with new information hierarchy (#5728)

This commit is contained in:
SuperDragonXD
2025-08-07 12:05:00 +08:00
committed by GitHub
parent eb1c6f27df
commit 99f017c552
11 changed files with 143 additions and 65 deletions

View File

@@ -1,9 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#000000"
android:pathData="M19.6239,5.39C18.2217,4.7467 16.7181,4.2726 15.1459,4.0011C15.1173,3.9959 15.0887,4.009 15.0739,4.0352C14.8805,4.3791 14.6663,4.8278 14.5163,5.1805C12.8254,4.9274 11.1431,4.9274 9.4868,5.1805C9.3368,4.82 9.1148,4.3791 8.9205,4.0352C8.9058,4.0099 8.8772,3.9968 8.8485,4.0011C7.2772,4.2718 5.7736,4.7458 4.3705,5.39C4.3584,5.3953 4.348,5.404 4.3411,5.4154C1.4889,9.6764 0.7076,13.8326 1.0909,17.9374C1.0927,17.9574 1.1039,17.9766 1.1195,17.9889C3.0013,19.3708 4.8241,20.2097 6.613,20.7658C6.6416,20.7745 6.672,20.764 6.6902,20.7405C7.1134,20.1626 7.4906,19.5532 7.814,18.9125C7.8331,18.8749 7.8149,18.8304 7.7759,18.8156C7.1775,18.5886 6.6078,18.3119 6.0598,17.9976C6.0164,17.9723 6.0129,17.9103 6.0528,17.8806C6.1681,17.7942 6.2835,17.7043 6.3936,17.6135C6.4135,17.5969 6.4413,17.5934 6.4647,17.6039C10.0652,19.2477 13.9631,19.2477 17.521,17.6039C17.5445,17.5925 17.5722,17.596 17.593,17.6126C17.7032,17.7034 17.8185,17.7942 17.9347,17.8806C17.9746,17.9103 17.972,17.9723 17.9286,17.9976C17.3806,18.318 16.8108,18.5886 16.2116,18.8147C16.1726,18.8295 16.1553,18.8749 16.1744,18.9125C16.5047,19.5523 16.882,20.1617 17.2973,20.7396C17.3147,20.764 17.3459,20.7745 17.3745,20.7658C19.1721,20.2097 20.9949,19.3708 22.8766,17.9889C22.8931,17.9766 22.9035,17.9583 22.9053,17.9382C23.364,13.1927 22.1369,9.0705 19.6525,5.4162C19.6465,5.404 19.6361,5.3953 19.6239,5.39ZM8.3517,15.438C7.2677,15.438 6.3745,14.4428 6.3745,13.2207C6.3745,11.9985 7.2504,11.0033 8.3517,11.0033C9.4616,11.0033 10.3462,12.0072 10.3288,13.2207C10.3288,14.4428 9.453,15.438 8.3517,15.438ZM15.6619,15.438C14.5779,15.438 13.6847,14.4428 13.6847,13.2207C13.6847,11.9985 14.5606,11.0033 15.6619,11.0033C16.7718,11.0033 17.6563,12.0072 17.639,13.2207C17.639,14.4428 16.7718,15.438 15.6619,15.438Z" />
android:width="192dp"
android:height="192dp"
android:viewportWidth="192"
android:viewportHeight="192"
android:tint="#000000">
<path android:pathData="m68,138 l-8,16c-10.19,-4.25 -20.74,-8.49 -31.96,-15.8 -3.91,-2.55 -6.28,-6.88 -6.38,-11.55 -0.49,-23.96 5.13,-48.06 19.37,-73.53 1.86,-3.33 4.97,-5.78 8.57,-7.06C58.19,43.02 64.02,40.66 74,39l6,11s6,-2 16,-2 16,2 16,2l6,-11c9.98,1.66 15.81,4.02 24.4,7.07 3.6,1.28 6.7,3.72 8.57,7.06 14.23,25.47 19.86,49.56 19.37,73.53 -0.09,4.67 -2.47,9 -6.38,11.55 -11.22,7.31 -21.77,11.55 -31.96,15.8l-8,-16m-68,-8s20,10 40,10 40,-10 40,-10" android:strokeLineJoin="round" android:strokeWidth="14" android:fillColor="#00000000" android:strokeColor="#000000" android:strokeLineCap="round"/>
<path android:pathData="M64.5,101a6.5,8.5 0,1 0,13 0a6.5,8.5 0,1 0,-13 0z" android:strokeWidth="14" android:fillColor="#00000000" android:strokeColor="#000000"/>
<path android:pathData="M114.5,101a6.5,8.5 0,1 0,13 0a6.5,8.5 0,1 0,-13 0z" android:strokeWidth="14" android:fillColor="#00000000" android:strokeColor="#000000"/>
</vector>

View File

@@ -0,0 +1,5 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#000000" android:viewportHeight="960" android:viewportWidth="960" android:width="24dp">
<path android:fillColor="@android:color/white" android:pathData="M856,570L570,856Q558,868 543,874Q528,880 513,880Q498,880 483,874Q468,868 456,856L103,503Q92,492 86,477.5Q80,463 80,447L80,160Q80,127 103.5,103.5Q127,80 160,80L447,80Q463,80 478,86.5Q493,93 504,104L856,457Q868,469 873.5,484Q879,499 879,514Q879,529 873.5,543.5Q868,558 856,570ZM513,800L799,514Q799,514 799,514Q799,514 799,514L446,160L160,160Q160,160 160,160Q160,160 160,160L160,446Q160,446 160,446Q160,446 160,446L513,800Q513,800 513,800Q513,800 513,800ZM260,320Q285,320 302.5,302.5Q320,285 320,260Q320,235 302.5,217.5Q285,200 260,200Q235,200 217.5,217.5Q200,235 200,260Q200,285 217.5,302.5Q235,320 260,320ZM480,480Q480,480 480,480Q480,480 480,480L480,480Q480,480 480,480Q480,480 480,480L480,480Q480,480 480,480Q480,480 480,480L480,480L480,480Q480,480 480,480Q480,480 480,480ZM548,672L660,560Q671,549 677.5,534Q684,519 684,502Q684,468 660,444Q636,420 602,420Q583,420 564.5,431Q546,442 520,468Q490,440 473,430Q456,420 438,420Q404,420 380,444Q356,468 356,502Q356,519 362.5,534Q369,549 380,560L492,672Q504,684 520,684Q536,684 548,672Z"/>
</vector>

View File

@@ -1,10 +1,5 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#000000"
android:fillType="evenOdd"
android:pathData="M11.9991,2C6.4771,2 2,6.4771 2,12.0003C2,16.4185 4.865,20.1663 8.8388,21.4892C9.3391,21.5807 9.5214,21.2719 9.5214,21.0067C9.5214,20.7698 9.5128,20.1405 9.5079,19.3062C6.7264,19.9103 6.1395,17.9655 6.1395,17.9655C5.6846,16.8102 5.0289,16.5026 5.0289,16.5026C4.121,15.8826 5.0977,15.8948 5.0977,15.8948C6.1014,15.9654 6.6294,16.9256 6.6294,16.9256C7.5213,18.4535 8.9701,18.0122 9.5398,17.7562C9.6307,17.1103 9.8885,16.6696 10.1746,16.4197C7.9541,16.1674 5.6195,15.3092 5.6195,11.4773C5.6195,10.3858 6.0093,9.4932 6.649,8.7939C6.5459,8.541 6.2027,7.5244 6.7466,6.1474C6.7466,6.1474 7.5864,5.8786 9.4969,7.1726C10.2943,6.9504 11.1501,6.8399 12.0003,6.8362C12.8493,6.8399 13.7051,6.9504 14.5038,7.1726C16.413,5.8786 17.2509,6.1474 17.2509,6.1474C17.7967,7.5244 17.4535,8.541 17.3504,8.7939C17.9913,9.4932 18.3786,10.3858 18.3786,11.4773C18.3786,15.319 16.0403,16.1643 13.8125,16.4117C14.1716,16.7205 14.4915,17.3307 14.4915,18.2638C14.4915,19.6003 14.4792,20.6789 14.4792,21.0067C14.4792,21.2744 14.6591,21.5856 15.1668,21.488C19.1374,20.1626 22,16.4173 22,12.0003C22,6.4771 17.5223,2 11.9991,2Z" />
<?xml version="1.0" encoding="UTF-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="192dp" android:height="192dp" android:viewportWidth="192" android:viewportHeight="192" android:tint="#000000">
<path android:pathData="M121.75,170c0.03,-4.67 0.06,-20.87 0.06,-27.29 0,-9.27 -3.17,-15.34 -6.72,-18.41 22.05,-2.46 45.2,-10.86 45.2,-49.07 0,-10.85 -3.82,-19.74 -10.18,-26.68 1.02,-2.52 4.41,-12.63 -0.99,-26.32 0,0 -8.3,-2.67 -27.2,10.2 -7.91,-2.21 -16.37,-3.31 -24.78,-3.35 -8.41,0.04 -16.87,1.14 -24.78,3.35C53.46,19.56 45.16,22.23 45.16,22.23c-5.4,13.69 -2,23.8 -0.99,26.32C37.82,55.5 34,64.38 34,75.23c0,38.2 23.15,46.6 45.2,49.07 -3.55,3.07 -6.72,9.14 -6.72,18.41 0,6.42 0.03,22.62 0.06,27.29M28,130c9.94,0.7 15.67,9.73 15.67,9.73 8.83,15.2 23.18,10.8 28.82,8.27" android:strokeLineJoin="round" android:strokeWidth="14" android:fillColor="#00000000" android:strokeColor="#000000" android:strokeLineCap="round"/>
</vector>

View File

@@ -0,0 +1,8 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="192dp"
android:height="192dp"
android:viewportWidth="192"
android:viewportHeight="192"
android:tint="#000000">
<path android:pathData="M31.07,87.11s65.46,-26.77 88.16,-36.2c8.7,-3.77 38.22,-15.84 38.22,-15.84s13.62,-5.28 12.49,7.54c-0.38,5.28 -3.41,23.75 -6.43,43.74 -4.54,28.28 -9.46,59.2 -9.46,59.2s-0.76,8.67 -7.19,10.18c-6.43,1.51 -15.35,-3.78 -17.92,-4.79 -2.57,-1.01 -28.38,-18.1 -38.21,-26.39 -2.65,-2.26 -5.68,-6.79 0.38,-12.07 13.62,-12.44 43.53,-45.5 43.53,-45.5l-66.99,41.35c-4.64,2.13 -9.64,2.7 -17.4,0.38 -11.35,-3.39 -25.59,-9.92 -25.59,-9.92s-9.08,-5.66 6.43,-11.69h-0Z" android:strokeLineJoin="round" android:strokeWidth="14" android:fillColor="#00000000" android:strokeColor="#000000"/>
</vector>

View File

@@ -0,0 +1,5 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#000000" android:viewportHeight="960" android:viewportWidth="960" android:width="24dp">
<path android:fillColor="@android:color/white" android:pathData="M603,758L569,855Q565,866 555,873Q545,880 533,880Q513,880 500.5,863.5Q488,847 496,827L648,425Q653,414 663,407Q673,400 685,400L715,400Q727,400 737,407Q747,414 752,425L904,828Q912,847 900,863.5Q888,880 868,880Q855,880 845.5,873Q836,866 831,854L797,758L603,758ZM362,559L188,732Q177,743 160.5,743.5Q144,744 132,732Q121,721 121,704Q121,687 132,676L306,502Q271,467 242.5,422Q214,377 190,320L274,320Q294,359 314,388Q334,417 362,446Q395,413 430.5,353.5Q466,294 484,240L80,240Q63,240 51.5,228.5Q40,217 40,200Q40,183 51.5,171.5Q63,160 80,160L320,160L320,120Q320,103 331.5,91.5Q343,80 360,80Q377,80 388.5,91.5Q400,103 400,120L400,160L640,160Q657,160 668.5,171.5Q680,183 680,200Q680,217 668.5,228.5Q657,240 640,240L564,240Q543,312 501,388Q459,464 418,504L514,602L484,684L362,559ZM628,688L772,688L700,484L628,688Z"/>
</vector>

View File

@@ -1,9 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="512"
android:viewportHeight="512">
<path
android:fillColor="#FF000000"
android:pathData="M389.2,48h70.6L305.6,224.2 487,464H345L233.7,318.6 106.5,464H35.8L200.7,275.5 26.8,48H172.4L272.9,180.9 389.2,48zM364.4,421.8h39.1L151.1,88h-42L364.4,421.8z" />
android:width="192dp"
android:height="192dp"
android:viewportWidth="192"
android:viewportHeight="192"
android:tint="#000000">
<path android:pathData="m22,22 l112,148" android:strokeLineJoin="round" android:strokeWidth="14" android:fillColor="#00000000" android:strokeColor="#000000" android:strokeLineCap="round"/>
<path android:pathData="m83,108 l-51,61M154,23l-49,58.61" android:strokeLineJoin="round" android:strokeWidth="14" android:fillColor="#00000000" android:strokeColor="#000000" android:strokeLineCap="round"/>
<path android:pathData="m58,22 l112,148M22,22h36m76,148h36" android:strokeLineJoin="round" android:strokeWidth="14" android:fillColor="#00000000" android:strokeColor="#000000" android:strokeLineCap="round"/>
</vector>

View File

@@ -440,11 +440,11 @@
About the app
-->
<string name="news">News</string>
<string name="support">Support</string>
<string name="x_twitter" translatable="false">X</string>
<string name="github" translatable="false">GitHub</string>
<string name="discord" translatable="false">Discord</string>
<string name="support">Support</string>
<string name="translate">Translate</string>
<string name="donate">Donate</string>
<string name="product">Product</string>
<string name="design_and_development">Design and development</string>
@@ -453,9 +453,15 @@
<string name="devops">DevOps</string>
<string name="support_and_pr">Support and PR</string>
<string name="community">Community</string>
<string name="x_twitter" translatable="false">X</string>
<string name="telegram">Telegram</string>
<string name="news">News</string>
<string name="discord" translatable="false">Discord</string>
<string name="legal">Legal</string>
<string name="acknowledgements">Acknowledgements</string>
<string name="translate">Translate</string>
<string name="donate">Donate</string>
<string name="privacy_policy">Privacy policy</string>
<string name="contributor_status_active">Active</string>

View File

@@ -46,6 +46,7 @@ import app.lawnchair.ui.preferences.LocalIsExpandedScreen
import app.lawnchair.ui.preferences.components.NavigationActionPreference
import app.lawnchair.ui.preferences.components.controls.ClickablePreference
import app.lawnchair.ui.preferences.components.layout.PreferenceDivider
import app.lawnchair.ui.preferences.components.layout.PreferenceGroupHeading
import app.lawnchair.ui.preferences.components.layout.PreferenceGroupItem
import app.lawnchair.ui.preferences.components.layout.PreferenceLayoutLazyColumn
import app.lawnchair.ui.preferences.components.layout.preferenceGroupItems
@@ -136,7 +137,7 @@ fun About(
.fillMaxWidth()
.padding(horizontal = 16.dp),
) {
uiState.links.forEach { link ->
uiState.topLinks.forEach { link ->
LawnchairLink(
iconResId = link.iconResId,
label = stringResource(id = link.labelResId),
@@ -166,8 +167,22 @@ fun About(
member = it,
)
}
preferenceGroupItems(
items = uiState.bottomLinks,
key = { _, it -> it.labelResId },
isFirstChild = false,
heading = { stringResource(id = R.string.community) },
) { _, it ->
HorizontalLawnchairLink(
iconResId = it.iconResId,
label = stringResource(id = it.labelResId),
url = it.url,
)
}
item {
Spacer(modifier = Modifier.requiredHeight(16.dp))
PreferenceGroupHeading(
stringResource(R.string.legal),
)
}
item {
PreferenceGroupItem(
@@ -187,27 +202,9 @@ fun About(
) {
PreferenceDivider()
ClickablePreference(
label = stringResource(id = R.string.translate),
label = stringResource(id = R.string.privacy_policy),
onClick = {
val webpage = CROWDIN_URL.toUri()
val intent = Intent(Intent.ACTION_VIEW, webpage)
if (intent.resolveActivity(context.packageManager) != null) {
context.startActivity(intent)
}
},
)
}
}
item {
PreferenceGroupItem(
cutTop = true,
cutBottom = false,
) {
PreferenceDivider()
ClickablePreference(
label = stringResource(id = R.string.donate),
onClick = {
val webpage = OPENCOLLECTIVE_FUNDING_URL.toUri()
val webpage = PRIVACY_POLICY.toUri()
val intent = Intent(Intent.ACTION_VIEW, webpage)
if (intent.resolveActivity(context.packageManager) != null) {
context.startActivity(intent)
@@ -219,5 +216,4 @@ fun About(
}
}
private const val OPENCOLLECTIVE_FUNDING_URL = "https://opencollective.com/lawnchair"
private const val CROWDIN_URL = "https://lawnchair.crowdin.com/lawnchair"
private const val PRIVACY_POLICY = "https://lawnchair.app/privacy_policy"

View File

@@ -16,7 +16,7 @@ import java.io.File
* @param commitHash The commit hash of the current build.
* @param coreTeam A list of [TeamMember] objects representing the core development team.
* @param supportAndPr A list of [TeamMember] objects representing those involved in support and public relations.
* @param links A list of [Link] objects representing useful external links (e.g., social media, website).
* @param topLinks A list of [Link] objects representing useful external links (e.g., social media, website).
* @param updateState The current [UpdateState] of the application's update checker.
*/
data class AboutUiState(
@@ -24,7 +24,8 @@ data class AboutUiState(
val commitHash: String = "",
val coreTeam: List<TeamMember> = emptyList(),
val supportAndPr: List<TeamMember> = emptyList(),
val links: List<Link> = emptyList(),
val topLinks: List<Link> = emptyList(),
val bottomLinks: List<Link> = emptyList(),
val updateState: UpdateState = UpdateState.Hidden,
)

View File

@@ -32,7 +32,8 @@ class AboutViewModel(
commitHash = BuildConfig.COMMIT_HASH,
coreTeam = team,
supportAndPr = supportAndPr,
links = links,
topLinks = topLinks,
bottomLinks = bottomLinks,
)
}
@@ -155,7 +156,7 @@ class AboutViewModel(
),
)
private val links = listOf(
private val topLinks = listOf(
Link(
iconResId = R.drawable.ic_new_releases,
labelResId = R.string.news,
@@ -164,23 +165,41 @@ class AboutViewModel(
Link(
iconResId = R.drawable.ic_help,
labelResId = R.string.support,
url = "https://t.me/lccommunity",
),
Link(
iconResId = R.drawable.ic_x_twitter,
labelResId = R.string.x_twitter,
url = "https://x.com/lawnchairapp",
url = "https://lawnchair.app/support",
),
Link(
iconResId = R.drawable.ic_github,
labelResId = R.string.github,
url = "https://github.com/LawnchairLauncher/lawnchair",
),
Link(
iconResId = R.drawable.ic_translate,
labelResId = R.string.translate,
url = "https://lawnchair.crowdin.com/lawnchair",
),
Link(
iconResId = R.drawable.ic_donate,
labelResId = R.string.donate,
url = "https://opencollective.com/lawnchair",
),
)
private val bottomLinks = listOf(
Link(
iconResId = R.drawable.ic_telegram,
labelResId = R.string.telegram,
url = "https://t.me/lccommunity",
),
Link(
iconResId = R.drawable.ic_discord,
labelResId = R.string.discord,
url = "https://discord.com/invite/3x8qNWxgGZ",
),
Link(
iconResId = R.drawable.ic_x_twitter,
labelResId = R.string.x_twitter,
url = "https://x.com/lawnchairapp",
),
)
private val supportAndPr = listOf(

View File

@@ -17,7 +17,6 @@
package app.lawnchair.ui.preferences.about
import android.content.Intent
import android.net.Uri
import androidx.annotation.DrawableRes
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
@@ -26,9 +25,12 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.requiredHeight
import androidx.compose.foundation.layout.requiredSize
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
@@ -39,6 +41,8 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.core.net.toUri
import app.lawnchair.ui.preferences.components.layout.PreferenceTemplate
@Composable
fun LawnchairLink(
@@ -56,7 +60,7 @@ fun LawnchairLink(
.height(64.dp)
.clip(MaterialTheme.shapes.medium)
.clickable {
val webpage = Uri.parse(url)
val webpage = url.toUri()
val intent = Intent(Intent.ACTION_VIEW, webpage)
if (intent.resolveActivity(context.packageManager) != null) {
context.startActivity(intent)
@@ -78,3 +82,40 @@ fun LawnchairLink(
)
}
}
@Composable
fun HorizontalLawnchairLink(
@DrawableRes iconResId: Int,
label: String,
url: String,
modifier: Modifier = Modifier,
) {
val context = LocalContext.current
PreferenceTemplate(
modifier = modifier.clickable {
val webpage = url.toUri()
val intent = Intent(Intent.ACTION_VIEW, webpage)
if (intent.resolveActivity(context.packageManager) != null) {
context.startActivity(intent)
}
},
title = {
Text(label)
},
startWidget = {
Surface(
shape = CircleShape,
color = MaterialTheme.colorScheme.secondaryContainer,
modifier = Modifier.requiredSize(32.dp),
) {
Image(
painterResource(id = iconResId),
contentDescription = null,
colorFilter = ColorFilter.tint(color = MaterialTheme.colorScheme.onSecondaryContainer),
modifier = Modifier.requiredSize(20.dp),
)
}
},
)
}