Skip to content

Commit

Permalink
Fix #319: show cancelable modal dialog while connecting to server on …
Browse files Browse the repository at this point in the history
…startup
  • Loading branch information
dweymouth committed Feb 15, 2024
1 parent 6ac9337 commit b61afb1
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 11 deletions.
6 changes: 2 additions & 4 deletions backend/servermanager.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,18 +58,16 @@ func (s *ServerManager) ConnectToServer(conf *ServerConfig, password string) err
}

func (s *ServerManager) TestConnectionAndAuth(
connection ServerConnection, password string, timeout time.Duration,
ctx context.Context, connection ServerConnection, password string,
) error {
err := ErrUnreachable
done := make(chan bool)
go func() {
_, err = s.connect(connection, password)
close(done)
}()
t := time.NewTimer(timeout)
defer t.Stop()
select {
case <-t.C:
case <-ctx.Done():
return err
case <-done:
return err
Expand Down
48 changes: 41 additions & 7 deletions ui/controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package controller

import (
"archive/zip"
"context"
"fmt"
"image"
"io"
Expand Down Expand Up @@ -348,20 +349,45 @@ func (m *Controller) DoEditPlaylistWorkflow(playlist *mediaprovider.Playlist) {
pop.Show()
}

// DoConnectToServerWorkflow does the workflow for connecting to the last active server on startup
func (c *Controller) DoConnectToServerWorkflow(server *backend.ServerConfig) {
pass, err := c.App.ServerManager.GetServerPassword(server.ID)
if err != nil {
log.Printf("error getting password from keyring: %v", err)
c.PromptForLoginAndConnect()
} else {
if err := c.tryConnectToServer(server, pass); err != nil {
return
}

// try connecting to last used server - set up cancelable modal dialog
canceled := false
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
dlg := dialog.NewCustom("Connecting", "Cancel",
widget.NewLabel(fmt.Sprintf("Connecting to %s", server.Nickname)), c.MainWindow)
dlg.SetOnClosed(func() {
canceled = true
cancel()
})
c.haveModal = true
dlg.Show()
// try to connect
if err := c.tryConnectToServer(ctx, server, pass); err != nil {
dlg.Hide()
c.haveModal = false
if canceled {
c.PromptForLoginAndConnect()
} else {
// connection failure
dlg := dialog.NewError(err, c.MainWindow)
dlg.SetOnClosed(func() {
c.PromptForLoginAndConnect()
})
c.haveModal = true
dlg.Show()
}
} else {
dlg.Hide()
c.haveModal = false
}
}

Expand All @@ -372,7 +398,10 @@ func (m *Controller) PromptForLoginAndConnect() {
d.DisableSubmit()
d.SetInfoText("Testing connection...")
go func() {
err := m.App.ServerManager.TestConnectionAndAuth(server.ServerConnection, password, 5*time.Second)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

err := m.App.ServerManager.TestConnectionAndAuth(ctx, server.ServerConnection, password)
if err == backend.ErrUnreachable {
d.SetErrorText("Server unreachable")
} else if err != nil {
Expand Down Expand Up @@ -560,11 +589,14 @@ func (c *Controller) trySetPasswordAndConnectToServer(server *backend.ServerConf
// Don't return an error; fall back to just using the password in-memory
// User will need to log in with the password on subsequent runs.
}
return c.tryConnectToServer(server, password)
return c.tryConnectToServer(context.Background(), server, password)
}

func (c *Controller) tryConnectToServer(server *backend.ServerConfig, password string) error {
if err := c.App.ServerManager.TestConnectionAndAuth(server.ServerConnection, password, 10*time.Second); err != nil {
// try to connect to the given server, with a 10 second 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)
defer cancel()
if err := c.App.ServerManager.TestConnectionAndAuth(ctx, server.ServerConnection, password); err != nil {
return err
}
if err := c.App.ServerManager.ConnectToServer(server, password); err != nil {
Expand All @@ -583,7 +615,9 @@ func (c *Controller) testConnectionAndUpdateDialogText(dlg *dialogs.AddEditServe
Username: dlg.Username,
LegacyAuth: dlg.LegacyAuth,
}
err := c.App.ServerManager.TestConnectionAndAuth(conn, dlg.Password, 5*time.Second)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
err := c.App.ServerManager.TestConnectionAndAuth(ctx, conn, dlg.Password)
if err == backend.ErrUnreachable {
dlg.SetErrorText("Could not reach server (wrong hostname?)")
return false
Expand Down

0 comments on commit b61afb1

Please sign in to comment.