diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/drawer/DrawerContent.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/drawer/DrawerContent.kt
index 8290085a1f..ff06f6daa0 100644
--- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/drawer/DrawerContent.kt
+++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/drawer/DrawerContent.kt
@@ -125,6 +125,8 @@ import com.vitorpamplona.amethyst.commons.resources.route_chess
import com.vitorpamplona.amethyst.commons.resources.share_hls_video
import com.vitorpamplona.amethyst.commons.resources.show_npub_as_a_qr_code
import com.vitorpamplona.amethyst.commons.resources.status_update
+import com.vitorpamplona.amethyst.commons.resources.tor_splash_connecting
+import com.vitorpamplona.amethyst.commons.resources.tor_status_connected
import com.vitorpamplona.amethyst.commons.scheduledposts.ScheduledPostStatus
import com.vitorpamplona.amethyst.commons.ui.components.RobohashFallbackAsyncImage
import com.vitorpamplona.amethyst.commons.ui.layouts.PermanentDrawerWidth
@@ -164,6 +166,7 @@ import com.vitorpamplona.amethyst.commons.viewmodels.AccountViewModel
import com.vitorpamplona.amethyst.commons.viewmodels.mockAccountViewModel
import com.vitorpamplona.amethyst.isDebug
import com.vitorpamplona.amethyst.ui.painterRes
+import com.vitorpamplona.amethyst.ui.tor.TorServiceStatus
import com.vitorpamplona.quartz.nip01Core.core.Address
import com.vitorpamplona.quartz.nip01Core.core.HexKey
import kotlinx.coroutines.flow.Flow
@@ -1074,8 +1077,11 @@ fun BottomContent(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Absolute.SpaceBetween,
) {
- // Grouping version text and Tor status icon together on the left side
- Row(verticalAlignment = Alignment.CenterVertically) {
+ // The version (release notes link) and, while Tor is in use, its status beside it.
+ Row(
+ modifier = Modifier.weight(1f, fill = false),
+ verticalAlignment = Alignment.CenterVertically,
+ ) {
val string =
remember {
buildAnnotatedString {
@@ -1098,31 +1104,13 @@ fun BottomContent(
Text(
text = string,
- modifier = Modifier.padding(start = 16.dp, end = 8.dp),
+ // Yields to the Tor icon on a narrow drawer instead of pushing it off.
+ modifier = Modifier.weight(1f, fill = false).padding(start = 16.dp),
overflow = TextOverflow.Ellipsis,
maxLines = 1,
)
- val torStatus by Amethyst.instance.torManager.status
- .collectAsStateWithLifecycle()
-
- // Tip uyuşmazlığı hatalarını aşmak için değeri güvenli bir şekilde String'e çeviriyoruz
- val statusString = torStatus.toString()
- val torColor =
- if (statusString.contains("Active", ignoreCase = true) || statusString.contains("Connected", ignoreCase = true)) {
- MaterialTheme.colorScheme.primary // Bağlıysa ana tema rengi (Yeşil/Mor vb.)
- } else if (statusString.contains("Connecting", ignoreCase = true) || statusString.contains("Bootstrapping", ignoreCase = true)) {
- MaterialTheme.colorScheme.secondary // Bağlanıyorsa ara renk
- } else {
- MaterialTheme.colorScheme.error // Kapalı/Hata durumunda hata rengi (Kırmızı)
- }
-
- Icon(
- painter = painterRes(Res.drawable.ic_tor, 2),
- contentDescription = "Tor Status",
- modifier = Size20Modifier,
- tint = torColor,
- )
+ TorStatusIcon(nav)
}
IconButton(
@@ -1142,6 +1130,34 @@ fun BottomContent(
}
}
+/**
+ * Tor's state next to the app version, opening the Tor settings on tap. Hidden while Tor is off: that
+ * is a choice, not a fault, so it gets no icon at all rather than an alarming one. Connected only once
+ * the directory is ready ([TorServiceStatus.isFullyBootstrapped]); a bound proxy still downloading it
+ * cannot carry traffic yet, so it reads as connecting.
+ */
+@Composable
+private fun TorStatusIcon(nav: INav) {
+ val torStatus by Amethyst.instance.torManager.status
+ .collectAsStateWithLifecycle()
+ if (torStatus is TorServiceStatus.Off) return
+
+ val connected = torStatus.isFullyBootstrapped
+ IconButton(
+ onClick = {
+ nav.nav(Route.PrivacyOptions)
+ nav.closeDrawer()
+ },
+ ) {
+ Icon(
+ painter = painterRes(Res.drawable.ic_tor, 2),
+ contentDescription = stringRes(if (connected) Res.string.tor_status_connected else Res.string.tor_splash_connecting),
+ modifier = Size20Modifier,
+ tint = if (connected) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant,
+ )
+ }
+}
+
@Preview
@Composable
private fun CollapsibleSectionPreview() {
diff --git a/commonsUI/src/commonMain/composeResources/values/strings.xml b/commonsUI/src/commonMain/composeResources/values/strings.xml
index 868b66caca..379858b712 100644
--- a/commonsUI/src/commonMain/composeResources/values/strings.xml
+++ b/commonsUI/src/commonMain/composeResources/values/strings.xml
@@ -1917,6 +1917,7 @@
Use regular connection
Keep waiting
Connecting to Tor…
+ Connected to Tor
Tor error: %1$s
Amethyst uses Tor to hide your IP address from relays. Starting Tor can take a minute and needs internet access.
Tap a category to open Android notification settings for it — sound, importance, badges and Do Not Disturb live there.