Fix #319: show cancelable modal dialog while connecting to server on startup
This commit is contained in:
@@ -58,7 +58,7 @@ func (s *ServerManager) ConnectToServer(conf *ServerConfig, password string) err
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *ServerManager) TestConnectionAndAuth(
|
func (s *ServerManager) TestConnectionAndAuth(
|
||||||
connection ServerConnection, password string, timeout time.Duration,
|
ctx context.Context, connection ServerConnection, password string,
|
||||||
) error {
|
) error {
|
||||||
err := ErrUnreachable
|
err := ErrUnreachable
|
||||||
done := make(chan bool)
|
done := make(chan bool)
|
||||||
@@ -66,10 +66,8 @@ func (s *ServerManager) TestConnectionAndAuth(
|
|||||||
_, err = s.connect(connection, password)
|
_, err = s.connect(connection, password)
|
||||||
close(done)
|
close(done)
|
||||||
}()
|
}()
|
||||||
t := time.NewTimer(timeout)
|
|
||||||
defer t.Stop()
|
|
||||||
select {
|
select {
|
||||||
case <-t.C:
|
case <-ctx.Done():
|
||||||
return err
|
return err
|
||||||
case <-done:
|
case <-done:
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package controller
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"archive/zip"
|
"archive/zip"
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"image"
|
"image"
|
||||||
"io"
|
"io"
|
||||||
@@ -348,13 +349,35 @@ func (m *Controller) DoEditPlaylistWorkflow(playlist *mediaprovider.Playlist) {
|
|||||||
pop.Show()
|
pop.Show()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DoConnectToServerWorkflow does the workflow for connecting to the last active server on startup
|
||||||
func (c *Controller) DoConnectToServerWorkflow(server *backend.ServerConfig) {
|
func (c *Controller) DoConnectToServerWorkflow(server *backend.ServerConfig) {
|
||||||
pass, err := c.App.ServerManager.GetServerPassword(server.ID)
|
pass, err := c.App.ServerManager.GetServerPassword(server.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("error getting password from keyring: %v", err)
|
log.Printf("error getting password from keyring: %v", err)
|
||||||
c.PromptForLoginAndConnect()
|
c.PromptForLoginAndConnect()
|
||||||
} else {
|
return
|
||||||
if err := c.tryConnectToServer(server, pass); err != nil {
|
}
|
||||||
|
|
||||||
|
// 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 := dialog.NewError(err, c.MainWindow)
|
||||||
dlg.SetOnClosed(func() {
|
dlg.SetOnClosed(func() {
|
||||||
c.PromptForLoginAndConnect()
|
c.PromptForLoginAndConnect()
|
||||||
@@ -362,6 +385,9 @@ func (c *Controller) DoConnectToServerWorkflow(server *backend.ServerConfig) {
|
|||||||
c.haveModal = true
|
c.haveModal = true
|
||||||
dlg.Show()
|
dlg.Show()
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
dlg.Hide()
|
||||||
|
c.haveModal = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -372,7 +398,10 @@ func (m *Controller) PromptForLoginAndConnect() {
|
|||||||
d.DisableSubmit()
|
d.DisableSubmit()
|
||||||
d.SetInfoText("Testing connection...")
|
d.SetInfoText("Testing connection...")
|
||||||
go func() {
|
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 {
|
if err == backend.ErrUnreachable {
|
||||||
d.SetErrorText("Server unreachable")
|
d.SetErrorText("Server unreachable")
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
@@ -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
|
// 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.
|
// 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 {
|
// try to connect to the given server, with a 10 second timeout added to the context
|
||||||
if err := c.App.ServerManager.TestConnectionAndAuth(server.ServerConnection, password, 10*time.Second); err != nil {
|
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
|
return err
|
||||||
}
|
}
|
||||||
if err := c.App.ServerManager.ConnectToServer(server, password); err != nil {
|
if err := c.App.ServerManager.ConnectToServer(server, password); err != nil {
|
||||||
@@ -583,7 +615,9 @@ func (c *Controller) testConnectionAndUpdateDialogText(dlg *dialogs.AddEditServe
|
|||||||
Username: dlg.Username,
|
Username: dlg.Username,
|
||||||
LegacyAuth: dlg.LegacyAuth,
|
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 {
|
if err == backend.ErrUnreachable {
|
||||||
dlg.SetErrorText("Could not reach server (wrong hostname?)")
|
dlg.SetErrorText("Could not reach server (wrong hostname?)")
|
||||||
return false
|
return false
|
||||||
|
|||||||
Reference in New Issue
Block a user