From efcfe2a99f84abf9610c958acdc13d27a5443669 Mon Sep 17 00:00:00 2001 From: Drew Weymouth Date: Sat, 1 Jun 2024 10:42:31 -0700 Subject: [PATCH] refactor: make ReorderItems generic --- sharedutil/sharedutil.go | 81 ++++++----------------------------- sharedutil/sharedutil_test.go | 10 ++--- ui/browsing/nowplayingpage.go | 2 +- ui/browsing/playlistpage.go | 2 +- 4 files changed, 19 insertions(+), 76 deletions(-) diff --git a/sharedutil/sharedutil.go b/sharedutil/sharedutil.go index 00bcfb7..bad0e27 100644 --- a/sharedutil/sharedutil.go +++ b/sharedutil/sharedutil.go @@ -115,67 +115,10 @@ const ( MoveDown ) -// TODO: it's a shame the below function is just duplicated for a slice of mediaprovider.MediaItem -// Find out if there's a better way with refactoring. - -// Reorder tracks and return a new track slice. +// Reorder items and return a new track slice. // idxToMove must contain only valid indexes into tracks, and no repeats -func ReorderTracks(tracks []*mediaprovider.Track, idxToMove []int, op TrackReorderOp) []*mediaprovider.Track { - newTracks := make([]*mediaprovider.Track, len(tracks)) - switch op { - case MoveToTop: - topIdx := 0 - botIdx := len(idxToMove) - idxToMoveSet := ToSet(idxToMove) - for i, t := range tracks { - if _, ok := idxToMoveSet[i]; ok { - newTracks[topIdx] = t - topIdx++ - } else { - newTracks[botIdx] = t - botIdx++ - } - } - case MoveToBottom: - topIdx := 0 - botIdx := len(tracks) - len(idxToMove) - idxToMoveSet := ToSet(idxToMove) - for i, t := range tracks { - if _, ok := idxToMoveSet[i]; ok { - 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 -} - -// Reorder media items and return a new item slice. -// idxToMove must contain only valid indexes into items, and no repeats -func ReorderMediaItems(items []mediaprovider.MediaItem, idxToMove []int, op TrackReorderOp) []mediaprovider.MediaItem { - newTracks := make([]mediaprovider.MediaItem, len(items)) +func ReorderItems[T any](items []T, idxToMove []int, op TrackReorderOp) []T { + newItems := make([]T, len(items)) switch op { case MoveToTop: topIdx := 0 @@ -183,10 +126,10 @@ func ReorderMediaItems(items []mediaprovider.MediaItem, idxToMove []int, op Trac idxToMoveSet := ToSet(idxToMove) for i, t := range items { if _, ok := idxToMoveSet[i]; ok { - newTracks[topIdx] = t + newItems[topIdx] = t topIdx++ } else { - newTracks[botIdx] = t + newItems[botIdx] = t botIdx++ } } @@ -196,34 +139,34 @@ func ReorderMediaItems(items []mediaprovider.MediaItem, idxToMove []int, op Trac idxToMoveSet := ToSet(idxToMove) for i, t := range items { if _, ok := idxToMoveSet[i]; ok { - newTracks[botIdx] = t + newItems[botIdx] = t botIdx++ } else { - newTracks[topIdx] = t + newItems[topIdx] = t topIdx++ } } case MoveUp: first := firstIdxCanMoveUp(idxToMove) - copy(newTracks, items) + copy(newItems, items) for _, i := range idxToMove { if i < first { continue } - newTracks[i-1], newTracks[i] = newTracks[i], newTracks[i-1] + newItems[i-1], newItems[i] = newItems[i], newItems[i-1] } case MoveDown: last := lastIdxCanMoveDown(idxToMove, len(items)) - copy(newTracks, items) + copy(newItems, items) 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] + newItems[idx+1], newItems[idx] = newItems[idx], newItems[idx+1] } } - return newTracks + return newItems } func firstIdxCanMoveUp(idxs []int) int { diff --git a/sharedutil/sharedutil_test.go b/sharedutil/sharedutil_test.go index 05b5312..4d395e4 100644 --- a/sharedutil/sharedutil_test.go +++ b/sharedutil/sharedutil_test.go @@ -7,7 +7,7 @@ import ( "github.com/dweymouth/supersonic/backend/mediaprovider" ) -func Test_ReorderTracks(t *testing.T) { +func Test_ReorderItems(t *testing.T) { tracks := []*mediaprovider.Track{ {ID: "a"}, // 0 {ID: "b"}, // 1 @@ -27,7 +27,7 @@ func Test_ReorderTracks(t *testing.T) { {ID: "b"}, {ID: "e"}, } - newTracks := ReorderTracks(tracks, idxToMove, MoveToTop) + newTracks := ReorderItems(tracks, idxToMove, MoveToTop) if !tracklistsEqual(t, newTracks, want) { t.Error("ReorderTracks: MoveToTop order incorrect") } @@ -42,7 +42,7 @@ func Test_ReorderTracks(t *testing.T) { {ID: "c"}, {ID: "f"}, } - newTracks = ReorderTracks(tracks, idxToMove, MoveToBottom) + newTracks = ReorderItems(tracks, idxToMove, MoveToBottom) if !tracklistsEqual(t, newTracks, want) { t.Error("ReorderTracks: MoveToBottom order incorrect") } @@ -57,7 +57,7 @@ func Test_ReorderTracks(t *testing.T) { {ID: "f"}, {ID: "e"}, } - newTracks = ReorderTracks(tracks, idxToMove, MoveUp) + newTracks = ReorderItems(tracks, idxToMove, MoveUp) if !tracklistsEqual(t, newTracks, want) { t.Error("ReorderTracks: MoveUp order incorrect") } @@ -72,7 +72,7 @@ func Test_ReorderTracks(t *testing.T) { {ID: "e"}, {ID: "f"}, } - newTracks = ReorderTracks(tracks, idxToMove, MoveDown) + newTracks = ReorderItems(tracks, idxToMove, MoveDown) if !tracklistsEqual(t, newTracks, want) { t.Error("ReorderTracks: MoveDown order incorrect") } diff --git a/ui/browsing/nowplayingpage.go b/ui/browsing/nowplayingpage.go index c0334b2..6c7401f 100644 --- a/ui/browsing/nowplayingpage.go +++ b/ui/browsing/nowplayingpage.go @@ -462,7 +462,7 @@ func (a *NowPlayingPage) doSetNewTrackOrder(trackIDs []string, op sharedutil.Tra idxs = append(idxs, i) } } - newTracks := sharedutil.ReorderMediaItems(a.queue, idxs, op) + newTracks := sharedutil.ReorderItems(a.queue, idxs, op) a.pm.UpdatePlayQueue(newTracks) } diff --git a/ui/browsing/playlistpage.go b/ui/browsing/playlistpage.go index 4044fff..c7dc245 100644 --- a/ui/browsing/playlistpage.go +++ b/ui/browsing/playlistpage.go @@ -187,7 +187,7 @@ func (a *PlaylistPage) doSetNewTrackOrder(op sharedutil.TrackReorderOp) { idxs = append(idxs, i) } } - newTracks := sharedutil.ReorderTracks(a.tracks, idxs, op) + newTracks := sharedutil.ReorderItems(a.tracks, idxs, op) ids := sharedutil.TracksToIDs(newTracks) if err := a.sm.Server.ReplacePlaylistTracks(a.playlistID, ids); err != nil { log.Printf("error updating playlist: %s", err.Error())