expose repeat mode through MPRIS
This commit is contained in:
@@ -17,6 +17,7 @@ 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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
@@ -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)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user