Review follow-ups: globe deep-link, fil translation, pane-routing test

Three items from review feedback on the gear PR:

- The gateway globe's accessibility hint promises "opens settings", but
  its action presented the sheet on the sticky pane. It now passes
  .settings like the gear.
- fil had English "settings" marked translated (Chessing234's catch);
  now "mga setting", matching the catalog's own fil precedent in
  content.accessibility.gateway_settings_hint. Also applied to
  app_info.tab.settings — the label of the very tab both controls
  deep-link to — so fil users don't hear "mga setting" and land on a
  tab labeled "settings". (content.alert.bluetooth_required.settings
  names the iOS Settings app and is left for a separate pass.)
- A regression test pins the routing contract: a promised pane
  overwrites the sticky appInfo.selectedPane default, a plain present
  never touches it, and first-open leaves the key absent so new users
  still land on Info.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Rod Bahmanyari 2026-08-25 17:54:09 -07:00
parent 9c01cd4fa1
commit 9f2dcedb1a
3 changed files with 46 additions and 3 deletions

View File

@ -32410,7 +32410,7 @@
"fil" : {
"stringUnit" : {
"state" : "translated",
"value" : "settings"
"value" : "mga setting"
}
},
"fr" : {
@ -56149,7 +56149,7 @@
"en" : { "stringUnit" : { "state" : "translated", "value" : "settings" } },
"es" : { "stringUnit" : { "state" : "translated", "value" : "ajustes" } },
"fa" : { "stringUnit" : { "state" : "translated", "value" : "تنظیمات" } },
"fil" : { "stringUnit" : { "state" : "translated", "value" : "settings" } },
"fil" : { "stringUnit" : { "state" : "translated", "value" : "mga setting" } },
"fr" : { "stringUnit" : { "state" : "translated", "value" : "réglages" } },
"he" : { "stringUnit" : { "state" : "translated", "value" : "הגדרות" } },
"hi" : { "stringUnit" : { "state" : "translated", "value" : "सेटिंग्स" } },

View File

@ -129,7 +129,7 @@ struct ContentHeaderView: View {
if locationChannelsModel.gatewayEnabled {
// The gateway toggle lives in the App Info settings pane
// now, so the indicator deep-links there.
Button(action: { appChromeModel.presentAppInfo() }) {
Button(action: { appChromeModel.presentAppInfo(pane: .settings) }) {
Image(systemName: "globe")
.font(.bitchatSystem(size: 12))
.foregroundColor(palette.secondary.opacity(0.8))

View File

@ -462,6 +462,49 @@ struct AppArchitectureTests {
#expect(chromeModel.showingFingerprintFor == nil)
}
@Test("App Info pane routing: a promised pane overrides the sticky memory, a plain present never touches it")
@MainActor
func presentAppInfoPaneRouting() {
let viewModel = makeArchitectureViewModel()
let privateInboxModel = PrivateInboxModel(conversations: ConversationStore())
let chromeModel = AppChromeModel(chatViewModel: viewModel, privateInboxModel: privateInboxModel)
// The sticky pane lives in standard defaults (@AppStorage's store);
// restore whatever was there so this test can't leak state.
let key = "appInfo.selectedPane"
let defaults = UserDefaults.standard
let original = defaults.string(forKey: key)
defer {
if let original {
defaults.set(original, forKey: key)
} else {
defaults.removeObject(forKey: key)
}
}
// First-ever open: the logo tap passes no pane, and the absent key is
// what lands new users on the gentler Info default — a plain present
// must not create it.
defaults.removeObject(forKey: key)
chromeModel.presentAppInfo()
#expect(defaults.string(forKey: key) == nil)
#expect(chromeModel.isAppInfoPresented)
// Later opens: the logo tap keeps whatever pane the sheet was left on.
chromeModel.isAppInfoPresented = false
defaults.set(AppInfoView.Pane.info.rawValue, forKey: key)
chromeModel.presentAppInfo()
#expect(defaults.string(forKey: key) == AppInfoView.Pane.info.rawValue)
#expect(chromeModel.isAppInfoPresented)
// Controls that promise a pane (the header gear and the gateway globe
// both say "settings") must land there even against sticky memory.
chromeModel.isAppInfoPresented = false
chromeModel.presentAppInfo(pane: .settings)
#expect(defaults.string(forKey: key) == AppInfoView.Pane.settings.rawValue)
#expect(chromeModel.isAppInfoPresented)
}
@Test("Triple-tap panic entry point only raises the confirmation dialog")
@MainActor
func requestPanicWipeAsksBeforeDestroying() {