mirror of
https://github.com/miniflux/v2.git
synced 2025-08-11 17:51:01 +00:00
refactor(js): rewrite toast notification implementation
This commit is contained in:
parent
e9d9256ae2
commit
b505a63f3b
2 changed files with 72 additions and 34 deletions
|
@ -199,10 +199,6 @@
|
|||
<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 }}
|
||||
|
|
|
@ -143,6 +143,71 @@ function findEntry(element) {
|
|||
return document.querySelector(".entry");
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an icon label element with the given text.
|
||||
*
|
||||
* @param {string} labelText - The text to display in the icon label.
|
||||
* @returns {Element} The created icon label element.
|
||||
*/
|
||||
function createIconLabelElement(labelText) {
|
||||
const labelElement = document.createElement("span");
|
||||
labelElement.classList.add("icon-label");
|
||||
labelElement.textContent = labelText;
|
||||
return labelElement;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the icon and label element in the parent element.
|
||||
*
|
||||
* @param {Element} parentElement - The parent element to insert the icon and label into.
|
||||
* @param {string} iconName - The name of the icon to display.
|
||||
* @param {string} labelText - The text to display in the label.
|
||||
*/
|
||||
function setIconAndLabelElement(parentElement, iconName, labelText) {
|
||||
const iconElement = document.querySelector(`template#icon-${iconName}`);
|
||||
if (iconElement) {
|
||||
const iconClone = iconElement.content.cloneNode(true);
|
||||
parentElement.textContent = ""; // Clear existing content
|
||||
parentElement.appendChild(iconClone);
|
||||
}
|
||||
|
||||
if (labelText) {
|
||||
const labelElement = createIconLabelElement(labelText);
|
||||
parentElement.appendChild(labelElement);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a toast notification.
|
||||
*
|
||||
* @param {string} iconType - The type of icon to display.
|
||||
* @param {string} notificationMessage - The message to display in the toast.
|
||||
* @returns {void}
|
||||
*/
|
||||
function showToastNotification(iconType, notificationMessage) {
|
||||
const toastMsgElement = document.createElement("span");
|
||||
toastMsgElement.id = "toast-msg";
|
||||
|
||||
setIconAndLabelElement(toastMsgElement, iconType, notificationMessage);
|
||||
|
||||
const toastElementWrapper = document.createElement("div");
|
||||
toastElementWrapper.id = "toast-wrapper";
|
||||
toastElementWrapper.setAttribute("role", "alert");
|
||||
toastElementWrapper.setAttribute("aria-live", "assertive");
|
||||
toastElementWrapper.setAttribute("aria-atomic", "true");
|
||||
toastElementWrapper.appendChild(toastMsgElement);
|
||||
toastElementWrapper.addEventListener("animationend", () => {
|
||||
toastElementWrapper.remove();
|
||||
});
|
||||
|
||||
document.body.appendChild(toastElementWrapper);
|
||||
|
||||
setTimeout(() => {
|
||||
toastElementWrapper.classList.add("toast-animate");
|
||||
|
||||
}, 100);
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert an icon label element into the parent element.
|
||||
*
|
||||
|
@ -492,12 +557,11 @@ function markPageAsReadAction() {
|
|||
* @returns {void}
|
||||
*/
|
||||
function handleEntryStatus(navigationDirection, element, setToRead) {
|
||||
const toasting = !element;
|
||||
const currentEntry = findEntry(element);
|
||||
|
||||
if (currentEntry) {
|
||||
if (!setToRead || currentEntry.querySelector(":is(a, button)[data-toggle-status]").dataset.value === "unread") {
|
||||
toggleEntryStatus(currentEntry, toasting);
|
||||
toggleEntryStatus(currentEntry, isEntryView());
|
||||
}
|
||||
if (isListView() && currentEntry.classList.contains('current-item')) {
|
||||
switch (navigationDirection) {
|
||||
|
@ -536,13 +600,13 @@ function toggleEntryStatus(element, toasting) {
|
|||
iconElement = document.querySelector("template#icon-read");
|
||||
label = link.dataset.labelRead;
|
||||
if (toasting) {
|
||||
showToast(link.dataset.toastUnread, iconElement);
|
||||
showToastNotification("read", link.dataset.toastUnread);
|
||||
}
|
||||
} else {
|
||||
iconElement = document.querySelector("template#icon-unread");
|
||||
label = link.dataset.labelUnread;
|
||||
if (toasting) {
|
||||
showToast(link.dataset.toastRead, iconElement);
|
||||
showToastNotification("unread", link.dataset.toastUnread);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -608,8 +672,8 @@ function handleSaveEntryAction(element = null) {
|
|||
sendPOSTRequest(buttonElement.dataset.saveUrl).then(() => {
|
||||
insertIconLabelElement(buttonElement, buttonElement.dataset.labelDone);
|
||||
buttonElement.dataset.completed = "true";
|
||||
if (!element) {
|
||||
showToast(buttonElement.dataset.toastDone, document.querySelector("template#icon-save"));
|
||||
if (isEntryView()) {
|
||||
showToastNotification("save", buttonElement.dataset.toastDone);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -640,9 +704,8 @@ function handleBookmarkAction(element) {
|
|||
insertIconLabelElement(buttonElement, label, false);
|
||||
buttonElement.dataset.value = newStarStatus;
|
||||
|
||||
if (!element) {
|
||||
const toastKey = isStarred ? "toastUnstar" : "toastStar";
|
||||
showToast(buttonElement.dataset[toastKey], iconElement);
|
||||
if (isEntryView()) {
|
||||
showToastNotification(newStarStatus, buttonElement.dataset[isStarred ? "toastUnstar" : "toastStar"]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -877,27 +940,6 @@ function handleConfirmationMessage(linkElement, callback) {
|
|||
containerElement.appendChild(questionElement);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a toast notification.
|
||||
*
|
||||
* @param {string} toastMessage - The label to display in the toast.
|
||||
* @param {Element} iconElement - The icon element to display in the toast.
|
||||
* @returns {void}
|
||||
*/
|
||||
function showToast(toastMessage, iconElement) {
|
||||
if (!toastMessage || !iconElement) {
|
||||
return;
|
||||
}
|
||||
|
||||
const toastMsgElement = document.getElementById("toast-msg");
|
||||
toastMsgElement.replaceChildren(iconElement.content.cloneNode(true));
|
||||
insertIconLabelElement(toastMsgElement, toastMessage);
|
||||
|
||||
const toastElementWrapper = document.getElementById("toast-wrapper");
|
||||
toastElementWrapper.classList.remove('toast-animate');
|
||||
setTimeout(() => toastElementWrapper.classList.add('toast-animate'), 100);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the player is actually playing a media
|
||||
*
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue