expose repeat mode through MPRIS

This commit is contained in:
Drew Weymouth
2023-07-13 13:12:57 -07:00
parent 41053a22a8
commit a12b6dd276
4 changed files with 61 additions and 10 deletions
+27 -2
View File
@@ -15,8 +15,9 @@ import (
const dbusTrackIDPrefix = "/Supersonic/Track/" const dbusTrackIDPrefix = "/Supersonic/Track/"
var ( var (
_ types.OrgMprisMediaPlayer2Adapter = (*MPRISHandler)(nil) _ types.OrgMprisMediaPlayer2Adapter = (*MPRISHandler)(nil)
_ types.OrgMprisMediaPlayer2PlayerAdapter = (*MPRISHandler)(nil) _ types.OrgMprisMediaPlayer2PlayerAdapter = (*MPRISHandler)(nil)
_ types.OrgMprisMediaPlayer2PlayerAdapterLoopStatus = (*MPRISHandler)(nil)
) )
var ( var (
@@ -186,6 +187,30 @@ func (m *MPRISHandler) PlaybackStatus() (types.PlaybackStatus, error) {
return "", errors.New("unknown playback status") return "", errors.New("unknown playback status")
} }
func (m *MPRISHandler) LoopStatus() (types.LoopStatus, error) {
switch m.pm.LoopMode() {
case LoopModeAll:
return types.LoopStatusPlaylist, nil
case LoopModeOne:
return types.LoopStatusTrack, nil
case LoopModeNone:
return types.LoopStatusNone, nil
}
return "", errors.New("unknown loop status")
}
func (m *MPRISHandler) SetLoopStatus(status types.LoopStatus) error {
switch status {
case types.LoopStatusPlaylist:
return m.pm.SetLoopMode(LoopModeAll)
case types.LoopStatusTrack:
return m.pm.SetLoopMode(LoopModeOne)
case types.LoopStatusNone:
return m.pm.SetLoopMode(LoopModeNone)
}
return errors.New("unknown loop status")
}
func (m *MPRISHandler) Rate() (float64, error) { func (m *MPRISHandler) Rate() (float64, error) {
return 1, nil return 1, nil
} }
+27 -3
View File
@@ -17,6 +17,14 @@ const (
ReplayGainTrack = string(player.ReplayGainTrack) ReplayGainTrack = string(player.ReplayGainTrack)
) )
type LoopMode int
const (
LoopModeNone LoopMode = LoopMode(player.LoopNone)
LoopModeAll LoopMode = LoopMode(player.LoopAll)
LoopModeOne LoopMode = LoopMode(player.LoopOne)
)
// A high-level Subsonic-aware playback backend. // A high-level Subsonic-aware playback backend.
// Manages loading tracks into the Player queue, // Manages loading tracks into the Player queue,
// sending callbacks on play time updates and track changes. // sending callbacks on play time updates and track changes.
@@ -40,7 +48,7 @@ type PlaybackManager struct {
onSongChange []func(nowPlaying, justScrobbledIfAny *mediaprovider.Track) onSongChange []func(nowPlaying, justScrobbledIfAny *mediaprovider.Track)
onPlayTimeUpdate []func(float64, float64) onPlayTimeUpdate []func(float64, float64)
onLoopModeChange []func(string) onLoopModeChange []func(LoopMode)
} }
func NewPlaybackManager( func NewPlaybackManager(
@@ -130,7 +138,7 @@ func (p *PlaybackManager) OnPlayTimeUpdate(cb func(float64, float64)) {
} }
// Registers a callback that is notified whenever the loop mode changes. // Registers a callback that is notified whenever the loop mode changes.
func (p *PlaybackManager) OnLoopModeChange(cb func(string)) { func (p *PlaybackManager) OnLoopModeChange(cb func(LoopMode)) {
p.onLoopModeChange = append(p.onLoopModeChange, cb) p.onLoopModeChange = append(p.onLoopModeChange, cb)
} }
@@ -305,12 +313,28 @@ func (p *PlaybackManager) SetNextLoopMode() error {
} }
for _, cb := range p.onLoopModeChange { for _, cb := range p.onLoopModeChange {
cb(p.player.GetLoopMode().String()) cb(LoopMode(p.player.GetLoopMode()))
} }
return nil return nil
} }
func (p *PlaybackManager) SetLoopMode(loopMode LoopMode) error {
if err := p.player.SetLoopMode(player.LoopMode(loopMode)); err != nil {
return err
}
for _, cb := range p.onLoopModeChange {
cb(loopMode)
}
return nil
}
func (p *PlaybackManager) LoopMode() LoopMode {
return LoopMode(p.player.GetLoopMode())
}
// call BEFORE updating p.nowPlayingIdx // call BEFORE updating p.nowPlayingIdx
func (p *PlaybackManager) checkScrobble() { func (p *PlaybackManager) checkScrobble() {
if !p.scrobbleCfg.Enabled || len(p.playQueue) == 0 || p.nowPlayingIdx < 0 { if !p.scrobbleCfg.Enabled || len(p.playQueue) == 0 || p.nowPlayingIdx < 0 {
+1 -1
View File
@@ -54,7 +54,7 @@ func NewBottomPanel(p *player.Player, pm *backend.PlaybackManager, contr *contro
p.OnStopped(func() { p.OnStopped(func() {
bp.Controls.SetPlaying(false) bp.Controls.SetPlaying(false)
}) })
pm.OnLoopModeChange(func(mode string) { pm.OnLoopModeChange(func(mode backend.LoopMode) {
bp.AuxControls.SetLoopMode(mode) bp.AuxControls.SetLoopMode(mode)
}) })
+6 -4
View File
@@ -7,6 +7,7 @@ import (
"fyne.io/fyne/v2/theme" "fyne.io/fyne/v2/theme"
"fyne.io/fyne/v2/widget" "fyne.io/fyne/v2/widget"
"github.com/dweymouth/supersonic/backend"
myTheme "github.com/dweymouth/supersonic/ui/theme" myTheme "github.com/dweymouth/supersonic/ui/theme"
"github.com/dweymouth/supersonic/ui/util" "github.com/dweymouth/supersonic/ui/util"
) )
@@ -67,14 +68,15 @@ func (a *AuxControls) OnChangeLoopMode(f func()) {
a.loop.OnTapped = f a.loop.OnTapped = f
} }
func (a *AuxControls) SetLoopMode(mode string) { func (a *AuxControls) SetLoopMode(mode backend.LoopMode) {
if mode == "all" { switch mode {
case backend.LoopModeAll:
a.loop.Importance = widget.HighImportance a.loop.Importance = widget.HighImportance
a.loop.Icon = myTheme.RepeatIcon a.loop.Icon = myTheme.RepeatIcon
} else if mode == "one" { case backend.LoopModeOne:
a.loop.Importance = widget.HighImportance a.loop.Importance = widget.HighImportance
a.loop.Icon = myTheme.RepeatOneIcon a.loop.Icon = myTheme.RepeatOneIcon
} else { case backend.LoopModeNone:
a.loop.Importance = widget.MediumImportance a.loop.Importance = widget.MediumImportance
a.loop.Icon = myTheme.RepeatIcon a.loop.Icon = myTheme.RepeatIcon
} }