mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-08-29 07:27:16 +00:00
fix: move public trust caption to a localized caption band (#1064)
Ask 6 — SE-width header overflow: the mesh trust caption lived as a `.fixedSize(horizontal: true)` `Text` inside the header's trailing `.layoutPriority(3)` (non-compressible) cluster, so on a narrow (SE-width) header it forced the row to overflow. Relocated it out of the header into a persistent full-width caption band under the public timeline — the parity twin of the DM sheet's `privacyCaption` band (#1366): same structure (full width, `.themedSurface()`, centered, combined a11y), rendered above the composer in both the glass and matrix layouts, mesh-only (geohash/location channels carry no such caption). It is muted (`palette.secondary`), not orange, because orange is the DM privacy signal and this surface is deliberately public. `ContentView` gains `locationChannelsModel` (already injected on its environment in `BitchatApp`) to gate the mesh condition. Ask 7 — untranslatable hardcoded vocabulary: the caption and its accessibility label were `Text(verbatim:)` literals ("public · unencrypted" / "public, unencrypted") that bypassed `Localizable.xcstrings`. Replaced with two new localized keys — `content.header.public_caption` ("public · nearby", visible, `·` separator matching the DM caption band's "private · end-to-end encrypted") and `content.header.public_caption.a11y` ("public, nearby", VoiceOver, comma form). Both reuse the established public-surface vocabulary from #1357's `content.input.placeholder.mesh` ("… public, nearby") rather than coining a new "unencrypted" string. Only the `en` source value is seeded; other locales are left for translators, matching the existing DM-caption keys. NOT locally compiled (Swift/iOS; CI runs Build iOS + Swift Tests). Visual placement/spacing of the new band is unverified — needs an SE-width eyeball. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
e3acdfb599
commit
87f1561f34
@ -18051,6 +18051,30 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"content.header.public_caption" : {
|
||||
"comment" : "Trust caption under the public mesh timeline: this channel is public and reaches nearby devices. Reuses the composer placeholder vocabulary (content.input.placeholder.mesh).",
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "public · nearby"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"content.header.public_caption.a11y" : {
|
||||
"comment" : "Accessibility label for the public mesh trust caption; comma form of content.header.public_caption for VoiceOver.",
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "public, nearby"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"content.help.verification" : {
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
|
||||
@ -186,15 +186,6 @@ struct ContentHeaderView: View {
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
|
||||
if case .mesh = locationChannelsModel.selectedChannel {
|
||||
Text(verbatim: "public · unencrypted")
|
||||
.bitchatFont(size: 10)
|
||||
.foregroundColor(palette.secondary)
|
||||
.lineLimit(1)
|
||||
.fixedSize(horizontal: true, vertical: false)
|
||||
.accessibilityLabel(Text(verbatim: "public, unencrypted"))
|
||||
}
|
||||
|
||||
Button(action: {
|
||||
withAnimation(.easeInOut(duration: TransportConfig.uiAnimationMediumSeconds)) {
|
||||
showSidebar.toggle()
|
||||
|
||||
@ -35,6 +35,7 @@ struct ContentView: View {
|
||||
@EnvironmentObject private var privateConversationModel: PrivateConversationModel
|
||||
@EnvironmentObject private var verificationModel: VerificationModel
|
||||
@EnvironmentObject private var conversationUIModel: ConversationUIModel
|
||||
@EnvironmentObject private var locationChannelsModel: LocationChannelsModel
|
||||
|
||||
@StateObject private var voiceRecordingVM = VoiceRecordingViewModel()
|
||||
@State private var messageText = ""
|
||||
@ -239,7 +240,10 @@ struct ContentView: View {
|
||||
}
|
||||
.safeAreaInset(edge: .bottom, spacing: 0) {
|
||||
if selectedPrivatePeerID == nil {
|
||||
composerView
|
||||
VStack(spacing: 0) {
|
||||
meshPrivacyCaption
|
||||
composerView
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -260,12 +264,32 @@ struct ContentView: View {
|
||||
Divider()
|
||||
|
||||
if selectedPrivatePeerID == nil {
|
||||
meshPrivacyCaption
|
||||
composerView
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Persistent trust caption under the PUBLIC mesh timeline — the parity
|
||||
/// twin of the DM sheet's `privacyCaption` (#1366). Moved here out of the
|
||||
/// header's non-compressible trailing cluster, where its `.fixedSize` text
|
||||
/// overflowed narrow (SE-width) headers. Mesh-only: geohash/location
|
||||
/// channels carry no such caption. Muted rather than orange — orange is the
|
||||
/// DM privacy signal; this surface is deliberately public.
|
||||
@ViewBuilder
|
||||
private var meshPrivacyCaption: some View {
|
||||
if case .mesh = locationChannelsModel.selectedChannel {
|
||||
Text("content.header.public_caption")
|
||||
.bitchatFont(size: 11, weight: .medium)
|
||||
.foregroundColor(palette.secondary)
|
||||
.frame(maxWidth: .infinity)
|
||||
.padding(.vertical, 4)
|
||||
.themedSurface()
|
||||
.accessibilityLabel(Text("content.header.public_caption.a11y"))
|
||||
}
|
||||
}
|
||||
|
||||
private var headerView: some View {
|
||||
ContentHeaderView(
|
||||
showSidebar: $appChromeModel.showSidebar,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user