Skip to content

Commit

Permalink
Merge remote-tracking branch 'xxxserxxx/reorder-queue' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
spezifisch committed Sep 19, 2024
2 parents f738818 + 4757a39 commit 0f2ecdc
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 5 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,10 @@ These controls are accessible from any view:
- `d`/`Delete`: Remove currently selected song from the queue
- `D`: Remove all songs from queue
- `y`: Toggle star on song
- `k`: Move song up in queue
- `j`: Move song down in queue

If the currently playing song is moved, the music is stopped before the move, and must be re-started manually.

### Playlist Controls

Expand Down
3 changes: 3 additions & 0 deletions help_text.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ const helpPageQueue = `
d/DEL remove currently selected song from the queue
D remove all songs from queue
y toggle star on song
k move selected song up in queue
j move selected song down in queue
S shuffle the current queue
`

const helpPagePlaylists = `
Expand Down
34 changes: 34 additions & 0 deletions mpvplayer/player.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package mpvplayer

import (
"errors"
"math/rand"
"strconv"

"github.com/spezifisch/stmps/logger"
Expand Down Expand Up @@ -283,6 +284,39 @@ func (p *Player) AddToQueue(item *QueueItem) {
p.queue = append(p.queue, *item)
}

func (p *Player) MoveSongUp(index int) {
if index < 1 {
p.logger.Printf("MoveSongUp(%d) can't move top item", index)
return
}
if index >= len(p.queue) {
p.logger.Printf("MoveSongUp(%d) not that many songs in queue", index)
return
}
p.queue[index-1], p.queue[index] = p.queue[index], p.queue[index-1]
}

func (p *Player) MoveSongDown(index int) {
if index < 0 {
p.logger.Printf("MoveSongUp(%d) invalid index", index)
return
}
if index >= len(p.queue)-1 {
p.logger.Printf("MoveSongUp(%d) can't move last song down", index)
return
}
p.queue[index], p.queue[index+1] = p.queue[index+1], p.queue[index]
}

func (p *Player) Shuffle() {
max := len(p.queue)
for range max / 2 {
ra := rand.Intn(max)
rb := rand.Intn(max)
p.queue[ra], p.queue[rb] = p.queue[rb], p.queue[ra]
}
}

func (p *Player) GetQueueItem(index int) (QueueItem, error) {
if index < 0 || index >= len(p.queue) {
return QueueItem{}, errors.New("invalid queue entry")
Expand Down
89 changes: 84 additions & 5 deletions page_queue.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,22 @@ func (ui *Ui) createQueuePage() *QueuePage {
queuePage.queueList.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
if event.Key() == tcell.KeyDelete || event.Rune() == 'd' {
queuePage.handleDeleteFromQueue()
return nil
} else if event.Rune() == 'y' {
queuePage.handleToggleStar()
return nil
} else {
switch event.Rune() {
case 'y':
queuePage.handleToggleStar()
case 'j':
queuePage.moveSongDown()
case 'k':
queuePage.moveSongUp()
case 'S':
queuePage.shuffle()
default:
return event
}
}

return event
return nil
})

// flex wrapper
Expand Down Expand Up @@ -151,6 +160,76 @@ func (q *QueuePage) updateQueue() {
}
}

// moveSongUp moves the currently selected song up in the queue
// If the selected song isn't the third or higher, this is a NOP
// and no error is reported.
func (q *QueuePage) moveSongUp() {
if len(q.queueData.playerQueue) == 0 {
return
}

currentIndex, column := q.queueList.GetSelection()
if currentIndex < 0 || column < 0 {
q.logger.Printf("moveSongUp: invalid selection (%d, %d)", currentIndex, column)
return
}

if currentIndex == 0 {
return
}

if currentIndex == 1 {
q.ui.player.Stop()
}

// remove the item from the queue
q.ui.player.MoveSongUp(currentIndex)
q.queueList.Select(currentIndex-1, column)
q.updateQueue()
}

// moveSongUp moves the currently selected song up in the queue
// If the selected song is not the second-to-the-last or lower, this is a NOP,
// and no error is reported
func (q *QueuePage) moveSongDown() {
queueLen := len(q.queueData.playerQueue)
if queueLen == 0 {
return
}

currentIndex, column := q.queueList.GetSelection()
if currentIndex < 0 || column < 0 {
q.logger.Printf("moveSongDown: invalid selection (%d, %d)", currentIndex, column)
return
}

if currentIndex == 0 {
q.ui.player.Stop()
}

if currentIndex > queueLen-2 {
q.logger.Printf("moveSongDown: can't move last song")
return
}

// remove the item from the queue
q.ui.player.MoveSongDown(currentIndex)
q.queueList.Select(currentIndex+1, column)
q.updateQueue()
}

func (q *QueuePage) shuffle() {
if len(q.queueData.playerQueue) == 0 {
return
}

q.ui.player.Stop()
q.ui.player.Shuffle()

q.queueList.Select(0, 0)
q.updateQueue()
}

// queueData methods, used by tview to lazily render the table
func (q *queueData) GetCell(row, column int) *tview.TableCell {
if row >= len(q.playerQueue) || column >= queueDataColumns || row < 0 || column < 0 {
Expand Down

0 comments on commit 0f2ecdc

Please sign in to comment.