aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobin Jarry <robin@jarry.cc>2021-11-01 21:38:26 +0100
committerRobin Jarry <robin@jarry.cc>2021-11-05 10:45:31 +0100
commite41ed82cf3dbb4a1152a562ab754a9dc4a6c57b3 (patch)
tree098cc67f60eb3e0d7c16ad82adb4c988aa08c61e
parent20752df89c3bef0aca23493bfe8a668b93db9947 (diff)
downloadaerc-e41ed82cf3dbb4a1152a562ab754a9dc4a6c57b3.tar.gz
imap: add manual {dis,}connect support
Signed-off-by: Robin Jarry <robin@jarry.cc>
-rw-r--r--commands/account/connection.go37
-rw-r--r--widgets/account.go59
-rw-r--r--worker/imap/worker.go16
3 files changed, 82 insertions, 30 deletions
diff --git a/commands/account/connection.go b/commands/account/connection.go
new file mode 100644
index 00000000..a87993b6
--- /dev/null
+++ b/commands/account/connection.go
@@ -0,0 +1,37 @@
+package account
+
+import (
+ "errors"
+
+ "git.sr.ht/~rjarry/aerc/widgets"
+ "git.sr.ht/~rjarry/aerc/worker/types"
+)
+
+type Connection struct{}
+
+func init() {
+ register(Connection{})
+}
+
+func (Connection) Aliases() []string {
+ return []string{"connect", "disconnect"}
+}
+
+func (Connection) Complete(aerc *widgets.Aerc, args []string) []string {
+ return nil
+}
+
+func (Connection) Execute(aerc *widgets.Aerc, args []string) error {
+ acct := aerc.SelectedAccount()
+ if acct == nil {
+ return errors.New("No account selected")
+ }
+ if args[0] == "connect" {
+ acct.Worker().PostAction(&types.Connect{}, nil)
+ acct.SetStatus("Connecting...")
+ } else {
+ acct.Worker().PostAction(&types.Disconnect{}, nil)
+ acct.SetStatus("Disconnecting...")
+ }
+ return nil
+}
diff --git a/widgets/account.go b/widgets/account.go
index 891278a3..2f126a30 100644
--- a/widgets/account.go
+++ b/widgets/account.go
@@ -85,7 +85,7 @@ func NewAccountView(aerc *Aerc, conf *config.AercConfig, acct *config.AccountCon
go worker.Backend.Run()
worker.PostAction(&types.Configure{Config: acct}, nil)
- worker.PostAction(&types.Connect{}, view.connected)
+ worker.PostAction(&types.Connect{}, nil)
host.SetStatus("Connecting...")
return view, nil
@@ -105,6 +105,10 @@ func (acct *AccountView) Tick() bool {
}
}
+func (acct *AccountView) SetStatus(msg string) {
+ acct.host.SetStatus(msg)
+}
+
func (acct *AccountView) AccountConfig() *config.AccountConfig {
return acct.acct
}
@@ -147,33 +151,6 @@ func (acct *AccountView) Focus(focus bool) {
// TODO: Unfocus children I guess
}
-func (acct *AccountView) connected(msg types.WorkerMessage) {
- switch msg.(type) {
- case *types.Done:
- acct.host.SetStatus("Listing mailboxes...")
- acct.logger.Println("Listing mailboxes...")
- acct.dirlist.UpdateList(func(dirs []string) {
- var dir string
- for _, _dir := range dirs {
- if _dir == acct.acct.Default {
- dir = _dir
- break
- }
- }
- if dir == "" && len(dirs) > 0 {
- dir = dirs[0]
- }
- if dir != "" {
- acct.dirlist.Select(dir)
- }
-
- acct.msglist.SetInitDone()
- acct.logger.Println("Connected.")
- acct.host.SetStatus("Connected.")
- })
- }
-}
-
func (acct *AccountView) Directories() *DirectoryList {
return acct.dirlist
}
@@ -225,6 +202,32 @@ func (acct *AccountView) onMessage(msg types.WorkerMessage) {
switch msg := msg.(type) {
case *types.Done:
switch msg.InResponseTo().(type) {
+ case *types.Connect:
+ acct.host.SetStatus("Listing mailboxes...")
+ acct.logger.Println("Listing mailboxes...")
+ acct.dirlist.UpdateList(func(dirs []string) {
+ var dir string
+ for _, _dir := range dirs {
+ if _dir == acct.acct.Default {
+ dir = _dir
+ break
+ }
+ }
+ if dir == "" && len(dirs) > 0 {
+ dir = dirs[0]
+ }
+ if dir != "" {
+ acct.dirlist.Select(dir)
+ }
+ acct.msglist.SetInitDone()
+ acct.logger.Println("Connected.")
+ acct.host.SetStatus("Connected.")
+ })
+ case *types.Disconnect:
+ acct.dirlist.UpdateList(nil)
+ acct.msglist.SetStore(nil)
+ acct.logger.Println("Disconnected.")
+ acct.host.SetStatus("Disconnected.")
case *types.OpenDirectory:
if store, ok := acct.dirlist.SelectedMsgStore(); ok {
// If we've opened this dir before, we can re-render it from
diff --git a/worker/imap/worker.go b/worker/imap/worker.go
index 82b81bdc..cd525369 100644
--- a/worker/imap/worker.go
+++ b/worker/imap/worker.go
@@ -59,7 +59,7 @@ func NewIMAPWorker(worker *types.Worker) (types.Backend, error) {
}
func (w *IMAPWorker) handleMessage(msg types.WorkerMessage) error {
- if w.idleStop != nil {
+ if w.client != nil && w.client.State() == imap.SelectedState {
close(w.idleStop)
if err := <-w.idleDone; err != nil {
w.worker.PostMessage(&types.Error{Error: err}, nil)
@@ -110,6 +110,9 @@ func (w *IMAPWorker) handleMessage(msg types.WorkerMessage) error {
c *client.Client
err error
)
+ if w.client != nil {
+ return fmt.Errorf("Already connected")
+ }
switch w.config.scheme {
case "imap":
c, err = client.Dial(w.config.addr)
@@ -157,6 +160,15 @@ func (w *IMAPWorker) handleMessage(msg types.WorkerMessage) error {
c.Updates = w.updates
w.client = &imapClient{c, sortthread.NewSortClient(c)}
w.worker.PostMessage(&types.Done{types.RespondTo(msg)}, nil)
+ case *types.Disconnect:
+ if w.client == nil {
+ return fmt.Errorf("Not connected")
+ }
+ if err := w.client.Logout(); err != nil {
+ return err
+ }
+ w.client = nil
+ w.worker.PostMessage(&types.Done{types.RespondTo(msg)}, nil)
case *types.ListDirectories:
w.handleListDirectories(msg)
case *types.OpenDirectory:
@@ -189,7 +201,7 @@ func (w *IMAPWorker) handleMessage(msg types.WorkerMessage) error {
reterr = errUnsupported
}
- if w.idleStop != nil {
+ if w.client != nil && w.client.State() == imap.SelectedState {
w.idleStop = make(chan struct{})
go func() {
w.idleDone <- w.client.Idle(w.idleStop, &client.IdleOptions{0, 0})