fix(player): show mute in the volume indicator
Muting does not change the volume level, and VolumeChanged carried nothing but that level — so pressing M silenced playback and left the indicator showing the volume it still had. The UI had nothing to react to. Mute rides on its own event rather than widening the volume payload, since the two are genuinely independent: a muted player at 40% is a different state from a player at 0%, and only one of them comes back when you unmute. The icon crosses out and dims, and the popup gains an explicit Mute/Unmute so the keyboard shortcut is not the only way in. MuteToggle also now takes the speaker lock (it was mutating the effects chain from outside it) and refuses politely rather than dereferencing a nil streamer when nothing has been loaded yet.
This commit is contained in:
@@ -12,6 +12,7 @@ const (
|
||||
TrackChanged = "TrackChanged"
|
||||
SeekFailed = "SeekFailed"
|
||||
VolumeChanged = "VolumeChanged"
|
||||
MuteChanged = "MuteChanged"
|
||||
)
|
||||
|
||||
// Queue events (backend → frontend push).
|
||||
|
||||
@@ -224,12 +224,19 @@ func (p *Player) emitVolumeChanged() {
|
||||
}
|
||||
|
||||
volume := int(p.getUserVolume())
|
||||
muted := p.volume != nil && p.volume.Silent
|
||||
p.logger.Info(
|
||||
"Emitting VolumeChangedEvent", "volume", volume,
|
||||
"Emitting VolumeChangedEvent", "volume", volume, "muted", muted,
|
||||
)
|
||||
|
||||
events.Emit(p.ctx, events.VolumeChanged, volume)
|
||||
|
||||
// Mute rides on its own event rather than widening the volume
|
||||
// payload: silence does not change the volume level, so a UI that
|
||||
// only watched VolumeChanged saw nothing happen when the user hit
|
||||
// the mute key.
|
||||
events.Emit(p.ctx, events.MuteChanged, muted)
|
||||
|
||||
if p.mediaControls != nil {
|
||||
// MPRIS volume is 0.0–1.0 linear.
|
||||
p.mediaControls.UpdateVolume(
|
||||
@@ -692,12 +699,27 @@ func (p *Player) getUserVolume() UserVolume {
|
||||
return Volume(p.volume.Volume).ToUserVolume()
|
||||
}
|
||||
|
||||
// Muted reports whether playback is currently silenced.
|
||||
func (p *Player) Muted() bool {
|
||||
p.mu.Lock()
|
||||
defer p.mu.Unlock()
|
||||
|
||||
return p.volume != nil && p.volume.Silent
|
||||
}
|
||||
|
||||
// MuteToggle toggles the mute state.
|
||||
func (p *Player) MuteToggle() error {
|
||||
p.mu.Lock()
|
||||
defer p.mu.Unlock()
|
||||
|
||||
if p.volume == nil {
|
||||
return errNoAudioFileLoaded
|
||||
}
|
||||
|
||||
speaker.Lock()
|
||||
p.volume.Silent = !p.volume.Silent
|
||||
speaker.Unlock()
|
||||
|
||||
p.emitVolumeChanged()
|
||||
p.saveState()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user