mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-08-29 07:27:16 +00:00
fix: localize mute strings and reset empty gate for muted-only mesh
Add catalog entries for the three mute UI strings, exclude suppressed peers from the notification reset-path count, treat muted-only meshes as empty so a later stranger still alerts, and cover that path in tests.
This commit is contained in:
parent
9e6f8121fb
commit
e54f760ada
@ -62336,6 +62336,378 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"mesh_peers.action.mute_nearby" : {
|
||||
"comment" : "Context menu action to stop nearby notifications for this peer",
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
"ar" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "كتم تنبيهات القرب"
|
||||
}
|
||||
},
|
||||
"bn" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "কাছাকাছি সতর্কতা নিঃশব্দ"
|
||||
}
|
||||
},
|
||||
"de" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "nahe benachrichtigungen stummschalten"
|
||||
}
|
||||
},
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Mute nearby alerts"
|
||||
}
|
||||
},
|
||||
"es" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "silenciar alertas cercanas"
|
||||
}
|
||||
},
|
||||
"fa" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "بیصدا کردن هشدارهای نزدیک"
|
||||
}
|
||||
},
|
||||
"fil" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "i-mute ang nearby alerts"
|
||||
}
|
||||
},
|
||||
"fr" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "couper les alertes de proximité"
|
||||
}
|
||||
},
|
||||
"he" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "השתק התראות קרובות"
|
||||
}
|
||||
},
|
||||
"hi" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "नज़दीकी अलर्ट म्यूट करें"
|
||||
}
|
||||
},
|
||||
"id" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "bisukan peringatan terdekat"
|
||||
}
|
||||
},
|
||||
"it" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "silenzia avvisi vicini"
|
||||
}
|
||||
},
|
||||
"ja" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "近くの通知をミュート"
|
||||
}
|
||||
},
|
||||
"ko" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "근처 알림 음소거"
|
||||
}
|
||||
},
|
||||
"ms" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "redam amaran berdekatan"
|
||||
}
|
||||
},
|
||||
"ne" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "नजिकका अलर्ट म्यूट गर्नुहोस्"
|
||||
}
|
||||
},
|
||||
"nl" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "nabije meldingen dempen"
|
||||
}
|
||||
},
|
||||
"pl" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "wycisz alerty w pobliżu"
|
||||
}
|
||||
},
|
||||
"pt" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "silenciar alertas próximos"
|
||||
}
|
||||
},
|
||||
"pt-BR" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "silenciar alertas próximos"
|
||||
}
|
||||
},
|
||||
"ru" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "отключить уведомления о рядом"
|
||||
}
|
||||
},
|
||||
"sv" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "tysta närhetsaviseringar"
|
||||
}
|
||||
},
|
||||
"ta" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "அருகிலுள்ள எச்சரிக்கைகளை முடக்கு"
|
||||
}
|
||||
},
|
||||
"th" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "ปิดเสียงการแจ้งเตือนใกล้เคียง"
|
||||
}
|
||||
},
|
||||
"tr" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "yakındaki uyarıları sessize al"
|
||||
}
|
||||
},
|
||||
"uk" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "вимкнути сповіщення про близькість"
|
||||
}
|
||||
},
|
||||
"ur" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "قریبی الرٹس خاموش کریں"
|
||||
}
|
||||
},
|
||||
"vi" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "tắt cảnh báo gần"
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "静音附近提醒"
|
||||
}
|
||||
},
|
||||
"zh-Hant" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "靜音附近提醒"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"mesh_peers.action.unmute_nearby" : {
|
||||
"comment" : "Context menu action to resume nearby notifications for this peer",
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
"ar" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "إلغاء كتم تنبيهات القرب"
|
||||
}
|
||||
},
|
||||
"bn" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "কাছাকাছি সতর্কতা আনমিউট"
|
||||
}
|
||||
},
|
||||
"de" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "nahe benachrichtigungen wieder an"
|
||||
}
|
||||
},
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Unmute nearby alerts"
|
||||
}
|
||||
},
|
||||
"es" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "reactivar alertas cercanas"
|
||||
}
|
||||
},
|
||||
"fa" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "صدادار کردن هشدارهای نزدیک"
|
||||
}
|
||||
},
|
||||
"fil" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "i-unmute ang nearby alerts"
|
||||
}
|
||||
},
|
||||
"fr" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "rétablir les alertes de proximité"
|
||||
}
|
||||
},
|
||||
"he" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "בטל השתקת התראות קרובות"
|
||||
}
|
||||
},
|
||||
"hi" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "नज़दीकी अलर्ट अनम्यूट करें"
|
||||
}
|
||||
},
|
||||
"id" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "bunyikan lagi peringatan terdekat"
|
||||
}
|
||||
},
|
||||
"it" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "riattiva avvisi vicini"
|
||||
}
|
||||
},
|
||||
"ja" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "近くの通知のミュート解除"
|
||||
}
|
||||
},
|
||||
"ko" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "근처 알림 음소거 해제"
|
||||
}
|
||||
},
|
||||
"ms" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "nyahredam amaran berdekatan"
|
||||
}
|
||||
},
|
||||
"ne" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "नजिकका अलर्ट अनम्यूट गर्नुहोस्"
|
||||
}
|
||||
},
|
||||
"nl" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "nabije meldingen dempen opheffen"
|
||||
}
|
||||
},
|
||||
"pl" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "przywróć alerty w pobliżu"
|
||||
}
|
||||
},
|
||||
"pt" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "reativar alertas próximos"
|
||||
}
|
||||
},
|
||||
"pt-BR" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "reativar alertas próximos"
|
||||
}
|
||||
},
|
||||
"ru" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "включить уведомления о рядом"
|
||||
}
|
||||
},
|
||||
"sv" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "slå på närhetsaviseringar"
|
||||
}
|
||||
},
|
||||
"ta" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "அருகிலுள்ள எச்சரிக்கைகளை இயக்கு"
|
||||
}
|
||||
},
|
||||
"th" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "เปิดเสียงการแจ้งเตือนใกล้เคียง"
|
||||
}
|
||||
},
|
||||
"tr" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "yakındaki uyarıların sesini aç"
|
||||
}
|
||||
},
|
||||
"uk" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "увімкнути сповіщення про близькість"
|
||||
}
|
||||
},
|
||||
"ur" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "قریبی الرٹس بحال کریں"
|
||||
}
|
||||
},
|
||||
"vi" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "bật lại cảnh báo gần"
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "取消静音附近提醒"
|
||||
}
|
||||
},
|
||||
"zh-Hant" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "取消靜音附近提醒"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"mesh_peers.state.blocked" : {
|
||||
"comment" : "State label for a blocked peer",
|
||||
"extractionState" : "manual",
|
||||
@ -62708,6 +63080,192 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"mesh_peers.state.nearby_muted" : {
|
||||
"comment" : "State label for a peer muted for proximity notifications",
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
"ar" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "تنبيهات القرب مكتومة"
|
||||
}
|
||||
},
|
||||
"bn" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "কাছাকাছি সতর্কতা নিঃশব্দ"
|
||||
}
|
||||
},
|
||||
"de" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "nahe benachrichtigungen stumm"
|
||||
}
|
||||
},
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "nearby alerts muted"
|
||||
}
|
||||
},
|
||||
"es" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "alertas cercanas silenciadas"
|
||||
}
|
||||
},
|
||||
"fa" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "هشدارهای نزدیک بیصدا"
|
||||
}
|
||||
},
|
||||
"fil" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "naka-mute ang nearby alerts"
|
||||
}
|
||||
},
|
||||
"fr" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "alertes de proximité coupées"
|
||||
}
|
||||
},
|
||||
"he" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "התראות קרובות מושתקות"
|
||||
}
|
||||
},
|
||||
"hi" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "नज़दीकी अलर्ट म्यूट"
|
||||
}
|
||||
},
|
||||
"id" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "peringatan terdekat dibisukan"
|
||||
}
|
||||
},
|
||||
"it" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "avvisi vicini silenziati"
|
||||
}
|
||||
},
|
||||
"ja" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "近くの通知をミュート中"
|
||||
}
|
||||
},
|
||||
"ko" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "근처 알림 음소거됨"
|
||||
}
|
||||
},
|
||||
"ms" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "amaran berdekatan diredam"
|
||||
}
|
||||
},
|
||||
"ne" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "नजिकका अलर्ट म्यूट"
|
||||
}
|
||||
},
|
||||
"nl" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "nabije meldingen gedempt"
|
||||
}
|
||||
},
|
||||
"pl" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "alerty w pobliżu wyciszone"
|
||||
}
|
||||
},
|
||||
"pt" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "alertas próximos silenciados"
|
||||
}
|
||||
},
|
||||
"pt-BR" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "alertas próximos silenciados"
|
||||
}
|
||||
},
|
||||
"ru" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "уведомления о рядом отключены"
|
||||
}
|
||||
},
|
||||
"sv" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "närhetsaviseringar tystade"
|
||||
}
|
||||
},
|
||||
"ta" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "அருகிலுள்ள எச்சரிக்கைகள் முடக்கப்பட்டன"
|
||||
}
|
||||
},
|
||||
"th" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "ปิดเสียงการแจ้งเตือนใกล้เคียงแล้ว"
|
||||
}
|
||||
},
|
||||
"tr" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "yakındaki uyarılar sessiz"
|
||||
}
|
||||
},
|
||||
"uk" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "сповіщення про близькість вимкнено"
|
||||
}
|
||||
},
|
||||
"ur" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "قریبی الرٹس خاموش"
|
||||
}
|
||||
},
|
||||
"vi" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "đã tắt cảnh báo gần"
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "已静音附近提醒"
|
||||
}
|
||||
},
|
||||
"zh-Hant" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "已靜音附近提醒"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"mesh_peers.state.offline" : {
|
||||
"comment" : "State label for a peer that is not currently reachable",
|
||||
"extractionState" : "manual",
|
||||
|
||||
@ -57,10 +57,13 @@ extension ChatViewModel: ChatPeerListContext {
|
||||
// call.
|
||||
|
||||
func activeMeshPeerCount() -> Int {
|
||||
// Exclude blocked / proximity-muted peers so a muted-only mesh
|
||||
// still counts as empty for the notification reset timers.
|
||||
meshService
|
||||
.currentPeerSnapshots()
|
||||
.filter { snapshot in
|
||||
snapshot.isConnected || meshService.isPeerReachable(snapshot.peerID)
|
||||
(snapshot.isConnected || meshService.isPeerReachable(snapshot.peerID))
|
||||
&& !suppressesNearbyNotification(for: snapshot.peerID)
|
||||
}
|
||||
.count
|
||||
}
|
||||
@ -115,7 +118,7 @@ final class ChatPeerListCoordinator: @unchecked Sendable {
|
||||
}
|
||||
}
|
||||
|
||||
private extension ChatPeerListCoordinator {
|
||||
extension ChatPeerListCoordinator {
|
||||
@MainActor
|
||||
func handlePeerListUpdate(_ peers: [PeerID]) {
|
||||
context.isConnected = !peers.isEmpty
|
||||
@ -147,14 +150,19 @@ private extension ChatPeerListCoordinator {
|
||||
return
|
||||
}
|
||||
|
||||
invalidateNetworkEmptyTimer()
|
||||
context.recordMeshSightings(peerIDs: meshPeers)
|
||||
|
||||
// Only peers that aren't blocked / proximity-muted count toward the
|
||||
// empty→populated notification. Muted-only meshes stay "empty" for
|
||||
// that gate so a stranger joining later still alerts.
|
||||
// empty→populated notification and the reset-path emptiness check.
|
||||
// A muted-only mesh stays "empty" so a stranger joining later still
|
||||
// alerts, and so meshWasEmpty can reset after the first alert.
|
||||
let countablePeers = meshPeers.filter { !context.suppressesNearbyNotification(for: $0) }
|
||||
guard !countablePeers.isEmpty else { return }
|
||||
if countablePeers.isEmpty {
|
||||
scheduleNetworkEmptyTimer()
|
||||
return
|
||||
}
|
||||
|
||||
invalidateNetworkEmptyTimer()
|
||||
|
||||
let countableSet = Set(countablePeers)
|
||||
let newPeers = countableSet.subtracting(recentlySeenPeers)
|
||||
|
||||
@ -1317,7 +1317,15 @@ final class ChatViewModel: ObservableObject, BitchatDelegate, SynchronousMessage
|
||||
|
||||
@MainActor
|
||||
func setNearbyNotificationMuted(for peerID: PeerID, muted: Bool) {
|
||||
guard let fingerprint = getFingerprint(for: peerID) else { return }
|
||||
guard let fingerprint = getFingerprint(for: peerID) else {
|
||||
// Pre-handshake peers have no Noise fingerprint yet — the mute
|
||||
// key is fingerprint-stable, so there is nothing to persist.
|
||||
SecureLogger.debug(
|
||||
"🔇 Nearby-notification mute no-op for \(peerID.id.prefix(8))… (no fingerprint yet)",
|
||||
category: .session
|
||||
)
|
||||
return
|
||||
}
|
||||
identityManager.setNearbyNotificationMuted(fingerprint, muted: muted)
|
||||
objectWillChange.send()
|
||||
}
|
||||
|
||||
@ -304,4 +304,35 @@ struct ChatPeerListCoordinatorContextTests {
|
||||
await drainMainActorTasks()
|
||||
#expect(context.networkAvailableNotifications == [1])
|
||||
}
|
||||
|
||||
@Test @MainActor
|
||||
func didUpdatePeerList_mutedOnlyMeshResetsEmptyGateForNextStranger() async {
|
||||
let context = MockChatPeerListContext()
|
||||
let coordinator = ChatPeerListCoordinator(context: context, notificationCooldownSeconds: 0)
|
||||
let mutedPeer = PeerID(str: "0011223344556677")
|
||||
let stranger = PeerID(str: "8899aabbccddeeff")
|
||||
context.connectedMeshPeers = [mutedPeer, stranger]
|
||||
context.suppressedNearbyPeerIDs = [mutedPeer]
|
||||
|
||||
// First stranger alerts and marks the mesh populated.
|
||||
coordinator.didUpdatePeerList([mutedPeer, stranger])
|
||||
await drainMainActorTasks()
|
||||
#expect(context.networkAvailableNotifications == [1])
|
||||
|
||||
// Stranger leaves; only the muted peer remains. Reset-path count
|
||||
// must treat that as empty (activeMeshPeerCount excludes muted).
|
||||
context.connectedMeshPeers = [mutedPeer]
|
||||
context.activeMeshPeerCountValue = 0
|
||||
coordinator.didUpdatePeerList([mutedPeer])
|
||||
await drainMainActorTasks()
|
||||
coordinator.handleNetworkEmptyTimerFired()
|
||||
|
||||
// A later stranger must alert again — the muted peer must not pin
|
||||
// meshWasEmpty to false forever.
|
||||
context.connectedMeshPeers = [mutedPeer, stranger]
|
||||
context.activeMeshPeerCountValue = 1
|
||||
coordinator.didUpdatePeerList([mutedPeer, stranger])
|
||||
await drainMainActorTasks()
|
||||
#expect(context.networkAvailableNotifications == [1, 1])
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user