Parcourir la source

Add account selector

Alexey Edelev il y a 5 ans
Parent
commit
6622b046db

+ 45 - 0
web/assets/down.svg

@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   enable-background="new 0 0 32 32"
+   height="32px"
+   id="Layer_1"
+   version="1.1"
+   viewBox="0 0 32 32"
+   width="32px"
+   xml:space="preserve"
+   sodipodi:docname="down.svg"
+   inkscape:version="0.92.4 5da689c313, 2019-01-14"><metadata
+     id="metadata9"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+     id="defs7" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="745"
+     inkscape:window-height="480"
+     id="namedview5"
+     showgrid="false"
+     inkscape:zoom="7.375"
+     inkscape:cx="16"
+     inkscape:cy="21.423729"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="Layer_1" /><path
+     d="m 17.71925,22.795152 9.586,-9.585999 c 0.878,-0.878 0.878,-2.317 0,-3.195 l -0.8,-0.8 c -0.877,-0.878 -2.316,-0.878 -3.194,0 l -7.316,7.314 -7.315,-7.315 c -0.878,-0.878 -2.317,-0.878 -3.194,0 l -0.8,0.8 c -0.879,0.878 -0.879,2.317 0,3.195 l 9.587,9.585999 c 0.471,0.472 1.103,0.682 1.723,0.647 0.619,0.036 1.251,-0.174 1.723,-0.646 z"
+     id="path2"
+     inkscape:connector-curvature="0"
+     style="fill:#515151" /></svg>

+ 58 - 1
web/css/controls.css

@@ -8,7 +8,7 @@
 
 
     border-width: 0;
     border-width: 0;
     outline: none;
     outline: none;
-    box-shadow: 0 1pt 4pt rgba(0, 0, 0, .6);
+    box-shadow: 0 1pt 3pt rgba(0, 0, 0, .6);
 
 
     background-color: var(--primary-color);
     background-color: var(--primary-color);
     color: var(--secondary-text-color);
     color: var(--secondary-text-color);
@@ -17,6 +17,13 @@
     font-weight: bold;
     font-weight: bold;
     text-align: center;
     text-align: center;
     transition: background-color .3s;
     transition: background-color .3s;
+
+    -webkit-touch-callout: none;
+    -webkit-user-select: none;
+    -khtml-user-select: none;
+    -moz-user-select: none;
+    -ms-user-select: none;
+    user-select: none;
 }
 }
 
 
 .btn:hover, .btn:focus {
 .btn:hover, .btn:focus {
@@ -208,6 +215,13 @@
     border-bottom-right-radius: var(--default-radius);
     border-bottom-right-radius: var(--default-radius);
     border-top-right-radius: var(--default-radius);
     border-top-right-radius: var(--default-radius);
     background-color: var(--secondary-color);
     background-color: var(--secondary-color);
+
+    -webkit-touch-callout: none;
+    -webkit-user-select: none;
+    -khtml-user-select: none;
+    -moz-user-select: none;
+    -ms-user-select: none;
+    user-select: none;
 }
 }
 
 
 .folderBtn:hover {
 .folderBtn:hover {
@@ -222,4 +236,47 @@
 .iconBtn {
 .iconBtn {
     width: 20pt;
     width: 20pt;
     min-width: 20pt;
     min-width: 20pt;
+}
+
+/* Dropdown Button */
+.dropbtn {
+    display: inline;
+    background-color: var(--bg-color);
+    color: var(--primary-text-color);
+    font-size: 12pt;
+    cursor: pointer;
+    padding: var(--base-text-padding);
+}
+
+.dropdown-content {
+    display: none;
+    position: absolute;
+    margin-top: var(--base-text-padding);
+
+    background-color: var(--bg-color);
+    min-width: 160pt;
+    box-shadow: 0 1pt 3pt rgba(0, 0, 0, .6);
+    z-index: 1;
+}
+
+.dropdown-content a {
+    padding: var(--base-text-padding);
+    text-decoration: none;
+    display: block;
+
+    -webkit-touch-callout: none;
+    -webkit-user-select: none;
+    -khtml-user-select: none;
+    -moz-user-select: none;
+    -ms-user-select: none;
+    user-select: none;
+}
+
+.noselect {
+    -webkit-touch-callout: none;
+    -webkit-user-select: none;
+    -khtml-user-select: none;
+    -moz-user-select: none;
+    -ms-user-select: none;
+    user-select: none;
 }
 }

+ 3 - 1
web/css/index.css

@@ -27,11 +27,13 @@ html, body {
 }
 }
 
 
 #statusLine {
 #statusLine {
+    display: flex;
     flex: 1 1 auto;
     flex: 1 1 auto;
     text-overflow: ellipsis;
     text-overflow: ellipsis;
     overflow: hidden;
     overflow: hidden;
     white-space: nowrap;
     white-space: nowrap;
     padding: var(--base-text-padding);
     padding: var(--base-text-padding);
+    min-height: 50pt;
 }
 }
 
 
 #pager {
 #pager {
@@ -154,4 +156,4 @@ html, body {
     right: 0;
     right: 0;
 
 
     padding: 5pt;
     padding: 5pt;
-}
+}

+ 11 - 0
web/css/styles.css

@@ -8,6 +8,7 @@
     --secondary-color: #ebffee;
     --secondary-color: #ebffee;
     --secondary-dark-color: #b8d4bc;
     --secondary-dark-color: #b8d4bc;
     --bg-color: #ffffff;
     --bg-color: #ffffff;
+    --bg-dark-color: #ebffee;
     --primary-text-color: #000000;
     --primary-text-color: #000000;
     --primary-text-dark-color: #000000;
     --primary-text-dark-color: #000000;
     --secondary-text-color: #ffffff;
     --secondary-text-color: #ffffff;
@@ -79,4 +80,14 @@ body {
 }
 }
 
 
 .iconBtn:hover {
 .iconBtn:hover {
+}
+
+.dropdown-content a {
+    color: var(--primary-text-color);
+    background-color: var(--bg-color);
+    transition: background-color .3s;
+}
+
+.dropdown-content a:hover, a:focus {
+    background-color: var(--bg-dark-color);
 }
 }

+ 18 - 0
web/js/index.js

@@ -33,6 +33,20 @@ var pageMax = 10
 const mailboxRegex = /^(\/m\d+)/g
 const mailboxRegex = /^(\/m\d+)/g
 var folders = new Array()
 var folders = new Array()
 
 
+$(window).click(function(e){
+    var target = $(e.target)
+    var isDropDown = false
+    for (var i = 0; i < target.parents().length; i++) {
+        isDropDown = target.parents()[i].classList.contains("dropbtn")
+        if (isDropDown) {
+            break
+        }
+    }
+    if (!e.target.matches('.dropbtn') && !isDropDown) {
+        $(".dropdown-content").hide()
+    }
+})
+
 $(document).ready(function(){
 $(document).ready(function(){
     $.ajaxSetup({
     $.ajaxSetup({
         global: false,
         global: false,
@@ -308,4 +322,8 @@ function nextPage() {
 function prevPage() {
 function prevPage() {
     var newPage = currentPage > 0 ? currentPage - 1 : 0
     var newPage = currentPage > 0 ? currentPage - 1 : 0
     window.location.hash = currentFolder + newPage
     window.location.hash = currentFolder + newPage
+}
+
+function toggleDropDown(dd) {
+    $("#"+dd).toggle()
 }
 }

+ 30 - 6
web/mailbox.go

@@ -175,15 +175,39 @@ func (s *Server) handleStatusLine(w http.ResponseWriter, user, email string) {
 		return
 		return
 	}
 	}
 
 
+	type EmailIndexes struct {
+		Index int
+		Email string
+	}
+	emails, err := s.storage.GetEmails(user)
+	emailsIndexes := []EmailIndexes{}
+
+	k := 0
+	for i, existingEmail := range emails {
+		emailsIndexes = append(emailsIndexes, EmailIndexes{i, existingEmail})
+
+		if existingEmail == email {
+			k = i
+		}
+	}
+
+	emailsIndexes = emailsIndexes[:k+copy(emailsIndexes[k:], emailsIndexes[k+1:])]
+	if err != nil {
+		s.error(http.StatusInternalServerError, "Could not read user info", w)
+		return
+	}
+
 	emailHash := md5.Sum([]byte(strings.Trim(email, "\t ")))
 	emailHash := md5.Sum([]byte(strings.Trim(email, "\t ")))
 	fmt.Fprint(w, s.templater.ExecuteStatusLine(&struct {
 	fmt.Fprint(w, s.templater.ExecuteStatusLine(&struct {
-		Name      string
-		Email     string
-		EmailHash string
+		Name          string
+		Email         string
+		EmailHash     string
+		EmailsIndexes []EmailIndexes
 	}{
 	}{
-		Name:      info.FullName,
-		Email:     email,
-		EmailHash: hex.EncodeToString(emailHash[:]),
+		Name:          info.FullName,
+		Email:         email,
+		EmailHash:     hex.EncodeToString(emailHash[:]),
+		EmailsIndexes: emailsIndexes,
 	}))
 	}))
 }
 }
 
 

+ 4 - 4
web/templates/index.html

@@ -14,12 +14,12 @@
         <div id="main">
         <div id="main">
             <div id="headerBox">
             <div id="headerBox">
                 <div id="statusLine"></div>
                 <div id="statusLine"></div>
-                <div id="pager">
+                <div id="pager" class="noselect">
                     <img style="width: 20pt;" src="/assets/prev.svg" onclick="prevPage()">
                     <img style="width: 20pt;" src="/assets/prev.svg" onclick="prevPage()">
                     <div style="width: 60pt;display: flex;">
                     <div style="width: 60pt;display: flex;">
-                        <span id="currentPageIndex" style="margin:auto"></span>
-                        <span style="margin:auto">/</span>
-                        <span id="totalPageCount" style="margin:auto"></span>
+                        <span id="currentPageIndex" style="margin:auto" class="noselect"></span>
+                        <span style="margin:auto" class="noselect">/</span>
+                        <span id="totalPageCount" style="margin:auto" class="noselect"></span>
                     </div>
                     </div>
                     <img style="width: 20pt;" src="/assets/next.svg" onclick="nextPage()">
                     <img style="width: 20pt;" src="/assets/next.svg" onclick="nextPage()">
                 </div>
                 </div>

+ 4 - 4
web/templates/maillist.html

@@ -1,9 +1,9 @@
 <!-- <div class="fadeIn" style="position: absolute; top: 5pt; left: 0; right: 0; height: 10pt"></div> -->
 <!-- <div class="fadeIn" style="position: absolute; top: 5pt; left: 0; right: 0; height: 10pt"></div> -->
 {{range .}}
 {{range .}}
-<div id="mail{{.Id}}" class="mailHeader {{if .Read}}read{{else}}unread{{end}}" onclick="openEmail('{{.Id}}');">
-    <div class="mailFrom">{{.Mail.Header.From}}</div>
-    <div class="mailSubject">{{.Mail.Header.Subject}}</div>
-    <div id="mailDate{{.Id}}" class="mailDate" onload="$('#mailDate{{.Id}}').html(localDate({{.Mail.Header.Date}}))">{{.Mail.Header.Subject}}</div>
+<div id="mail{{.Id}}" class="mailHeader noselect {{if .Read}}read{{else}}unread{{end}}" onclick="openEmail('{{.Id}}');">
+    <div class="mailFrom noselect">{{.Mail.Header.From}}</div>
+    <div class="mailSubject noselect">{{.Mail.Header.Subject}}</div>
+    <div id="mailDate{{.Id}}" class="mailDate noselect" onload="$('#mailDate{{.Id}}').html(localDate({{.Mail.Header.Date}}))">{{.Mail.Header.Subject}}</div>
 </div>
 </div>
 {{end}}
 {{end}}
 <!-- <div class="fadeOut" style="position: absolute; bottom: 5pt; left: 0; right: 0; height:10pt"></div> -->
 <!-- <div class="fadeOut" style="position: absolute; bottom: 5pt; left: 0; right: 0; height:10pt"></div> -->

+ 16 - 1
web/templates/statusline.html

@@ -1 +1,16 @@
-<img src="https://www.gravatar.com/avatar/{{.EmailHash}}?s=70&d=monsterid" style="border-radius: 100%; border-color: var(--primary-color); border-width: 2pt; border-style: solid;"> {{.Name}} {{.Email}}
+<div class="dropbtn materialLevel1" onclick="toggleDropDown('emailSelector')">
+    <div style="display: flex;" class="noselect">
+        <img src="https://www.gravatar.com/avatar/{{.EmailHash}}?s=100&d=monsterid" style="border-radius: 100%; border-color: var(--primary-color); border-width: 2pt; border-style: solid; height: 30pt; width: 30pt;">
+        <div style="margin-top: auto; margin-bottom: auto; margin-left: 10pt;" class="noselect">
+            {{.Name}} {{.Email}}
+        </div>
+    </div>
+    <div id="emailSelector" class="dropdown-content">
+        {{range .EmailsIndexes}}
+        <a href="/m{{.Index}}">{{.Email}}</a>
+        {{end}}
+    </div>
+    <div class="noselect" style="position: relative;">
+        <img src="/assets/down.svg" style="position: absolute; bottom: 0; right: 0; margin-right: -5pt; margin-bottom: -5pt; height: 7pt;">
+    </div>
+</div>