Files
supersonic/sharedutil/sharedutil.go
T

139 lines
2.5 KiB
Go

package sharedutil
import (
"math"
"sort"
"github.com/dweymouth/go-subsonic/subsonic"
)
func StringSliceContains(slice []string, str string) bool {
for _, s := range slice {
if s == str {
return true
}
}
return false
}
func IntSliceContains(slice []int, i int) bool {
for _, x := range slice {
if x == i {
return true
}
}
return false
}
func FilterSlice[T any](ss []T, test func(T) bool) []T {
result := make([]T, 0)
for _, s := range ss {
if test(s) {
result = append(result, s)
}
}
return result
}
func FindTrackByID(id string, tracks []*subsonic.Child) *subsonic.Child {
for _, tr := range tracks {
if id == tr.ID {
return tr
}
}
return nil
}
func TrackIDOrEmptyStr(track *subsonic.Child) string {
if track == nil {
return ""
}
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
}