diff --git a/cmd/xwebmail/xwebmail.go b/cmd/xwebmail/xwebmail.go
index c579304..3494f5d 100644
--- a/cmd/xwebmail/xwebmail.go
+++ b/cmd/xwebmail/xwebmail.go
@@ -5,9 +5,9 @@ import (
"net/http"
"github.com/golang/glog"
- "github.com/gorilla/mux"
"xinu.tv/email/db"
+ "xinu.tv/email/handlers"
)
var addr = flag.String("addr", ":8080", "address:port to listen on")
@@ -21,10 +21,6 @@ func main() {
glog.Fatal(err)
}
- h := &handler{c: c}
-
- r := mux.NewRouter()
- r.HandleFunc("/raw/{hash}", h.OriginalHandler)
- r.HandleFunc("/l/{label}", h.LabelHandler)
- glog.Fatal(http.ListenAndServe(*addr, r))
+ h := handlers.Handlers(c)
+ glog.Fatal(http.ListenAndServe(*addr, h))
}
diff --git a/db/util.go b/db/util.go
index 6417620..5747ae5 100644
--- a/db/util.go
+++ b/db/util.go
@@ -42,7 +42,7 @@ type Original struct {
}
func (c *Conn) Originals(oCh chan<- Original, errc chan<- error, donec <-chan struct{}) {
- query := `
+ const query = `
SELECT
uid,
hash,
@@ -224,7 +224,7 @@ VALUES
return nil
}
-var MagicAllLabel = "[all]"
+const MagicAllLabel = "[all]"
type Paginator struct {
Label string
@@ -232,11 +232,84 @@ type Paginator struct {
Count int
}
+type Address mail.Address
+
+type MessageHeader struct {
+ Hash string
+ From *Address
+ To []*Address
+ Cc []*Address
+ Subject string
+ Date time.Time
+ Seen bool
+ // TODO
+ Summary, ListId string
+}
+
// Index returns ranges of metadata for messages as defined by paginator.
-func (c *Conn) Index(p *Paginator) error {
+func (c *Conn) Index(p *Paginator) ([]*MessageHeader, error) {
+ const query = `
+SELECT
+ hash, name, value
+FROM
+ search_header
+WHERE
+ name IN ('Date', 'Subject', 'To', 'From', 'Cc')
+ORDER BY
+ hash
+LIMIT
+ 100
+-- TODO add offset based on Paginator
+;
+`
+ var res []*MessageHeader
if p.Label == MagicAllLabel {
// Paginate all messages.
}
+
// Else, filter by label.
- return nil
+ rows, err := c.Query(query)
+ if err != nil {
+ return res, err
+ }
+ var mh *MessageHeader
+ for rows.Next() {
+ var hash, name, value string
+ if err := rows.Scan(&hash, &name, &value); err != nil {
+ return res, err
+ }
+ if mh == nil {
+ // First Row
+ mh = new(MessageHeader)
+ mh.Hash = hash
+ }
+
+ if hash != mh.Hash {
+ res = append(res, mh)
+ mh = new(MessageHeader)
+ mh.Hash = hash
+ }
+ switch name {
+ case "Date":
+ t, err := time.Parse(time.RFC3339Nano, value)
+ if err != nil {
+ return res, err
+ }
+ mh.Date = t
+ case "Subject":
+ mh.Subject = value
+ case "To":
+ mh.To = append(mh.To, &Address{Address: value})
+ case "From":
+ mh.From = &Address{Address: value}
+ case "Cc":
+ mh.Cc = append(mh.Cc, &Address{Address: value})
+ }
+ }
+ // Intentionally don't handle the last MessageHeader, it is likely
+ // incomplete if LIMIT in the query cuts off a message midstream.
+ if err := rows.Err(); err != nil {
+ return res, err
+ }
+ return res, nil
}
diff --git a/handlers/handlers.go b/handlers/handlers.go
index 590f6d8..9170087 100644
--- a/handlers/handlers.go
+++ b/handlers/handlers.go
@@ -2,6 +2,7 @@ package handlers
import (
"database/sql"
+ "encoding/json"
"flag"
"net/http"
"path/filepath"
@@ -53,7 +54,17 @@ func (h *handler) LabelHandler(w http.ResponseWriter, r *http.Request) {
return
}
glog.Infoln("Listing:", p)
- if err := h.c.Index(p); err != nil {
+ res, err := h.c.Index(p)
+ if err != nil {
+ glog.Errorln("LabelHandler:", err)
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ w.Header().Set("Content-Type", "application/json")
+ enc := json.NewEncoder(w)
+ err = enc.Encode(res)
+ if err != nil {
glog.Errorln("LabelHandler:", err)
http.Error(w, err.Error(), http.StatusInternalServerError)
return
diff --git a/static/css/layouts/email.css b/static/css/layouts/email.css
index ae1b190..befc41a 100644
--- a/static/css/layouts/email.css
+++ b/static/css/layouts/email.css
@@ -2,11 +2,23 @@
* -- BASE STYLES --
* Most of these are inherited from Base, but I want to change a few.
*/
-body {
- color: #333;
+html {
+ height: 100%;
}
+#content.loading {
+ background-image: url('/img/email-icon.jpg');
+ background-position: center center;
+ background-repeat: no-repeat;
+ background-size: contain;
+ height: 100%;
+ width: 100%;
+}
+body {
+ color: #333;
+ height: 100%;
+}
a {
text-decoration: none;
@@ -122,6 +134,7 @@ a {
color: rgb(75, 113, 151);
}
+.email-label,
.email-label-personal,
.email-label-work,
.email-label-travel {
@@ -131,6 +144,9 @@ a {
margin-right: 0.5em;
border-radius: 3px;
}
+.email-label {
+ background: #888;
+}
.email-label-personal {
background: #ffc94c;
}
@@ -188,7 +204,7 @@ a {
margin: 0;
font-weight: normal;
}
- .email-content-subtitle span {
+ .email-content-subtitle span.date {
color: #999;
}
.email-content-controls {
@@ -228,7 +244,7 @@ a {
}
#nav {
margin-left:-500px; /* "left col (nav + list)" width */
- width: 220px;
+ width:150px;
height: 100%;
}
@@ -244,7 +260,7 @@ a {
}
#list {
- margin-left: -280px;
+ margin-left: -350px;
width: 100%;
height: 33%;
border-bottom: 1px solid #ddd;
@@ -255,7 +271,7 @@ a {
top: 33%;
right: 0;
bottom: 0;
- left: 220px;
+ left: 150px;
overflow: auto;
width: auto; /* so that it's not 100% */
}
@@ -271,8 +287,8 @@ a {
/* This will take up the entire height, and be a little thinner */
#list {
- margin-left: -280px;
- width: 280px;
+ margin-left: -350px;
+ width:350px;
height: 100%;
border-right: 1px solid #ddd;
}
diff --git a/static/img/email-icon.jpg b/static/img/email-icon.jpg
new file mode 100644
index 0000000..77b12a4
Binary files /dev/null and b/static/img/email-icon.jpg differ
diff --git a/static/index.html b/static/index.html
index 47eda7c..1a0bfae 100755
--- a/static/index.html
+++ b/static/index.html
@@ -14,166 +14,13 @@
-
-
-
-
-
-
-

-
-
-
-
Tilo Mitra
-
Hello from Toronto
-
- Hey, I just wanted to check in with you from Toronto. I got here earlier today.
-
-
-
-
-
-
-

-
-
-
-
Eric Ferraiuolo
-
Re: Pull Requests
-
- Hey, I had some feedback for pull request #51. We should center the menu so it looks better on mobile.
-
-
-
-
-
-
-

-
-
-
-
YUI Library
-
You have 5 bugs assigned to you
-
- Duis aute irure dolor in reprehenderit in voluptate velit essecillum dolore eu fugiat nulla.
-
-
-
-
-
-
-

-
-
-
-
Reid Burke
-
Re: Design Language
-
- Excepteur sint occaecat cupidatat non proident, sunt in culpa.
-
-
-
-
-
-
-

-
-
-
-
Andrew Wooldridge
-
YUI Blog Updates?
-
- Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip.
-
-
-
-
-
-
-

-
-
-
-
Yahoo! Finance
-
How to protect your finances from winter storms
-
- Mauris tempor mi vitae sem aliquet pharetra. Fusce in dui purus, nec malesuada mauris.
-
-
-
-
-
-
-

-
-
-
-
Yahoo! News
-
Summary for April 3rd, 2012
-
- We found 10 news articles that you may like.
-
-
-
-
-
-
-
-
-
-
-
- Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
-
-
- Duis aute irure dolor in reprehenderit in voluptate velit essecillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
-
-
- Aliquam ac feugiat dolor. Proin mattis massa sit amet enim iaculis tincidunt. Mauris tempor mi vitae sem aliquet pharetra. Fusce in dui purus, nec malesuada mauris. Curabitur ornare arcu quis mi blandit laoreet. Vivamus imperdiet fermentum mauris, ac posuere urna tempor at. Duis pellentesque justo ac sapien aliquet egestas. Morbi enim mi, porta eget ullamcorper at, pharetra id lorem.
-
-
- Donec sagittis dolor ut quam pharetra pretium varius in nibh. Suspendisse potenti. Donec imperdiet, velit vel adipiscing bibendum, leo eros tristique augue, eu rutrum lacus sapien vel quam. Nam orci arcu, luctus quis vestibulum ut, ullamcorper ut enim. Morbi semper erat quis orci aliquet condimentum. Nam interdum mauris sed massa dignissim rhoncus.
-
-
- Regards,
- Tilo
-
-
-
-
-
+
-
+
+