mirror of
https://github.com/zapstore/zapstore.git
synced 2026-10-06 04:58:23 +00:00
Adopt Wix Madefor Text and share app card identity.
This commit is contained in:
@@ -37,6 +37,7 @@ import androidx.compose.ui.text.withStyle
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.TextUnit
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.em
|
||||
import androidx.compose.ui.unit.sp
|
||||
|
||||
object ZapMarkdown {
|
||||
@@ -86,9 +87,10 @@ object ZapMarkdown {
|
||||
val level = match.groupValues[1].length
|
||||
withStyle(
|
||||
SpanStyle(
|
||||
fontFamily = FigtreeFontFamily,
|
||||
fontFamily = WixMadeforTextFontFamily,
|
||||
fontWeight = FontWeight.ExtraBold,
|
||||
fontSize = headingSize(level),
|
||||
letterSpacing = (-0.016).em,
|
||||
),
|
||||
) {
|
||||
appendInline(match.groupValues[2], onOpenUrl)
|
||||
|
||||
@@ -9,6 +9,7 @@ import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.text.font.Font
|
||||
import androidx.compose.ui.text.font.FontFamily
|
||||
import androidx.compose.ui.text.font.FontStyle
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.em
|
||||
@@ -97,16 +98,21 @@ object ZapRadius {
|
||||
}
|
||||
|
||||
// ---- Type ----
|
||||
// One workhorse grotesque (Figtree) carries everything; hierarchy comes from size and weight.
|
||||
// One workhorse grotesque (Wix Madefor Text) carries everything; hierarchy comes from size and weight.
|
||||
|
||||
val FigtreeFontFamily = FontFamily(
|
||||
Font(R.font.figtree_light, FontWeight.Light),
|
||||
Font(R.font.figtree_regular, FontWeight.Normal),
|
||||
Font(R.font.figtree_medium, FontWeight.Medium),
|
||||
Font(R.font.figtree_semibold, FontWeight.SemiBold),
|
||||
Font(R.font.figtree_bold, FontWeight.Bold),
|
||||
Font(R.font.figtree_extra_bold, FontWeight.ExtraBold),
|
||||
Font(R.font.figtree_black, FontWeight.Black),
|
||||
private val ZapLetterSpacing = (-0.016).em
|
||||
|
||||
val WixMadeforTextFontFamily = FontFamily(
|
||||
Font(R.font.wix_madefor_text_regular, FontWeight.Normal),
|
||||
Font(R.font.wix_madefor_text_italic, FontWeight.Normal, FontStyle.Italic),
|
||||
Font(R.font.wix_madefor_text_medium, FontWeight.Medium),
|
||||
Font(R.font.wix_madefor_text_medium_italic, FontWeight.Medium, FontStyle.Italic),
|
||||
Font(R.font.wix_madefor_text_semibold, FontWeight.SemiBold),
|
||||
Font(R.font.wix_madefor_text_semibold_italic, FontWeight.SemiBold, FontStyle.Italic),
|
||||
Font(R.font.wix_madefor_text_bold, FontWeight.Bold),
|
||||
Font(R.font.wix_madefor_text_bold_italic, FontWeight.Bold, FontStyle.Italic),
|
||||
Font(R.font.wix_madefor_text_extrabold, FontWeight.ExtraBold),
|
||||
Font(R.font.wix_madefor_text_extrabold_italic, FontWeight.ExtraBold, FontStyle.Italic),
|
||||
)
|
||||
|
||||
private val ZapColorScheme = darkColorScheme(
|
||||
@@ -137,85 +143,91 @@ private val ZapColorScheme = darkColorScheme(
|
||||
private val ZapTypography = Typography(
|
||||
// Display — hero headline only.
|
||||
displayLarge = Typography().displayLarge.copy(
|
||||
fontFamily = FigtreeFontFamily,
|
||||
fontFamily = WixMadeforTextFontFamily,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
fontSize = 36.sp,
|
||||
lineHeight = 38.sp,
|
||||
letterSpacing = (-0.04).em,
|
||||
letterSpacing = ZapLetterSpacing,
|
||||
),
|
||||
// Heading 1 — section and screen titles.
|
||||
displaySmall = Typography().displaySmall.copy(
|
||||
fontFamily = FigtreeFontFamily,
|
||||
fontFamily = WixMadeforTextFontFamily,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
fontSize = 26.sp,
|
||||
lineHeight = 30.sp,
|
||||
letterSpacing = (-0.025).em,
|
||||
letterSpacing = ZapLetterSpacing,
|
||||
),
|
||||
// Heading 2 — sheet titles, welcome card.
|
||||
headlineSmall = Typography().headlineSmall.copy(
|
||||
fontFamily = FigtreeFontFamily,
|
||||
fontFamily = WixMadeforTextFontFamily,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
fontSize = 22.sp,
|
||||
lineHeight = 28.sp,
|
||||
letterSpacing = (-0.015).em,
|
||||
letterSpacing = ZapLetterSpacing,
|
||||
),
|
||||
titleLarge = Typography().titleLarge.copy(
|
||||
fontFamily = FigtreeFontFamily,
|
||||
fontFamily = WixMadeforTextFontFamily,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
fontSize = 22.sp,
|
||||
lineHeight = 28.sp,
|
||||
letterSpacing = (-0.015).em,
|
||||
letterSpacing = ZapLetterSpacing,
|
||||
),
|
||||
// Heading 3 — app names in detail heads and rows.
|
||||
titleMedium = Typography().titleMedium.copy(
|
||||
fontFamily = FigtreeFontFamily,
|
||||
fontFamily = WixMadeforTextFontFamily,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
fontSize = 17.sp,
|
||||
lineHeight = 24.sp,
|
||||
letterSpacing = ZapLetterSpacing,
|
||||
),
|
||||
// Body — 16sp on Android.
|
||||
bodyLarge = Typography().bodyLarge.copy(
|
||||
fontFamily = FigtreeFontFamily,
|
||||
fontFamily = WixMadeforTextFontFamily,
|
||||
fontWeight = FontWeight.Normal,
|
||||
fontSize = 16.sp,
|
||||
lineHeight = 24.sp,
|
||||
letterSpacing = ZapLetterSpacing,
|
||||
),
|
||||
// Body small — descriptions in rows and cards.
|
||||
bodyMedium = Typography().bodyMedium.copy(
|
||||
fontFamily = FigtreeFontFamily,
|
||||
fontFamily = WixMadeforTextFontFamily,
|
||||
fontWeight = FontWeight.Normal,
|
||||
fontSize = 15.sp,
|
||||
lineHeight = 22.sp,
|
||||
letterSpacing = ZapLetterSpacing,
|
||||
),
|
||||
// Caption — timestamps, secondary facts.
|
||||
bodySmall = Typography().bodySmall.copy(
|
||||
fontFamily = FigtreeFontFamily,
|
||||
fontFamily = WixMadeforTextFontFamily,
|
||||
fontWeight = FontWeight.Normal,
|
||||
fontSize = 13.sp,
|
||||
lineHeight = 18.sp,
|
||||
letterSpacing = ZapLetterSpacing,
|
||||
),
|
||||
// Button label — 14sp/600.
|
||||
labelLarge = Typography().labelLarge.copy(
|
||||
fontFamily = FigtreeFontFamily,
|
||||
fontFamily = WixMadeforTextFontFamily,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
fontSize = 14.sp,
|
||||
lineHeight = 20.sp,
|
||||
letterSpacing = ZapLetterSpacing,
|
||||
),
|
||||
// Evidence — verifiable values (versions, hashes, package IDs); tabular figures.
|
||||
labelMedium = Typography().labelMedium.copy(
|
||||
fontFamily = FigtreeFontFamily,
|
||||
fontFamily = WixMadeforTextFontFamily,
|
||||
fontWeight = FontWeight.Medium,
|
||||
fontSize = 13.sp,
|
||||
lineHeight = 17.sp,
|
||||
letterSpacing = ZapLetterSpacing,
|
||||
fontFeatureSettings = "tnum",
|
||||
),
|
||||
// Label — list-group headers, table headers, nav groups. Uppercase at call sites.
|
||||
labelSmall = Typography().labelSmall.copy(
|
||||
fontFamily = FigtreeFontFamily,
|
||||
fontFamily = WixMadeforTextFontFamily,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
fontSize = 11.sp,
|
||||
lineHeight = 16.sp,
|
||||
letterSpacing = 0.08.em,
|
||||
letterSpacing = ZapLetterSpacing,
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -89,29 +89,17 @@ fun AppCard(
|
||||
.clickable(onClick = onClick)
|
||||
.padding(ZapSpacing.space4),
|
||||
) {
|
||||
BoxWithConstraints {
|
||||
val iconSize = (maxWidth * 0.21f).coerceIn(50.dp, 68.dp)
|
||||
Row(verticalAlignment = Alignment.Top) {
|
||||
AppIcon(
|
||||
title = app.name,
|
||||
iconUrl = app.iconUrl,
|
||||
size = iconSize,
|
||||
)
|
||||
Spacer(Modifier.width(ZapSpacing.space3))
|
||||
Column(Modifier.weight(1f)) {
|
||||
AppNameWithByline(
|
||||
name = app.name,
|
||||
authorName = authorName,
|
||||
authorProfile = authorProfile,
|
||||
authorPubkey = authorPubkey,
|
||||
version = release?.version,
|
||||
onAuthorClick = onProfileClick,
|
||||
authorTestTag = authorPubkey?.let { "profile:$it" },
|
||||
showAuthor = showAuthor,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
AppIdentityRow(
|
||||
name = app.name,
|
||||
iconUrl = app.iconUrl,
|
||||
authorName = authorName,
|
||||
authorProfile = authorProfile,
|
||||
authorPubkey = authorPubkey,
|
||||
version = release?.version,
|
||||
onAuthorClick = onProfileClick,
|
||||
authorTestTag = authorPubkey?.let { "profile:$it" },
|
||||
showAuthor = showAuthor,
|
||||
)
|
||||
if (app.summary.isNotBlank()) {
|
||||
Spacer(Modifier.height(ZapSpacing.space2))
|
||||
Text(
|
||||
@@ -125,6 +113,43 @@ fun AppCard(
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun AppIdentityRow(
|
||||
name: String,
|
||||
iconUrl: String?,
|
||||
authorName: String?,
|
||||
authorProfile: ProfileInfo?,
|
||||
authorPubkey: String?,
|
||||
version: String?,
|
||||
modifier: Modifier = Modifier,
|
||||
onAuthorClick: (() -> Unit)? = null,
|
||||
authorTestTag: String? = null,
|
||||
showAuthor: Boolean = true,
|
||||
) {
|
||||
BoxWithConstraints(modifier = modifier.fillMaxWidth()) {
|
||||
val iconSize = (maxWidth * 0.21f).coerceIn(50.dp, 68.dp)
|
||||
Row(verticalAlignment = Alignment.Top) {
|
||||
AppIcon(
|
||||
title = name,
|
||||
iconUrl = iconUrl,
|
||||
size = iconSize,
|
||||
)
|
||||
Spacer(Modifier.width(ZapSpacing.space3))
|
||||
AppNameWithByline(
|
||||
name = name,
|
||||
authorName = authorName,
|
||||
authorProfile = authorProfile,
|
||||
authorPubkey = authorPubkey,
|
||||
version = version,
|
||||
onAuthorClick = onAuthorClick,
|
||||
authorTestTag = authorTestTag,
|
||||
showAuthor = showAuthor,
|
||||
modifier = Modifier.weight(1f),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun AppNameWithByline(
|
||||
name: String,
|
||||
@@ -137,18 +162,20 @@ fun AppNameWithByline(
|
||||
authorTestTag: String? = null,
|
||||
showAuthor: Boolean = true,
|
||||
) {
|
||||
Column(modifier = modifier) {
|
||||
Column(
|
||||
modifier = modifier,
|
||||
verticalArrangement = Arrangement.spacedBy(6.dp),
|
||||
) {
|
||||
Text(
|
||||
text = name,
|
||||
style = MaterialTheme.typography.titleMedium.copy(
|
||||
fontSize = 19.sp,
|
||||
lineHeight = 23.sp,
|
||||
fontSize = 23.sp,
|
||||
lineHeight = 28.sp,
|
||||
fontWeight = FontWeight.Black,
|
||||
),
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
Spacer(Modifier.height(8.dp))
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||
@@ -218,8 +245,8 @@ fun VersionPill(
|
||||
fun StackCard(
|
||||
stack: StackInfo,
|
||||
appsByAddress: Map<String, AppInfo>,
|
||||
onClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
onClick: (() -> Unit)? = null,
|
||||
) {
|
||||
Column(
|
||||
modifier = modifier
|
||||
@@ -227,7 +254,7 @@ fun StackCard(
|
||||
.clip(RoundedCornerShape(ZapRadius.lg))
|
||||
.background(ZapSurface1)
|
||||
.border(1.dp, ZapLine, RoundedCornerShape(ZapRadius.lg))
|
||||
.clickable(onClick = onClick)
|
||||
.then(if (onClick != null) Modifier.clickable(onClick = onClick) else Modifier)
|
||||
.padding(ZapSpacing.space4),
|
||||
) {
|
||||
Text(
|
||||
|
||||
@@ -57,7 +57,6 @@ import java.text.DateFormat
|
||||
import java.text.NumberFormat
|
||||
import java.util.Date
|
||||
|
||||
private val BigIconSize = 84.dp
|
||||
private val SmallIconSize = 26.dp
|
||||
private val SmallHeaderHeight = 32.dp
|
||||
|
||||
@@ -350,29 +349,16 @@ private fun RegularAppHeader(
|
||||
authorProfile: ProfileInfo?,
|
||||
onProfileClick: () -> Unit,
|
||||
) {
|
||||
// Reuses the same icon+title+version+byline block as the search/home AppCard, so the
|
||||
// header reads as the same component, just bigger — not a bespoke hero layout.
|
||||
val authorName = authorPubkey?.let { profileDisplayName(authorProfile, it) }
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
verticalAlignment = Alignment.Top,
|
||||
horizontalArrangement = Arrangement.spacedBy(ZapSpacing.space3),
|
||||
) {
|
||||
AppIcon(
|
||||
title = app.name,
|
||||
iconUrl = app.iconUrl,
|
||||
size = BigIconSize,
|
||||
)
|
||||
AppNameWithByline(
|
||||
name = app.name,
|
||||
authorName = authorName,
|
||||
authorProfile = authorProfile,
|
||||
authorPubkey = authorPubkey,
|
||||
version = release?.version,
|
||||
onAuthorClick = onProfileClick,
|
||||
modifier = Modifier.weight(1f),
|
||||
)
|
||||
}
|
||||
AppIdentityRow(
|
||||
name = app.name,
|
||||
iconUrl = app.iconUrl,
|
||||
authorName = authorName,
|
||||
authorProfile = authorProfile,
|
||||
authorPubkey = authorPubkey,
|
||||
version = release?.version,
|
||||
onAuthorClick = onProfileClick,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<font-family xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<font
|
||||
android:font="@font/wix_madefor_text_regular"
|
||||
android:fontStyle="normal"
|
||||
android:fontWeight="400" />
|
||||
<font
|
||||
android:font="@font/wix_madefor_text_italic"
|
||||
android:fontStyle="italic"
|
||||
android:fontWeight="400" />
|
||||
<font
|
||||
android:font="@font/wix_madefor_text_medium"
|
||||
android:fontStyle="normal"
|
||||
android:fontWeight="500" />
|
||||
<font
|
||||
android:font="@font/wix_madefor_text_medium_italic"
|
||||
android:fontStyle="italic"
|
||||
android:fontWeight="500" />
|
||||
<font
|
||||
android:font="@font/wix_madefor_text_semibold"
|
||||
android:fontStyle="normal"
|
||||
android:fontWeight="600" />
|
||||
<font
|
||||
android:font="@font/wix_madefor_text_semibold_italic"
|
||||
android:fontStyle="italic"
|
||||
android:fontWeight="600" />
|
||||
<font
|
||||
android:font="@font/wix_madefor_text_bold"
|
||||
android:fontStyle="normal"
|
||||
android:fontWeight="700" />
|
||||
<font
|
||||
android:font="@font/wix_madefor_text_bold_italic"
|
||||
android:fontStyle="italic"
|
||||
android:fontWeight="700" />
|
||||
<font
|
||||
android:font="@font/wix_madefor_text_extrabold"
|
||||
android:fontStyle="normal"
|
||||
android:fontWeight="800" />
|
||||
<font
|
||||
android:font="@font/wix_madefor_text_extrabold_italic"
|
||||
android:fontStyle="italic"
|
||||
android:fontWeight="800" />
|
||||
</font-family>
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,6 +1,6 @@
|
||||
<resources>
|
||||
<style name="AppTheme" parent="android:style/Theme.Material.NoActionBar">
|
||||
<item name="android:fontFamily">@font/figtree_regular</item>
|
||||
<item name="android:fontFamily">@font/wix_madefor_text</item>
|
||||
<item name="android:windowActionModeOverlay">true</item>
|
||||
<item name="android:windowLightStatusBar">false</item>
|
||||
<item name="android:windowLightNavigationBar">false</item>
|
||||
|
||||
Reference in New Issue
Block a user