feat(desktop): add Amethyst logo to Tor and account-loading splashes

Both loading splashes (the Tor-connect gate and the account-loading
screen between Tor active and LoginScreen) now show the Amethyst
icon tinted to the theme primary, anchored below the status text.

Layout pattern (status-forward, both splashes):
  spinner → status text → Amethyst logo (96.dp, primary tint)

Brief research summary backing the choice:
- Apple HIG argues against splash branding, but its model assumes
  near-instant launch — not applicable here where the Tor gate
  can block for seconds.
- Material Design 2's branded-launch-screen pattern endorses
  logo + brand color while a placeholder UI loads.
- The status-forward order keeps the dynamic info (what we're
  waiting on) leading and the brand as the anchor below — the
  right call when the wait is non-trivial.
This commit is contained in:
nrobi144
2026-06-03 07:31:49 +03:00
parent 38a191341f
commit 44febcc77f
@@ -713,6 +713,15 @@ fun App(
val torStatus by torManager.status.collectAsState()
val isTorExpected = torSettings.torType != com.vitorpamplona.amethyst.commons.tor.TorType.OFF
if (isTorExpected && torStatus !is com.vitorpamplona.amethyst.commons.tor.TorServiceStatus.Active) {
val splashIcon =
remember {
val bytes = Unit::class.java.getResourceAsStream("/icon.png")!!.readBytes()
val bitmap =
org.jetbrains.skia.Image
.makeFromEncoded(bytes)
.toComposeImageBitmap()
BitmapPainter(bitmap)
}
androidx.compose.foundation.layout.Box(
modifier =
androidx.compose.ui.Modifier
@@ -735,6 +744,19 @@ fun App(
} else {
androidx.compose.material3.Text("Connecting to Tor...")
}
androidx.compose.foundation.layout.Spacer(
modifier =
androidx.compose.ui.Modifier
.height(24.dp),
)
androidx.compose.material3.Icon(
painter = splashIcon,
contentDescription = "Amethyst",
modifier =
androidx.compose.ui.Modifier
.size(96.dp),
tint = androidx.compose.material3.MaterialTheme.colorScheme.primary,
)
}
}
return // Nothing below runs until Tor is Active
@@ -962,6 +984,15 @@ fun App(
when (accountState) {
is AccountState.Loading -> {
// Branded loading screen while accounts load from storage
val loadingIcon =
remember {
val bytes = Unit::class.java.getResourceAsStream("/icon.png")!!.readBytes()
val bitmap =
org.jetbrains.skia.Image
.makeFromEncoded(bytes)
.toComposeImageBitmap()
BitmapPainter(bitmap)
}
Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center,
@@ -978,6 +1009,13 @@ fun App(
style = MaterialTheme.typography.headlineMedium,
color = MaterialTheme.colorScheme.onBackground,
)
Spacer(Modifier.height(24.dp))
androidx.compose.material3.Icon(
painter = loadingIcon,
contentDescription = "Amethyst",
modifier = Modifier.size(96.dp),
tint = MaterialTheme.colorScheme.primary,
)
}
}
}