Skip to content

Commit

Permalink
Fix #496: Persist repeat mode setting across restarts
Browse files Browse the repository at this point in the history
  • Loading branch information
dweymouth committed Jan 1, 2025
1 parent 16d8cb4 commit 6572e74
Show file tree
Hide file tree
Showing 8 changed files with 46 additions and 8 deletions.
10 changes: 9 additions & 1 deletion backend/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ func StartupApp(appName, displayAppName, appVersion, appVersionTag, latestReleas
}

a.ServerManager = NewServerManager(appName, appVersion, a.Config, !portableMode /*use keyring*/)
a.PlaybackManager = NewPlaybackManager(a.bgrndCtx, a.ServerManager, a.LocalPlayer, &a.Config.Scrobbling, &a.Config.Transcoding, &a.Config.Application)
a.PlaybackManager = NewPlaybackManager(a.bgrndCtx, a.ServerManager, a.LocalPlayer, &a.Config.Playback, &a.Config.Scrobbling, &a.Config.Transcoding, &a.Config.Application)
a.ImageManager = NewImageManager(a.bgrndCtx, a.ServerManager, cacheDir)
a.Config.Application.MaxImageCacheSizeMB = clamp(a.Config.Application.MaxImageCacheSizeMB, 1, 500)
a.ImageManager.SetMaxOnDiskCacheSizeBytes(int64(a.Config.Application.MaxImageCacheSizeMB) * 1_048_576)
Expand Down Expand Up @@ -336,6 +336,14 @@ func (a *App) DeleteServerCacheDir(serverID uuid.UUID) error {
}

func (a *App) Shutdown() {
repeatMode := "None"
switch a.PlaybackManager.GetLoopMode() {
case LoopOne:
repeatMode = "One"
case LoopAll:
repeatMode = "All"
}
a.Config.Playback.RepeatMode = repeatMode
a.Config.LocalPlayback.Volume = a.LocalPlayer.GetVolume()
a.SavePlayQueueIfEnabled()
a.SaveConfigFile()
Expand Down
8 changes: 8 additions & 0 deletions backend/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,10 @@ type NowPlayingPageConfig struct {
InitialView string
}

type PlaybackConfig struct {
RepeatMode string
}

type LocalPlaybackConfig struct {
AudioDeviceName string
AudioExclusive bool
Expand Down Expand Up @@ -146,6 +150,7 @@ type Config struct {
PlaylistsPage PlaylistsPageConfig
TracksPage TracksPageConfig
NowPlayingConfig NowPlayingPageConfig
Playback PlaybackConfig
LocalPlayback LocalPlaybackConfig
Scrobbling ScrobbleConfig
ReplayGain ReplayGainConfig
Expand Down Expand Up @@ -209,6 +214,9 @@ func DefaultConfig(appVersionTag string) *Config {
TracksPage: TracksPageConfig{
TracklistColumns: []string{"Album", "Time", "Plays"},
},
Playback: PlaybackConfig{
RepeatMode: "None",
},
LocalPlayback: LocalPlaybackConfig{
// "auto" is the name to pass to MPV for autoselecting the output device
AudioDeviceName: "auto",
Expand Down
7 changes: 7 additions & 0 deletions backend/playbackengine.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ func NewPlaybackEngine(
ctx context.Context,
s *ServerManager,
p player.BasePlayer,
playbackCfg *PlaybackConfig,
scrobbleCfg *ScrobbleConfig,
transcodeCfg *TranscodingConfig,
) *playbackEngine {
Expand All @@ -92,6 +93,12 @@ func NewPlaybackEngine(
nowPlayingIdx: -1,
wasStopped: true,
}
switch playbackCfg.RepeatMode {
case "All":
pm.loopMode = LoopAll
case "One":
pm.loopMode = LoopOne
}
p.OnTrackChange(pm.handleOnTrackChange)
p.OnSeek(func() {
pm.doUpdateTimePos(true)
Expand Down
3 changes: 2 additions & 1 deletion backend/playbackmanager.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,12 @@ func NewPlaybackManager(
ctx context.Context,
s *ServerManager,
p player.BasePlayer,
playbackCfg *PlaybackConfig,
scrobbleCfg *ScrobbleConfig,
transcodeCfg *TranscodingConfig,
appCfg *AppConfig,
) *PlaybackManager {
e := NewPlaybackEngine(ctx, s, p, scrobbleCfg, transcodeCfg)
e := NewPlaybackEngine(ctx, s, p, playbackCfg, scrobbleCfg, transcodeCfg)
q := NewCommandQueue()
pm := &PlaybackManager{
engine: e,
Expand Down
2 changes: 1 addition & 1 deletion ui/bottompanel.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ func NewBottomPanel(pm *backend.PlaybackManager, im *backend.ImageManager, contr
pm.SeekFraction(f)
})

bp.AuxControls = widgets.NewAuxControls(pm.Volume())
bp.AuxControls = widgets.NewAuxControls(pm.Volume(), pm.GetLoopMode())
pm.OnLoopModeChange(bp.AuxControls.SetLoopMode)
pm.OnVolumeChange(bp.AuxControls.VolumeControl.SetVolume)
bp.AuxControls.VolumeControl.OnSetVolume = func(v int) {
Expand Down
8 changes: 8 additions & 0 deletions ui/mainwindow.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,14 @@ func NewMainWindow(fyneApp fyne.App, appName, displayAppName, appVersion string,
// TODO: when all shutdowns exit cleanly, remove these lines
// as they are already executed in app.Shutdown()
app.Config.LocalPlayback.Volume = app.LocalPlayer.GetVolume()
repeatMode := "None"
switch app.PlaybackManager.GetLoopMode() {
case backend.LoopOne:
repeatMode = "One"
case backend.LoopAll:
repeatMode = "All"
}
app.Config.Playback.RepeatMode = repeatMode
app.SavePlayQueueIfEnabled()
app.SaveConfigFile()

Expand Down
3 changes: 2 additions & 1 deletion ui/widgets/auxcontrols.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,15 @@ type AuxControls struct {
container *fyne.Container
}

func NewAuxControls(initialVolume int) *AuxControls {
func NewAuxControls(initialVolume int, initialLoopMode backend.LoopMode) *AuxControls {
a := &AuxControls{
VolumeControl: NewVolumeControl(initialVolume),
loop: NewIconButton(myTheme.RepeatIcon, nil),
showQueue: NewIconButton(myTheme.PlayQueueIcon, nil),
}
a.loop.IconSize = IconButtonSizeSmaller
a.loop.SetToolTip(lang.L("Repeat"))
a.SetLoopMode(initialLoopMode)
a.showQueue.IconSize = IconButtonSizeSmaller
a.showQueue.SetToolTip(lang.L("Show play queue"))
a.container = container.NewHBox(
Expand Down
13 changes: 9 additions & 4 deletions ui/widgets/iconbutton.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,17 +120,21 @@ func (i *IconButton) iconSize() fyne.Size {
}
}

func (i *IconButton) Refresh() {
if i.img == nil {
return
}
func (i *IconButton) updateColor() {
if i.Highlighted || i.focused {
i.themed.ColorName = theme.ColorNamePrimary
} else if i.hovered {
i.themed.ColorName = myTheme.ColorNameHoveredIconButton
} else {
i.themed.ColorName = myTheme.ColorNameIconButton
}
}

func (i *IconButton) Refresh() {
if i.img == nil {
return
}
i.updateColor()
i.img.SetMinSize(i.iconSize())
i.img.Refresh()
}
Expand All @@ -141,6 +145,7 @@ func (i *IconButton) CreateRenderer() fyne.WidgetRenderer {
i.img = canvas.NewImageFromResource(i.themed)
i.img.FillMode = canvas.ImageFillContain
i.img.SetMinSize(i.iconSize())
i.updateColor()
}
return widget.NewSimpleRenderer(container.NewCenter(i.img))
}

0 comments on commit 6572e74

Please sign in to comment.