Improved issue handling

This commit is contained in:
Thorsten Sommer 2026-01-18 20:44:08 +01:00
parent cc3560fdd2
commit ce7a334fef
Signed by untrusted user who does not match committer: tsommer
GPG Key ID: 371BBA77A02C0108

View File

@ -26,9 +26,16 @@ public partial class VoiceRecorder : MSGComponentBase
{
await base.OnInitializedAsync();
try
{
// Initialize sound effects. This "warms up" the AudioContext and preloads all sounds for reliable playback:
await this.JsRuntime.InvokeVoidAsync("initSoundEffects");
}
catch (Exception ex)
{
this.Logger.LogError(ex, "Failed to initialize sound effects.");
}
}
#endregion
@ -50,9 +57,16 @@ public partial class VoiceRecorder : MSGComponentBase
private async Task OnRecordingToggled(bool toggled)
{
if (toggled)
{
try
{
// Warm up sound effects:
await this.JsRuntime.InvokeVoidAsync("initSoundEffects");
}
catch (Exception ex)
{
this.Logger.LogError(ex, "Failed to initialize sound effects.");
}
var mimeTypes = GetPreferredMimeTypes(
Builder.Create().UseAudio().UseSubtype(AudioSubtype.OGG).Build(),
@ -71,6 +85,8 @@ public partial class VoiceRecorder : MSGComponentBase
// Initialize the file stream for writing chunks:
await this.InitializeRecordingStream();
try
{
var mimeTypeStrings = mimeTypes.ToStringArray();
var actualMimeType = await this.JsRuntime.InvokeAsync<string>("audioRecorder.start", this.dotNetReference, mimeTypeStrings);
@ -80,11 +96,28 @@ public partial class VoiceRecorder : MSGComponentBase
this.Logger.LogInformation("Audio recording started with MIME type: '{ActualMimeType}'.", actualMimeType);
this.isRecording = true;
}
catch (Exception e)
{
this.Logger.LogError(e, "Failed to start audio recording.");
await this.MessageBus.SendError(new(Icons.Material.Filled.MicOff, this.T("Failed to start audio recording.")));
// Clean up the recording stream if starting failed:
await this.FinalizeRecordingStream();
}
}
else
{
try
{
var result = await this.JsRuntime.InvokeAsync<AudioRecordingResult>("audioRecorder.stop");
if (result.ChangedMimeType)
this.Logger.LogWarning("The recorded audio MIME type was changed to '{ResultMimeType}'.", result.MimeType);
}
catch (Exception e)
{
this.Logger.LogError(e, "Failed to stop audio recording.");
await this.MessageBus.SendError(new(Icons.Material.Filled.MicOff, this.T("Failed to stop audio recording.")));
}
// Close and finalize the recording stream:
await this.FinalizeRecordingStream();
@ -280,8 +313,15 @@ public partial class VoiceRecorder : MSGComponentBase
this.Logger.LogInformation("Transcription completed successfully. Result length: {Length} characters.", transcribedText.Length);
try
{
// Play the transcription done sound effect:
await this.JsRuntime.InvokeVoidAsync("playSound", "/sounds/transcription_done.ogg");
}
catch (Exception ex)
{
this.Logger.LogError(ex, "Failed to play transcription done sound effect.");
}
// Copy the transcribed text to the clipboard:
await this.RustService.CopyText2Clipboard(this.Snackbar, transcribedText);
@ -320,8 +360,16 @@ public partial class VoiceRecorder : MSGComponentBase
// Wait a moment for any queued sounds to finish playing, then release the microphone.
// This allows Bluetooth headsets to switch back to A2DP profile without interrupting audio:
await Task.Delay(1_800);
try
{
await this.JsRuntime.InvokeVoidAsync("audioRecorder.releaseMicrophone");
}
catch (Exception e)
{
this.Logger.LogError(e, "Failed to release the microphone.");
}
}
private sealed class AudioRecordingResult
{