Преглед на файлове

Use SVG icons for toast notifications

Frédéric Guillot преди 5 години
родител
ревизия
548c4d4efe
променени са 5 файла, в които са добавени 62 реда и са изтрити 43 реда
  1. 11 7
      template/templates/common/layout.html
  2. 4 4
      template/templates/views/entry.html
  3. 10 7
      ui/static/bin/sprite.svg
  4. 6 4
      ui/static/css/common.css
  5. 31 21
      ui/static/js/app.js

+ 11 - 7
template/templates/common/layout.html

@@ -46,9 +46,7 @@
     data-entries-status-url="{{ route "updateEntriesStatus" }}"
     data-refresh-all-feeds-url="{{ route "refreshAllFeeds" }}"
     {{ if .user }}{{ if not .user.KeyboardShortcuts }}data-disable-keyboard-shortcuts="true"{{ end }}{{ end }}>
-    <div class="toast-wrap">
-        <span class="toast-msg"></span>
-    </div>
+
     {{ if .user }}
     <header class="header">
         <nav>
@@ -157,10 +155,16 @@
             </div>
         </div>
     </template>
-    <template id="icon_read">{{ icon "read" }}</template>
-    <template id="icon_unread">{{ icon "unread" }}</template>
-    <template id="icon_star">{{ icon "star" }}</template>
-    <template id="icon_unstar">{{ icon "unstar" }}</template>
+
+    <template id="icon-read">{{ icon "read" }}</template>
+    <template id="icon-unread">{{ icon "unread" }}</template>
+    <template id="icon-star">{{ icon "star" }}</template>
+    <template id="icon-unstar">{{ icon "unstar" }}</template>
+    <template id="icon-save">{{ icon "save" }}</template>
+
+    <div id="toast-wrapper" role="alert" aria-live="assertive" aria-atomic="true">
+        <span id="toast-msg"></span>
+    </div>
 </body>
 </html>
 {{ end }}

+ 4 - 4
template/templates/views/entry.html

@@ -15,8 +15,8 @@
                         data-toggle-status="true"
                         data-label-unread="{{ t "entry.status.unread" }}"
                         data-label-read="{{ t "entry.status.read" }}"
-                        data-toast-unread="✘&nbsp;{{ t "entry.status.toast.unread" }}"
-                        data-toast-read="✔︎&nbsp;{{ t "entry.status.toast.read" }}"
+                        data-toast-unread="{{ t "entry.status.toast.unread" }}"
+                        data-toast-read="{{ t "entry.status.toast.read" }}"
                         data-value="{{ if eq .entry.Status "read" }}read{{ else }}unread{{ end }}"
                         >{{ if eq .entry.Status "unread" }}{{ icon "read" }}{{ else }}{{ icon "unread" }}{{ end }}<span class="icon-label">{{ if eq .entry.Status "unread" }}{{ t "entry.status.read" }}{{ else }}{{ t "entry.status.unread" }}{{ end }}</span></a>
                 </li>
@@ -27,8 +27,8 @@
                         data-label-loading="{{ t "entry.state.saving" }}"
                         data-label-star="{{ t "entry.bookmark.toggle.on" }}"
                         data-label-unstar="{{ t "entry.bookmark.toggle.off" }}"
-                        data-toast-star="★&nbsp;{{ t "entry.bookmark.toast.on" }}"
-                        data-toast-unstar="☆&nbsp;{{ t "entry.bookmark.toast.off" }}"
+                        data-toast-star="{{ t "entry.bookmark.toast.on" }}"
+                        data-toast-unstar="{{ t "entry.bookmark.toast.off" }}"
                         data-value="{{ if .entry.Starred }}star{{ else }}unstar{{ end }}"
                         >{{ if .entry.Starred }}{{ icon "unstar" }}{{ else }}{{ icon "star" }}{{ end }}<span class="icon-label">{{ if .entry.Starred }}{{ t "entry.bookmark.toggle.off" }}{{ else }}{{ t "entry.bookmark.toggle.on" }}{{ end }}</span></a>
                 </li>

+ 10 - 7
ui/static/bin/sprite.svg

@@ -22,6 +22,8 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
 
+Source: https://github.com/tabler/tabler-icons
+
 -->
 <svg xmlns="http://www.w3.org/2000/svg">
     <symbol id="icon-read" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
@@ -43,10 +45,10 @@ SOFTWARE.
         <path fill="currentColor" d="M12 17.75l-6.172 3.245 1.179-6.873-4.993-4.867 6.9-1.002L12 2l3.086 6.253 6.9 1.002-4.993 4.867 1.179 6.873z" />
     </symbol>
     <symbol id="icon-save" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
-        <path stroke="none" d="M0 0h24v24H0z"/>
-        <path d="M4 17v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2 -2v-2" />
-        <polyline points="7 11 12 16 17 11" />
-        <line x1="12" y1="4" x2="12" y2="16" />
+        <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
+        <path d="M6 4h10l4 4v10a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2v-12a2 2 0 0 1 2 -2"></path>
+        <circle cx="12" cy="14" r="2"></circle>
+        <polyline points="14 4 14 8 8 8 8 4"></polyline>
     </symbol>
     <symbol id="icon-scraper" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
         <path stroke="none" d="M0 0h24v24H0z"/>
@@ -90,9 +92,10 @@ SOFTWARE.
         <line x1="16" y1="5" x2="19" y2="8" />
     </symbol>
     <symbol id="icon-feeds" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
-        <path stroke="none" d="M0 0h24v24H0z"/>
-        <path d="M9 4h3l2 2h5a2 2 0 0 1 2 2v7a2 2 0 0 1 -2 2h-10a2 2 0 0 1 -2 -2v-9a2 2 0 0 1 2 -2" />
-        <path d="M17 17v2a2 2 0 0 1 -2 2h-10a2 2 0 0 1 -2 -2v-9a2 2 0 0 1 2 -2h2" />
+        <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
+        <circle cx="5" cy="19" r="1"></circle>
+        <path d="M4 4a16 16 0 0 1 16 16"></path>
+        <path d="M4 11a9 9 0 0 1 9 9"></path>
     </symbol>
     <symbol id="icon-entries" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
         <path stroke="none" d="M0 0h24v24H0z"/>

+ 6 - 4
ui/static/css/common.css

@@ -184,7 +184,7 @@ a:hover {
 }
 
 /* Notification - "Toast" */
-.toast-wrap {
+#toast-wrapper {
     visibility: hidden;
     opacity: 0;
     position: fixed;
@@ -195,13 +195,15 @@ a:hover {
     text-align: center;
 }
 
-.toast-msg {
+#toast-msg {
     background-color: rgba(0,0,0,0.7);
-    padding: 2px 5px;
+    padding-bottom: 4px;
+    padding-left: 4px;
+    padding-right: 5px;
     border-radius: 5px;
 }
 
-.toastAnimate {
+.toast-animate {
     animation: toastKeyFrames 2s;
 }
 

+ 31 - 21
ui/static/js/app.js

@@ -136,23 +136,23 @@ function toggleEntryStatus(element, toasting) {
 
     updateEntriesStatus([entryID], newStatus);
 
-    let icon, label;
+    let iconElement, label;
 
     if (currentStatus === "read") {
-        icon = document.querySelector("template#icon_read");
+        iconElement = document.querySelector("template#icon-read");
         label = link.dataset.labelRead;
         if (toasting) {
-            toast(link.dataset.toastUnread);
+            showToast(link.dataset.toastUnread, iconElement);
         }
     } else {
-        icon = document.querySelector("template#icon_unread");
+        iconElement = document.querySelector("template#icon-unread");
         label = link.dataset.labelUnread;
         if (toasting) {
-            toast(link.dataset.toastRead);
+            showToast(link.dataset.toastRead, iconElement);
         }
     }
 
-    link.innerHTML = icon.innerHTML + '<span class="icon-label">' + label + '</span>';
+    link.innerHTML = iconElement.innerHTML + '<span class="icon-label">' + label + '</span>';
     link.dataset.value = newStatus;
 
     if (element.classList.contains("item-status-" + currentStatus)) {
@@ -227,7 +227,8 @@ function saveEntry(element, toasting) {
         element.innerHTML = previousInnerHTML;
         element.dataset.completed = true;
         if (toasting) {
-            toast(element.dataset.toastDone);
+            let iconElement = document.querySelector("template#icon-save");
+            showToast(element.dataset.toastDone, iconElement);
         }
     });
     request.execute();
@@ -257,23 +258,23 @@ function toggleBookmark(parentElement, toasting) {
         let currentStarStatus = element.dataset.value;
         let newStarStatus = currentStarStatus === "star" ? "unstar" : "star";
 
-        let icon, label;
+        let iconElement, label;
 
         if (currentStarStatus === "star") {
-            icon = document.querySelector("template#icon_star");
+            iconElement = document.querySelector("template#icon-star");
             label = element.dataset.labelStar;
             if (toasting) {
-                toast(element.dataset.toastUnstar);
+                showToast(element.dataset.toastUnstar, iconElement);
             }
         } else {
-            icon = document.querySelector("template#icon_unstar");
+            iconElement = document.querySelector("template#icon-unstar");
             label = element.dataset.labelUnstar;
             if (toasting) {
-                toast(element.dataset.toastStar);
+                showToast(element.dataset.toastStar, iconElement);
             }
         }
 
-        element.innerHTML = icon.innerHTML + '<span class="icon-label">' + label + '</span>';
+        element.innerHTML = iconElement.innerHTML + '<span class="icon-label">' + label + '</span>';
         element.dataset.value = newStarStatus;
     });
     request.execute();
@@ -592,12 +593,21 @@ function handleConfirmationMessage(linkElement, callback) {
     containerElement.appendChild(questionElement);
 }
 
-function toast(msg) {
-    if (!msg) return;
-    document.querySelector('.toast-wrap .toast-msg').innerHTML = msg;
-    let toastWrapper = document.querySelector('.toast-wrap');
-    toastWrapper.classList.remove('toastAnimate');
-    setTimeout(function () {
-        toastWrapper.classList.add('toastAnimate');
-    }, 100);
+function showToast(label, iconElement) {
+    if (!label || !iconElement) {
+        return;
+    }
+
+    const toastMsgElement = document.getElementById("toast-msg");
+    if (toastMsgElement) {
+        toastMsgElement.innerHTML = iconElement.innerHTML + '<span class="icon-label">' + label + '</span>';
+
+        const toastElementWrapper = document.getElementById("toast-wrapper");
+        if (toastElementWrapper) {
+            toastElementWrapper.classList.remove('toast-animate');
+            setTimeout(function () {
+                toastElementWrapper.classList.add('toast-animate');
+            }, 100);
+        }
+    }
 }