misc: Upgrade Go to v1.21
Upgrade to 1.21 as 1.20 is now unmaintained. Most changes are related to the new `slices` package from standard library, which can replace some existing custom functions.
This commit is contained in:
@@ -24,7 +24,7 @@ jobs:
|
|||||||
- name: Set up Go
|
- name: Set up Go
|
||||||
uses: actions/setup-go@v4
|
uses: actions/setup-go@v4
|
||||||
with:
|
with:
|
||||||
go-version: '1.20'
|
go-version: '1.21'
|
||||||
|
|
||||||
- name: Install Dependencies
|
- name: Install Dependencies
|
||||||
run: brew install --force mpv && brew install dylibbundler
|
run: brew install --force mpv && brew install dylibbundler
|
||||||
@@ -60,4 +60,4 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
name: Supersonic_mac_x64_HighSierra+.zip
|
name: Supersonic_mac_x64_HighSierra+.zip
|
||||||
path: Supersonic_HighSierra+.zip
|
path: Supersonic_HighSierra+.zip
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ jobs:
|
|||||||
- name: Set up Go
|
- name: Set up Go
|
||||||
uses: actions/setup-go@v4
|
uses: actions/setup-go@v4
|
||||||
with:
|
with:
|
||||||
go-version: '1.20'
|
go-version: '1.21'
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: sudo apt update && sudo apt install libmpv-dev gcc libegl1-mesa-dev xorg-dev
|
run: sudo apt update && sudo apt install libmpv-dev gcc libegl1-mesa-dev xorg-dev
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ jobs:
|
|||||||
- name: Set up Go
|
- name: Set up Go
|
||||||
uses: actions/setup-go@v4
|
uses: actions/setup-go@v4
|
||||||
with:
|
with:
|
||||||
go-version: '1.20'
|
go-version: '1.21'
|
||||||
|
|
||||||
- name: Install Dependencies
|
- name: Install Dependencies
|
||||||
run: >
|
run: >
|
||||||
|
|||||||
+2
-2
@@ -8,12 +8,12 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"slices"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/dweymouth/supersonic/backend/player"
|
"github.com/dweymouth/supersonic/backend/player"
|
||||||
"github.com/dweymouth/supersonic/backend/player/mpv"
|
"github.com/dweymouth/supersonic/backend/player/mpv"
|
||||||
"github.com/dweymouth/supersonic/backend/util"
|
"github.com/dweymouth/supersonic/backend/util"
|
||||||
"github.com/dweymouth/supersonic/sharedutil"
|
|
||||||
"github.com/fsnotify/fsnotify"
|
"github.com/fsnotify/fsnotify"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
|
||||||
@@ -233,7 +233,7 @@ func (a *App) setupMPV() error {
|
|||||||
a.LocalPlayer.SetAudioDevice(desiredDevice)
|
a.LocalPlayer.SetAudioDevice(desiredDevice)
|
||||||
|
|
||||||
rgainOpts := []string{ReplayGainNone, ReplayGainAlbum, ReplayGainTrack, ReplayGainAuto}
|
rgainOpts := []string{ReplayGainNone, ReplayGainAlbum, ReplayGainTrack, ReplayGainAuto}
|
||||||
if !sharedutil.SliceContains(rgainOpts, a.Config.ReplayGain.Mode) {
|
if !slices.Contains(rgainOpts, a.Config.ReplayGain.Mode) {
|
||||||
a.Config.ReplayGain.Mode = ReplayGainNone
|
a.Config.ReplayGain.Mode = ReplayGainNone
|
||||||
}
|
}
|
||||||
mode := player.ReplayGainNone
|
mode := player.ReplayGainNone
|
||||||
|
|||||||
@@ -64,9 +64,7 @@ func (r *baseIter[T]) Next() *T {
|
|||||||
}
|
}
|
||||||
r.serverPos += len(items)
|
r.serverPos += len(items)
|
||||||
if !r.filter.IsNil() {
|
if !r.filter.IsNil() {
|
||||||
items = sharedutil.FilterSlice(items, func(al *T) bool {
|
items = sharedutil.FilterSlice(items, r.filter.Matches)
|
||||||
return r.filter.Matches(al)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
r.prefetched = items
|
r.prefetched = items
|
||||||
if len(items) > 0 {
|
if len(items) > 0 {
|
||||||
|
|||||||
@@ -5,15 +5,6 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Return a slice of range [0, n)
|
|
||||||
func Range(n int) []int {
|
|
||||||
s := make([]int, n)
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
s[i] = i
|
|
||||||
}
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
func CopyFile(srcPath, dstPath string) error {
|
func CopyFile(srcPath, dstPath string) error {
|
||||||
fin, err := os.Open(srcPath)
|
fin, err := os.Open(srcPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
module github.com/dweymouth/supersonic
|
module github.com/dweymouth/supersonic
|
||||||
|
|
||||||
go 1.20
|
go 1.21
|
||||||
|
|
||||||
require (
|
require (
|
||||||
fyne.io/fyne/v2 v2.4.4
|
fyne.io/fyne/v2 v2.4.4
|
||||||
|
|||||||
@@ -110,6 +110,7 @@ github.com/go-text/render v0.0.0-20230619120952-35bccb6164b8/go.mod h1:h29xCucjN
|
|||||||
github.com/go-text/typesetting v0.1.0 h1:vioSaLPYcHwPEPLT7gsjCGDCoYSbljxoHJzMnKwVvHw=
|
github.com/go-text/typesetting v0.1.0 h1:vioSaLPYcHwPEPLT7gsjCGDCoYSbljxoHJzMnKwVvHw=
|
||||||
github.com/go-text/typesetting v0.1.0/go.mod h1:d22AnmeKq/on0HNv73UFriMKc4Ez6EqZAofLhAzpSzI=
|
github.com/go-text/typesetting v0.1.0/go.mod h1:d22AnmeKq/on0HNv73UFriMKc4Ez6EqZAofLhAzpSzI=
|
||||||
github.com/go-text/typesetting-utils v0.0.0-20231211103740-d9332ae51f04 h1:zBx+p/W2aQYtNuyZNcTfinWvXBQwYtDfme051PR/lAY=
|
github.com/go-text/typesetting-utils v0.0.0-20231211103740-d9332ae51f04 h1:zBx+p/W2aQYtNuyZNcTfinWvXBQwYtDfme051PR/lAY=
|
||||||
|
github.com/go-text/typesetting-utils v0.0.0-20231211103740-d9332ae51f04/go.mod h1:DDxDdQEnB70R8owOx3LVpEFvpMK9eeH1o2r0yZhFI9o=
|
||||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||||
github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||||
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
|
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
|
||||||
|
|||||||
@@ -2,32 +2,11 @@ package sharedutil
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"math"
|
"math"
|
||||||
"sort"
|
"slices"
|
||||||
|
|
||||||
"github.com/dweymouth/supersonic/backend/mediaprovider"
|
"github.com/dweymouth/supersonic/backend/mediaprovider"
|
||||||
)
|
)
|
||||||
|
|
||||||
func SliceEqual[T comparable](a []T, b []T) bool {
|
|
||||||
if len(a) != len(b) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
for i := 0; i < len(a); i++ {
|
|
||||||
if a[i] != b[i] {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func SliceContains[T comparable](ts []T, t T) bool {
|
|
||||||
for _, x := range ts {
|
|
||||||
if x == t {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func FilterSlice[T any](ss []T, test func(T) bool) []T {
|
func FilterSlice[T any](ss []T, test func(T) bool) []T {
|
||||||
if ss == nil {
|
if ss == nil {
|
||||||
return nil
|
return nil
|
||||||
@@ -52,19 +31,6 @@ func MapSlice[T any, U any](ts []T, f func(T) U) []U {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func Find[T any](ts []T, f func(T) bool) int {
|
|
||||||
for i, tt := range ts {
|
|
||||||
if f(tt) {
|
|
||||||
return i
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
|
|
||||||
func IndexOf[T comparable](ts []T, t T) int {
|
|
||||||
return Find(ts, func(tt T) bool { return t == tt })
|
|
||||||
}
|
|
||||||
|
|
||||||
func Reversed[T any](ts []T) []T {
|
func Reversed[T any](ts []T) []T {
|
||||||
if ts == nil {
|
if ts == nil {
|
||||||
return nil
|
return nil
|
||||||
@@ -133,7 +99,7 @@ func ReorderTracks(tracks []*mediaprovider.Track, idxToMove []int, op TrackReord
|
|||||||
topIdx := 0
|
topIdx := 0
|
||||||
botIdx := len(idxToMove)
|
botIdx := len(idxToMove)
|
||||||
for i, t := range tracks {
|
for i, t := range tracks {
|
||||||
if SliceContains(idxToMove, i) {
|
if slices.Contains(idxToMove, i) {
|
||||||
newTracks[topIdx] = t
|
newTracks[topIdx] = t
|
||||||
topIdx++
|
topIdx++
|
||||||
} else {
|
} else {
|
||||||
@@ -145,7 +111,7 @@ func ReorderTracks(tracks []*mediaprovider.Track, idxToMove []int, op TrackReord
|
|||||||
topIdx := 0
|
topIdx := 0
|
||||||
botIdx := len(tracks) - len(idxToMove)
|
botIdx := len(tracks) - len(idxToMove)
|
||||||
for i, t := range tracks {
|
for i, t := range tracks {
|
||||||
if SliceContains(idxToMove, i) {
|
if slices.Contains(idxToMove, i) {
|
||||||
newTracks[botIdx] = t
|
newTracks[botIdx] = t
|
||||||
botIdx++
|
botIdx++
|
||||||
} else {
|
} else {
|
||||||
@@ -178,7 +144,7 @@ func ReorderTracks(tracks []*mediaprovider.Track, idxToMove []int, op TrackReord
|
|||||||
|
|
||||||
func firstIdxCanMoveUp(idxs []int) int {
|
func firstIdxCanMoveUp(idxs []int) int {
|
||||||
prevIdx := -1
|
prevIdx := -1
|
||||||
sort.Ints(idxs)
|
slices.Sort(idxs)
|
||||||
for _, idx := range idxs {
|
for _, idx := range idxs {
|
||||||
if idx > prevIdx+1 {
|
if idx > prevIdx+1 {
|
||||||
return idx
|
return idx
|
||||||
@@ -190,7 +156,7 @@ func firstIdxCanMoveUp(idxs []int) int {
|
|||||||
|
|
||||||
func lastIdxCanMoveDown(idxs []int, lenSlice int) int {
|
func lastIdxCanMoveDown(idxs []int, lenSlice int) int {
|
||||||
prevIdx := lenSlice
|
prevIdx := lenSlice
|
||||||
sort.Ints(idxs)
|
slices.Sort(idxs)
|
||||||
for i := len(idxs) - 1; i >= 0; i-- {
|
for i := len(idxs) - 1; i >= 0; i-- {
|
||||||
idx := idxs[i]
|
idx := idxs[i]
|
||||||
if idx < prevIdx-1 {
|
if idx < prevIdx-1 {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package sharedutil
|
package sharedutil
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"slices"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/dweymouth/supersonic/backend/mediaprovider"
|
"github.com/dweymouth/supersonic/backend/mediaprovider"
|
||||||
@@ -79,13 +80,7 @@ func Test_ReorderTracks(t *testing.T) {
|
|||||||
|
|
||||||
func tracklistsEqual(t *testing.T, a, b []*mediaprovider.Track) bool {
|
func tracklistsEqual(t *testing.T, a, b []*mediaprovider.Track) bool {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
if len(a) != len(b) {
|
return slices.EqualFunc(a, b, func(a, b *mediaprovider.Track) bool {
|
||||||
return false
|
return a.ID == b.ID
|
||||||
}
|
})
|
||||||
for i, _ := range a {
|
|
||||||
if a[i].ID != b[i].ID {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
package browsing
|
package browsing
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"slices"
|
||||||
|
|
||||||
"fyne.io/fyne/v2"
|
"fyne.io/fyne/v2"
|
||||||
"fyne.io/fyne/v2/widget"
|
"fyne.io/fyne/v2/widget"
|
||||||
"github.com/dweymouth/supersonic/backend"
|
"github.com/dweymouth/supersonic/backend"
|
||||||
"github.com/dweymouth/supersonic/backend/mediaprovider"
|
"github.com/dweymouth/supersonic/backend/mediaprovider"
|
||||||
"github.com/dweymouth/supersonic/sharedutil"
|
|
||||||
"github.com/dweymouth/supersonic/ui/controller"
|
"github.com/dweymouth/supersonic/ui/controller"
|
||||||
myTheme "github.com/dweymouth/supersonic/ui/theme"
|
myTheme "github.com/dweymouth/supersonic/ui/theme"
|
||||||
"github.com/dweymouth/supersonic/ui/util"
|
"github.com/dweymouth/supersonic/ui/util"
|
||||||
@@ -37,7 +38,7 @@ func (a *albumsPageAdapter) Route() controller.Route { return controller.AlbumsR
|
|||||||
func (a *albumsPageAdapter) SortOrders() ([]string, string) {
|
func (a *albumsPageAdapter) SortOrders() ([]string, string) {
|
||||||
orders := a.mp.AlbumSortOrders()
|
orders := a.mp.AlbumSortOrders()
|
||||||
sortOrder := a.cfg.SortOrder
|
sortOrder := a.cfg.SortOrder
|
||||||
if !sharedutil.SliceContains(orders, sortOrder) {
|
if !slices.Contains(orders, sortOrder) {
|
||||||
sortOrder = string(orders[0])
|
sortOrder = string(orders[0])
|
||||||
}
|
}
|
||||||
return orders, sortOrder
|
return orders, sortOrder
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"image"
|
"image"
|
||||||
"log"
|
"log"
|
||||||
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/dweymouth/supersonic/backend"
|
"github.com/dweymouth/supersonic/backend"
|
||||||
@@ -106,13 +107,13 @@ func NewNowPlayingPage(
|
|||||||
}
|
}
|
||||||
a.queueList.OnSetRating = func(trackIDs []string, rating int) {
|
a.queueList.OnSetRating = func(trackIDs []string, rating int) {
|
||||||
contr.SetTrackRatings(trackIDs, rating)
|
contr.SetTrackRatings(trackIDs, rating)
|
||||||
if sharedutil.SliceContains(trackIDs, a.nowPlayingID) {
|
if slices.Contains(trackIDs, a.nowPlayingID) {
|
||||||
a.card.SetDisplayedRating(rating)
|
a.card.SetDisplayedRating(rating)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
a.queueList.OnSetFavorite = func(trackIDs []string, fav bool) {
|
a.queueList.OnSetFavorite = func(trackIDs []string, fav bool) {
|
||||||
contr.SetTrackFavorites(trackIDs, fav)
|
contr.SetTrackFavorites(trackIDs, fav)
|
||||||
if sharedutil.SliceContains(trackIDs, a.nowPlayingID) {
|
if slices.Contains(trackIDs, a.nowPlayingID) {
|
||||||
a.card.SetDisplayedFavorite(fav)
|
a.card.SetDisplayedFavorite(fav)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -232,7 +233,7 @@ func (a *NowPlayingPage) Tapped(*fyne.PointEvent) {
|
|||||||
func (a *NowPlayingPage) doSetNewTrackOrder(trackIDs []string, op sharedutil.TrackReorderOp) {
|
func (a *NowPlayingPage) doSetNewTrackOrder(trackIDs []string, op sharedutil.TrackReorderOp) {
|
||||||
idxs := make([]int, 0, len(trackIDs))
|
idxs := make([]int, 0, len(trackIDs))
|
||||||
for i, tr := range a.queue {
|
for i, tr := range a.queue {
|
||||||
if sharedutil.SliceContains(trackIDs, tr.ID) {
|
if slices.Contains(trackIDs, tr.ID) {
|
||||||
idxs = append(idxs, i)
|
idxs = append(idxs, i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package browsing
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
"slices"
|
||||||
|
|
||||||
"github.com/dweymouth/supersonic/backend"
|
"github.com/dweymouth/supersonic/backend"
|
||||||
"github.com/dweymouth/supersonic/backend/mediaprovider"
|
"github.com/dweymouth/supersonic/backend/mediaprovider"
|
||||||
@@ -183,7 +184,7 @@ func (a *PlaylistPage) doSetNewTrackOrder(op sharedutil.TrackReorderOp) {
|
|||||||
ids := a.tracklist.SelectedTrackIDs()
|
ids := a.tracklist.SelectedTrackIDs()
|
||||||
idxs := make([]int, 0, len(ids))
|
idxs := make([]int, 0, len(ids))
|
||||||
for i, tr := range a.tracks {
|
for i, tr := range a.tracks {
|
||||||
if sharedutil.SliceContains(ids, tr.ID) {
|
if slices.Contains(ids, tr.ID) {
|
||||||
idxs = append(idxs, i)
|
idxs = append(idxs, i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-5
@@ -4,15 +4,15 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"image/color"
|
"image/color"
|
||||||
"io/ioutil"
|
|
||||||
"log"
|
"log"
|
||||||
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/dweymouth/supersonic/backend"
|
"github.com/dweymouth/supersonic/backend"
|
||||||
"github.com/dweymouth/supersonic/res"
|
"github.com/dweymouth/supersonic/res"
|
||||||
"github.com/dweymouth/supersonic/sharedutil"
|
|
||||||
|
|
||||||
"fyne.io/fyne/v2"
|
"fyne.io/fyne/v2"
|
||||||
"fyne.io/fyne/v2/theme"
|
"fyne.io/fyne/v2/theme"
|
||||||
@@ -200,7 +200,7 @@ func (m *MyTheme) Font(style fyne.TextStyle) fyne.Resource {
|
|||||||
}
|
}
|
||||||
case fyne.TextStyle{Bold: true}:
|
case fyne.TextStyle{Bold: true}:
|
||||||
if m.BoldFont != "" && boldFont == nil {
|
if m.BoldFont != "" && boldFont == nil {
|
||||||
if content, err := ioutil.ReadFile(m.BoldFont); err != nil {
|
if content, err := os.ReadFile(m.BoldFont); err != nil {
|
||||||
m.BoldFont = ""
|
m.BoldFont = ""
|
||||||
} else {
|
} else {
|
||||||
normalFont = fyne.NewStaticResource("boldFont", content)
|
normalFont = fyne.NewStaticResource("boldFont", content)
|
||||||
@@ -222,7 +222,7 @@ func (m *MyTheme) Size(name fyne.ThemeSizeName) float32 {
|
|||||||
|
|
||||||
func (m *MyTheme) getVariant() fyne.ThemeVariant {
|
func (m *MyTheme) getVariant() fyne.ThemeVariant {
|
||||||
v := DefaultAppearance // default if config has invalid or missing setting
|
v := DefaultAppearance // default if config has invalid or missing setting
|
||||||
if sharedutil.SliceContains(
|
if slices.Contains(
|
||||||
[]string{string(AppearanceLight), string(AppearanceDark), string(AppearanceAuto)},
|
[]string{string(AppearanceLight), string(AppearanceDark), string(AppearanceAuto)},
|
||||||
m.config.Appearance) {
|
m.config.Appearance) {
|
||||||
v = AppearanceMode(m.config.Appearance)
|
v = AppearanceMode(m.config.Appearance)
|
||||||
@@ -242,7 +242,7 @@ func readTTFFile(filepath string) ([]byte, error) {
|
|||||||
log.Printf("error loading custom font %q: %s", filepath, err.Error())
|
log.Printf("error loading custom font %q: %s", filepath, err.Error())
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
content, err := ioutil.ReadFile(filepath)
|
content, err := os.ReadFile(filepath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("error loading custom font %q: %s", filepath, err.Error())
|
log.Printf("error loading custom font %q: %s", filepath, err.Error())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,11 +7,11 @@ import (
|
|||||||
"image/color"
|
"image/color"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"fyne.io/fyne/v2"
|
"fyne.io/fyne/v2"
|
||||||
"fyne.io/fyne/v2/theme"
|
"fyne.io/fyne/v2/theme"
|
||||||
"github.com/dweymouth/supersonic/sharedutil"
|
|
||||||
"github.com/pelletier/go-toml/v2"
|
"github.com/pelletier/go-toml/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -109,7 +109,7 @@ func DecodeThemeFile(reader io.Reader) (*ThemeFile, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if theme.SupersonicTheme.Name == "" || !sharedutil.SliceContains(validThemeVersions, theme.SupersonicTheme.Version) {
|
if theme.SupersonicTheme.Name == "" || !slices.Contains(validThemeVersions, theme.SupersonicTheme.Version) {
|
||||||
return nil, errors.New("invalid theme file name or version")
|
return nil, errors.New("invalid theme file name or version")
|
||||||
}
|
}
|
||||||
if !(theme.SupersonicTheme.SupportsDark || theme.SupersonicTheme.SupportsLight) {
|
if !(theme.SupersonicTheme.SupportsDark || theme.SupersonicTheme.SupportsLight) {
|
||||||
@@ -129,7 +129,7 @@ func (t *ThemeFile) SupportsVariant(v fyne.ThemeVariant) bool {
|
|||||||
|
|
||||||
// Parses a CSS-style #RRGGBB or #RRGGBBAA string
|
// Parses a CSS-style #RRGGBB or #RRGGBBAA string
|
||||||
func ColorStringToColor(colorStr string) (color.Color, error) {
|
func ColorStringToColor(colorStr string) (color.Color, error) {
|
||||||
if !strings.HasPrefix(colorStr, "#") || !sharedutil.SliceContains([]int{7, 9}, len(colorStr)) {
|
if !strings.HasPrefix(colorStr, "#") || !slices.Contains([]int{7, 9}, len(colorStr)) {
|
||||||
return color.Black, errors.New("invalid color string")
|
return color.Black, errors.New("invalid color string")
|
||||||
}
|
}
|
||||||
colorBytes := make([]byte, 4)
|
colorBytes := make([]byte, 4)
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package util
|
package util
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"slices"
|
||||||
|
|
||||||
"github.com/dweymouth/supersonic/backend/mediaprovider"
|
"github.com/dweymouth/supersonic/backend/mediaprovider"
|
||||||
"github.com/dweymouth/supersonic/sharedutil"
|
"github.com/dweymouth/supersonic/sharedutil"
|
||||||
)
|
)
|
||||||
@@ -69,15 +71,15 @@ func SelectTrackRange(tracks []*TrackListModel, idx int) {
|
|||||||
tracks[idx].Selected = true
|
tracks[idx].Selected = true
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
from := minInt(idx, lastSelected)
|
from := min(idx, lastSelected)
|
||||||
to := maxInt(idx, lastSelected)
|
to := max(idx, lastSelected)
|
||||||
for i := from; i <= to; i++ {
|
for i := from; i <= to; i++ {
|
||||||
tracks[i].Selected = true
|
tracks[i].Selected = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func FindTrackByID(tracks []*TrackListModel, id string) (*mediaprovider.Track, int) {
|
func FindTrackByID(tracks []*TrackListModel, id string) (*mediaprovider.Track, int) {
|
||||||
idx := sharedutil.Find(tracks, func(tr *TrackListModel) bool {
|
idx := slices.IndexFunc(tracks, func(tr *TrackListModel) bool {
|
||||||
return tr.Track.ID == id
|
return tr.Track.ID == id
|
||||||
})
|
})
|
||||||
if idx >= 0 {
|
if idx >= 0 {
|
||||||
@@ -85,17 +87,3 @@ func FindTrackByID(tracks []*TrackListModel, id string) (*mediaprovider.Track, i
|
|||||||
}
|
}
|
||||||
return nil, -1
|
return nil, -1
|
||||||
}
|
}
|
||||||
|
|
||||||
func minInt(a, b int) int {
|
|
||||||
if a < b {
|
|
||||||
return a
|
|
||||||
}
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
func maxInt(a, b int) int {
|
|
||||||
if a > b {
|
|
||||||
return a
|
|
||||||
}
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package widgets
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"sort"
|
"slices"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
@@ -49,7 +49,7 @@ func NewAlbumFilterButton(filter *mediaprovider.AlbumFilter, fetchGenresFunc fun
|
|||||||
genreNames := sharedutil.MapSlice(genres, func(g *mediaprovider.Genre) string {
|
genreNames := sharedutil.MapSlice(genres, func(g *mediaprovider.Genre) string {
|
||||||
return g.Name
|
return g.Name
|
||||||
})
|
})
|
||||||
sort.Strings(genreNames)
|
slices.Sort(genreNames)
|
||||||
a.genreListChan <- genreNames
|
a.genreListChan <- genreNames
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ package widgets
|
|||||||
import (
|
import (
|
||||||
"image"
|
"image"
|
||||||
"image/color"
|
"image/color"
|
||||||
|
"slices"
|
||||||
|
|
||||||
"github.com/dweymouth/supersonic/res"
|
"github.com/dweymouth/supersonic/res"
|
||||||
"github.com/dweymouth/supersonic/sharedutil"
|
|
||||||
"github.com/dweymouth/supersonic/ui/layouts"
|
"github.com/dweymouth/supersonic/ui/layouts"
|
||||||
"github.com/dweymouth/supersonic/ui/util"
|
"github.com/dweymouth/supersonic/ui/util"
|
||||||
|
|
||||||
@@ -205,7 +205,7 @@ func (g *GridViewItem) createContainer() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (g *GridViewItem) NeedsUpdate(model GridViewItemModel) bool {
|
func (g *GridViewItem) NeedsUpdate(model GridViewItemModel) bool {
|
||||||
return g.itemID != model.ID || !sharedutil.SliceEqual(g.secondaryIDs, model.SecondaryIDs)
|
return g.itemID != model.ID || !slices.Equal(g.secondaryIDs, model.SecondaryIDs)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GridViewItem) Update(model GridViewItemModel) {
|
func (g *GridViewItem) Update(model GridViewItemModel) {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package widgets
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
"slices"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -271,7 +272,7 @@ func (t *Tracklist) Sorting() TracklistSort {
|
|||||||
func (t *Tracklist) SetSorting(sorting TracklistSort) {
|
func (t *Tracklist) SetSorting(sorting TracklistSort) {
|
||||||
if sorting.ColumnName == "" {
|
if sorting.ColumnName == "" {
|
||||||
// nil case - reset current sort
|
// nil case - reset current sort
|
||||||
if sharedutil.SliceContains(columns, t.sorting.ColumnName) {
|
if slices.Contains(columns, t.sorting.ColumnName) {
|
||||||
t.hdr.SetSorting(ListHeaderSort{ColNumber: ColNumber(t.sorting.ColumnName), Type: SortNone})
|
t.hdr.SetSorting(ListHeaderSort{ColNumber: ColNumber(t.sorting.ColumnName), Type: SortNone})
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
@@ -667,7 +668,7 @@ func (t *Tracklist) lenTracks() int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ColNumber(colName string) int {
|
func ColNumber(colName string) int {
|
||||||
i := sharedutil.IndexOf(columns, colName)
|
i := slices.Index(columns, colName)
|
||||||
if i < 0 {
|
if i < 0 {
|
||||||
log.Printf("error: Tracklist: invalid column name %s", colName)
|
log.Printf("error: Tracklist: invalid column name %s", colName)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user