Categorize and normalize folder listing
This commit is contained in:
parent
8de661b3bb
commit
9e2c420461
4 changed files with 110 additions and 34 deletions
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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">
|
||||
|
|
Loading…
Reference in a new issue