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