From 94ed8835717df757fef6b0ae2d7cbb2d199ae4d8 Mon Sep 17 00:00:00 2001 From: Arkerthan <arkerthan@mailbox.org> Date: Mon, 12 Sep 2022 18:39:29 +0200 Subject: [PATCH] Allow showing arbitrarily many reminder displays --- src/js/reminder.js | 91 +++++++++++++++++++++--------- src/zz1-last/setupEventHandlers.js | 1 + 2 files changed, 66 insertions(+), 26 deletions(-) diff --git a/src/js/reminder.js b/src/js/reminder.js index 719581a6c74..595923d3a6d 100644 --- a/src/js/reminder.js +++ b/src/js/reminder.js @@ -1,6 +1,9 @@ App.Reminders = (function() { - const displayDiv = document.createElement("div"); - const addDiv = document.createElement("div"); + /** + * @type {Array<function():void>} + */ + let activeViewRefreshers = []; + return { add: add, list: list, @@ -8,6 +11,7 @@ App.Reminders = (function() { slaveDisplay: slaveDisplay, slaveLink: slaveLink, dialog: dialog, + clear: clearActive, }; /** @@ -15,10 +19,11 @@ App.Reminders = (function() { * @param {number} week * @param {string} [category] * @param {number} [slaveID] + * @returns {boolean} Whether a reminder was actually added or we aborted. */ function add(message, week, category = "manual", slaveID = 0) { if (message === "" || message === null) { - return; + return false; } const entry = {message: message, week: week, category: category}; if (slaveID) { @@ -32,6 +37,7 @@ App.Reminders = (function() { } else { V.reminders.splice(index, 0, entry); } + return true; } /** @@ -52,28 +58,23 @@ App.Reminders = (function() { const outerSpan = document.createElement("span"); - function replace() { - App.UI.DOM.replace(outerSpan, list({maxFuture, filter, link})); - App.Utils.scheduleSidebarRefresh(); - } - /** * @param {FC.ReminderEntry} entry */ function clearEntry(entry) { V.reminders.splice(V.reminders.indexOf(entry), 1); - replace(); + refreshActive(); } // We only want to remove visible entries function clearOverdue() { V.reminders = V.reminders.filter(e => e.week >= V.week || e.week > V.week + maxFuture || !filter(e)); - replace(); + refreshActive(); } function clearAll() { V.reminders = V.reminders.filter(e => e.week > V.week + maxFuture || !filter(e)); - replace(); + refreshActive(); } let overdue = 0; @@ -126,25 +127,27 @@ App.Reminders = (function() { } /** - * @param {function():void} refresh * @param {string} [category] * @param {number} [slaveID] * @returns {HTMLDivElement} */ - function addField(refresh, category, slaveID) { - jQuery(addDiv).empty(); + function addField(category, slaveID) { + const addDiv = document.createElement("div"); let entry = ""; let week = 0; addDiv.append( - App.UI.DOM.makeTextBox("", v => { entry = v; }), - " in ", App.UI.DOM.makeTextBox(0, v => { week = v; }, true), " weeks.", + App.UI.DOM.makeTextBox("", v => { + entry = v; + }), + " in ", App.UI.DOM.makeTextBox(0, v => { + week = v; + }, true), " weeks.", " ", App.UI.DOM.link("Add", () => { - add(entry, V.week + week, category, slaveID); - refresh(); - App.Utils.scheduleSidebarRefresh(); - jQuery(addDiv).append(addField(refresh, category, slaveID)); + if (add(entry, V.week + week, category, slaveID)) { + refreshActive(); + } }) ); @@ -153,10 +156,22 @@ App.Reminders = (function() { /** * @param {boolean} [link=false] show passage links + * @param {HTMLElement} [displayDiv] Only to be used by the refresh functionality * @returns {HTMLElement} */ - function fullDisplay(link) { - jQuery(displayDiv).empty(); + function fullDisplay(link, displayDiv) { + if (displayDiv) { + // If displayDiv is given, it either is currently being shown or the tree it belonged to was removed from + // the page. In that case we don't need to refresh it ever again. + if (!displayDiv.isConnected) { + return null; + } + jQuery(displayDiv).empty(); + } else { + displayDiv = document.createElement("div"); + } + activeViewRefreshers.push(() => fullDisplay(link, displayDiv)); + displayDiv.append(App.UI.DOM.makeElement("h2", "Reminders")); const listEl = list({link}); @@ -165,17 +180,27 @@ App.Reminders = (function() { } displayDiv.append(App.UI.DOM.makeElement("h3", "Add new")); - displayDiv.append(App.UI.DOM.makeElement("p", addField(() => fullDisplay(link)))); + displayDiv.append(App.UI.DOM.makeElement("p", addField())); return displayDiv; } /** * @param {number} slaveID + * @param {HTMLElement} [displayDiv] Only to be used by the refresh functionality * @returns {HTMLElement} */ - function slaveDisplay(slaveID) { - jQuery(displayDiv).empty(); + function slaveDisplay(slaveID, displayDiv) { + if (displayDiv) { + if (!displayDiv.isConnected) { + return null; + } + jQuery(displayDiv).empty(); + } else { + displayDiv = document.createElement("div"); + } + activeViewRefreshers.push(() => slaveDisplay(slaveID, displayDiv)); + displayDiv.append(App.UI.DOM.makeElement("h2", `Reminders for ${SlaveFullName(getSlave(slaveID))}`)); const listEl = list({filter: e => e.slaveID === slaveID}); @@ -184,7 +209,7 @@ App.Reminders = (function() { } displayDiv.append(App.UI.DOM.makeElement("h3", "Add new")); - displayDiv.append(App.UI.DOM.makeElement("p", addField(() => slaveDisplay(slaveID), "slave", slaveID))); + displayDiv.append(App.UI.DOM.makeElement("p", addField("slave", slaveID))); return displayDiv; } @@ -211,4 +236,18 @@ App.Reminders = (function() { $(Dialog.body()).empty().append(slaveID ? slaveDisplay(slaveID) : fullDisplay(showLinks)); Dialog.open(); } + + function refreshActive() { + console.log(activeViewRefreshers.length); + const ars = activeViewRefreshers; + activeViewRefreshers = []; + for (const refresher of ars) { + refresher(); + } + App.Utils.scheduleSidebarRefresh(); + } + + function clearActive() { + activeViewRefreshers = []; + } })(); diff --git a/src/zz1-last/setupEventHandlers.js b/src/zz1-last/setupEventHandlers.js index 44e3eb0ff12..896ed386a42 100644 --- a/src/zz1-last/setupEventHandlers.js +++ b/src/zz1-last/setupEventHandlers.js @@ -14,6 +14,7 @@ $(document).on(":passageinit", () => { delete V.passageSwitchHandler; } App.UI.Tabs.clear(); + App.Reminders.clear(); profileEvents.passageinit(); }); -- GitLab