mirror of
https://github.com/miniflux/v2.git
synced 2025-08-11 17:51:01 +00:00
refactor(js): create utility functions to manage buttons state
This commit is contained in:
parent
b505a63f3b
commit
3bb965913d
1 changed files with 78 additions and 64 deletions
|
@ -177,6 +177,67 @@ function setIconAndLabelElement(parentElement, iconName, labelText) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the button to a loading state and return a clone of the original button element.
|
||||||
|
*
|
||||||
|
* @param {Element} buttonElement - The button element to set to loading state.
|
||||||
|
* @return {Element} The original button element cloned before modification.
|
||||||
|
*/
|
||||||
|
function setButtonToLoadingState(buttonElement) {
|
||||||
|
const originalButtonElement = buttonElement.cloneNode(true);
|
||||||
|
|
||||||
|
buttonElement.textContent = "";
|
||||||
|
buttonElement.appendChild(createIconLabelElement(buttonElement.dataset.labelLoading));
|
||||||
|
|
||||||
|
return originalButtonElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restore the button to its original state.
|
||||||
|
*
|
||||||
|
* @param {Element} buttonElement The button element to restore.
|
||||||
|
* @param {Element} originalButtonElement The original button element to restore from.
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
function restoreButtonState(buttonElement, originalButtonElement) {
|
||||||
|
buttonElement.textContent = "";
|
||||||
|
buttonElement.appendChild(originalButtonElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the button to a saved state.
|
||||||
|
*
|
||||||
|
* @param {Element} buttonElement The button element to set to saved state.
|
||||||
|
*/
|
||||||
|
function setButtonToSavedState(buttonElement) {
|
||||||
|
buttonElement.dataset.completed = "true";
|
||||||
|
setIconAndLabelElement(buttonElement, "save", buttonElement.dataset.labelDone);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the bookmark button state.
|
||||||
|
*
|
||||||
|
* @param {Element} buttonElement - The button element to update.
|
||||||
|
* @param {string} newState - The new state to set ("star" or "unstar").
|
||||||
|
*/
|
||||||
|
function setBookmarkButtonState(buttonElement, newState) {
|
||||||
|
buttonElement.dataset.value = newState;
|
||||||
|
const iconType = newState === "star" ? "unstar" : "star";
|
||||||
|
setIconAndLabelElement(buttonElement, iconType, buttonElement.dataset[newState === "star" ? "labelUnstar" : "labelStar"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the read status button state.
|
||||||
|
*
|
||||||
|
* @param {Element} buttonElement - The button element to update.
|
||||||
|
* @param {string} newState - The new state to set ("read" or "unread").
|
||||||
|
*/
|
||||||
|
function setReadStatusButtonState(buttonElement, newState) {
|
||||||
|
buttonElement.dataset.value = newState;
|
||||||
|
const iconType = newState === "read" ? "unread" : "read";
|
||||||
|
setIconAndLabelElement(buttonElement, iconType, buttonElement.dataset[newState === "read" ? "labelUnread" : "labelRead"]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show a toast notification.
|
* Show a toast notification.
|
||||||
*
|
*
|
||||||
|
@ -202,29 +263,7 @@ function showToastNotification(iconType, notificationMessage) {
|
||||||
|
|
||||||
document.body.appendChild(toastElementWrapper);
|
document.body.appendChild(toastElementWrapper);
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => toastElementWrapper.classList.add("toast-animate"), 100);
|
||||||
toastElementWrapper.classList.add("toast-animate");
|
|
||||||
|
|
||||||
}, 100);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Insert an icon label element into the parent element.
|
|
||||||
*
|
|
||||||
* @param {Element} parentElement The parent element to insert the icon label into.
|
|
||||||
* @param {string} iconLabelText The text to display in the icon label.
|
|
||||||
* @param {boolean} clearParentTextcontent If true, clear the parent's text content before appending the icon label.
|
|
||||||
* @returns {void}
|
|
||||||
*/
|
|
||||||
function insertIconLabelElement(parentElement, iconLabelText, clearParentTextcontent = true) {
|
|
||||||
const span = document.createElement('span');
|
|
||||||
span.classList.add('icon-label');
|
|
||||||
span.textContent = iconLabelText;
|
|
||||||
|
|
||||||
if (clearParentTextcontent) {
|
|
||||||
parentElement.textContent = '';
|
|
||||||
}
|
|
||||||
parentElement.appendChild(span);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -584,36 +623,21 @@ function handleEntryStatus(navigationDirection, element, setToRead) {
|
||||||
*/
|
*/
|
||||||
function toggleEntryStatus(element, toasting) {
|
function toggleEntryStatus(element, toasting) {
|
||||||
const entryID = parseInt(element.dataset.id, 10);
|
const entryID = parseInt(element.dataset.id, 10);
|
||||||
const link = element.querySelector(":is(a, button)[data-toggle-status]");
|
const buttonElement = element.querySelector(":is(a, button)[data-toggle-status]");
|
||||||
if (!link) {
|
if (!buttonElement) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const currentStatus = link.dataset.value;
|
const currentStatus = buttonElement.dataset.value;
|
||||||
const newStatus = currentStatus === "read" ? "unread" : "read";
|
const newStatus = currentStatus === "read" ? "unread" : "read";
|
||||||
|
|
||||||
link.querySelector("span").textContent = link.dataset.labelLoading;
|
setButtonToLoadingState(buttonElement);
|
||||||
|
|
||||||
updateEntriesStatus([entryID], newStatus, () => {
|
updateEntriesStatus([entryID], newStatus, () => {
|
||||||
let iconElement, label;
|
setReadStatusButtonState(buttonElement, newStatus);
|
||||||
|
|
||||||
if (currentStatus === "read") {
|
if (toasting) {
|
||||||
iconElement = document.querySelector("template#icon-read");
|
showToastNotification(currentStatus, currentStatus === "read" ? buttonElement.dataset.toastUnread : buttonElement.dataset.toastRead);
|
||||||
label = link.dataset.labelRead;
|
|
||||||
if (toasting) {
|
|
||||||
showToastNotification("read", link.dataset.toastUnread);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
iconElement = document.querySelector("template#icon-unread");
|
|
||||||
label = link.dataset.labelUnread;
|
|
||||||
if (toasting) {
|
|
||||||
showToastNotification("unread", link.dataset.toastUnread);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
link.replaceChildren(iconElement.content.cloneNode(true));
|
|
||||||
insertIconLabelElement(link, label, false);
|
|
||||||
link.dataset.value = newStatus;
|
|
||||||
|
|
||||||
if (element.classList.contains("item-status-" + currentStatus)) {
|
if (element.classList.contains("item-status-" + currentStatus)) {
|
||||||
element.classList.remove("item-status-" + currentStatus);
|
element.classList.remove("item-status-" + currentStatus);
|
||||||
element.classList.add("item-status-" + newStatus);
|
element.classList.add("item-status-" + newStatus);
|
||||||
|
@ -667,11 +691,10 @@ function handleSaveEntryAction(element = null) {
|
||||||
const buttonElement = currentEntry.querySelector(":is(a, button)[data-save-entry]");
|
const buttonElement = currentEntry.querySelector(":is(a, button)[data-save-entry]");
|
||||||
if (!buttonElement || buttonElement.dataset.completed) return;
|
if (!buttonElement || buttonElement.dataset.completed) return;
|
||||||
|
|
||||||
insertIconLabelElement(buttonElement, buttonElement.dataset.labelLoading);
|
setButtonToLoadingState(buttonElement);
|
||||||
|
|
||||||
sendPOSTRequest(buttonElement.dataset.saveUrl).then(() => {
|
sendPOSTRequest(buttonElement.dataset.saveUrl).then(() => {
|
||||||
insertIconLabelElement(buttonElement, buttonElement.dataset.labelDone);
|
setButtonToSavedState(buttonElement);
|
||||||
buttonElement.dataset.completed = "true";
|
|
||||||
if (isEntryView()) {
|
if (isEntryView()) {
|
||||||
showToastNotification("save", buttonElement.dataset.toastDone);
|
showToastNotification("save", buttonElement.dataset.toastDone);
|
||||||
}
|
}
|
||||||
|
@ -690,19 +713,13 @@ function handleBookmarkAction(element) {
|
||||||
const buttonElement = currentEntry.querySelector(":is(a, button)[data-toggle-bookmark]");
|
const buttonElement = currentEntry.querySelector(":is(a, button)[data-toggle-bookmark]");
|
||||||
if (!buttonElement) return;
|
if (!buttonElement) return;
|
||||||
|
|
||||||
insertIconLabelElement(buttonElement, buttonElement.dataset.labelLoading);
|
setButtonToLoadingState(buttonElement);
|
||||||
|
|
||||||
sendPOSTRequest(buttonElement.dataset.bookmarkUrl).then(() => {
|
sendPOSTRequest(buttonElement.dataset.bookmarkUrl).then(() => {
|
||||||
const currentStarStatus = buttonElement.dataset.value;
|
const isStarred = buttonElement.dataset.value === "star";
|
||||||
const newStarStatus = currentStarStatus === "star" ? "unstar" : "star";
|
const newStarStatus = isStarred ? "unstar" : "star";
|
||||||
const isStarred = currentStarStatus === "star";
|
|
||||||
|
|
||||||
const iconElement = document.querySelector(isStarred ? "template#icon-star" : "template#icon-unstar");
|
setBookmarkButtonState(buttonElement, newStarStatus);
|
||||||
const label = isStarred ? buttonElement.dataset.labelStar : buttonElement.dataset.labelUnstar;
|
|
||||||
|
|
||||||
buttonElement.replaceChildren(iconElement.content.cloneNode(true));
|
|
||||||
insertIconLabelElement(buttonElement, label, false);
|
|
||||||
buttonElement.dataset.value = newStarStatus;
|
|
||||||
|
|
||||||
if (isEntryView()) {
|
if (isEntryView()) {
|
||||||
showToastNotification(newStarStatus, buttonElement.dataset[isStarred ? "toastUnstar" : "toastStar"]);
|
showToastNotification(newStarStatus, buttonElement.dataset[isStarred ? "toastUnstar" : "toastStar"]);
|
||||||
|
@ -721,13 +738,10 @@ function handleFetchOriginalContentAction() {
|
||||||
const buttonElement = document.querySelector(":is(a, button)[data-fetch-content-entry]");
|
const buttonElement = document.querySelector(":is(a, button)[data-fetch-content-entry]");
|
||||||
if (!buttonElement) return;
|
if (!buttonElement) return;
|
||||||
|
|
||||||
const previousElement = buttonElement.cloneNode(true);
|
const originalButtonElement = setButtonToLoadingState(buttonElement);
|
||||||
|
|
||||||
insertIconLabelElement(buttonElement, buttonElement.dataset.labelLoading);
|
|
||||||
|
|
||||||
sendPOSTRequest(buttonElement.dataset.fetchContentUrl).then((response) => {
|
sendPOSTRequest(buttonElement.dataset.fetchContentUrl).then((response) => {
|
||||||
buttonElement.textContent = '';
|
restoreButtonState(buttonElement, originalButtonElement);
|
||||||
buttonElement.appendChild(previousElement);
|
|
||||||
|
|
||||||
response.json().then((data) => {
|
response.json().then((data) => {
|
||||||
if (data.content && data.reading_time) {
|
if (data.content && data.reading_time) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue