Merge branch 'dweymouth:main' into main
This commit is contained in:
+2
-1
@@ -148,7 +148,8 @@ func StartupApp(appName, displayAppName, appVersion, appVersionTag, latestReleas
|
||||
_, _ = a.ImageManager.GetCoverThumbnail(coverID)
|
||||
})
|
||||
if a.Config.Application.EnableLrcLib {
|
||||
a.LrcLibFetcher = NewLrcLibFetcher(a.cacheDir, a.Config.Application.CustomLrcLibUrl)
|
||||
timeout := time.Duration(a.Config.Application.RequestTimeoutSeconds) * time.Second
|
||||
a.LrcLibFetcher = NewLrcLibFetcher(a.cacheDir, a.Config.Application.CustomLrcLibUrl, timeout)
|
||||
}
|
||||
|
||||
a.PlaybackManager.OnPlaying(func() {
|
||||
|
||||
+2
-1
@@ -54,8 +54,8 @@ type AppConfig struct {
|
||||
Language string
|
||||
DisableDPIDetection bool
|
||||
EnableAutoUpdateChecker bool
|
||||
RequestTimeoutSeconds int
|
||||
|
||||
// Experimental - may be removed in future
|
||||
FontNormalTTF string
|
||||
FontBoldTTF string
|
||||
UIScaleSize string
|
||||
@@ -191,6 +191,7 @@ func DefaultConfig(appVersionTag string) *Config {
|
||||
EnqueueBatchSize: 100,
|
||||
Language: "auto",
|
||||
EnableAutoUpdateChecker: true,
|
||||
RequestTimeoutSeconds: 15,
|
||||
},
|
||||
AlbumPage: AlbumPageConfig{
|
||||
TracklistColumns: []string{"Artist", "Time", "Plays", "Favorite", "Rating"},
|
||||
|
||||
+4
-3
@@ -26,12 +26,13 @@ const lrclibCacheFolder = "lrclib"
|
||||
type LrcLibFetcher struct {
|
||||
cachePath string
|
||||
customLrcLibUrl string
|
||||
timeout time.Duration
|
||||
}
|
||||
|
||||
func NewLrcLibFetcher(baseCacheDir string, customLrcLibUrl string) *LrcLibFetcher {
|
||||
func NewLrcLibFetcher(baseCacheDir string, customLrcLibUrl string, timeout time.Duration) *LrcLibFetcher {
|
||||
cachePath := filepath.Join(baseCacheDir, lrclibCacheFolder)
|
||||
configdir.MakePath(cachePath)
|
||||
return &LrcLibFetcher{cachePath: cachePath, customLrcLibUrl: customLrcLibUrl}
|
||||
return &LrcLibFetcher{cachePath: cachePath, customLrcLibUrl: customLrcLibUrl, timeout: timeout}
|
||||
}
|
||||
|
||||
func (l *LrcLibFetcher) FetchLrcLibLyrics(name, artist, album string, durationSecs int) (*mediaprovider.Lyrics, error) {
|
||||
@@ -67,7 +68,7 @@ func (l *LrcLibFetcher) FetchLrcLibLyrics(name, artist, album string, durationSe
|
||||
}
|
||||
|
||||
func (l *LrcLibFetcher) fetchFromServer(name, artist, album string, durationSecs int) (*mediaprovider.Lyrics, error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), l.timeout)
|
||||
defer cancel()
|
||||
|
||||
lrclibUrl := l.getLrclibUrl()
|
||||
|
||||
@@ -177,9 +177,10 @@ func (s *ServerManager) SetServerPassword(server *ServerConfig, password string)
|
||||
|
||||
func (s *ServerManager) connect(connection ServerConnection, password string) (mediaprovider.Server, error) {
|
||||
var cli, altCli mediaprovider.Server
|
||||
timeout := time.Second * time.Duration(s.config.Application.RequestTimeoutSeconds)
|
||||
|
||||
if connection.ServerType == ServerTypeJellyfin {
|
||||
client, err := jellyfin.NewClient(connection.Hostname, res.AppName, res.AppVersion, jellyfin.WithTimeout(10*time.Second))
|
||||
client, err := jellyfin.NewClient(connection.Hostname, res.AppName, res.AppVersion, jellyfin.WithTimeout(timeout))
|
||||
if err != nil {
|
||||
log.Printf("error creating Jellyfin client: %s", err.Error())
|
||||
return nil, err
|
||||
@@ -190,7 +191,7 @@ func (s *ServerManager) connect(connection ServerConnection, password string) (m
|
||||
}
|
||||
|
||||
if connection.AltHostname != "" {
|
||||
altClient, err := jellyfin.NewClient(connection.AltHostname, res.AppName, res.AppVersion, jellyfin.WithTimeout(10*time.Second))
|
||||
altClient, err := jellyfin.NewClient(connection.AltHostname, res.AppName, res.AppVersion, jellyfin.WithTimeout(timeout))
|
||||
if err != nil {
|
||||
log.Printf("error creating Jellyfin alternative client: %s", err.Error())
|
||||
return nil, err
|
||||
@@ -205,7 +206,7 @@ func (s *ServerManager) connect(connection ServerConnection, password string) (m
|
||||
cli = &subsonicMP.SubsonicServer{
|
||||
Client: subsonic.Client{
|
||||
UserAgent: ua,
|
||||
Client: &http.Client{Timeout: 10 * time.Second},
|
||||
Client: &http.Client{Timeout: timeout},
|
||||
BaseUrl: connection.Hostname,
|
||||
User: connection.Username,
|
||||
PasswordAuth: connection.LegacyAuth,
|
||||
@@ -216,7 +217,7 @@ func (s *ServerManager) connect(connection ServerConnection, password string) (m
|
||||
altCli = &subsonicMP.SubsonicServer{
|
||||
Client: subsonic.Client{
|
||||
UserAgent: ua,
|
||||
Client: &http.Client{Timeout: 10 * time.Second},
|
||||
Client: &http.Client{Timeout: timeout},
|
||||
BaseUrl: connection.AltHostname,
|
||||
User: connection.Username,
|
||||
PasswordAuth: connection.LegacyAuth,
|
||||
|
||||
@@ -27,7 +27,6 @@ import (
|
||||
"github.com/dweymouth/supersonic/ui/widgets"
|
||||
|
||||
"fyne.io/fyne/v2"
|
||||
"fyne.io/fyne/v2/canvas"
|
||||
"fyne.io/fyne/v2/container"
|
||||
"fyne.io/fyne/v2/dialog"
|
||||
"fyne.io/fyne/v2/lang"
|
||||
@@ -64,7 +63,7 @@ type Controller struct {
|
||||
popUpQueue *widget.PopUp
|
||||
popUpQueueList *widgets.PlayQueueList
|
||||
popUpQueueLastUsed int64
|
||||
escapablePopUp *widget.PopUp
|
||||
escapablePopUp fyne.CanvasObject
|
||||
haveModal bool
|
||||
runOnModalClosed func()
|
||||
}
|
||||
@@ -128,7 +127,7 @@ func (m *Controller) NavigateTo(route Route) {
|
||||
m.NavHandler(route)
|
||||
}
|
||||
|
||||
func (m *Controller) ClosePopUpOnEscape(pop *widget.PopUp) {
|
||||
func (m *Controller) ClosePopUpOnEscape(pop fyne.CanvasObject) {
|
||||
m.escapablePopUp = pop
|
||||
}
|
||||
|
||||
@@ -232,9 +231,6 @@ func (m *Controller) ShowPopUpPlayQueue() {
|
||||
}
|
||||
|
||||
func (m *Controller) ShowPopUpImage(img image.Image) {
|
||||
im := canvas.NewImageFromImage(img)
|
||||
im.FillMode = canvas.ImageFillContain
|
||||
pop := widget.NewPopUp(im, m.MainWindow.Canvas())
|
||||
s := m.MainWindow.Canvas().Size()
|
||||
var popS fyne.Size
|
||||
if asp := util.ImageAspect(img); s.Width/s.Height > asp {
|
||||
@@ -245,12 +241,11 @@ func (m *Controller) ShowPopUpImage(img image.Image) {
|
||||
w := s.Width * 0.8
|
||||
popS = fyne.NewSize(w, w*(1/asp))
|
||||
}
|
||||
|
||||
pop := widgets.NewImagePopUp(img, m.MainWindow.Canvas(), popS)
|
||||
|
||||
m.ClosePopUpOnEscape(pop)
|
||||
pop.Resize(popS)
|
||||
pop.ShowAtPosition(fyne.NewPos(
|
||||
(s.Width-popS.Width)/2,
|
||||
(s.Height-popS.Height)/2,
|
||||
))
|
||||
pop.Show()
|
||||
}
|
||||
|
||||
func (m *Controller) GetArtistTracks(artistID string) []*mediaprovider.Track {
|
||||
@@ -696,9 +691,10 @@ func (c *Controller) trySetPasswordAndConnectToServer(server *backend.ServerConf
|
||||
return c.tryConnectToServer(context.Background(), server, password)
|
||||
}
|
||||
|
||||
// try to connect to the given server, with a 10 second timeout added to the context
|
||||
// try to connect to the given server, with the configured timeout added to the context
|
||||
func (c *Controller) tryConnectToServer(ctx context.Context, server *backend.ServerConfig, password string) error {
|
||||
ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
|
||||
timeout := time.Duration(c.App.Config.Application.RequestTimeoutSeconds) * time.Second
|
||||
ctx, cancel := context.WithTimeout(ctx, timeout)
|
||||
defer cancel()
|
||||
if err := c.App.ServerManager.TestConnectionAndAuth(ctx, server.ServerConnection, password); err != nil {
|
||||
return err
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
package widgets
|
||||
|
||||
import (
|
||||
"image"
|
||||
|
||||
"fyne.io/fyne/v2"
|
||||
"fyne.io/fyne/v2/canvas"
|
||||
"fyne.io/fyne/v2/widget"
|
||||
)
|
||||
|
||||
const (
|
||||
imagePopUpLowRezDim = 128
|
||||
)
|
||||
|
||||
type ImagePopUp struct {
|
||||
widget.PopUp
|
||||
|
||||
img image.Image
|
||||
desiredSize fyne.Size
|
||||
aspect float64
|
||||
}
|
||||
|
||||
func NewImagePopUp(img image.Image, canv fyne.Canvas, size fyne.Size) *ImagePopUp {
|
||||
i := &ImagePopUp{
|
||||
img: img,
|
||||
desiredSize: size,
|
||||
PopUp: widget.PopUp{
|
||||
Canvas: canv,
|
||||
Content: canvas.NewImageFromImage(img),
|
||||
},
|
||||
}
|
||||
i.ExtendBaseWidget(i)
|
||||
return i
|
||||
}
|
||||
|
||||
func (i *ImagePopUp) Show() {
|
||||
i.Content.(*canvas.Image).FillMode = canvas.ImageFillContain
|
||||
i.Content.(*canvas.Image).ScaleMode = canvas.ImageScaleFastest
|
||||
canvSize := i.Canvas.Size()
|
||||
i.ShowAtPosition(fyne.NewPos(
|
||||
canvSize.Width/2,
|
||||
canvSize.Height/2,
|
||||
))
|
||||
anim := fyne.NewAnimation(canvas.DurationShort, func(f float32) {
|
||||
if f == 1 {
|
||||
i.Content.(*canvas.Image).ScaleMode = canvas.ImageScaleSmooth
|
||||
}
|
||||
size := fyne.NewSize(i.desiredSize.Width*f, i.desiredSize.Height*f)
|
||||
i.Content.(*canvas.Image).SetMinSize(size)
|
||||
size = i.Content.MinSize()
|
||||
i.Resize(size)
|
||||
i.Move(fyne.NewPos(
|
||||
(canvSize.Width-size.Width)/2,
|
||||
(canvSize.Height-size.Height)/2,
|
||||
))
|
||||
})
|
||||
anim.Start()
|
||||
}
|
||||
Reference in New Issue
Block a user