playlist timer pause/resume without affecting active feeds

This commit is contained in:
Dmitry Sergeev
2026-09-01 22:32:19 +03:00
parent b0e7bc4cc3
commit ca25bf88a7
11 changed files with 371 additions and 28 deletions
+26
View File
@@ -753,6 +753,21 @@ func main() {
if cimgui.Button("Next##playlist") && !playlistRuntime.Next() {
log.Print("playlist command queue is full")
}
if hasPlaylistSnapshot &&
playlistSnapshot.State.HasSelection &&
playlistSnapshot.Entry.Duration > 0 &&
!playlistSnapshot.Timing.Expired {
cimgui.SameLine()
if playlistSnapshot.Timing.Paused {
if cimgui.Button("Resume timer##playlist") &&
!playlistRuntime.Resume() {
log.Print("playlist command queue is full")
}
} else if cimgui.Button("Pause timer##playlist") &&
!playlistRuntime.Pause() {
log.Print("playlist command queue is full")
}
}
if hasPlaylistSnapshot && playlistSnapshot.State.HasSelection {
entry := playlistSnapshot.Entry
@@ -786,6 +801,17 @@ func main() {
switch {
case entry.Duration == 0:
cimgui.Text("Timing: manual advance")
case playlistSnapshot.Timing.Paused:
fraction, remaining := playlistTimingProgress(
playlistSnapshot.Timing,
time.Now(),
)
cimgui.Text("Timing: paused")
cimgui.ProgressBarV(
fraction,
cimgui.Vec2{X: -1, Y: 0},
remaining.Round(time.Second).String(),
)
case playlistSnapshot.Timing.Started:
fraction, remaining := playlistTimingProgress(
playlistSnapshot.Timing,
+14 -3
View File
@@ -111,6 +111,14 @@ func (p *playerPlaylist) Previous() bool {
return p.enqueue(playback.PlaylistCommand{Kind: playback.PlaylistPrevious})
}
func (p *playerPlaylist) Pause() bool {
return p.enqueue(playback.PlaylistCommand{Kind: playback.PlaylistPause})
}
func (p *playerPlaylist) Resume() bool {
return p.enqueue(playback.PlaylistCommand{Kind: playback.PlaylistResume})
}
func (p *playerPlaylist) enqueue(command playback.PlaylistCommand) bool {
select {
case p.Commands <- command:
@@ -154,11 +162,14 @@ func playlistTimingProgress(
if timing.Expired {
return 1, 0
}
if !timing.Started {
remaining := timing.Remaining
if timing.Paused {
// Retain the remaining time captured when the owned timer stopped.
} else if !timing.Started {
return 0, timing.Duration
} else {
remaining = timing.Deadline.Sub(now)
}
remaining := timing.Deadline.Sub(now)
if remaining < 0 {
remaining = 0
}
+15 -1
View File
@@ -3,6 +3,7 @@ package main
import (
"context"
"errors"
"math"
"testing"
"time"
@@ -127,6 +128,8 @@ func TestPlayerPlaylistNavigationHelpers(t *testing.T) {
{send: func() bool { return runtime.Select(4) }, want: playback.PlaylistCommand{Kind: playback.PlaylistSelect, Index: 4}},
{send: runtime.Next, want: playback.PlaylistCommand{Kind: playback.PlaylistNext}},
{send: runtime.Previous, want: playback.PlaylistCommand{Kind: playback.PlaylistPrevious}},
{send: runtime.Pause, want: playback.PlaylistCommand{Kind: playback.PlaylistPause}},
{send: runtime.Resume, want: playback.PlaylistCommand{Kind: playback.PlaylistResume}},
}
for _, test := range tests {
if !test.send() {
@@ -344,6 +347,16 @@ func TestPlaylistTimingProgress(t *testing.T) {
timing: playback.PlaylistTimingState{Duration: 10 * time.Second, Expired: true},
wantFraction: 1,
},
{
name: "paused",
timing: playback.PlaylistTimingState{
Duration: 10 * time.Second,
Paused: true,
Remaining: 6 * time.Second,
},
wantFraction: 0.4,
wantRemaining: 6 * time.Second,
},
{
name: "deadline passed",
timing: playback.PlaylistTimingState{
@@ -358,7 +371,8 @@ func TestPlaylistTimingProgress(t *testing.T) {
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
fraction, remaining := playlistTimingProgress(test.timing, now)
if fraction != test.wantFraction || remaining != test.wantRemaining {
if math.Abs(float64(fraction-test.wantFraction)) > 0.000001 ||
remaining != test.wantRemaining {
t.Fatalf(
"playlistTimingProgress() = %v, %v; want %v, %v",
fraction,