TRAX: error display, retain track on failure, gray idle dot
1. Error text shows in red inside the desktop audio meter bar (scrollable) when TRAX load or playback fails — user gets feedback, not just a silent red dot. 2. LoadTrax no longer nulls _music on error — the track path is retained so the user sees what failed and can retry. 3. OnTraxPlaybackEnded now receives the NAudio exception and surfaces it. 4. TRAX dot is green (playing) or gray (idle/no track) — no more yellow or red states. 207 tests, 0 warnings.
This commit is contained in:
@@ -476,6 +476,7 @@ public class MainViewModel : ViewModelBase
|
||||
// ─── Mic status dot (the MIC button) ───
|
||||
|
||||
private static readonly SolidColorBrush MicProblemBrush = CreateBrush("#f1c40f");
|
||||
private static readonly SolidColorBrush TraxIdleBrush = CreateBrush("#555");
|
||||
|
||||
/// <summary>Mic connection state, driven by the mixer's MicConnected/MicFailed
|
||||
/// events and the startup device check (see StartMicCaptureAsync).</summary>
|
||||
@@ -525,12 +526,19 @@ public class MainViewModel : ViewModelBase
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>TRAX status dot: green = playing, yellow = loaded/stopped, red = no track.</summary>
|
||||
private string? _traxError;
|
||||
|
||||
/// <summary>Error message from the last TRAX load/playback failure; null = no error.</summary>
|
||||
public string? TraxError
|
||||
{
|
||||
get => _traxError;
|
||||
private set => SetProperty(ref _traxError, value);
|
||||
}
|
||||
|
||||
/// <summary>TRAX status dot: green = playing, gray = idle or no track.</summary>
|
||||
public SolidColorBrush TraxDotBrush => _musicPlayer.IsPlaying
|
||||
? BarOnBrush
|
||||
: _music != null && !string.IsNullOrWhiteSpace(_music.TrackPath)
|
||||
? MicProblemBrush
|
||||
: BarOffBrush;
|
||||
: TraxIdleBrush;
|
||||
|
||||
public string TraxToolTip => _musicPlayer.TrackName != null
|
||||
? $"TRAX: {_musicPlayer.TrackName} — left-click {(IsMusicPlaying ? "pauses" : "plays")}, right-click chooses a track"
|
||||
@@ -574,13 +582,14 @@ public class MainViewModel : ViewModelBase
|
||||
_musicPlayer.Load(_music.TrackPath);
|
||||
UpdateTraxLocalGain();
|
||||
_music.IsEnabled = true;
|
||||
TraxError = null;
|
||||
if (play)
|
||||
_musicPlayer.Play();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AppLog.Write($"TRAX: failed to load '{_music.TrackPath}': {ex.Message}");
|
||||
_music = null;
|
||||
TraxError = $"Failed to load: {Path.GetFileName(_music.TrackPath)} — {ex.Message}";
|
||||
}
|
||||
RefreshTraxUi();
|
||||
ScheduleSave();
|
||||
@@ -590,10 +599,13 @@ public class MainViewModel : ViewModelBase
|
||||
|
||||
private void PauseTrax() => _musicPlayer.Pause();
|
||||
|
||||
private void OnTraxPlaybackEnded()
|
||||
private void OnTraxPlaybackEnded(Exception? ex)
|
||||
{
|
||||
// Natural end loops inside the player; here only an explicit stop or a
|
||||
// device failure lands — flip the dot back to loaded/stopped.
|
||||
if (ex != null)
|
||||
{
|
||||
AppLog.Write($"TRAX: playback error: {ex.Message}");
|
||||
TraxError = $"Playback error: {ex.Message}";
|
||||
}
|
||||
RefreshTraxUi();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user