add autoplay UI toggle

This commit is contained in:
Drew Weymouth
2025-01-06 18:34:35 -08:00
parent 834d024735
commit 966e792f6f
10 changed files with 51 additions and 4 deletions
+1
View File
@@ -361,6 +361,7 @@ func (a *App) Shutdown() {
repeatMode = "All" repeatMode = "All"
} }
a.Config.Playback.RepeatMode = repeatMode a.Config.Playback.RepeatMode = repeatMode
a.Config.Playback.Autoplay = a.PlaybackManager.IsAutoplay()
a.Config.LocalPlayback.Volume = a.LocalPlayer.GetVolume() a.Config.LocalPlayback.Volume = a.LocalPlayer.GetVolume()
a.SavePlayQueueIfEnabled() a.SavePlayQueueIfEnabled()
a.SaveConfigFile() a.SaveConfigFile()
+2
View File
@@ -99,6 +99,7 @@ type NowPlayingPageConfig struct {
} }
type PlaybackConfig struct { type PlaybackConfig struct {
Autoplay bool
RepeatMode string RepeatMode string
} }
@@ -215,6 +216,7 @@ func DefaultConfig(appVersionTag string) *Config {
TracklistColumns: []string{"Album", "Time", "Plays"}, TracklistColumns: []string{"Album", "Time", "Plays"},
}, },
Playback: PlaybackConfig{ Playback: PlaybackConfig{
Autoplay: false,
RepeatMode: "None", RepeatMode: "None",
}, },
LocalPlayback: LocalPlaybackConfig{ LocalPlayback: LocalPlaybackConfig{
+12 -1
View File
@@ -42,7 +42,7 @@ func NewPlaybackManager(
engine: e, engine: e,
cmdQueue: q, cmdQueue: q,
cfg: appCfg, cfg: appCfg,
autoplay: true, // TODO autoplay: playbackCfg.Autoplay,
} }
pm.addOnTrackChangeHook() pm.addOnTrackChangeHook()
go pm.runCmdQueue(ctx) go pm.runCmdQueue(ctx)
@@ -364,6 +364,10 @@ func (p *PlaybackManager) GetLoopMode() LoopMode {
return p.engine.loopMode return p.engine.loopMode
} }
func (p *PlaybackManager) IsAutoplay() bool {
return p.autoplay
}
func (p *PlaybackManager) PlayerStatus() player.Status { func (p *PlaybackManager) PlayerStatus() player.Status {
return p.engine.PlayerStatus() return p.engine.PlayerStatus()
} }
@@ -372,6 +376,13 @@ func (p *PlaybackManager) SetVolume(vol int) {
p.cmdQueue.SetVolume(vol) p.cmdQueue.SetVolume(vol)
} }
func (p *PlaybackManager) SetAutoplay(autoplay bool) {
p.autoplay = autoplay
if autoplay && p.NowPlayingIndex() == len(p.engine.playQueue)-1 {
p.enqueueAutoplayTracks()
}
}
func (p *PlaybackManager) Volume() int { func (p *PlaybackManager) Volume() int {
return p.engine.CurrentPlayer().GetVolume() return p.engine.CurrentPlayer().GetVolume()
} }
+5
View File
@@ -40,6 +40,11 @@ var ResHeartOutlineSvg = &fyne.StaticResource{
StaticContent: []byte( StaticContent: []byte(
"<?xml version=\"1.0\" encoding=\"utf-8\"?><svg xmlns=\"http://www.w3.org/2000/svg\" height=\"16\" width=\"16\" viewBox=\"0 0 512 512\"><!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2023 Fonticons, Inc.--><path d=\"M225.8 468.2l-2.5-2.3L48.1 303.2C17.4 274.7 0 234.7 0 192.8v-3.3c0-70.4 50-130.8 119.2-144C158.6 37.9 198.9 47 231 69.6c9 6.4 17.4 13.8 25 22.3c4.2-4.8 8.7-9.2 13.5-13.3c3.7-3.2 7.5-6.2 11.5-9c0 0 0 0 0 0C313.1 47 353.4 37.9 392.8 45.4C462 58.6 512 119.1 512 189.5v3.3c0 41.9-17.4 81.9-48.1 110.4L288.7 465.9l-2.5 2.3c-8.2 7.6-19 11.9-30.2 11.9s-22-4.2-30.2-11.9zM239.1 145c-.4-.3-.7-.7-1-1.1l-17.8-20c0 0-.1-.1-.1-.1c0 0 0 0 0 0c-23.1-25.9-58-37.7-92-31.2C81.6 101.5 48 142.1 48 189.5v3.3c0 28.5 11.9 55.8 32.8 75.2L256 430.7 431.2 268c20.9-19.4 32.8-46.7 32.8-75.2v-3.3c0-47.3-33.6-88-80.1-96.9c-34-6.5-69 5.4-92 31.2c0 0 0 0-.1 .1s0 0-.1 .1l-17.8 20c-.3 .4-.7 .7-1 1.1c-4.5 4.5-10.6 7-16.9 7s-12.4-2.5-16.9-7z\"/></svg>"), "<?xml version=\"1.0\" encoding=\"utf-8\"?><svg xmlns=\"http://www.w3.org/2000/svg\" height=\"16\" width=\"16\" viewBox=\"0 0 512 512\"><!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2023 Fonticons, Inc.--><path d=\"M225.8 468.2l-2.5-2.3L48.1 303.2C17.4 274.7 0 234.7 0 192.8v-3.3c0-70.4 50-130.8 119.2-144C158.6 37.9 198.9 47 231 69.6c9 6.4 17.4 13.8 25 22.3c4.2-4.8 8.7-9.2 13.5-13.3c3.7-3.2 7.5-6.2 11.5-9c0 0 0 0 0 0C313.1 47 353.4 37.9 392.8 45.4C462 58.6 512 119.1 512 189.5v3.3c0 41.9-17.4 81.9-48.1 110.4L288.7 465.9l-2.5 2.3c-8.2 7.6-19 11.9-30.2 11.9s-22-4.2-30.2-11.9zM239.1 145c-.4-.3-.7-.7-1-1.1l-17.8-20c0 0-.1-.1-.1-.1c0 0 0 0 0 0c-23.1-25.9-58-37.7-92-31.2C81.6 101.5 48 142.1 48 189.5v3.3c0 28.5 11.9 55.8 32.8 75.2L256 430.7 431.2 268c20.9-19.4 32.8-46.7 32.8-75.2v-3.3c0-47.3-33.6-88-80.1-96.9c-34-6.5-69 5.4-92 31.2c0 0 0 0-.1 .1s0 0-.1 .1l-17.8 20c-.3 .4-.7 .7-1 1.1c-4.5 4.5-10.6 7-16.9 7s-12.4-2.5-16.9-7z\"/></svg>"),
} }
var ResInfinitySvg = &fyne.StaticResource{
StaticName: "infinity.svg",
StaticContent: []byte(
"<?xml version=\"1.0\" encoding=\"utf-8\"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->\n<svg fill=\"#000000\" width=\"800px\" height=\"800px\" viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path fill-rule=\"evenodd\" d=\"M13.8953301,9.49438552 C13.5245249,8.8053229 13.1631795,8.23232447 12.787113,7.76330109 C12.9146953,7.63245274 13.0230614,7.52301032 13.0881226,7.46104725 C14.1672616,6.43329581 15.2308059,6 17,6 C20.2160271,6 23,8.59837471 23,12 C23,15.4016253 20.2160271,18 17,18 C14.1474839,18 12.9356928,16.5161742 11.0880785,12.4103647 C9.56069278,9.0161742 8.73081718,8 7,8 C4.74909152,8 3,9.86806378 3,12 C3,14.1411158 4.73495862,16 7,16 C8.04331411,16 9.29028192,15.5849395 10.3793264,14.9973112 C10.7662435,15.6627411 11.149328,16.202911 11.5567767,16.631918 C10.1542402,17.4308849 8.51106941,18 7,18 C3.59837471,18 1,15.2160271 1,12 C1,8.79183891 3.61403375,6 7,6 C9.85251615,6 11.0643072,7.4838258 12.9119215,11.5896353 C14.4393072,14.9838258 15.2691828,16 17,16 C19.1411158,16 21,14.2650414 21,12 C21,9.73495862 19.1411158,8 17,8 C15.7489921,8 15.177938,8.23265169 14.467433,8.90932312 C14.3735045,8.99877883 14.1397256,9.24036553 13.8953301,9.49438552 Z\"/>\n</svg>"),
}
var ResMusicnotesSvg = &fyne.StaticResource{ var ResMusicnotesSvg = &fyne.StaticResource{
StaticName: "musicnotes.svg", StaticName: "musicnotes.svg",
StaticContent: []byte( StaticContent: []byte(
+1
View File
@@ -7,6 +7,7 @@ fyne bundle -append -prefix Res icons/publicdomain/disc.svg >> bundled.go
fyne bundle -append -prefix Res icons/publicdomain/headphones.svg >> bundled.go fyne bundle -append -prefix Res icons/publicdomain/headphones.svg >> bundled.go
fyne bundle -append -prefix Res icons/publicdomain/heart-filled.svg >> bundled.go fyne bundle -append -prefix Res icons/publicdomain/heart-filled.svg >> bundled.go
fyne bundle -append -prefix Res icons/publicdomain/heart-outline.svg >> bundled.go fyne bundle -append -prefix Res icons/publicdomain/heart-outline.svg >> bundled.go
fyne bundle -append -prefix Res icons/publicdomain/infinity.svg >> bundled.go
fyne bundle -append -prefix Res icons/publicdomain/musicnotes.svg >> bundled.go fyne bundle -append -prefix Res icons/publicdomain/musicnotes.svg >> bundled.go
fyne bundle -append -prefix Res icons/publicdomain/people.svg >> bundled.go fyne bundle -append -prefix Res icons/publicdomain/people.svg >> bundled.go
fyne bundle -append -prefix Res icons/publicdomain/playlist.svg >> bundled.go fyne bundle -append -prefix Res icons/publicdomain/playlist.svg >> bundled.go
+1
View File
@@ -28,6 +28,7 @@
"Audiobook": "Audiobook", "Audiobook": "Audiobook",
"Authentication failed": "Authentication failed", "Authentication failed": "Authentication failed",
"Auto": "Auto", "Auto": "Auto",
"Autoplay": "Autoplay",
"Autoselect device": "Autoselect device", "Autoselect device": "Autoselect device",
"Back": "Back", "Back": "Back",
"Bit rate": "Bit rate", "Bit rate": "Bit rate",
+4 -1
View File
@@ -102,7 +102,7 @@ func NewBottomPanel(pm *backend.PlaybackManager, im *backend.ImageManager, contr
pm.SeekFraction(f) pm.SeekFraction(f)
}) })
bp.AuxControls = widgets.NewAuxControls(pm.Volume(), pm.GetLoopMode()) bp.AuxControls = widgets.NewAuxControls(pm.Volume(), pm.GetLoopMode(), pm.IsAutoplay())
pm.OnLoopModeChange(bp.AuxControls.SetLoopMode) pm.OnLoopModeChange(bp.AuxControls.SetLoopMode)
pm.OnVolumeChange(bp.AuxControls.VolumeControl.SetVolume) pm.OnVolumeChange(bp.AuxControls.VolumeControl.SetVolume)
bp.AuxControls.VolumeControl.OnSetVolume = func(v int) { bp.AuxControls.VolumeControl.OnSetVolume = func(v int) {
@@ -111,6 +111,9 @@ func NewBottomPanel(pm *backend.PlaybackManager, im *backend.ImageManager, contr
bp.AuxControls.OnChangeLoopMode(func() { bp.AuxControls.OnChangeLoopMode(func() {
pm.SetNextLoopMode() pm.SetNextLoopMode()
}) })
bp.AuxControls.OnChangeAutoplay = func(autoplay bool) {
pm.SetAutoplay(autoplay)
}
bp.AuxControls.OnShowPlayQueue(contr.ShowPopUpPlayQueue) bp.AuxControls.OnShowPlayQueue(contr.ShowPopUpPlayQueue)
bp.imageLoader = util.NewThumbnailLoader(im, bp.NowPlaying.SetImage) bp.imageLoader = util.NewThumbnailLoader(im, bp.NowPlaying.SetImage)
+1
View File
@@ -160,6 +160,7 @@ func NewMainWindow(fyneApp fyne.App, appName, displayAppName, appVersion string,
repeatMode = "All" repeatMode = "All"
} }
app.Config.Playback.RepeatMode = repeatMode app.Config.Playback.RepeatMode = repeatMode
app.Config.Playback.Autoplay = app.PlaybackManager.IsAutoplay()
app.SavePlayQueueIfEnabled() app.SavePlayQueueIfEnabled()
app.SaveConfigFile() app.SaveConfigFile()
+1
View File
@@ -38,6 +38,7 @@ var (
AlbumIcon fyne.Resource = theme.NewThemedResource(res.ResDiscSvg) AlbumIcon fyne.Resource = theme.NewThemedResource(res.ResDiscSvg)
ArtistIcon fyne.Resource = theme.NewThemedResource(res.ResPeopleSvg) ArtistIcon fyne.Resource = theme.NewThemedResource(res.ResPeopleSvg)
AutoplayIcon fyne.Resource = theme.NewThemedResource(res.ResInfinitySvg)
RadioIcon fyne.Resource = theme.NewThemedResource(res.ResBroadcastSvg) RadioIcon fyne.Resource = theme.NewThemedResource(res.ResBroadcastSvg)
FavoriteIcon fyne.Resource = theme.NewThemedResource(res.ResHeartFilledSvg) FavoriteIcon fyne.Resource = theme.NewThemedResource(res.ResHeartFilledSvg)
NotFavoriteIcon fyne.Resource = theme.NewThemedResource(res.ResHeartOutlineSvg) NotFavoriteIcon fyne.Resource = theme.NewThemedResource(res.ResHeartOutlineSvg)
+23 -2
View File
@@ -18,21 +18,34 @@ import (
type AuxControls struct { type AuxControls struct {
widget.BaseWidget widget.BaseWidget
OnChangeAutoplay func(autoplay bool)
VolumeControl *VolumeControl VolumeControl *VolumeControl
autoplay *IconButton
loop *IconButton loop *IconButton
showQueue *IconButton showQueue *IconButton
container *fyne.Container container *fyne.Container
} }
func NewAuxControls(initialVolume int, initialLoopMode backend.LoopMode) *AuxControls { func NewAuxControls(initialVolume int, initialLoopMode backend.LoopMode, initialAutoplay bool) *AuxControls {
a := &AuxControls{ a := &AuxControls{
VolumeControl: NewVolumeControl(initialVolume), VolumeControl: NewVolumeControl(initialVolume),
autoplay: NewIconButton(myTheme.AutoplayIcon, nil),
loop: NewIconButton(myTheme.RepeatIcon, nil), loop: NewIconButton(myTheme.RepeatIcon, nil),
showQueue: NewIconButton(myTheme.PlayQueueIcon, nil), showQueue: NewIconButton(myTheme.PlayQueueIcon, nil),
} }
a.loop.IconSize = IconButtonSizeSmaller a.loop.IconSize = IconButtonSizeSmaller
a.loop.SetToolTip(lang.L("Repeat")) a.loop.SetToolTip(lang.L("Repeat"))
a.loop.Highlighted = initialAutoplay
//a.autoplay.IconSize = IconButtonSizeSmaller
a.autoplay.SetToolTip(lang.L("Autoplay"))
a.autoplay.OnTapped = func() {
a.SetAutoplay(!a.autoplay.Highlighted)
if a.OnChangeAutoplay != nil {
a.OnChangeAutoplay(a.autoplay.Highlighted)
}
}
a.SetLoopMode(initialLoopMode) a.SetLoopMode(initialLoopMode)
a.showQueue.IconSize = IconButtonSizeSmaller a.showQueue.IconSize = IconButtonSizeSmaller
a.showQueue.SetToolTip(lang.L("Show play queue")) a.showQueue.SetToolTip(lang.L("Show play queue"))
@@ -43,7 +56,7 @@ func NewAuxControls(initialVolume int, initialLoopMode backend.LoopMode) *AuxCon
a.VolumeControl, a.VolumeControl,
container.New( container.New(
layout.NewCustomPaddedHBoxLayout(theme.Padding()*1.5), layout.NewCustomPaddedHBoxLayout(theme.Padding()*1.5),
layout.NewSpacer(), a.loop, a.showQueue, util.NewHSpace(5)), layout.NewSpacer(), a.autoplay, a.loop, a.showQueue, util.NewHSpace(5)),
layout.NewSpacer(), layout.NewSpacer(),
), ),
) )
@@ -73,6 +86,14 @@ func (a *AuxControls) SetLoopMode(mode backend.LoopMode) {
} }
} }
func (a *AuxControls) SetAutoplay(autoplay bool) {
if autoplay == a.autoplay.Highlighted {
return
}
a.autoplay.Highlighted = autoplay
a.autoplay.Refresh()
}
func (a *AuxControls) OnShowPlayQueue(f func()) { func (a *AuxControls) OnShowPlayQueue(f func()) {
a.showQueue.OnTapped = f a.showQueue.OnTapped = f
} }