diff options
author | Simon Garrelou <simon.garrelou@gmail.com> | 2022-12-09 15:39:14 +0100 |
---|---|---|
committer | Simon Garrelou <simon.garrelou@gmail.com> | 2022-12-09 15:39:14 +0100 |
commit | 67d60877df816196e51b868e76f091261a2d08da (patch) | |
tree | 9595451d851fab7aa40f24f73cd672bf4711c9dd | |
parent | 9d1d1a02fde0a1561ad6a61e551a144bbeadc45b (diff) | |
download | termsonic-67d60877df816196e51b868e76f091261a2d08da.tar.gz termsonic-67d60877df816196e51b868e76f091261a2d08da.zip |
Move songs in queue
-rw-r--r-- | music/playqueue.go | 59 | ||||
-rw-r--r-- | src/footer.go | 4 | ||||
-rw-r--r-- | src/keybinds.go | 39 |
3 files changed, 91 insertions, 11 deletions
diff --git a/music/playqueue.go b/music/playqueue.go index fe82c4e..7c21b9b 100644 --- a/music/playqueue.go +++ b/music/playqueue.go | |||
@@ -81,9 +81,7 @@ func (q *Queue) PlaySong(s *subsonic.Child) error { | |||
81 | speaker.Clear() | 81 | speaker.Clear() |
82 | speaker.Play(beep.Seq(streamer, beep.Callback(func() { go q.Next() }))) | 82 | speaker.Play(beep.Seq(streamer, beep.Callback(func() { go q.Next() }))) |
83 | 83 | ||
84 | if q.onChange != nil { | 84 | q.triggerChange() |
85 | q.onChange(s, false) | ||
86 | } | ||
87 | 85 | ||
88 | return nil | 86 | return nil |
89 | } | 87 | } |
@@ -135,11 +133,7 @@ func (q *Queue) TogglePause() { | |||
135 | 133 | ||
136 | q.isPaused = !q.isPaused | 134 | q.isPaused = !q.isPaused |
137 | 135 | ||
138 | if q.onChange != nil { | 136 | q.triggerChange() |
139 | if len(q.songs) > 0 { | ||
140 | q.onChange(q.songs[0], q.isPaused) | ||
141 | } | ||
142 | } | ||
143 | } | 137 | } |
144 | 138 | ||
145 | func (q *Queue) SkipTo(s *subsonic.Child) { | 139 | func (q *Queue) SkipTo(s *subsonic.Child) { |
@@ -159,6 +153,55 @@ func (q *Queue) SkipTo(s *subsonic.Child) { | |||
159 | q.Play() | 153 | q.Play() |
160 | } | 154 | } |
161 | 155 | ||
156 | func (q *Queue) RemoveSong(i int) error { | ||
157 | if i >= len(q.songs) { | ||
158 | return fmt.Errorf("index out of bounds") | ||
159 | } | ||
160 | |||
161 | q.songs = append(q.songs[:i], q.songs[i+1:]...) | ||
162 | if i == 0 { | ||
163 | // We removed the first song: this stops it and prepares for the next | ||
164 | q.Stop() | ||
165 | if !q.isPaused { | ||
166 | q.Play() | ||
167 | } | ||
168 | } | ||
169 | q.triggerChange() | ||
170 | |||
171 | return nil | ||
172 | } | ||
173 | |||
174 | func (q *Queue) Switch(a, b int) error { | ||
175 | if a >= len(q.songs) { | ||
176 | return fmt.Errorf("%d is out of bounds", a) | ||
177 | } | ||
178 | |||
179 | if b >= len(q.songs) { | ||
180 | return fmt.Errorf("%d is out of bounds", b) | ||
181 | } | ||
182 | |||
183 | tmp := q.songs[a] | ||
184 | q.songs[a] = q.songs[b] | ||
185 | q.songs[b] = tmp | ||
186 | |||
187 | if (a == 0 || b == 0) && !q.isPaused { | ||
188 | // If we're switching the first song, and it's currently playing, start Play() again | ||
189 | q.Play() | ||
190 | } | ||
191 | |||
192 | q.triggerChange() | ||
193 | |||
194 | return nil | ||
195 | } | ||
196 | |||
197 | func (q *Queue) triggerChange() { | ||
198 | if q.onChange != nil { | ||
199 | if len(q.songs) > 0 { | ||
200 | q.onChange(q.songs[0], q.isPaused) | ||
201 | } | ||
202 | } | ||
203 | } | ||
204 | |||
162 | func (p *Queue) setupSpeaker(s beep.Streamer, format beep.Format) (beep.Streamer, error) { | 205 | func (p *Queue) setupSpeaker(s beep.Streamer, format beep.Format) (beep.Streamer, error) { |
163 | if !p.speakerInitialized { | 206 | if !p.speakerInitialized { |
164 | err := speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/10)) | 207 | err := speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/10)) |
diff --git a/src/footer.go b/src/footer.go index 7240b0f..1db1843 100644 --- a/src/footer.go +++ b/src/footer.go | |||
@@ -3,9 +3,9 @@ package src | |||
3 | func (a *app) updateFooter() { | 3 | func (a *app) updateFooter() { |
4 | switch a.headerSections.GetHighlights()[0] { | 4 | switch a.headerSections.GetHighlights()[0] { |
5 | case "artists": | 5 | case "artists": |
6 | a.footer.SetText("[blue]l:[yellow] Next song [blue]k:[yellow] Toggle pause") | 6 | a.footer.SetText("[blue]l:[yellow] Next song [blue]p:[yellow] Toggle pause") |
7 | case "playqueue": | 7 | case "playqueue": |
8 | a.footer.SetText("[blue]l:[yellow] Next song [blue]k:[yellow] Toggle pause") | 8 | a.footer.SetText("[blue]l:[yellow] Next song [blue]p:[yellow] Toggle pause [blue]d:[yellow] Remove [blue]j:[yellow] Move up [blue]k:[yellow] Move down") |
9 | case "playlists": | 9 | case "playlists": |
10 | a.footer.SetText("Come back later!") | 10 | a.footer.SetText("Come back later!") |
11 | case "config": | 11 | case "config": |
diff --git a/src/keybinds.go b/src/keybinds.go index d69be0b..2a9c16b 100644 --- a/src/keybinds.go +++ b/src/keybinds.go | |||
@@ -13,10 +13,47 @@ func (a *app) setupMusicControlKeys(p *tview.Box) { | |||
13 | return nil | 13 | return nil |
14 | } | 14 | } |
15 | 15 | ||
16 | if event.Rune() == 'k' { | 16 | if event.Rune() == 'p' { |
17 | a.playQueue.TogglePause() | 17 | a.playQueue.TogglePause() |
18 | return nil | 18 | return nil |
19 | } | 19 | } |
20 | |||
21 | if a.tv.GetFocus() == a.playQueueList { | ||
22 | if event.Rune() == 'd' { | ||
23 | sel := a.playQueueList.GetCurrentItem() | ||
24 | err := a.playQueue.RemoveSong(sel) | ||
25 | if err != nil { | ||
26 | a.alert("Error: %v", err) | ||
27 | } | ||
28 | } else if event.Rune() == 'k' { | ||
29 | sel := a.playQueueList.GetCurrentItem() | ||
30 | if sel == a.playQueueList.GetItemCount()-1 { | ||
31 | return nil | ||
32 | } | ||
33 | err := a.playQueue.Switch(sel, sel+1) | ||
34 | if err != nil { | ||
35 | a.alert("Error: %v", err) | ||
36 | } | ||
37 | |||
38 | a.playQueueList.SetCurrentItem(sel + 1) | ||
39 | |||
40 | return nil | ||
41 | } else if event.Rune() == 'j' { | ||
42 | sel := a.playQueueList.GetCurrentItem() | ||
43 | if sel == 0 { | ||
44 | return nil | ||
45 | } | ||
46 | err := a.playQueue.Switch(sel, sel-1) | ||
47 | if err != nil { | ||
48 | a.alert("Error: %v", err) | ||
49 | } | ||
50 | |||
51 | a.playQueueList.SetCurrentItem(sel - 1) | ||
52 | |||
53 | return nil | ||
54 | } | ||
55 | } | ||
56 | |||
20 | return event | 57 | return event |
21 | }) | 58 | }) |
22 | } | 59 | } |