diff --git a/bitchat/Services/Gateway/BridgeStatusSummary.swift b/bitchat/Services/Gateway/BridgeStatusSummary.swift new file mode 100644 index 00000000..3737fe4c --- /dev/null +++ b/bitchat/Services/Gateway/BridgeStatusSummary.swift @@ -0,0 +1,63 @@ +// +// BridgeStatusSummary.swift +// bitchat +// +// This is free and unencumbered software released into the public domain. +// For more information, see +// + +import Foundation + +/// One-line mesh bridge status for the settings pane. +enum BridgeStatusSummary { + static func formatted( + enabled: Bool, + cell: String?, + bridgedCount: Int, + nearbyOnly: Bool + ) -> String { + if !enabled { + return String( + localized: "app_info.settings.bridge.status.off", + defaultValue: "bridge off — only radio-range mesh traffic", + comment: "Bridge status line when the mesh bridge toggle is off" + ) + } + let cellPart = cell.map { + String( + format: String( + localized: "app_info.settings.bridge.status.cell", + defaultValue: "rendezvous #%@", + comment: "Bridge status fragment showing rendezvous cell; %@ is geohash" + ), + locale: .current, + $0 + ) + } ?? String( + localized: "app_info.settings.bridge.status.no_cell", + defaultValue: "no rendezvous cell", + comment: "Bridge status fragment when no cell is active" + ) + let peoplePart = String( + format: String( + localized: "app_info.settings.bridge.status.people", + defaultValue: "%lld people via bridge", + comment: "Bridge status fragment counting bridged participants; %lld is count" + ), + locale: .current, + bridgedCount + ) + let composePart = nearbyOnly + ? String( + localized: "app_info.settings.bridge.status.compose_nearby", + defaultValue: "compose: nearby only", + comment: "Bridge status fragment when outgoing mesh messages stay on radio" + ) + : String( + localized: "app_info.settings.bridge.status.compose_bridged", + defaultValue: "compose: bridged", + comment: "Bridge status fragment when outgoing mesh messages cross the bridge" + ) + return [cellPart, peoplePart, composePart].joined(separator: " · ") + } +} diff --git a/bitchat/Views/AppInfoView.swift b/bitchat/Views/AppInfoView.swift index cb99fbac..29d1aafe 100644 --- a/bitchat/Views/AppInfoView.swift +++ b/bitchat/Views/AppInfoView.swift @@ -78,6 +78,14 @@ struct AppInfoView: View { ) } static let bridgeNoCell = String(localized: "app_info.settings.bridge.no_cell", defaultValue: "no rendezvous cell yet — needs location access or a nearby bridge peer", comment: "Caption under the mesh bridge toggle when the bridge is on but has no geohash cell to meet on") + static func bridgeStatusSummary(enabled: Bool, cell: String?, bridgedCount: Int, nearbyOnly: Bool) -> String { + BridgeStatusSummary.formatted( + enabled: enabled, + cell: cell, + bridgedCount: bridgedCount, + nearbyOnly: nearbyOnly + ) + } // Moved from LocationChannelsSheet; keys unchanged. (The former // internet-gateway toggle is gone: the bridge switch drives all @@ -440,6 +448,17 @@ struct AppInfoView: View { .bitchatFont(size: 11) .foregroundColor(secondaryTextColor) } + Text( + verbatim: Strings.Settings.bridgeStatusSummary( + enabled: bridgeService.isEnabled, + cell: bridgeService.activeCell, + bridgedCount: bridgeService.bridgedPeerCount, + nearbyOnly: bridgeService.nearbyOnly + ) + ) + .bitchatFont(size: 11) + .foregroundColor(secondaryTextColor) + .fixedSize(horizontal: false, vertical: true) } settingsCard {