refactor: improve separation of concerns in call feature

1. Move UI toggle state out of CallState.Connected:
   - Removed isAudioMuted/isVideoEnabled/isSpeakerOn from domain
     CallState. These are UI concerns, not call state.
   - Added StateFlows for toggles in CallController (isAudioMuted,
     isVideoEnabled, isSpeakerOn) with proper toggle methods.
   - CallScreen reads toggle state from CallController flows.
   - Removed toggleAudioMute/toggleVideo/toggleSpeaker from
     CallManager (no longer manages UI state).

2. Move ICE candidate parsing to quartz layer:
   - Added candidateSdp(), sdpMid(), sdpMLineIndex() parsers and
     serializeCandidate() to CallIceCandidateEvent in quartz.
   - Removed companion object with parseIceCandidate/
     serializeIceCandidate from CallController.
   - CallController now uses quartz-layer parsing directly.
   - Updated IceCandidateSerializationTest accordingly.

3. Add helper methods to CallManager:
   - currentCallId() and currentPeerPubKey() extract from any
     active state, reducing repeated when expressions.

4. Fix empty callId bug in ChatroomScreen:
   - Navigation to ActiveCall now uses callManager.currentCallId()
     instead of hardcoded empty string.

https://claude.ai/code/session_017hZm7yu7CzmcQgZGSaqSXS
This commit is contained in:
Claude
2026-04-02 02:39:41 +00:00
parent f344f00e9d
commit 44d6345e16
7 changed files with 118 additions and 113 deletions
@@ -45,11 +45,32 @@ class CallIceCandidateEvent(
fun candidateJson() = content
fun candidateSdp(): String = CANDIDATE_REGEX.find(content)?.groupValues?.get(1) ?: ""
fun sdpMid(): String = SDP_MID_REGEX.find(content)?.groupValues?.get(1) ?: "0"
fun sdpMLineIndex(): Int =
SDP_MLINE_INDEX_REGEX
.find(content)
?.groupValues
?.get(1)
?.toIntOrNull() ?: 0
companion object {
const val KIND = 25052
const val ALT_DESCRIPTION = "WebRTC ICE candidate"
const val EXPIRATION_SECONDS = 20L
private val CANDIDATE_REGEX = """"candidate"\s*:\s*"([^"]*)"""".toRegex()
private val SDP_MID_REGEX = """"sdpMid"\s*:\s*"([^"]*)"""".toRegex()
private val SDP_MLINE_INDEX_REGEX = """"sdpMLineIndex"\s*:\s*(\d+)""".toRegex()
fun serializeCandidate(
sdp: String,
sdpMid: String,
sdpMLineIndex: Int,
): String = """{"candidate":"$sdp","sdpMid":"$sdpMid","sdpMLineIndex":$sdpMLineIndex}"""
fun build(
candidateJson: String,
peerPubKey: HexKey,