mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-07-25 08:45:19 +00:00
Make peer lists accessible and actionable; block mesh peers by stable identity (#1360)
* Make peer lists accessible and actionable; block by stable identity Who you can reach — the app's most important fact — was encoded in unlabeled 10pt icons with macOS-only tooltips, and the mesh list had no actions (block/favorite/verify were slash-command-only). - Both peer lists become real accessibility citizens: each row is one element announcing name, reachability, and favorite/unread/blocked state, with a button trait and custom actions for the gesture-only interactions. Neither file previously had a single accessibility modifier. Reachability icons gain tooltips reusing existing strings; teleported vs in-area pins are explained. - Mesh rows gain the context menu the geohash list already had: direct message, favorite, show fingerprint, block/unblock. The fingerprint double-tap, previously shadowed by the single tap, is reordered so it fires. - The DM header's offline state (previously EmptyView — absence of a glyph as the only signal) becomes a dimmed "offline" tag, and a geohash DM — always Nostr-routed — no longer mislabels itself "offline". - App Info gains a SYMBOLS legend defining every glyph the lists and headers use; nothing defined them before. - Mesh block/unblock now resolve by the peer's stable Noise identity instead of a `/block <displayName>` string, so the exact tapped row is affected and offline peers can be unblocked (with covering tests). New strings are added source-language (en) only. * Surface block/unblock feedback in the conversation where it was triggered setMeshPeerBlocked silently returned when the peer's identity could not be resolved (e.g. long-press-blocking an old public message from a sender who left and was never a favorite), where the /block command printed "cannot block X: not found or unable to verify identity" — post that same message from the guard branch. Both the failure and confirmation messages now route through addCommandOutput instead of addSystemMessage, so blocking from inside a private chat prints into that chat rather than invisibly into the public timeline (same routing #1363 applied to command output). The confirmation also reuses the /block wording ("blocked X. you will no longer receive messages from them") for parity with the command. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Remove dead accessibility label and unreachable /unblock fallback The favorite button's .accessibilityLabel in MeshPeerList is unreachable: the row-level .accessibilityElement(children: .ignore) swallows child elements, and the row's custom accessibility action already covers favoriting. ConversationUIModel.unblock is only called from the mesh peer list with a non-optional mesh peerID, so the "/unblock <name>" fallback branch could never run — take PeerID directly and drop the branch. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: jack <212554440+jackjackbits@users.noreply.github.com> Co-authored-by: jack <jackjackbits@users.noreply.github.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
jack
jack
Claude Fable 5
parent
7a0c821807
commit
c74e212ea3
@@ -5015,6 +5015,162 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"app_info.legend.blocked" : {
|
||||
"comment" : "Legend entry for the nosign glyph",
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "blocked"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"app_info.legend.encrypted" : {
|
||||
"comment" : "Legend entry for the lock glyph",
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "end-to-end encrypted session"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"app_info.legend.encryption_failed" : {
|
||||
"comment" : "Legend entry for the failed-encryption lock-slash glyph",
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "encryption failed — messages not secured"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"app_info.legend.favorite" : {
|
||||
"comment" : "Legend entry for the star glyph",
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "favorite — enables offline messages via nostr when mutual"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"app_info.legend.location_nearby" : {
|
||||
"comment" : "Legend entry for the map pin glyph",
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "physically in this location channel's area"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"app_info.legend.mesh_connected" : {
|
||||
"comment" : "Legend entry for the antenna glyph",
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "connected directly over bluetooth"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"app_info.legend.mesh_relayed" : {
|
||||
"comment" : "Legend entry for the relayed-mesh glyph",
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "reachable through the mesh, relayed by others"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"app_info.legend.nostr" : {
|
||||
"comment" : "Legend entry for the globe glyph",
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "reachable over the internet (nostr) — mutual favorites only"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"app_info.legend.offline" : {
|
||||
"comment" : "Legend entry for the offline person glyph",
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "offline — not currently reachable"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"app_info.legend.teleported" : {
|
||||
"comment" : "Legend entry for the teleported glyph",
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "teleported — joined the channel from somewhere else"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"app_info.legend.title" : {
|
||||
"comment" : "Section header for the symbols legend in app info",
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "symbols"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"app_info.legend.unread" : {
|
||||
"comment" : "Legend entry for the envelope glyph",
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "unread private messages"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"app_info.legend.verified" : {
|
||||
"comment" : "Legend entry for the verified seal glyph",
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "identity verified"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"app_info.privacy.ephemeral.description" : {
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
@@ -23742,6 +23898,42 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"geohash_people.state.nearby" : {
|
||||
"comment" : "State label for someone physically in the location channel's area",
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "in this area"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"geohash_people.state.teleported" : {
|
||||
"comment" : "State label for someone who joined the location channel from elsewhere",
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "teleported from elsewhere"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"geohash_people.state.you" : {
|
||||
"comment" : "State label marking your own row in the people list",
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "you"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"geohash_people.tooltip.blocked" : {
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
@@ -31492,6 +31684,78 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"mesh_peers.accessibility.open_dm_hint" : {
|
||||
"comment" : "Accessibility hint on a peer row explaining activation opens a private chat",
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "opens a private chat"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"mesh_peers.action.fingerprint" : {
|
||||
"comment" : "Context menu action that shows a peer's fingerprint/verification screen",
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "show fingerprint"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"mesh_peers.state.blocked" : {
|
||||
"comment" : "State label for a blocked peer",
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "blocked"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"mesh_peers.state.favorite" : {
|
||||
"comment" : "State label for a favorited peer",
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "favorite"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"mesh_peers.state.offline" : {
|
||||
"comment" : "State label for a peer that is not currently reachable",
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "offline"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"mesh_peers.state.unread" : {
|
||||
"comment" : "State label for a peer with unread private messages",
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "new messages"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"mesh_peers.tooltip.new_messages" : {
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
@@ -33819,6 +34083,54 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"system.mesh.block_failed" : {
|
||||
"comment" : "System message shown when a mesh peer cannot be blocked",
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "cannot block %@: not found or unable to verify identity"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"system.mesh.blocked" : {
|
||||
"comment" : "System message shown when a mesh peer is blocked",
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "blocked %@. you will no longer receive messages from them"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"system.mesh.unblock_failed" : {
|
||||
"comment" : "System message shown when a mesh peer cannot be unblocked",
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "cannot unblock %@: not found"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"system.mesh.unblocked" : {
|
||||
"comment" : "System message shown when a mesh peer is unblocked",
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "unblocked %@"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"system.tor.dev_bypass" : {
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
|
||||
Reference in New Issue
Block a user