add reorder tracks options to playlist page context menu
This commit is contained in:
+101
-1
@@ -1,6 +1,11 @@
|
||||
package sharedutil
|
||||
|
||||
import "github.com/dweymouth/go-subsonic/subsonic"
|
||||
import (
|
||||
"math"
|
||||
"sort"
|
||||
|
||||
"github.com/dweymouth/go-subsonic/subsonic"
|
||||
)
|
||||
|
||||
func StringSliceContains(slice []string, str string) bool {
|
||||
for _, s := range slice {
|
||||
@@ -11,6 +16,15 @@ func StringSliceContains(slice []string, str string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func IntSliceContains(slice []int, i int) bool {
|
||||
for _, x := range slice {
|
||||
if x == i {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func FindTrackByID(id string, tracks []*subsonic.Child) *subsonic.Child {
|
||||
for _, tr := range tracks {
|
||||
if id == tr.ID {
|
||||
@@ -26,3 +40,89 @@ func TrackIDOrEmptyStr(track *subsonic.Child) string {
|
||||
}
|
||||
return track.ID
|
||||
}
|
||||
|
||||
type TrackReorderOp int
|
||||
|
||||
const (
|
||||
MoveToTop TrackReorderOp = iota
|
||||
MoveToBottom
|
||||
MoveUp
|
||||
MoveDown
|
||||
)
|
||||
|
||||
// Reorder tracks and return a new track slice.
|
||||
// idxToMove must contain only valid indexes into tracks, and no repeats
|
||||
func ReorderTracks(tracks []*subsonic.Child, idxToMove []int, op TrackReorderOp) []*subsonic.Child {
|
||||
newTracks := make([]*subsonic.Child, len(tracks))
|
||||
switch op {
|
||||
case MoveToTop:
|
||||
topIdx := 0
|
||||
botIdx := len(idxToMove)
|
||||
for i, t := range tracks {
|
||||
if IntSliceContains(idxToMove, i) {
|
||||
newTracks[topIdx] = t
|
||||
topIdx++
|
||||
} else {
|
||||
newTracks[botIdx] = t
|
||||
botIdx++
|
||||
}
|
||||
}
|
||||
case MoveToBottom:
|
||||
topIdx := 0
|
||||
botIdx := len(tracks) - len(idxToMove)
|
||||
for i, t := range tracks {
|
||||
if IntSliceContains(idxToMove, i) {
|
||||
newTracks[botIdx] = t
|
||||
botIdx++
|
||||
} else {
|
||||
newTracks[topIdx] = t
|
||||
topIdx++
|
||||
}
|
||||
}
|
||||
case MoveUp:
|
||||
first := firstIdxCanMoveUp(idxToMove)
|
||||
copy(newTracks, tracks)
|
||||
for _, i := range idxToMove {
|
||||
if i < first {
|
||||
continue
|
||||
}
|
||||
newTracks[i-1], newTracks[i] = newTracks[i], newTracks[i-1]
|
||||
}
|
||||
case MoveDown:
|
||||
last := lastIdxCanMoveDown(idxToMove, len(tracks))
|
||||
copy(newTracks, tracks)
|
||||
for i := len(idxToMove) - 1; i >= 0; i-- {
|
||||
idx := idxToMove[i]
|
||||
if idx > last {
|
||||
continue
|
||||
}
|
||||
newTracks[idx+1], newTracks[idx] = newTracks[idx], newTracks[idx+1]
|
||||
}
|
||||
}
|
||||
return newTracks
|
||||
}
|
||||
|
||||
func firstIdxCanMoveUp(idxs []int) int {
|
||||
prevIdx := -1
|
||||
sort.Ints(idxs)
|
||||
for _, idx := range idxs {
|
||||
if idx > prevIdx+1 {
|
||||
return idx
|
||||
}
|
||||
prevIdx = idx
|
||||
}
|
||||
return math.MaxInt
|
||||
}
|
||||
|
||||
func lastIdxCanMoveDown(idxs []int, lenSlice int) int {
|
||||
prevIdx := lenSlice
|
||||
sort.Ints(idxs)
|
||||
for i := len(idxs) - 1; i >= 0; i-- {
|
||||
idx := idxs[i]
|
||||
if idx < prevIdx-1 {
|
||||
return idx
|
||||
}
|
||||
prevIdx = idx
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user