@using DeepDrftPublic.Client.Common @using DeepDrftPublic.Client.Services @* The streaming-quality control (Phase 18 wave 18.6, §4) — the first occupant of the Settings menu. Binds the listener's choice to PublicSiteSettings.StreamQuality and persists it via the cookie seam. Honest capability gate (OQ2 / AC7): on a browser that cannot decode Ogg Opus the Low-data option still selects, but a note tells the listener the effective stream is lossless — we never let the choice silently imply a format that can't play. *@
Low-data (Opus) Lossless (WAV) @if (_opusUnavailable && _quality == StreamQuality.LowData) {
This browser can't decode Opus — you'll stream lossless.
}
@code { [Inject] public required PublicSiteSettings Settings { get; set; } [Inject] public required SettingsCookieService CookieService { get; set; } [Inject] public required AudioInteropService AudioInterop { get; set; } private StreamQuality _quality; // Null until the capability probe runs (post-render JS interop). false → can decode Opus; true → cannot. private bool _opusUnavailable; protected override void OnInitialized() { // Read the current preference (already seeded at prerender + bridged into WASM). _quality = Settings.StreamQuality; } protected override async Task OnAfterRenderAsync(bool firstRender) { if (!firstRender) return; // Capability probe is JS interop — only valid once interactive. Surfaces the honest note when the // browser can't decode Ogg Opus, so a Low-data pick reads as "effectively lossless" rather than // silently failing. The player applies the same gate independently; this is purely the UI honesty. var canDecodeOpus = await AudioInterop.CanDecodeOggOpus(); if (canDecodeOpus == _opusUnavailable) { _opusUnavailable = !canDecodeOpus; StateHasChanged(); } } private async Task OnQualityChanged(StreamQuality quality) { _quality = quality; await CookieService.SetStreamQualityAsync(quality); } }