chore: comment cleanup pass ahead of open-sourcing
Removes leftover debug scaffolding (stray Console.WriteLine/NSLog traces, dead nick_buf_ptr, a no-op --print-config flag now implemented for real), fixes stale/misleading comments (channel passwords are no longer a "future M5+" feature, a wrong cross-reference, a stale TlsContext::close() mention, an incomplete BanRecord::subject_type doc, and a smoke test pointing at a build/m1-dev preset that no longer exists), strips internal M1-M5 milestone jargon from comments now that the roadmap is done, trims comments that just restated the following line, and consolidates a few "why" explanations that were duplicated 2-3 times in the same file. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -116,16 +116,6 @@ final class AppState {
|
||||
ServerListStore.shared.save(servers)
|
||||
}
|
||||
|
||||
// MARK: - Teardown
|
||||
|
||||
/// `AppState` is the @Observable app root owned by the SwiftUI `App`; it lives for the
|
||||
/// whole app process and is torn down only on process exit, at which point OS cleanup
|
||||
/// suffices. Reconnect state (the in-flight `Task` and the `NWPathMonitor`) is cancelled
|
||||
/// via `cancelReconnect()` driven by `disconnect()`/`cancelConnect()` and on successful
|
||||
/// restore — those run on user-initiated teardown, which is the only path that matters.
|
||||
/// (The `Task` captures `[weak self]` and guards on `nil`/`userInitiatedDisconnect`, so a
|
||||
/// stray task left running when AppState is gone is a no-op; the monitor similarly guards.)
|
||||
|
||||
// MARK: - Connect flow
|
||||
|
||||
/// Public connect entry. Always starts a fresh session (no restore).
|
||||
@@ -245,6 +235,13 @@ final class AppState {
|
||||
/// Cancel any in-flight reconnect task and stop the path monitor. Safe to call when nothing
|
||||
/// is armed (no-op). Does NOT touch `userInitiatedDisconnect` or `lastSession` — callers set
|
||||
/// those as needed (disconnect/cancelConnect clear them; scheduleReconnect keeps them).
|
||||
///
|
||||
/// `AppState` is the @Observable app root owned by the SwiftUI `App`; it lives for the
|
||||
/// whole app process and is torn down only on process exit, at which point OS cleanup
|
||||
/// suffices. This method is driven by `disconnect()`/`cancelConnect()` and on successful
|
||||
/// restore — those run on user-initiated teardown, which is the only path that matters.
|
||||
/// (The reconnect `Task` captures `[weak self]` and guards on `nil`/`userInitiatedDisconnect`,
|
||||
/// so a stray task left running when AppState is gone is a no-op; the monitor similarly guards.)
|
||||
private func cancelReconnect() {
|
||||
reconnectTask?.cancel()
|
||||
reconnectTask = nil
|
||||
@@ -310,15 +307,12 @@ final class AppState {
|
||||
if prevSig == nil { return }
|
||||
|
||||
if self.session != nil {
|
||||
// Connected — tear down + reconnect on a meaningful path change.
|
||||
// `.unsatisfied` (all radios off) OR a primary-interface change (Wi-Fi↔cellular)
|
||||
// almost always breaks the live TCP connection; reconnecting proactively beats
|
||||
// waiting for the C core's keepalive/reaper timeout.
|
||||
// See this method's doc comment for why these conditions trigger a
|
||||
// proactive reconnect.
|
||||
if path.status != .satisfied || sig != prevSig {
|
||||
self.proactiveReconnect()
|
||||
}
|
||||
} else if self.lastSession != nil {
|
||||
// Mid-reconnect — a path is available again; fast-fresh the next attempt.
|
||||
if path.status == .satisfied {
|
||||
self.reconnectAttempt = 0
|
||||
self.scheduleReconnect()
|
||||
|
||||
@@ -163,13 +163,8 @@ final class IOSAudioRouter: ObservableObject {
|
||||
/// burns CPU and cycles the audio session on/off (the "glitching" bug).
|
||||
private var isApplyingConfiguration = false
|
||||
|
||||
/// Last `overrideOutputAudioPort` value we successfully applied (`.none` or `.speaker`),
|
||||
/// so `applyA2dpSpeakerFallback` can skip a redundant `overrideOutputAudioPort` call.
|
||||
/// That call fires a `.override` route-change notification on every invocation, and on
|
||||
/// an AirPods disconnect the fallback is invoked once per `recoverAudio()` — which
|
||||
/// itself fires on every non-skipped route change — so without this guard the override
|
||||
/// call and the route-change handler ping-pong: the AirPods-disconnect reinitialize
|
||||
/// loop (each iteration also rebuilds the AVAudioEngine via reconfigure()).
|
||||
/// Last `overrideOutputAudioPort` value we successfully applied (`.none` or `.speaker`).
|
||||
/// See `applyA2dpSpeakerFallback`'s doc comment for why this cache exists.
|
||||
/// `nil` = "unknown / assume not applied" — reset at the top of `applyConfiguration()`
|
||||
/// because `setCategory` can reset the override out from under us, and on first run.
|
||||
private var lastAppliedOutputOverride: AVAudioSession.PortOverride?
|
||||
@@ -382,13 +377,8 @@ final class IOSAudioRouter: ObservableObject {
|
||||
|
||||
// 3. Input & mic-capsule configuration.
|
||||
if captureChannels == .stereo {
|
||||
// Stereo: enable the built-in mic's .stereo polar pattern AND anchor the input
|
||||
// route explicitly via setPreferredInput + setInputDataSource. With HFP disabled
|
||||
// the system routes input to the built-in mic, but without the explicit
|
||||
// preferred-input anchor the route can collapse during the mode switch
|
||||
// (.voiceChat → .default) and the output dies. The channel count is carried by the
|
||||
// engine's mic tap + vc_set_capture_channels, NOT via
|
||||
// setPreferredInputNumberOfChannels(2) — that call collapses the A2DP output route.
|
||||
// See configureStereoCapture's doc comment for the full stereo-capture recipe
|
||||
// and why each step is necessary.
|
||||
configureStereoCapture(session: session)
|
||||
} else if let portId = selectedInputPortId, !portId.isEmpty,
|
||||
let port = session.availableInputs?.first(where: { $0.uid == portId }) {
|
||||
@@ -434,8 +424,6 @@ final class IOSAudioRouter: ObservableObject {
|
||||
do {
|
||||
try builtIn.setPreferredDataSource(stereoSource)
|
||||
try stereoSource.setPreferredPolarPattern(.stereo)
|
||||
// Anchor the input route explicitly; without it the route can collapse during
|
||||
// the mode switch (.voiceChat → .default) and the A2DP output dies.
|
||||
try session.setPreferredInput(builtIn)
|
||||
// Commit the data source at the session level. setPreferredDataSource alone only
|
||||
// sets the port-level preference; setInputDataSource makes it the active source.
|
||||
@@ -697,8 +685,6 @@ final class IOSAudioRouter: ObservableObject {
|
||||
}
|
||||
let desired: AVAudioSession.PortOverride = hasExternalOutput ? .none : .speaker
|
||||
if desired == lastAppliedOutputOverride {
|
||||
// Already in the desired state — calling overrideOutputAudioPort again would just
|
||||
// fire a redundant `.override` route-change notification (the loop driver).
|
||||
logger.debug("A2DP fallback — desired=\(self.overrideLabel(desired)) already applied, skipping")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -54,11 +54,11 @@ final class SessionState {
|
||||
var accounts: [Account] = []
|
||||
var devices: [Device] = []
|
||||
|
||||
/// Back-reference to the app state. Once `SessionState.init` overwrites `client.onEvent`
|
||||
/// (`SessionState.swift:87`), `AppState.handleConnectEvent` no longer receives per-session
|
||||
/// events — so the `.disconnected` event for a LIVE session arrives here in `handleEvent`,
|
||||
/// not in AppState. This weak ref lets us hand the disconnect back to AppState (which owns
|
||||
/// the reconnect state machine) so the auto-reconnect fires. Set by AppState on auth success.
|
||||
/// Back-reference to the app state. Once `SessionState.init` overwrites `client.onEvent`,
|
||||
/// `AppState.handleConnectEvent` no longer receives per-session events — so the
|
||||
/// `.disconnected` event for a LIVE session arrives here in `handleEvent`, not in AppState.
|
||||
/// This weak ref lets us hand the disconnect back to AppState (which owns the reconnect
|
||||
/// state machine) so the auto-reconnect fires. Set by AppState on auth success.
|
||||
weak var appState: AppState?
|
||||
|
||||
// MARK: - Reconnect restore state
|
||||
@@ -260,17 +260,18 @@ final class SessionState {
|
||||
// MARK: - Self-channel / server-mute sync
|
||||
|
||||
/// Sync currentChannelId from the self user's channelId in the user list. Mirrors macOS
|
||||
/// MainWindowController.swift:461,491,522. The server auto-places every authed user into
|
||||
/// the Lobby (channel 1) on connect, but without this sync currentChannelId stays 0 and
|
||||
/// the mic button (gated on currentChannelId == 0) stays permanently dimmed.
|
||||
/// MainWindowController's bootstrap/event-handling sync. The server auto-places every
|
||||
/// authed user into the Lobby (channel 1) on connect, but without this sync
|
||||
/// currentChannelId stays 0 and the mic button (gated on currentChannelId == 0) stays
|
||||
/// permanently dimmed.
|
||||
private func syncSelfChannel() {
|
||||
if let me = users.first(where: { $0.id == selfUserId }) {
|
||||
currentChannelId = me.channelId
|
||||
}
|
||||
}
|
||||
|
||||
/// Apply server-side mute/deafen state — mirrors macOS MainWindowController.swift:693-700.
|
||||
/// iOS was previously ignoring server mute/deafen entirely.
|
||||
/// Apply server-side mute/deafen state — mirrors macOS MainWindowController's handling
|
||||
/// of UserEvent.UPDATED for the self user.
|
||||
private func applyServerMuteState(muted: Bool, deafened: Bool) {
|
||||
if muted && !voiceState.serverMuted { addActivity("You have been server-muted") }
|
||||
if deafened && !voiceState.serverDeafened { addActivity("You have been server-deafened") }
|
||||
|
||||
@@ -48,7 +48,6 @@ struct PerUserTuningView: View {
|
||||
}
|
||||
}
|
||||
.onAppear {
|
||||
// Load from first stream if available
|
||||
let streams = streamsForUser
|
||||
if let first = streams.first {
|
||||
let (_, state) = session.client.getRemoteStream(userId: user.id, streamId: first.id)
|
||||
|
||||
Reference in New Issue
Block a user