ソースを参照

Add stub for status line

- Add stub for status line
- Prettify some interfaces
Alexey Edelev 5 年 前
コミット
a42eb45cea

+ 19 - 15
web/css/controls.css

@@ -91,12 +91,12 @@
     background: -ms-linear-gradient(top, rgba(255, 255, 255, 1) 0%,  rgba(0, 0, 0, 0) 100%); /* IE10+ */
     background: linear-gradient(to bottom, rgba(255, 255, 255, 1) 0%,  rgba(0, 0, 0, 0) 100%); /* W3C */
 }
-  
+
 /*Input fields*/
 .inpt {
-    position:relative; 
+    position:relative;
     margin-top: 20pt;
-    margin-bottom: 50px; 
+    margin-bottom: 50px;
 }
 
 .inpt input {
@@ -120,18 +120,18 @@
 }
 
 .inpt label {
-    color: #000000; 
+    color: #000000;
     font-size: 18pt;
     font-weight: normal;
     position: absolute;
     pointer-events: none;
     left: 5pt;
     top: 10pt;
-    transition: 0.2s ease all; 
-    -moz-transition: 0.2s ease all; 
+    transition: 0.2s ease all;
+    -moz-transition: 0.2s ease all;
     -webkit-transition: 0.2s ease all;
 }
-  
+
 .inpt input:focus ~ label {
     top: -20pt;
     font-size: 12pt;
@@ -153,11 +153,11 @@
     content: '';
     height: 2pt;
     width: 0;
-    bottom: 0; 
+    bottom: 0;
     position: absolute;
-    background: #3ab849; 
-    transition: 0.2s ease all; 
-    -moz-transition: 0.2s ease all; 
+    background: #3ab849;
+    transition: 0.2s ease all;
+    -moz-transition: 0.2s ease all;
     -webkit-transition: 0.2s ease all;
 }
 
@@ -166,18 +166,18 @@
 }
 
 .inpt .bar:after {
-    right:50%; 
+    right:50%;
 }
-  
+
 .inpt input:focus ~ .bar:before, input:focus ~ .bar:after {
     width:50%;
 }
-  
+
 .inpt .highlight {
     position: absolute;
     height:75%;
     width: 213pt;
-    bottom: 4pt; 
+    bottom: 4pt;
     left:0;
     pointer-events: none;
     opacity: 0.5;
@@ -202,4 +202,8 @@
 @keyframes inputHighlighter {
     from { background:#ebffee; }
     to { width:0; background:transparent; }
+}
+
+.folderBtn {
+
 }

+ 11 - 2
web/css/index.css

@@ -19,7 +19,7 @@ table {
 
 .contentBox {
     position: absolute;
-    top: 0;
+    top: 40pt;
     left: 0;
     right: 0;
     bottom: 0;
@@ -27,7 +27,7 @@ table {
     margin-left: 150pt!important;
     margin-top: 5pt!important;
     margin-right: 5pt!important;
-    
+
     padding: 5pt
 }
 
@@ -51,6 +51,15 @@ table {
     width: 150pt;
 }
 
+#statusLine {
+    position: absolute;
+    top: 0;
+    font-size: 16pt;
+    left: 150pt;
+    height: 40pt;
+    padding: 5pt
+}
+
 .copyrights {
     position: absolute;
     right: 0;

+ 13 - 0
web/js/index.js

@@ -32,6 +32,7 @@ $(document).ready(function(){
     })
     $(window).bind('hashchange', requestDetails);
     requestDetails();
+    loadStatusLine();
 })
 
 function openEmail(id) {
@@ -62,4 +63,16 @@ function requestDetails() {
 
 function closeDetails() {
     window.location.hash = ""
+}
+
+function loadStatusLine() {
+    $.ajax({
+        url: "/statusLine",
+        success: function(result) {
+            $("#statusLine").html(result);
+        },
+        error: function(jqXHR, textStatus, errorThrown) {
+            //TODO: some toast message here once implemented
+        }
+    })
 }

+ 38 - 13
web/server.go

@@ -77,8 +77,8 @@ type Server struct {
 func NewServer() *Server {
 	return &Server{
 		authenticator: auth.NewAuthenticator(),
-		templater:     NewTemplater("./data/templates"),
-		fileServer:    http.FileServer(http.Dir("./data")),
+		templater:     NewTemplater("data/templates"),
+		fileServer:    http.FileServer(http.Dir("data")),
 		sessionStore:  sessions.NewCookieStore(make([]byte, 32)),
 	}
 }
@@ -102,6 +102,8 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 			s.handleLogout(w, r)
 		case "/messageDetails":
 			s.handleMessageDetails(w, r)
+		case "/statusLine":
+			s.handleStatusLine(w, r)
 		default:
 			s.handleMailbox(w, r)
 		}
@@ -109,55 +111,78 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 }
 
 func (s *Server) handleLogin(w http.ResponseWriter, r *http.Request) {
+	//Check passed in form login/password pair first
 	if err := r.ParseForm(); err == nil {
 		user := r.FormValue("user")
 		password := r.FormValue("password")
 		token, ok := s.authenticator.Authenticate(user, password)
 		if ok {
-			s.Login(user, token, w, r)
+			s.login(user, token, w, r)
 			return
 		}
 	}
 
+	//Check if user already logged in and entered login page accidently
 	if s.authenticator.Verify(s.extractAuth(w, r)) {
 		http.Redirect(w, r, "/mailbox", http.StatusTemporaryRedirect)
 		return
 	}
 
-	s.Logout(w, r)
+	//Otherwise make sure user logged out and show login page
+	s.logout(w, r)
 	fmt.Fprint(w, s.templater.ExecuteLogin(&LoginTemplateData{
 		common.Version,
 	}))
 }
 
 func (s *Server) handleLogout(w http.ResponseWriter, r *http.Request) {
-	s.Logout(w, r)
+	s.logout(w, r)
 	http.Redirect(w, r, "/login", http.StatusTemporaryRedirect)
 }
 
 func (s *Server) handleMessageDetails(w http.ResponseWriter, r *http.Request) {
 	//TODO: Not implemented yet. Need database mail storage implemented first
+	user, token := s.extractAuth(w, r)
+	if !s.authenticator.Verify(user, token) {
+		fmt.Fprint(w, "")
+		return
+	}
 	fmt.Fprint(w, s.templater.ExecuteDetails(""))
 }
 
+func (s *Server) handleStatusLine(w http.ResponseWriter, r *http.Request) {
+	//TODO: Not implemented yet. Need database mail storage implemented first
+	user, token := s.extractAuth(w, r)
+	if !s.authenticator.Verify(user, token) {
+		fmt.Fprint(w, "")
+		return
+	}
+
+	fmt.Fprint(w, s.templater.ExecuteStatusLine(&StatusLineTemplateData{
+		Name:   "No name", //TODO: read from database
+		Read:   0,         //TODO: read from database
+		Unread: 0,         //TODO: read from database
+	}))
+}
+
 func (s *Server) handleMailbox(w http.ResponseWriter, r *http.Request) {
 	user, token := s.extractAuth(w, r)
 	if !s.authenticator.Verify(user, token) {
-		s.Logout(w, r)
+		s.logout(w, r)
 		http.Redirect(w, r, "/login", http.StatusTemporaryRedirect)
 	}
 
 	mailPath := config.ConfigInstance().VMailboxBase + "/" + s.authenticator.MailPath(user)
 	if !utils.FileExists(mailPath) {
-		s.Logout(w, r)
-		s.Error(http.StatusInternalServerError, "Unable to access your mailbox. Please contact Administrator.", w, r)
+		s.logout(w, r)
+		s.error(http.StatusInternalServerError, "Unable to access your mailbox. Please contact Administrator.", w, r)
 		return
 	}
 
 	file, err := utils.OpenAndLockWait(mailPath)
 	if err != nil {
-		s.Logout(w, r)
-		s.Error(http.StatusInternalServerError, "Unable to access your mailbox. Please contact Administrator.", w, r)
+		s.logout(w, r)
+		s.error(http.StatusInternalServerError, "Unable to access your mailbox. Please contact Administrator.", w, r)
 		return
 	}
 	defer file.CloseAndUnlock()
@@ -279,7 +304,7 @@ func (s *Server) handleMailbox(w http.ResponseWriter, r *http.Request) {
 	}))
 }
 
-func (s *Server) Logout(w http.ResponseWriter, r *http.Request) {
+func (s *Server) logout(w http.ResponseWriter, r *http.Request) {
 	fmt.Println("logout")
 
 	session, _ := s.sessionStore.Get(r, CookieSessionToken)
@@ -288,7 +313,7 @@ func (s *Server) Logout(w http.ResponseWriter, r *http.Request) {
 	session.Save(r, w)
 }
 
-func (s *Server) Login(user, token string, w http.ResponseWriter, r *http.Request) {
+func (s *Server) login(user, token string, w http.ResponseWriter, r *http.Request) {
 	session, _ := s.sessionStore.Get(r, CookieSessionToken)
 	session.Values["user"] = user
 	session.Values["token"] = token
@@ -296,7 +321,7 @@ func (s *Server) Login(user, token string, w http.ResponseWriter, r *http.Reques
 	http.Redirect(w, r, "/mailbox", http.StatusTemporaryRedirect)
 }
 
-func (s *Server) Error(code int, text string, w http.ResponseWriter, r *http.Request) {
+func (s *Server) error(code int, text string, w http.ResponseWriter, r *http.Request) {
 	w.WriteHeader(http.StatusInternalServerError)
 	fmt.Fprint(w, s.templater.ExecuteError(&ErrorTemplateData{
 		Code: code,

+ 33 - 15
web/templater.go

@@ -33,19 +33,21 @@ import (
 )
 
 const (
-	IndexTemplateName    = "index.html"
-	MailListTemplateName = "maillist.html"
-	DetailsTemplateName  = "details.html"
-	ErrorTemplateName    = "error.html"
-	LoginTemplateName    = "login.html"
+	IndexTemplateName      = "index.html"
+	MailListTemplateName   = "maillist.html"
+	DetailsTemplateName    = "details.html"
+	ErrorTemplateName      = "error.html"
+	LoginTemplateName      = "login.html"
+	StatusLineTemplateName = "statusline.html"
 )
 
 type Templater struct {
-	indexTemplate    *template.Template
-	mailListTemplate *template.Template
-	detailsTemplate  *template.Template
-	errorTemplate    *template.Template
-	loginTemplate    *template.Template
+	indexTemplate      *template.Template
+	mailListTemplate   *template.Template
+	detailsTemplate    *template.Template
+	errorTemplate      *template.Template
+	loginTemplate      *template.Template
+	statusLineTemplate *template.Template
 }
 
 type IndexTemplateData struct {
@@ -64,6 +66,12 @@ type LoginTemplateData struct {
 	Version string
 }
 
+type StatusLineTemplateData struct {
+	Name   string
+	Read   int
+	Unread int
+}
+
 func NewTemplater(templatesPath string) (t *Templater) {
 	t = nil
 	index, err := parseTemplate(templatesPath + "/" + IndexTemplateName)
@@ -91,12 +99,18 @@ func NewTemplater(templatesPath string) (t *Templater) {
 		log.Fatal(err)
 	}
 
+	statusLine, err := parseTemplate(templatesPath + "/" + StatusLineTemplateName)
+	if err != nil {
+		log.Fatal(err)
+	}
+
 	t = &Templater{
-		indexTemplate:    index,
-		mailListTemplate: maillist,
-		detailsTemplate:  details,
-		errorTemplate:    errors,
-		loginTemplate:    login,
+		indexTemplate:      index,
+		mailListTemplate:   maillist,
+		detailsTemplate:    details,
+		errorTemplate:      errors,
+		loginTemplate:      login,
+		statusLineTemplate: statusLine,
 	}
 	return
 }
@@ -130,6 +144,10 @@ func (t *Templater) ExecuteLogin(data interface{}) string {
 	return executeTemplateCommon(t.loginTemplate, data)
 }
 
+func (t *Templater) ExecuteStatusLine(data interface{}) string {
+	return executeTemplateCommon(t.statusLineTemplate, data)
+}
+
 func executeTemplateCommon(t *template.Template, values interface{}) string {
 	buffer := &bytes.Buffer{}
 	err := t.Execute(buffer, values)

+ 5 - 0
web/templates/folders.html

@@ -0,0 +1,5 @@
+<div>
+    {{range .}}
+    <div class="folderBtn">{{.Folder.Name}}</div>
+    {{end}}
+</div>

+ 1 - 0
web/templates/index.html

@@ -15,6 +15,7 @@
                 <div class="btn materialLevel1" style="width: 110pt">New email</div>
                 {{.Folders}}
             </div>
+            <div id="statusLine"></div>
             <div class="materialLevel1 contentBox">
                 {{.MailList}}
             </div>

+ 1 - 0
web/templates/statusline.html

@@ -0,0 +1 @@
+Welcome {{.Name}}, you have {{.Read}}({{.Unread}}) messages