Merge branch 'fix/directory-address-and-refusal-copy' into 'main'

Read the contact's address from the directory, and name the refusals

See merge request paulhitt/flamenet-messenger-android!91
This commit was merged in pull request #118.
This commit is contained in:
Paul Hitt
2026-09-07 21:48:30 +00:00
6 changed files with 120 additions and 22 deletions
@@ -1,7 +1,6 @@
package io.flamenet.messenger.app
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
@@ -63,24 +62,24 @@ fun CallScreenBody(
Column(
modifier = Modifier
.fillMaxSize()
.background(MaterialTheme.colorScheme.background)
// ⚠️ The app's ground, not `colorScheme.background`. That token is
// a flat blue, and painting it full-screen here stamped a solid
// rectangle over the gradient every other screen shows — which
// read as "a blue box around the call area". The brush is used
// rather than transparency so this composable still stands on its
// own in the screenshot harness.
.background(groundBrush())
.padding(horizontal = Kit.margin)
.testTag("call-screen"),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Spacer(Modifier.height(Space.xxl))
// ⚠️ No rings. A pair of translucent `primary` circles sat behind the
// avatar as a stand-in for the kit's animation, and against the
// gradient they read as banding — two hard edges around the one thing
// on screen. The avatar carries the centre on its own.
Box(contentAlignment = Alignment.Center) {
Box(
modifier = Modifier
.size(260.dp)
.border(24.dp, MaterialTheme.colorScheme.primary.copy(alpha = 0.10f), CircleShape)
)
Box(
modifier = Modifier
.size(190.dp)
.border(16.dp, MaterialTheme.colorScheme.primary.copy(alpha = 0.18f), CircleShape)
)
Box(
modifier = Modifier.size(128.dp).clip(CircleShape).background(Palette.AvatarFill),
contentAlignment = Alignment.Center,
@@ -5,6 +5,8 @@ import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.viewModelScope
import io.flamenet.client.ChainRpc
import io.flamenet.client.IdentityChangedException
import io.flamenet.client.KeyLogForkException
import io.flamenet.client.KeyNotLoggedException
import io.flamenet.client.DeviceClock
import io.flamenet.client.AccountsClient
import io.flamenet.client.RelayClient
@@ -3901,6 +3903,24 @@ internal fun describeFailure(failure: Throwable): String = when (failure) {
is IdentityChangedException ->
"Their security code changed. Open the conversation to review it " +
"before sending anything else."
// 🔴 **The other two refusals reached the generic network line.**
// Only `IdentityChangedException` was named, and the send path throws
// these just as often — a key the log does not account for is the
// failure a person actually hits after a contact reinstalls. "Something
// went wrong reaching that server" sent them to check their signal for a
// decision this phone made, and the server was answering fine.
is KeyNotLoggedException -> if (failure.hadEntries) {
"This contact's device is offering a key that doesn't match what " +
"the server has on record for it. Open the conversation to " +
"review their security code before sending anything else."
} else {
"This contact's device is offering a key the server never recorded. " +
"Nothing was sent. Check their security code with them directly."
}
is KeyLogForkException ->
"This server's record of published keys doesn't add up, so nothing " +
"was sent. That can mean tampering \u2014 check this contact's " +
"security code with them another way before continuing."
is Vault.Corrupt -> "This phone's stored keys could not be read."
// 🔴 **Anything not named above used to reach the screen verbatim.**