diff --git a/gearslip/src/main/java/app/seb3thehacker/gearslip/ui/AboutLinks.kt b/gearslip/src/main/java/app/seb3thehacker/gearslip/ui/AboutLinks.kt index 1b2f642..943d58e 100644 --- a/gearslip/src/main/java/app/seb3thehacker/gearslip/ui/AboutLinks.kt +++ b/gearslip/src/main/java/app/seb3thehacker/gearslip/ui/AboutLinks.kt @@ -39,9 +39,9 @@ internal fun AboutLinkRows() { ) } SettingsRow( - "Join the discussion on Matrix", + "Join the chat on Matrix", Modifier.clickable { GearslipLinks.open(context, GearslipLinks.MATRIX) }, - subtitle = "Questions, ideas, or a car to report", + subtitle = "Talk with other drivers about cars, apps, and Gearslip", icon = Icons.AutoMirrored.Filled.Send, trailing = arrow, ) diff --git a/gearslip/src/main/java/app/seb3thehacker/gearslip/ui/IntroScreen.kt b/gearslip/src/main/java/app/seb3thehacker/gearslip/ui/IntroScreen.kt index a7fe37b..a07e7ae 100644 --- a/gearslip/src/main/java/app/seb3thehacker/gearslip/ui/IntroScreen.kt +++ b/gearslip/src/main/java/app/seb3thehacker/gearslip/ui/IntroScreen.kt @@ -49,6 +49,7 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip +import androidx.compose.ui.geometry.CornerRadius import androidx.compose.ui.geometry.Offset import androidx.compose.ui.geometry.Size import androidx.compose.ui.graphics.Color @@ -134,7 +135,7 @@ internal fun introColors(): IntroColors { ) } -private enum class IntroStep { WELCOME, WIRELESS, KNOBS, VOICE, GRAPHENE, THANKS, APPS, THEME, DRIVE } +private enum class IntroStep { WELCOME, WIRELESS, KNOBS, VOICE, GRAPHENE, THANKS, CHAT, APPS, THEME, DRIVE } private val Pop = CubicBezierEasing(0.3f, 1.6f, 0.5f, 1f) private val Rise = CubicBezierEasing(0.2f, 0.8f, 0.2f, 1f) @@ -191,6 +192,12 @@ fun IntroScreen(onDone: () -> Unit) { IntroStep.THANKS -> BadgeStep(c, ::cq, ::cqSp, c.tertiaryC, "Thank you.", "To everyone sending usage notes: they show me which cars Gearslip works in and which " + "ones still fail, so I know what to fix next. Every note helps.", step) { HeartIcon(c.onTertiaryC) } + IntroStep.CHAT -> BadgeStep(c, ::cq, ::cqSp, c.primaryC, "Come say hi.", + "Gearslip has a chat room on Matrix. Talk with other drivers about cars, apps, and " + + "where Gearslip is headed.", step, + action = "Join on Matrix" to { GearslipLinks.open(context, GearslipLinks.MATRIX) }, + outlined = true, + ) { ChatIcon(c.onPrimaryC, c.primaryC) } IntroStep.APPS -> BadgeStep(c, ::cq, ::cqSp, c.secondaryC, "Good company.", "Free, open-source apps that work well in the car. Tap one to see it on GitHub.", step, extra = { AppPicks(c, ::cq, ::cqSp, step) }) { StarIcon(c.onSecondaryC) } @@ -726,6 +733,27 @@ internal fun ShieldIcon(color: Color, tick: Color) { } } +/** A speech bubble with three dots that pulse, like someone typing. */ +@Composable +private fun ChatIcon(color: Color, dots: Color) { + val t = rememberInfiniteTransition(label = "typing") + val pulse = (0..2).map { i -> + t.animateFloat( + 0.35f, 1f, + infiniteRepeatable(tween(500, easing = FastOutSlowInEasing), RepeatMode.Reverse, + initialStartOffset = androidx.compose.animation.core.StartOffset(i * 170)), + label = "dot$i", + ) + } + Canvas(Modifier.fillMaxSize()) { + inIconBox { + drawRoundRect(color, Offset(4f, 7f), Size(40f, 28f), CornerRadius(10f, 10f)) + drawPath(Path().apply { moveTo(12f, 33f); lineTo(10f, 43f); lineTo(22f, 33f); close() }, color) + pulse.forEachIndexed { i, a -> drawCircle(dots.copy(alpha = a.value), 3.2f, Offset(15f + i * 9f, 21f)) } + } + } +} + @Composable internal fun HeartIcon(color: Color) { val beat by rememberInfiniteTransition(label = "beat").animateFloat(