Merge 108818d6eb728590273785e353fff7c792bd663f into 9b84b361225facd8e623f25d76f889d3dc54a879

This commit is contained in:
Taksh Kothari 2026-08-11 09:05:57 +02:00 committed by GitHub
commit a9da00a076
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 1226 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,63 @@
//
// BridgeStatusSummary.swift
// bitchat
//
// This is free and unencumbered software released into the public domain.
// For more information, see <https://unlicense.org>
//
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: " · ")
}
}

View File

@ -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 {

View File

@ -0,0 +1,28 @@
//
// BridgeStatusSummaryTests.swift
// bitchatTests
//
// This is free and unencumbered software released into the public domain.
// For more information, see <https://unlicense.org>
//
import Testing
@testable import bitchat
struct BridgeStatusSummaryTests {
@Test func offStateDoesNotMentionBridgePeople() {
let text = BridgeStatusSummary.formatted(enabled: false, cell: "u4pruy", bridgedCount: 3, nearbyOnly: false)
#expect(text.lowercased().contains("bridge off"))
}
@Test func enabledStateIncludesCellAndCount() {
let text = BridgeStatusSummary.formatted(enabled: true, cell: "u4pruy", bridgedCount: 2, nearbyOnly: true)
#expect(text.contains("u4pruy"))
#expect(text.contains("nearby"))
}
@Test func enabledWithZeroPeersMentionsBridgeCell() {
let text = BridgeStatusSummary.formatted(enabled: true, cell: "u4pruy", bridgedCount: 0, nearbyOnly: false)
#expect(text.localizedCaseInsensitiveContains("u4pruy") || text.localizedCaseInsensitiveContains("bridge"))
}
}