diff options
-rw-r--r-- | plugins/base/routes.go | 187 | ||||
-rw-r--r-- | themes/alps/compose.html | 13 | ||||
-rw-r--r-- | themes/alps/mailbox.html | 21 | ||||
-rw-r--r-- | themes/alps/message.html | 28 | ||||
-rw-r--r-- | themes/alps/util.html | 41 |
5 files changed, 148 insertions, 142 deletions
diff --git a/plugins/base/routes.go b/plugins/base/routes.go index 977b017..3cad8da 100644 --- a/plugins/base/routes.go +++ b/plugins/base/routes.go @@ -63,12 +63,16 @@ func registerRoutes(p *alps.GoPlugin) { p.POST("/settings", handleSettings) } -type MailboxRenderData struct { +type IMAPBaseRenderData struct { alps.BaseRenderData - Mailbox *MailboxStatus - Inbox *MailboxStatus CategorizedMailboxes CategorizedMailboxes Mailboxes []MailboxInfo + Mailbox *MailboxStatus + Inbox *MailboxStatus +} + +type MailboxRenderData struct { + IMAPBaseRenderData Messages []IMAPMessage PrevPage, NextPage int Query string @@ -87,21 +91,52 @@ type CategorizedMailboxes struct { Additional []*MailboxInfo } -func categorizeMailboxes(mailboxes []MailboxInfo, - inbox *MailboxStatus, active *MailboxStatus) CategorizedMailboxes { +func newIMAPBaseRenderData(ctx *alps.Context, + base *alps.BaseRenderData) (*IMAPBaseRenderData, error) { + + mboxName, err := url.PathUnescape(ctx.Param("mbox")) + if err != nil { + return nil, echo.NewHTTPError(http.StatusBadRequest, err) + } - var out CategorizedMailboxes + var mailboxes []MailboxInfo + var active, inbox *MailboxStatus + err = ctx.Session.DoIMAP(func(c *imapclient.Client) error { + var err error + if mailboxes, err = listMailboxes(c); err != nil { + return err + } + if mboxName != "" { + if active, err = getMailboxStatus(c, mboxName); err != nil { + return err + } + } + if mboxName == "INBOX" { + inbox = active + } else { + if inbox, err = getMailboxStatus(c, "INBOX"); err != nil { + return err + } + } + return nil + }) + if err != nil { + return nil, err + } + + var categorized 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, + "INBOX": &categorized.Common.Inbox, + "Drafts": &categorized.Common.Drafts, + "Sent": &categorized.Common.Sent, + "Junk": &categorized.Common.Junk, + "Trash": &categorized.Common.Trash, + "Archive": &categorized.Common.Archive, } + for i, _ := range mailboxes { // Populate unseen & active states - if mailboxes[i].Name == active.Name { + if active != nil && mailboxes[i].Name == active.Name { mailboxes[i].Unseen = int(active.Unseen) mailboxes[i].Active = true } @@ -112,17 +147,35 @@ func categorizeMailboxes(mailboxes []MailboxInfo, if ptr, ok := mmap[mailboxes[i].Name]; ok { *ptr = &mailboxes[i] } else { - out.Additional = append(out.Additional, &mailboxes[i]) + categorized.Additional = append( + categorized.Additional, &mailboxes[i]) } } - return out + + return &IMAPBaseRenderData{ + BaseRenderData: *base, + CategorizedMailboxes: categorized, + Mailboxes: mailboxes, + Inbox: inbox, + Mailbox: active, + }, nil } func handleGetMailbox(ctx *alps.Context) error { - mboxName, err := url.PathUnescape(ctx.Param("mbox")) + ibase, err := newIMAPBaseRenderData(ctx, alps.NewBaseRenderData(ctx)) if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, err) + return err + } + + mbox := ibase.Mailbox + title := mbox.Name + if title == "INBOX" { + title = "Inbox" + } + if mbox.Unseen > 0 { + title = fmt.Sprintf("(%d) %s", mbox.Unseen, title) } + ibase.BaseRenderData.WithTitle(title) page := 0 if pageStr := ctx.QueryParam("page"); pageStr != "" { @@ -140,33 +193,20 @@ func handleGetMailbox(ctx *alps.Context) error { query := ctx.QueryParam("query") - var mailboxes []MailboxInfo - var msgs []IMAPMessage - var mbox, inbox *MailboxStatus - var total int + var ( + msgs []IMAPMessage + total int + ) err = ctx.Session.DoIMAP(func(c *imapclient.Client) error { - var err error - if mailboxes, err = listMailboxes(c); err != nil { - return err - } - if mbox, err = getMailboxStatus(c, mboxName); err != nil { - return err - } + var err error if query != "" { - msgs, total, err = searchMessages(c, mboxName, query, page, messagesPerPage) + msgs, total, err = searchMessages(c, mbox.Name, query, page, messagesPerPage) } else { msgs, err = listMessages(c, mbox, page, messagesPerPage) } if err != nil { return err } - if mboxName == "INBOX" { - inbox = mbox - } else { - if inbox, err = getMailboxStatus(c, "INBOX"); err != nil { - return err - } - } return nil }) if err != nil { @@ -190,23 +230,8 @@ func handleGetMailbox(ctx *alps.Context) error { } } - title := mbox.Name - if title == "INBOX" { - title = "Inbox" - } - - if mbox.Unseen > 0 { - 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, - CategorizedMailboxes: categorized, - Mailboxes: mailboxes, + IMAPBaseRenderData: *ibase, Messages: msgs, PrevPage: prevPage, NextPage: nextPage, @@ -262,10 +287,7 @@ func handleLogout(ctx *alps.Context) error { } type MessageRenderData struct { - alps.BaseRenderData - Mailboxes []MailboxInfo - Mailbox *MailboxStatus - Inbox *MailboxStatus + IMAPBaseRenderData Message *IMAPMessage Part *IMAPPartNode View interface{} @@ -274,10 +296,13 @@ type MessageRenderData struct { } func handleGetPart(ctx *alps.Context, raw bool) error { - mboxName, uid, err := parseMboxAndUid(ctx.Param("mbox"), ctx.Param("uid")) + _, uid, err := parseMboxAndUid(ctx.Param("mbox"), ctx.Param("uid")) + ibase, err := newIMAPBaseRenderData(ctx, alps.NewBaseRenderData(ctx)) if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, err) + return err } + mbox := ibase.Mailbox + partPath, err := parsePartPath(ctx.QueryParam("part")) if err != nil { return echo.NewHTTPError(http.StatusBadRequest, err) @@ -289,28 +314,13 @@ func handleGetPart(ctx *alps.Context, raw bool) error { } messagesPerPage := settings.MessagesPerPage - var mailboxes []MailboxInfo var msg *IMAPMessage var part *message.Entity - var mbox, inbox *MailboxStatus err = ctx.Session.DoIMAP(func(c *imapclient.Client) error { var err error - if mailboxes, err = listMailboxes(c); err != nil { - return err - } - if msg, part, err = getMessagePart(c, mboxName, uid, partPath); err != nil { + if msg, part, err = getMessagePart(c, mbox.Name, uid, partPath); err != nil { return err } - if mbox, err = getMailboxStatus(c, mboxName); err != nil { - return err - } - if mboxName == "INBOX" { - inbox = mbox - } else { - if inbox, err = getMailboxStatus(c, "INBOX"); err != nil { - return err - } - } return nil }) if err != nil { @@ -367,22 +377,20 @@ func handleGetPart(ctx *alps.Context, raw bool) error { flags[f] = msg.HasFlag(f) } + ibase.BaseRenderData.WithTitle(msg.Envelope.Subject) + return ctx.Render(http.StatusOK, "message.html", &MessageRenderData{ - BaseRenderData: *alps.NewBaseRenderData(ctx). - WithTitle(msg.Envelope.Subject), - Mailboxes: mailboxes, - Mailbox: mbox, - Inbox: inbox, - Message: msg, - Part: msg.PartByPath(partPath), - View: view, - MailboxPage: int(mbox.Messages-msg.SeqNum) / messagesPerPage, - Flags: flags, + IMAPBaseRenderData: *ibase, + Message: msg, + Part: msg.PartByPath(partPath), + View: view, + MailboxPage: int(mbox.Messages-msg.SeqNum) / messagesPerPage, + Flags: flags, }) } type ComposeRenderData struct { - alps.BaseRenderData + IMAPBaseRenderData Message *OutgoingMessage } @@ -438,6 +446,11 @@ func submitCompose(ctx *alps.Context, msg *OutgoingMessage, options *composeOpti } func handleCompose(ctx *alps.Context, msg *OutgoingMessage, options *composeOptions) error { + ibase, err := newIMAPBaseRenderData(ctx, alps.NewBaseRenderData(ctx)) + if err != nil { + return err + } + if msg.From == "" && strings.ContainsRune(ctx.Session.Username(), '@') { msg.From = ctx.Session.Username() } @@ -537,8 +550,8 @@ func handleCompose(ctx *alps.Context, msg *OutgoingMessage, options *composeOpti } return ctx.Render(http.StatusOK, "compose.html", &ComposeRenderData{ - BaseRenderData: *alps.NewBaseRenderData(ctx), - Message: msg, + IMAPBaseRenderData: *ibase, + Message: msg, }) } diff --git a/themes/alps/compose.html b/themes/alps/compose.html index be84b03..fe3c86a 100644 --- a/themes/alps/compose.html +++ b/themes/alps/compose.html @@ -1,18 +1,9 @@ {{template "head.html" .}} {{template "nav.html" .}} - +{{template "util.html" .}} <div class="page-wrap"> - <aside> - <a href="/compose" class="new active">Compose Mail</a> - <!-- TODO: use mailbox list from template data --> - <a href="/mailbox/INBOX">Inbox</a> - <a href="/mailbox/Drafts">Drafts</a> - <a href="/mailbox/Sent">Sent</a> - <a href="/mailbox/Archive">Archive</a> - <a href="/mailbox/Junk">Junk</a> - <a href="/mailbox/Trash">Trash</a> - </aside> + {{ template "aside" . }} <div class="container"> <main class="create-update"> diff --git a/themes/alps/mailbox.html b/themes/alps/mailbox.html index e09f2b7..fca34ba 100644 --- a/themes/alps/mailbox.html +++ b/themes/alps/mailbox.html @@ -1,5 +1,6 @@ {{template "head.html" .}} {{template "nav.html" .}} +{{template "util.html" .}} {{ define "mbox-link" }} {{ if not (.HasAttr "\\Noselect") }} @@ -21,25 +22,7 @@ {{ end }} <div class="page-wrap"> - <aside> - <!-- the logo image, dimensions 200x32 may be present or not --> - <a href="/compose" class="new">Compose Mail</a> - {{ 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> - + {{ template "aside" . }} <div class="container"> <form id="messages-form" method="post"></form> <main class="message-list"> diff --git a/themes/alps/message.html b/themes/alps/message.html index 2926641..713d3bc 100644 --- a/themes/alps/message.html +++ b/themes/alps/message.html @@ -1,5 +1,6 @@ {{template "head.html" .}} {{template "nav.html" .}} +{{template "util.html" .}} {{define "message-part-tree"}} {{/* nested templates can't access the parent's context */}} @@ -28,31 +29,8 @@ {{end}} <div class="page-wrap"> - {{$current := .Mailbox}} - <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 $current.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}} - </aside> - + {{ $current := .Mailbox }} + {{ template "aside" . }} <div class="container"> <main class="message"> <section class="actions"> diff --git a/themes/alps/util.html b/themes/alps/util.html new file mode 100644 index 0000000..68736f1 --- /dev/null +++ b/themes/alps/util.html @@ -0,0 +1,41 @@ +{{ 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 }} + +{{ define "aside" }} +<aside> + <!-- the logo image, dimensions 200x32 may be present or not --> + <a href="/compose" class="new + {{ if eq $.GlobalData.URL.Path "/compose" }}active{{ end }} + ">Compose Mail</a> + {{ 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> +{{ end }} |