diff options
-rw-r--r-- | plugins/base/imap.go | 16 | ||||
-rw-r--r-- | plugins/base/routes.go | 74 | ||||
-rw-r--r-- | themes/alps/assets/style.css | 3 | ||||
-rw-r--r-- | themes/alps/mailbox.html | 51 |
4 files changed, 110 insertions, 34 deletions
diff --git a/plugins/base/imap.go b/plugins/base/imap.go index 16bd2ef..a7f4ea1 100644 --- a/plugins/base/imap.go +++ b/plugins/base/imap.go @@ -19,6 +19,9 @@ import ( type MailboxInfo struct { *imap.MailboxInfo + + Active bool + Unseen int } func (mbox *MailboxInfo) URL() *url.URL { @@ -27,6 +30,15 @@ func (mbox *MailboxInfo) URL() *url.URL { } } +func (mbox *MailboxInfo) HasAttr(flag string) bool { + for _, attr := range mbox.Attributes { + if attr == flag { + return true + } + } + return false +} + func listMailboxes(conn *imapclient.Client) ([]MailboxInfo, error) { ch := make(chan *imap.MailboxInfo, 10) done := make(chan error, 1) @@ -36,7 +48,7 @@ func listMailboxes(conn *imapclient.Client) ([]MailboxInfo, error) { var mailboxes []MailboxInfo for mbox := range ch { - mailboxes = append(mailboxes, MailboxInfo{mbox}) + mailboxes = append(mailboxes, MailboxInfo{mbox, false, -1}) } if err := <-done; err != nil { @@ -133,7 +145,7 @@ func getMailboxByType(conn *imapclient.Client, mboxType mailboxType) (*MailboxIn if best == nil { return nil, nil } - return &MailboxInfo{best}, nil + return &MailboxInfo{best, false, -1}, nil } func ensureMailboxSelected(conn *imapclient.Client, mboxName string) error { diff --git a/plugins/base/routes.go b/plugins/base/routes.go index b61b844..977b017 100644 --- a/plugins/base/routes.go +++ b/plugins/base/routes.go @@ -65,12 +65,57 @@ func registerRoutes(p *alps.GoPlugin) { type MailboxRenderData struct { alps.BaseRenderData - Mailbox *MailboxStatus - Inbox *MailboxStatus - Mailboxes []MailboxInfo - Messages []IMAPMessage - PrevPage, NextPage int - Query string + Mailbox *MailboxStatus + Inbox *MailboxStatus + CategorizedMailboxes CategorizedMailboxes + Mailboxes []MailboxInfo + Messages []IMAPMessage + PrevPage, NextPage int + Query string +} + +// Organizes mailboxes into common/uncommon categories +type CategorizedMailboxes struct { + Common struct { + Inbox *MailboxInfo + Drafts *MailboxInfo + Sent *MailboxInfo + Junk *MailboxInfo + Trash *MailboxInfo + Archive *MailboxInfo + } + Additional []*MailboxInfo +} + +func categorizeMailboxes(mailboxes []MailboxInfo, + inbox *MailboxStatus, active *MailboxStatus) CategorizedMailboxes { + + var out CategorizedMailboxes + mmap := map[string]**MailboxInfo{ + "INBOX": &out.Common.Inbox, + "Drafts": &out.Common.Drafts, + "Sent": &out.Common.Sent, + "Junk": &out.Common.Junk, + "Trash": &out.Common.Trash, + "Archive": &out.Common.Archive, + } + for i, _ := range mailboxes { + // Populate unseen & active states + if mailboxes[i].Name == active.Name { + mailboxes[i].Unseen = int(active.Unseen) + mailboxes[i].Active = true + } + if mailboxes[i].Name == inbox.Name { + mailboxes[i].Unseen = int(inbox.Unseen) + } + + if ptr, ok := mmap[mailboxes[i].Name]; ok { + *ptr = &mailboxes[i] + } else { + out.Additional = append(out.Additional, &mailboxes[i]) + } + } + return out } func handleGetMailbox(ctx *alps.Context) error { @@ -154,15 +199,18 @@ func handleGetMailbox(ctx *alps.Context) error { title = fmt.Sprintf("(%d) %s", mbox.Unseen, title) } + categorized := categorizeMailboxes(mailboxes, inbox, mbox) + return ctx.Render(http.StatusOK, "mailbox.html", &MailboxRenderData{ BaseRenderData: *alps.NewBaseRenderData(ctx).WithTitle(title), - Mailbox: mbox, - Inbox: inbox, - Mailboxes: mailboxes, - Messages: msgs, - PrevPage: prevPage, - NextPage: nextPage, - Query: query, + Mailbox: mbox, + Inbox: inbox, + CategorizedMailboxes: categorized, + Mailboxes: mailboxes, + Messages: msgs, + PrevPage: prevPage, + NextPage: nextPage, + Query: query, }) } diff --git a/themes/alps/assets/style.css b/themes/alps/assets/style.css index 6d107de..2ba4af7 100644 --- a/themes/alps/assets/style.css +++ b/themes/alps/assets/style.css @@ -127,7 +127,8 @@ footer { text-align: right; } aside { flex: 0 0 180px; } -aside a { width: 100%; display: block; padding: 0.4rem 0 0.4rem 0.5rem; } +aside a, +aside .noselect { width: 100%; display: block; padding: 0.4rem 0 0.4rem 0.5rem; } aside a.active { font-weight: bold; color: black; text-decoration: none; } aside img { display: block; } main { diff --git a/themes/alps/mailbox.html b/themes/alps/mailbox.html index 4582726..e09f2b7 100644 --- a/themes/alps/mailbox.html +++ b/themes/alps/mailbox.html @@ -1,28 +1,43 @@ {{template "head.html" .}} {{template "nav.html" .}} +{{ define "mbox-link" }} +{{ if not (.HasAttr "\\Noselect") }} +<a href="{{.URL}}" {{ if .Active }}class="active"{{ end }}> + {{- if eq .Name "INBOX" -}} + Inbox + {{- else -}} + {{ .Name }} + {{- end -}} + {{- if .HasAttr "\\HasChildren" }}/{{ end }} + + {{ if and (ne .Unseen -1) (ne .Unseen 0) }}({{ .Unseen }}){{ end }} +</a> +{{ else }} +<span class="noselect"> + {{.Name}}{{- if .HasAttr "\\HasChildren" }}/{{ end }} +</span> +{{ end }} +{{ end }} + <div class="page-wrap"> <aside> <!-- the logo image, dimensions 200x32 may be present or not --> <a href="/compose" class="new">Compose Mail</a> - {{range .Mailboxes}} - <a href="{{.URL}}" {{ if eq $.Mailbox.Name .Name }}class="active"{{ end }}> - {{ if eq .Name "INBOX" }} - Inbox - {{ else }} - {{ .Name }} - {{ end }} - - {{ $unseen := 0 }} - {{ if eq .Name "INBOX" }} - {{ $unseen = $.Inbox.Unseen }} - {{ end }} - {{ if eq .Name $.Mailbox.Name }} - {{ $unseen = $.Mailbox.Unseen }} - {{ end }} - {{ if $unseen }}({{ $unseen }}){{ end }} - </a> - {{end}} + {{ with .CategorizedMailboxes }} + {{ with .Common.Inbox }}{{ template "mbox-link" . }}{{ end}} + {{ with .Common.Drafts }}{{ template "mbox-link" . }}{{ end}} + {{ with .Common.Sent }}{{ template "mbox-link" . }}{{ end}} + {{ with .Common.Junk }}{{ template "mbox-link" . }}{{ end}} + {{ with .Common.Trash }}{{ template "mbox-link" . }}{{ end}} + {{ with .Common.Archive }}{{ template "mbox-link" . }}{{ end}} + {{ if .Additional }} + <hr /> + {{ range .Additional }} + {{ template "mbox-link" . }} + {{ end }} + {{ end }} + {{ end }} </aside> <div class="container"> |