mirror of
https://github.com/twinksoftware/Gearslip.git
synced 2026-11-10 16:02:25 +01:00
intro: only after an update, never on a new install; recommend Organic Maps before Vela and ViVi Music before Metrolist; the thanks page links the list of cars that work
This commit is contained in:
1 parent
cd7b13c88e
commit
76955669f5
2 files changed
+57
-25
No files matched your search
@@ -97,8 +97,8 @@ import kotlin.random.Random
|
||||
import kotlinx.coroutines.delay
|
||||
|
||||
/**
|
||||
* The release intro: a few tap-through screens shown once after each new release (and on a new
|
||||
* install), before setup. Its look follows the 0.3 mockup: Material shapes in the phone's own colours,
|
||||
* The release intro: a few screens shown once after updating to a new release, before setup. New
|
||||
* installs skip it. Its look follows the 0.3 mockup: Material shapes in the phone's own colours,
|
||||
* with every size taken from the screen's width so it scales from small phones to tablets.
|
||||
*/
|
||||
object Intro {
|
||||
@@ -108,8 +108,19 @@ object Intro {
|
||||
/** "0.3" from "0.3.00-alpha": the intro belongs to a release, not to each patch. */
|
||||
val release: String = BuildConfig.VERSION_NAME.split('.').take(2).joinToString(".")
|
||||
|
||||
fun due(context: Context): Boolean =
|
||||
context.getSharedPreferences(PREFS, Context.MODE_PRIVATE).getString(KEY_SEEN, null) != release
|
||||
/**
|
||||
* True once per release for people who updated. A new install gets the setup guide instead:
|
||||
* there's nothing "new" yet, so this release counts as seen and the next one shows.
|
||||
*/
|
||||
fun due(context: Context): Boolean {
|
||||
if (context.getSharedPreferences(PREFS, Context.MODE_PRIVATE).getString(KEY_SEEN, null) == release) return false
|
||||
val info = runCatching { context.packageManager.getPackageInfo(context.packageName, 0) }.getOrNull()
|
||||
if (info != null && info.firstInstallTime == info.lastUpdateTime) {
|
||||
markSeen(context)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
fun markSeen(context: Context) {
|
||||
context.getSharedPreferences(PREFS, Context.MODE_PRIVATE).edit().putString(KEY_SEEN, release).apply()
|
||||
@@ -187,7 +198,10 @@ fun IntroScreen(onDone: () -> Unit) {
|
||||
) { ShieldIcon(c.onSecondaryC, c.secondaryC) }
|
||||
IntroStep.THANKS -> BadgeStep(c, ::cq, ::cqSp, c.tertiaryC, "Thank you.",
|
||||
"Thanks to your usage notes, Gearslip is confirmed to work in cars newer than 2020. " +
|
||||
"Each note shows which cars work and which still fail, so I know what to fix next.", step) { HeartIcon(c.onTertiaryC) }
|
||||
"Each note shows which cars work and which still fail, so I know what to fix next.", step,
|
||||
action = "See which cars work" to { GearslipLinks.open(context, GearslipLinks.CARS) },
|
||||
outlined = true,
|
||||
) { 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,
|
||||
@@ -195,7 +209,7 @@ fun IntroScreen(onDone: () -> Unit) {
|
||||
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,
|
||||
"Free, open-source apps that work well in the car. The first in each row works best. Tap one to see it on GitHub.", step,
|
||||
extra = { AppPicks(c, ::cq, ::cqSp, step) }) { StarIcon(c.onSecondaryC) }
|
||||
IntroStep.THEME -> BadgeStep(c, ::cq, ::cqSp, c.tertiaryC, "Your buttons.",
|
||||
"Pick how the car's buttons look. Change it any time in the car's settings.", step,
|
||||
@@ -489,38 +503,56 @@ private fun CommandDrift(c: IntroColors, cq: (Float) -> Dp, cqSp: (Float) -> Tex
|
||||
}
|
||||
}
|
||||
|
||||
/** Each kind of app with its picks, the first recommended most. */
|
||||
private val APP_PICKS = listOf(
|
||||
Triple("Music", "Metrolist", "https://github.com/MetrolistGroup/Metrolist"),
|
||||
Triple("Maps", "Vela", "https://github.com/PimpinPumpkin/Vela"),
|
||||
Triple("Podcasts", "AntennaPod", "https://github.com/AntennaPod/AntennaPod"),
|
||||
"Maps" to listOf(
|
||||
"Organic Maps" to "https://github.com/organicmaps/organicmaps",
|
||||
"Vela" to "https://github.com/PimpinPumpkin/Vela",
|
||||
),
|
||||
"Music" to listOf(
|
||||
"ViVi Music" to "https://github.com/vivizzz007/vivi-music",
|
||||
"Metrolist" to "https://github.com/MetrolistGroup/Metrolist",
|
||||
),
|
||||
"Podcasts" to listOf(
|
||||
"AntennaPod" to "https://github.com/AntennaPod/AntennaPod",
|
||||
),
|
||||
)
|
||||
|
||||
/** One row per pick, each opening the app's GitHub page; they arrive one after another. */
|
||||
/** One row per kind, with a chip per app opening its GitHub page; the rows arrive one after another. */
|
||||
@Composable
|
||||
private fun AppPicks(c: IntroColors, cq: (Float) -> Dp, cqSp: (Float) -> TextUnit, key: IntroStep) {
|
||||
val context = LocalContext.current
|
||||
Column(Modifier.padding(top = cq(6f)), verticalArrangement = Arrangement.spacedBy(cq(2.6f))) {
|
||||
APP_PICKS.forEachIndexed { i, (kind, name, url) ->
|
||||
Row(
|
||||
APP_PICKS.forEachIndexed { i, (kind, apps) ->
|
||||
Column(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.up(entrance(key, 500 + i * 120, 700), cq(7f))
|
||||
.clip(RoundedCornerShape(cq(5f)))
|
||||
.background(c.secondaryC)
|
||||
.clickable {
|
||||
runCatching {
|
||||
context.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url)).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK))
|
||||
}
|
||||
}
|
||||
.padding(horizontal = cq(5f), vertical = cq(3.4f)),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
.padding(horizontal = cq(4f), vertical = cq(3f)),
|
||||
) {
|
||||
Column(Modifier.weight(1f)) {
|
||||
Text(kind.uppercase(), color = c.onSecondaryC.copy(alpha = 0.7f),
|
||||
style = TextStyle(fontSize = cqSp(3.2f), fontWeight = FontWeight.Bold, letterSpacing = cqSp(0.3f)))
|
||||
Text(name, color = c.onSecondaryC, style = TextStyle(fontSize = cqSp(5.2f), fontWeight = FontWeight.ExtraBold))
|
||||
Text(kind.uppercase(), color = c.onSecondaryC.copy(alpha = 0.7f),
|
||||
style = TextStyle(fontSize = cqSp(3.2f), fontWeight = FontWeight.Bold, letterSpacing = cqSp(0.3f)),
|
||||
modifier = Modifier.padding(start = cq(1f), bottom = cq(1.6f)))
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(cq(2f))) {
|
||||
apps.forEach { (name, url) ->
|
||||
Text(
|
||||
"$name ↗", color = c.onSecondaryC,
|
||||
style = TextStyle(fontSize = cqSp(4.4f), fontWeight = FontWeight.ExtraBold),
|
||||
maxLines = 1,
|
||||
modifier = Modifier
|
||||
.clip(RoundedCornerShape(50))
|
||||
.border(BorderStroke(1.5.dp, c.onSecondaryC.copy(alpha = 0.35f)), RoundedCornerShape(50))
|
||||
.clickable {
|
||||
runCatching {
|
||||
context.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url)).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK))
|
||||
}
|
||||
}
|
||||
.padding(horizontal = cq(3.6f), vertical = cq(2f)),
|
||||
)
|
||||
}
|
||||
}
|
||||
Text("GitHub ↗", color = c.onSecondaryC, style = TextStyle(fontSize = cqSp(3.8f), fontWeight = FontWeight.SemiBold))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,8 +47,8 @@ private class RecommendedApp(val name: String, val packageName: String, val url:
|
||||
|
||||
private val recommended = listOf(
|
||||
"Maps" to listOf(
|
||||
RecommendedApp("Vela Maps", "app.vela", "https://github.com/PimpinPumpkin/Vela", "Turn-by-turn navigation without Google."),
|
||||
RecommendedApp("Organic Maps", "app.organicmaps", "https://github.com/organicmaps/organicmaps", "Offline maps and routing."),
|
||||
RecommendedApp("Vela Maps", "app.vela", "https://github.com/PimpinPumpkin/Vela", "Turn-by-turn navigation without Google."),
|
||||
),
|
||||
"Music" to listOf(
|
||||
RecommendedApp("ViVi Music", "com.vivi.vivimusic", "https://github.com/vivizzz007/vivi-music", "A YouTube Music player."),
|
||||
|
||||
Reference in new issue
Block a user