aboutsummaryrefslogtreecommitdiff
path: root/models
diff options
context:
space:
mode:
authorBen Burwell <ben@benburwell.com>2019-07-04 22:34:52 -0400
committerBen Burwell <ben@benburwell.com>2019-07-04 22:37:29 -0400
commitb46b497f99d7f4dcba8936ce0ebfe8cf982cec1f (patch)
treeb9212d4b196706d3c0e2d93b8dfd8cc39cbacf3b /models
parent6574dedd8a4afdaedd3677283955a866214bd99a (diff)
Factor UI models out of the worker message packagemdps1
Before, the information needed to display different parts of the UI was tightly coupled to the specific messages being sent back and forth to the backend worker. Separating out a models package allows us to be more specific about exactly what a backend is able to and required to provide for the UI.
Diffstat (limited to 'models')
-rw-r--r--models/models.go88
1 files changed, 84 insertions, 4 deletions
diff --git a/models/models.go b/models/models.go
index 00297e9..1f6636f 100644
--- a/models/models.go
+++ b/models/models.go
@@ -1,18 +1,42 @@
package models
import (
+ "bytes"
+ "fmt"
"io"
+ "regexp"
+ "strings"
"time"
- "github.com/emersion/go-imap"
"github.com/emersion/go-message/mail"
)
+// Flag is an abstraction around the different flags which can be present in
+// different email backends and represents a flag that we use in the UI.
+type Flag int
+
+const (
+ // SeenFlag marks a message as having been seen previously
+ SeenFlag Flag = iota
+
+ // RecentFlag marks a message as being recent
+ RecentFlag
+
+ // AnsweredFlag marks a message as having been replied to
+ AnsweredFlag
+
+ // DeletedFlag marks a message as having been deleted
+ DeletedFlag
+
+ // FlaggedFlag marks a message with a user flag
+ FlaggedFlag
+)
+
// A MessageInfo holds information about the structure of a message
type MessageInfo struct {
- BodyStructure *imap.BodyStructure
- Envelope *imap.Envelope
- Flags []string
+ BodyStructure *BodyStructure
+ Envelope *Envelope
+ Flags []Flag
InternalDate time.Time
RFC822Headers *mail.Header
Size uint32
@@ -30,3 +54,59 @@ type FullMessage struct {
Reader io.Reader
Uid uint32
}
+
+type BodyStructure struct {
+ MIMEType string
+ MIMESubType string
+ Params map[string]string
+ Description string
+ Encoding string
+ Parts []*BodyStructure
+ Disposition string
+ DispositionParams map[string]string
+}
+
+type Envelope struct {
+ Date time.Time
+ Subject string
+ From []*Address
+ ReplyTo []*Address
+ To []*Address
+ Cc []*Address
+ Bcc []*Address
+ MessageId string
+}
+
+type Address struct {
+ Name string
+ Mailbox string
+ Host string
+}
+
+var atom *regexp.Regexp = regexp.MustCompile("^[a-z0-9!#$%7'*+-/=?^_`{}|~ ]+$")
+
+func (a Address) Format() string {
+ if a.Name != "" {
+ if atom.MatchString(a.Name) {
+ return fmt.Sprintf("%s <%s@%s>", a.Name, a.Mailbox, a.Host)
+ } else {
+ return fmt.Sprintf("\"%s\" <%s@%s>",
+ strings.ReplaceAll(a.Name, "\"", "'"),
+ a.Mailbox, a.Host)
+ }
+ } else {
+ return fmt.Sprintf("<%s@%s>", a.Mailbox, a.Host)
+ }
+}
+
+// FormatAddresses formats a list of addresses, separating each by a comma
+func FormatAddresses(addrs []*Address) string {
+ val := bytes.Buffer{}
+ for i, addr := range addrs {
+ val.WriteString(addr.Format())
+ if i != len(addrs)-1 {
+ val.WriteString(", ")
+ }
+ }
+ return val.String()
+}