Files
Luma/Sources/Shared/XMPP/LumaConnectionStatsModule.swift
T
wt 0317277d46
iOS CI / Build and Test SwiftUI App (push) Canceled after 0s
Build Unsigned iOS and macOS Apps / Build Unsigned iOS IPA (push) Canceled after 0s
Build Unsigned iOS and macOS Apps / Build macOS ZIP (push) Canceled after 0s
add server info screen, connection stats, and emoji picker
Server information (Monal-style):
- Add ServerInformation model and ServerInfoView reachable from
  Settings,
  showing server software (XEP-0092), disco#info identities and
  features,
  conference (MUC) services via disco#items, and STUN/TURN via XEP-0215.
- Add a curated XEP capability list with per-XEP success/error status
  derived
  from server/account disco features and connection flags.
- Detect PEP (0163) from account disco pubsub#* features, HTTP Upload
  (0363)
  from the main domain plus its components, and add Roster Versioning
  (0237),
  Pre-Authenticated Roster Subscription (0379), and SASL SCRAM Downgrade
  Protection (0474, neutral because Martin does not expose SSDP).

Connection statistics:
- Add LumaConnectionStatsModule, an XmppStanzaFilter registered before
  stream
  management, to count sent / acknowledged / received stanzas.
- Track last login and SMACKS session timestamps, and read SASL
  mechanisms
  and Client State Indication from the raw stream features.

MAM / OMEMO handling:
- Prefer a plaintext <body> fallback when OMEMO decryption fails instead
  of
  showing "failed to decrypt".
- Keep the optimistic text of our own outgoing message when its echo
  cannot
  be decrypted back, instead of replacing it with a placeholder.

Emoji picker:
- Add EmojiCatalog and a cross-platform EmojiPickerView.
- Open the picker for reactions (replacing the static quick list) and
  from
  the composer's smiley button, inserting the chosen emoji into the
  draft.
2026-08-18 21:44:27 +07:00

69 lines
2.1 KiB
Swift

import Foundation
import Martin
/// Counts XEP-0198 stanza statistics (sent / acknowledged / received) at the
/// stream level so the server-details screen can mirror Monal's connection
/// statistics. Registered as an `XmppStanzaFilter` *before* stream management
/// so it can also observe the server's `<a h='N'>` acknowledgements.
final class LumaConnectionStatsModule: XmppModuleBase, XmppModule, XmppStanzaFilter {
static let ID = "lumaConnectionStats"
static let smNamespace = "urn:xmpp:sm:3"
let criteria = Criteria.empty()
let features: [String] = []
private let lock = NSLock()
private var sent: UInt32 = 0
private var received: UInt32 = 0
private var acknowledged: UInt32 = 0
struct Snapshot: Equatable, Sendable {
let sent: UInt32
let acknowledged: UInt32
let received: UInt32
var unacknowledged: UInt32 {
sent > acknowledged ? sent - acknowledged : 0
}
}
var snapshot: Snapshot {
lock.lock()
defer { lock.unlock() }
return Snapshot(sent: sent, acknowledged: acknowledged, received: received)
}
func processIncoming(stanza: Stanza) -> Bool {
if stanza.xmlns == Self.smNamespace, stanza.name == "a" {
if let raw = stanza.getAttribute("h"), let value = UInt32(raw) {
lock.lock()
acknowledged = value
lock.unlock()
}
// Let StreamManagementModule consume the acknowledgement too.
return false
}
if Self.isCountable(stanza) {
lock.lock()
received += 1
lock.unlock()
}
return false
}
func processOutgoing(stanza: Stanza) {
guard Self.isCountable(stanza) else { return }
lock.lock()
sent += 1
lock.unlock()
}
func process(stanza: Stanza) throws {
// Criteria is empty, so this module is never selected by the dispatcher.
}
private static func isCountable(_ stanza: Stanza) -> Bool {
stanza.name == "iq" || stanza.name == "message" || stanza.name == "presence"
}
}