diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/napplets/ConnectedAppDetailScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/napplets/ConnectedAppDetailScreen.kt index dd450b3d1f..6220d0d5e2 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/napplets/ConnectedAppDetailScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/napplets/ConnectedAppDetailScreen.kt @@ -90,6 +90,7 @@ import com.vitorpamplona.amethyst.ui.navigation.navs.INav import com.vitorpamplona.amethyst.ui.navigation.topbars.TopBarWithBackButton import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.settings.nip46.Nip46ActivityCard +import com.vitorpamplona.amethyst.ui.screen.loggedIn.settings.nip46.nip46ClientSubtitle import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -319,7 +320,7 @@ private fun Nip46AppHeader( Column(modifier = Modifier.weight(1f)) { Text(title, style = MaterialTheme.typography.titleMedium, fontWeight = FontWeight.Bold, maxLines = 1, overflow = TextOverflow.Ellipsis) Text( - url?.ifBlank { null } ?: (clientPubKey.take(16) + "…"), + nip46ClientSubtitle(url, clientPubKey), style = MaterialTheme.typography.bodySmall, fontFamily = FontFamily.Monospace, color = MaterialTheme.colorScheme.onSurfaceVariant, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/nip46/Nip46ConnectedAppsScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/nip46/Nip46ConnectedAppsScreen.kt index 4cbfdc638c..9baf647e02 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/nip46/Nip46ConnectedAppsScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/nip46/Nip46ConnectedAppsScreen.kt @@ -160,7 +160,9 @@ private fun Nip46AppCard( entry: Nip46AppEntry, onClick: () -> Unit, ) { - val npub = remember(entry.clientPubKey) { runCatching { NPub.create(entry.clientPubKey) }.getOrDefault(entry.clientPubKey.take(12) + "…") } + // Same identity line the detail screen (Nip46AppHeader) uses: the app's self-declared website + // when it has one, npub otherwise — so a row and its detail never disagree. + val subtitle = remember(entry.info?.url, entry.clientPubKey) { nip46ClientSubtitle(entry.info?.url, entry.clientPubKey) } val title = entry.info?.name?.ifBlank { null } ?: stringResource(R.string.nip46_signer_remote_app) val relayCount = entry.info?.relays?.size ?: 0 @@ -190,7 +192,7 @@ private fun Nip46AppCard( overflow = TextOverflow.Ellipsis, ) Text( - npub, + subtitle, style = MaterialTheme.typography.labelSmall, color = MaterialTheme.colorScheme.onSurfaceVariant, fontFamily = FontFamily.Monospace, @@ -241,6 +243,25 @@ private fun AppSignerPolicy.shortLabel(): String = AppSignerPolicy.PARANOID -> stringResource(R.string.napplet_policy_paranoid) } +/** + * The identity line shown for a NIP-46 client: its self-declared website (host only) when it + * advertised one, otherwise its npub. Shared by the list card and the detail header so a row and + * the screen it opens always agree. + */ +internal fun nip46ClientSubtitle( + url: String?, + clientPubKey: HexKey, +): String { + val host = + url + ?.ifBlank { null } + ?.removePrefix("https://") + ?.removePrefix("http://") + ?.substringBefore('/') + ?.ifBlank { null } + return host ?: runCatching { NPub.create(clientPubKey) }.getOrDefault(clientPubKey.take(12) + "…") +} + private suspend fun loadNip46Apps(signerPubKey: HexKey): List { val store = Amethyst.instance.signerPermissionStore val clientStore = Amethyst.instance.nip46ClientStore