feat(android): introduce CloserGlyphs catalog + migrate CategoryGlyph to brand vector resources

This commit is contained in:
null 2026-06-28 17:46:05 -05:00
parent 582aefcec2
commit c31ae4b1f7
2 changed files with 87 additions and 43 deletions

View File

@ -3,27 +3,6 @@ package app.closer.ui.components
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.Chat
import androidx.compose.material.icons.filled.AttachMoney
import androidx.compose.material.icons.filled.CalendarToday
import androidx.compose.material.icons.filled.Check
import androidx.compose.material.icons.filled.Close
import androidx.compose.material.icons.filled.Favorite
import androidx.compose.material.icons.filled.FavoriteBorder
import androidx.compose.material.icons.filled.Home
import androidx.compose.material.icons.filled.Lock
import androidx.compose.material.icons.filled.People
import androidx.compose.material.icons.filled.Person
import androidx.compose.material.icons.filled.PlayArrow
import androidx.compose.material.icons.filled.Psychology
import androidx.compose.material.icons.filled.QuestionAnswer
import androidx.compose.material.icons.filled.Shield
import androidx.compose.material.icons.filled.Star
import androidx.compose.material.icons.filled.Sync
import androidx.compose.material.icons.filled.Timeline
import androidx.compose.material.icons.filled.Visibility
import androidx.compose.material.icons.filled.Warning
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
@ -32,8 +11,10 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import app.closer.R
import app.closer.ui.theme.CloserPalette
data class GlyphStyle(
@ -104,9 +85,9 @@ fun ResultGlyph(
size: Dp = 32.dp
) {
val icon = when {
isPositive -> Icons.Filled.Check
isClose -> Icons.Filled.Timeline
else -> Icons.Filled.Close
isPositive -> ImageVector.vectorResource(R.drawable.glyph_check)
isClose -> ImageVector.vectorResource(R.drawable.glyph_timeline)
else -> ImageVector.vectorResource(R.drawable.glyph_close)
}
val tint = when {
isPositive -> CloserPalette.Evergreen
@ -137,7 +118,7 @@ fun categoryGlyphStyle(
): GlyphStyle {
if (locked) {
return GlyphStyle(
icon = Icons.Filled.Lock,
icon = ImageVector.vectorResource(R.drawable.glyph_lock),
tint = MaterialTheme.colorScheme.outline,
container = CloserPalette.PurpleMist
)
@ -146,92 +127,92 @@ fun categoryGlyphStyle(
val key = (iconName ?: categoryId).lowercase().trim()
return when (key) {
"communication", "chat", "question", "questions" -> GlyphStyle(
icon = Icons.AutoMirrored.Filled.Chat,
icon = ImageVector.vectorResource(R.drawable.glyph_chat),
tint = CloserPalette.PurpleDeep,
container = CloserPalette.PurpleMist
)
"emotional_intimacy", "intimacy", "heart" -> GlyphStyle(
icon = Icons.Filled.Favorite,
icon = ImageVector.vectorResource(R.drawable.glyph_heart),
tint = CloserPalette.PinkAccentDeep,
container = CloserPalette.PinkMist
)
"physical_intimacy", "sex_and_desire", "sexual_preferences", "desire", "sex" -> GlyphStyle(
icon = Icons.Filled.FavoriteBorder,
icon = ImageVector.vectorResource(R.drawable.glyph_heart_outline),
tint = CloserPalette.Romantic,
container = CloserPalette.Romantic.copy(alpha = 0.12f)
)
"trust", "rebuilding_trust", "privacy" -> GlyphStyle(
icon = Icons.Filled.Shield,
icon = ImageVector.vectorResource(R.drawable.glyph_shield),
tint = CloserPalette.PurpleDeep,
container = CloserPalette.PurpleGlow
)
"conflict", "conflict_repair", "repair" -> GlyphStyle(
icon = Icons.Filled.Sync,
icon = ImageVector.vectorResource(R.drawable.glyph_sync),
tint = CloserPalette.PurpleRich,
container = CloserPalette.PurpleMist
)
"future", "timeline" -> GlyphStyle(
icon = Icons.Filled.Timeline,
icon = ImageVector.vectorResource(R.drawable.glyph_timeline),
tint = CloserPalette.PurpleDeep,
container = CloserPalette.PurpleSoft
)
"money", "payments" -> GlyphStyle(
icon = Icons.Filled.AttachMoney,
icon = ImageVector.vectorResource(R.drawable.glyph_attach_money),
tint = CloserPalette.PurpleDeep,
container = CloserPalette.PurpleMist
)
"home_life", "home" -> GlyphStyle(
icon = Icons.Filled.Home,
icon = ImageVector.vectorResource(R.drawable.glyph_home),
tint = CloserPalette.PurpleRich,
container = CloserPalette.PurpleGlow
)
"gratitude", "star" -> GlyphStyle(
icon = Icons.Filled.Star,
icon = ImageVector.vectorResource(R.drawable.glyph_star),
tint = CloserPalette.PinkAccentDeep,
container = CloserPalette.PinkMist
)
"parenting", "family", "people" -> GlyphStyle(
icon = Icons.Filled.People,
icon = ImageVector.vectorResource(R.drawable.glyph_couple),
tint = CloserPalette.PurpleDeep,
container = CloserPalette.PurpleSoft
)
"date_night", "date", "calendar" -> GlyphStyle(
icon = Icons.Filled.CalendarToday,
icon = ImageVector.vectorResource(R.drawable.glyph_calendar),
tint = CloserPalette.PinkAccentDeep,
container = CloserPalette.PinkMist
)
"fun", "play" -> GlyphStyle(
icon = Icons.Filled.PlayArrow,
icon = ImageVector.vectorResource(R.drawable.glyph_play),
tint = CloserPalette.PurpleDeep,
container = CloserPalette.PurpleGlow
)
"stress", "difficult_conversations", "boundaries" -> GlyphStyle(
icon = Icons.Filled.Warning,
icon = ImageVector.vectorResource(R.drawable.glyph_warning),
tint = CloserPalette.Danger,
container = CloserPalette.Danger.copy(alpha = 0.10f)
)
"values", "marriage" -> GlyphStyle(
icon = Icons.Filled.QuestionAnswer,
icon = ImageVector.vectorResource(R.drawable.glyph_question_answer),
tint = CloserPalette.PurpleDeep,
container = CloserPalette.PurpleMist
)
"profile", "person" -> GlyphStyle(
icon = Icons.Filled.Person,
icon = ImageVector.vectorResource(R.drawable.glyph_person),
tint = CloserPalette.PurpleDeep,
container = CloserPalette.PurpleMist
)
"reveal", "visibility" -> GlyphStyle(
icon = Icons.Filled.Visibility,
icon = ImageVector.vectorResource(R.drawable.glyph_eye),
tint = CloserPalette.PurpleDeep,
container = CloserPalette.PurpleGlow
)
"predict", "psychology" -> GlyphStyle(
icon = Icons.Filled.Psychology,
icon = ImageVector.vectorResource(R.drawable.glyph_psychology),
tint = CloserPalette.PurpleDeep,
container = CloserPalette.PurpleGlow
)
else -> GlyphStyle(
icon = Icons.Filled.Star,
icon = ImageVector.vectorResource(R.drawable.glyph_star),
tint = CloserPalette.PurpleDeep,
container = CloserPalette.PurpleMist
)

View File

@ -0,0 +1,63 @@
package app.closer.ui.components
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.vectorResource
import app.closer.R
/**
* Central accessors for the bespoke Closer brand glyphs (`res/drawable-nodpi/glyph_*.xml`) that replace
* generic Material `Icons.*` (brand rule 2 every icon is a custom Closer glyph). Each is a
* `@Composable` getter so a call site reads like an icon constant and needs only this one import:
*
* Icon(imageVector = CloserGlyphs.Back, contentDescription = "Back")
*
* Add a new accessor here whenever a `glyph_*.xml` is wired, then point the `Icons.*` call sites at it.
*/
object CloserGlyphs {
val Back: ImageVector @Composable get() = ImageVector.vectorResource(R.drawable.glyph_back)
val Forward: ImageVector @Composable get() = ImageVector.vectorResource(R.drawable.glyph_forward)
val Close: ImageVector @Composable get() = ImageVector.vectorResource(R.drawable.glyph_close)
val Check: ImageVector @Composable get() = ImageVector.vectorResource(R.drawable.glyph_check)
val Lock: ImageVector @Composable get() = ImageVector.vectorResource(R.drawable.glyph_lock)
val LockOpen: ImageVector @Composable get() = ImageVector.vectorResource(R.drawable.glyph_lock_open)
val Person: ImageVector @Composable get() = ImageVector.vectorResource(R.drawable.glyph_person)
val Couple: ImageVector @Composable get() = ImageVector.vectorResource(R.drawable.glyph_couple)
val Heart: ImageVector @Composable get() = ImageVector.vectorResource(R.drawable.glyph_heart)
val HeartOutline: ImageVector @Composable get() = ImageVector.vectorResource(R.drawable.glyph_heart_outline)
val Star: ImageVector @Composable get() = ImageVector.vectorResource(R.drawable.glyph_star)
val Eye: ImageVector @Composable get() = ImageVector.vectorResource(R.drawable.glyph_eye)
val EyeOff: ImageVector @Composable get() = ImageVector.vectorResource(R.drawable.glyph_eye_off)
val Play: ImageVector @Composable get() = ImageVector.vectorResource(R.drawable.glyph_play)
val Copy: ImageVector @Composable get() = ImageVector.vectorResource(R.drawable.glyph_copy)
val Sync: ImageVector @Composable get() = ImageVector.vectorResource(R.drawable.glyph_sync)
val Send: ImageVector @Composable get() = ImageVector.vectorResource(R.drawable.glyph_send)
val Photo: ImageVector @Composable get() = ImageVector.vectorResource(R.drawable.glyph_photo)
val Camera: ImageVector @Composable get() = ImageVector.vectorResource(R.drawable.glyph_camera)
val Trash: ImageVector @Composable get() = ImageVector.vectorResource(R.drawable.glyph_trash)
val Add: ImageVector @Composable get() = ImageVector.vectorResource(R.drawable.glyph_add)
val Chat: ImageVector @Composable get() = ImageVector.vectorResource(R.drawable.glyph_chat)
val Bell: ImageVector @Composable get() = ImageVector.vectorResource(R.drawable.glyph_bell)
val Warning: ImageVector @Composable get() = ImageVector.vectorResource(R.drawable.glyph_warning)
val Shield: ImageVector @Composable get() = ImageVector.vectorResource(R.drawable.glyph_shield)
val Share: ImageVector @Composable get() = ImageVector.vectorResource(R.drawable.glyph_share)
val Refresh: ImageVector @Composable get() = ImageVector.vectorResource(R.drawable.glyph_refresh)
val QuestionAnswer: ImageVector @Composable get() = ImageVector.vectorResource(R.drawable.glyph_question_answer)
val Pause: ImageVector @Composable get() = ImageVector.vectorResource(R.drawable.glyph_pause)
val Palette: ImageVector @Composable get() = ImageVector.vectorResource(R.drawable.glyph_palette)
val Mic: ImageVector @Composable get() = ImageVector.vectorResource(R.drawable.glyph_mic)
val Streak: ImageVector @Composable get() = ImageVector.vectorResource(R.drawable.glyph_streak)
val Key: ImageVector @Composable get() = ImageVector.vectorResource(R.drawable.glyph_key)
val Hourglass: ImageVector @Composable get() = ImageVector.vectorResource(R.drawable.glyph_hourglass)
val Home: ImageVector @Composable get() = ImageVector.vectorResource(R.drawable.glyph_home)
val Fingerprint: ImageVector @Composable get() = ImageVector.vectorResource(R.drawable.glyph_fingerprint)
val Edit: ImageVector @Composable get() = ImageVector.vectorResource(R.drawable.glyph_edit)
val CardGiftcard: ImageVector @Composable get() = ImageVector.vectorResource(R.drawable.glyph_card_giftcard)
val Calendar: ImageVector @Composable get() = ImageVector.vectorResource(R.drawable.glyph_calendar)
val Cake: ImageVector @Composable get() = ImageVector.vectorResource(R.drawable.glyph_cake)
val AttachMoney: ImageVector @Composable get() = ImageVector.vectorResource(R.drawable.glyph_attach_money)
val TrendingUp: ImageVector @Composable get() = ImageVector.vectorResource(R.drawable.glyph_trending_up)
val Timeline: ImageVector @Composable get() = ImageVector.vectorResource(R.drawable.glyph_timeline)
val Psychology: ImageVector @Composable get() = ImageVector.vectorResource(R.drawable.glyph_psychology)
val OpenInNew: ImageVector @Composable get() = ImageVector.vectorResource(R.drawable.glyph_open_in_new)
}