Use SVG icons for toast notifications

This commit is contained in:
Frédéric Guillot 2021-03-07 11:55:43 -08:00 committed by fguillot
parent f6ed2feab4
commit 548c4d4efe
5 changed files with 62 additions and 43 deletions

View file

@ -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 }}

View file

@ -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>

View file

@ -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"/>

View file

@ -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;
}

View file

@ -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);
}
}
}