mirror of
https://github.com/J3vb/OwnCord.git
synced 2026-09-03 03:50:00 +03:00
Research-driven voice/video polish pass based on Discord/TeamSpeak comparison. Refactor: - Split livekitSession.ts (1,509 lines) into 4 modules: audioPipeline.ts, audioElements.ts, deviceManager.ts + facade in livekitSession.ts - Facade pattern preserves all existing exports (zero breaking changes) AudioWorklet VAD: - Migrated VAD from setTimeout polling to AudioWorklet (vad-worklet.js) - Runs on audio thread, works when app is backgrounded - Graceful fallback to setTimeout if AudioWorklet unavailable Bug fixes: - Token TTL extended from 4h to 24h (eliminates fragile long sessions) - Ghost voice state: retry with exponential backoff (3 attempts, 100-400ms) - Client token refresh adjusted to 23h (1h before expiry) UX improvements: - Speaker indicator: pulsing green glow animation (speak-pulse keyframes) - Permission recovery: "Grant Microphone" button in VoiceWidget for listen-only mode with listenOnly state in voiceStore - Device hot-swap: devicechange listener with 500ms debounce, auto-fallback to default device, toast notification - Camera/screenshare stop: toast feedback on disable - Connection quality: auto-expand stats pane on poor/bad quality (3s debounce) - Bandwidth display: human-readable Mbps in stats pane (formatBitrate) Observability: - Voice session metrics: voice_sessions counter on /api/v1/metrics endpoint Tests: - 55 new unit tests for audioPipeline + audioElements modules - 22 new Go tests for HTTPS proxy (WebSocket upgrade, origin validation, path blocking) - 11 new voice E2E tests (lifecycle, widget, speaker indicators) - Pre-refactor snapshot tests for livekitSession public API Docs: - DESIGN.md: full design system documentation (tokens, typography, colors, spacing, motion, voice-specific tokens) - VOICE-COMPARISON-MATRIX.md: 25-behavior comparison across Discord, TeamSpeak, Guilded - voice-video-polish.md: CEO plan with scope decisions
50 lines
1.6 KiB
Go
50 lines
1.6 KiB
Go
package api
|
|
|
|
import (
|
|
"net/http"
|
|
"runtime"
|
|
"time"
|
|
)
|
|
|
|
// ServerMetrics holds runtime metrics for the /api/v1/metrics endpoint.
|
|
type ServerMetrics struct {
|
|
Uptime string `json:"uptime"`
|
|
UptimeSeconds float64 `json:"uptime_seconds"`
|
|
GoRoutines int `json:"goroutines"`
|
|
HeapAllocMB float64 `json:"heap_alloc_mb"`
|
|
HeapSysMB float64 `json:"heap_sys_mb"`
|
|
NumGC uint32 `json:"num_gc"`
|
|
ConnectedUsers int `json:"connected_users"`
|
|
VoiceSessions int `json:"voice_sessions"`
|
|
LiveKitHealthy *bool `json:"livekit_healthy,omitempty"`
|
|
}
|
|
|
|
// handleMetrics returns an HTTP handler that reports runtime server metrics.
|
|
// getConnectedUsers is a callback to retrieve the current WebSocket client count.
|
|
// livekitHealthCheck is optional — if non-nil, it probes the LiveKit companion process.
|
|
func handleMetrics(getConnectedUsers func() int, getVoiceSessions func() int, livekitHealthCheck func() (bool, error)) http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
var m runtime.MemStats
|
|
runtime.ReadMemStats(&m)
|
|
|
|
uptime := time.Since(serverStartTime)
|
|
metrics := ServerMetrics{
|
|
Uptime: uptime.Truncate(time.Second).String(),
|
|
UptimeSeconds: uptime.Seconds(),
|
|
GoRoutines: runtime.NumGoroutine(),
|
|
HeapAllocMB: float64(m.HeapAlloc) / 1024 / 1024,
|
|
HeapSysMB: float64(m.HeapSys) / 1024 / 1024,
|
|
NumGC: m.NumGC,
|
|
ConnectedUsers: getConnectedUsers(),
|
|
VoiceSessions: getVoiceSessions(),
|
|
}
|
|
|
|
if livekitHealthCheck != nil {
|
|
healthy, _ := livekitHealthCheck()
|
|
metrics.LiveKitHealthy = &healthy
|
|
}
|
|
|
|
writeJSON(w, http.StatusOK, metrics)
|
|
}
|
|
}
|