From 618c102eadebe3dece9e21e91fe7233db3c17a75 Mon Sep 17 00:00:00 2001 From: Arkerthan <arkerthan@mailbox.org> Date: Wed, 1 Mar 2023 18:40:21 +0100 Subject: [PATCH] Refactor broken quick links --- css/gui/slaveList/quickList.css | 99 +++++++++++++++ css/gui/slaveList/quickListCSS.css | 101 --------------- devTools/types/FC/gameState.d.ts | 1 - src/gui/options/options.js | 4 +- src/js/quickListJS.js | 31 ----- src/js/slaveListing.js | 195 ++++++++++++----------------- 6 files changed, 182 insertions(+), 249 deletions(-) create mode 100644 css/gui/slaveList/quickList.css delete mode 100644 css/gui/slaveList/quickListCSS.css diff --git a/css/gui/slaveList/quickList.css b/css/gui/slaveList/quickList.css new file mode 100644 index 00000000000..e307ca96368 --- /dev/null +++ b/css/gui/slaveList/quickList.css @@ -0,0 +1,99 @@ +button.quick-button { + width: auto; + margin-left: 10px; +} + +.quick-list { + text-align: center; +} + +.quick-list button { + margin: 10px; + border: 2px solid var(--button-border-color); + background-color: var(--button-color); +} + +.quick-list button:hover { + background-color: var(--button-hover-color); +} + +.quick-list.devotion .mindbroken { + background-color: red; +} + +.quick-list.devotion .very-hateful { + background-color: darkviolet; +} + +.quick-list.devotion .hateful { + background-color: darkviolet; +} + +.quick-list.devotion .resistant { + background-color: mediumorchid; +} + +.quick-list.devotion .ambivalent { + background-color: yellow; + color: #111; +} + +.quick-list.devotion .accepting { + background-color: hotpink; +} + +.quick-list.devotion .devoted { + background-color: deeppink; +} + +.quick-list.devotion .worshipful { + background-color: magenta; +} + +.quick-list.trust .mindbroken { + background-color: red; +} + +.quick-list.trust .extremely-terrified { + background-color: darkgoldenrod; +} + +.quick-list.trust .terrified { + background-color: goldenrod; + color: #111; +} + +.quick-list.trust .frightened { + background-color: gold; + color: #111; +} + +.quick-list.trust .fearful { + background-color: yellow; + color: #111; +} + +.quick-list.trust .hate-careful { + background-color: orange; +} + +.quick-list.trust .careful { + background-color: mediumaquamarine; + color: #111; +} + +.quick-list.trust .bold { + background-color: orangered; +} + +.quick-list.trust .trusting { + background-color: mediumseagreen; +} + +.quick-list.trust .defiant { + background-color: darkred; +} + +.quick-list.trust .profoundly-trusting { + background-color: seagreen; +} diff --git a/css/gui/slaveList/quickListCSS.css b/css/gui/slaveList/quickListCSS.css deleted file mode 100644 index cd6a54705a6..00000000000 --- a/css/gui/slaveList/quickListCSS.css +++ /dev/null @@ -1,101 +0,0 @@ -.ql-hidden -{ - display:none; -} - -div.quick-list.devotion button.mindbroken -{ - background-color:red; -} -div.quick-list.devotion button.very-hateful -{ - background-color:darkviolet; -} -div.quick-list.devotion button.hateful -{ - background-color:darkviolet; -} -div.quick-list.devotion button.resistant -{ - background-color:mediumorchid; -} -div.quick-list.devotion button.ambivalent -{ - background-color: yellow; - color: #444444; -} -div.quick-list.devotion button.accepting -{ - background-color: hotpink; -} -div.quick-list.devotion button.devoted -{ - background-color: deeppink; -} -div.quick-list.devotion button.worshipful -{ - background-color: magenta; -} -div.quick-list.trust button.mindbroken -{ - background-color:red; -} -div.quick-list.trust button.extremely-terrified -{ - background-color: darkgoldenrod; -} -div.quick-list.trust button.terrified -{ - background-color: goldenrod; -} -div.quick-list.trust button.frightened -{ - background-color: gold; - color: coral; -} -div.quick-list.trust button.fearful -{ - background-color: yellow; - color: green; -} -div.quick-list.trust button.hate-careful -{ - background-color: orange; -} -div.quick-list.trust button.careful -{ - background-color: mediumaquamarine; - color: forestgreen; -} -div.quick-list.trust button.bold -{ - background-color: orangered; -} -div.quick-list.trust button.trusting -{ - background-color: mediumseagreen; -} -div.quick-list.trust button.defiant -{ - background-color: darkred; -} -div.quick-list.trust button.profoundly-trusting -{ - background-color: seagreen; -} -div.quick-list -{ - table-layout: fixed; - text-align: center; - border-collapse: separate; - border-spacing: 2px; - border-style: hidden; - empty-cells: hide; - width: 70%; -} -div.quick-list button -{ - margin-top: 15px; - margin-right: 20px; - white-space: nowrap; -} diff --git a/devTools/types/FC/gameState.d.ts b/devTools/types/FC/gameState.d.ts index 0eeaaed949a..e9515407344 100644 --- a/devTools/types/FC/gameState.d.ts +++ b/devTools/types/FC/gameState.d.ts @@ -102,7 +102,6 @@ declare namespace FC { */ interface TemporaryVariablesInTheGameState { gameover?: string; - sortQuickList?: string; /** @deprecated */ returnTo: string; diff --git a/src/gui/options/options.js b/src/gui/options/options.js index 9e5acf93d9c..690127b3c03 100644 --- a/src/gui/options/options.js +++ b/src/gui/options/options.js @@ -842,8 +842,8 @@ App.Intro.display = function(isIntro) { options.addOption("Main menu slave tabs are", "useSlaveSummaryTabs") .addValue("Enabled", 1).on().addValue("CardStyle", 2).on().addValue("Disabled", 0).off(); - options.addOption("The slave Quick list in-page scroll-to is", "useSlaveListInPageJSNavigation") - .addValue("Enabled", 1).on().addValue("Disabled", 0).off(); + options.addOption("The slave list in-page scroll-to is", "useSlaveListInPageJSNavigation") + .addValue("Always", 2).on().addValue("Collapsable", 1).on().addValue("Disabled", 0).off(); options.addOption("Condense special slaves into their own tab", "useSlaveSummaryOverviewTab") .addValue("Enabled", 1).on().addValue("Disabled", 0).off(); diff --git a/src/js/quickListJS.js b/src/js/quickListJS.js index 6f6b45c2bfe..db5cbc3dbe4 100644 --- a/src/js/quickListJS.js +++ b/src/js/quickListJS.js @@ -16,37 +16,6 @@ globalThis.sortDomObjects = function(objects, attrName, reverse = 0) { return objects.toArray().sort(sortingByAttr); }; -globalThis.sortButtonsByDevotion = function() { - let $sortedButtons = $('#qlWrapper button').remove(); - $sortedButtons = sortDomObjects($sortedButtons, 'data-devotion'); - $($sortedButtons).appendTo($('#qlWrapper')); - quickListBuildLinks(); -}; - -globalThis.sortButtonsByTrust = function() { - let $sortedButtons = $('#qlWrapper button').remove(); - $sortedButtons = sortDomObjects($sortedButtons, 'data-trust'); - $($sortedButtons).appendTo($('#qlWrapper')); - quickListBuildLinks(); -}; - -globalThis.quickListBuildLinks = function() { - $("[data-scroll-to]").click(App.UI.quickBtnScrollToHandler); -}; - -App.UI.quickBtnScrollToHandler = function() { - let $this = $(this); - let $toElement = $this.attr('data-scroll-to'); - // note the * 1 enforces $offset to be an integer, without - // it we scroll to True, which goes nowhere fast. - let $offset = parseInt($this.attr('data-scroll-offset') || "0"); - let $speed = parseInt($this.attr('data-scroll-speed') || "500"); - // Use javascript scrollTop animation for in page navigation. - $('html, body').animate({ - scrollTop: $($toElement).offset().top + $offset - }, $speed); -}; - globalThis.sortNurseryPossiblesByName = function() { let $sortedNurseryPossibles = $('#ql-nursery div.possible').detach(); $sortedNurseryPossibles = sortDomObjects($sortedNurseryPossibles, 'data-name'); diff --git a/src/js/slaveListing.js b/src/js/slaveListing.js index 4c4831e3267..aab9d64ec23 100644 --- a/src/js/slaveListing.js +++ b/src/js/slaveListing.js @@ -21,14 +21,12 @@ App.UI.SlaveList = {}; App.UI.SlaveList.render = function() { const facilityPassages = new Set( - ["Main", "Head Girl Suite", "Spa", "Brothel", "Club", "Arcade", "Clinic", "Schoolroom", "Dairy", "Farmyard", "Servants' Quarters", "Master Suite", "Cellblock"]); + ["Main", "Head Girl Suite", "Spa", "Brothel", "Club", "Arcade", "Clinic", "Schoolroom", "Dairy", "Farmyard", + "Servants' Quarters", "Master Suite", "Cellblock"]); /** @type {string} */ let passageName; - // potentially can be a problem if played long enough to reach Number.MAX_SAFE_INTEGER - let listID = Number.MIN_SAFE_INTEGER; - /** @type {App.Art.SlaveArtBatch} */ let batchRenderer = null; @@ -43,6 +41,8 @@ App.UI.SlaveList.render = function() { */ function listDOM(IDs, rejectedSlaves, interactionLink, postNote) { passageName = passage(); + // required, if multiple list are displayed on the same passage + const uuid = generateNewID(); let res = document.createDocumentFragment(); @@ -53,9 +53,7 @@ App.UI.SlaveList.render = function() { batchRenderer = null; } - if (V.useSlaveListInPageJSNavigation === 1) { - res.appendChild(createQuickList(IDs)); - } + res.append(createQuickList(IDs, uuid)); const fcs = App.Entity.facilities; const penthouse = fcs.penthouse; @@ -80,7 +78,7 @@ App.UI.SlaveList.render = function() { for (const sid of IDs) { let ss = renderSlave(sid, interactionLink, showTransfers, postNote); let slaveDiv = document.createElement("div"); - slaveDiv.id = `slave-${sid}`; + slaveDiv.id = `slave-${sid}-${uuid}`; slaveDiv.classList.add("slaveSummary"); if (V.slavePanelStyle === 2) { slaveDiv.classList.add("card"); @@ -327,117 +325,77 @@ App.UI.SlaveList.render = function() { /** * @param {number[]} IDs + * @param {string} uuid * @returns {DocumentFragment} */ - function createQuickList(IDs) { + function createQuickList(IDs, uuid) { + if (V.useSlaveListInPageJSNavigation < 1 || IDs.length < 2 || passageName !== "Main") { + return new DocumentFragment(); + } + + const f = new DocumentFragment(); + let currentSort = null; + + let toggleButton; + if (V.useSlaveListInPageJSNavigation === 1) { + toggleButton = App.UI.DOM.appendNewElement("button", f, "Quick-List", ["quick-button"]); + } + + const indexSorting = document.createElement("div"); + f.append(indexSorting); + + const sortSpan = App.UI.DOM.makeElement("span", "None", ["bold"]); + + indexSorting.append("Sorting: ", sortSpan, " ", + App.UI.DOM.link("Sort by Devotion", + () => sortButtons("Devotion", (a, b) => b.devotion - a.devotion, "devotion")), + " | ", + App.UI.DOM.link("Sort by Trust", () => sortButtons("Trust", (a, b) => b.trust - a.trust, "trust")) + ); + + const indexContainer = document.createElement("div"); + indexContainer.classList.add("quick-list"); + f.append(indexContainer); /** - * - * @param {Node} container - * @param {string} tagName - * @param {string} [content] - * @param {string|string[]} [classNames] - * @param {Object.<string, any>} [attributes] - * @returns {HTMLElement} + * @typedef {object} JumpButton + * @property {App.Entity.SlaveState} slave + * @property {HTMLButtonElement} button */ - function makeElement(container, tagName, content, classNames, attributes) { - let res = document.createElement(tagName); - container.appendChild(res); - if (content) { - res.textContent = content; - } - if (Array.isArray(classNames)) { - for (const c of classNames) { - res.classList.add(c); - } - } else if (classNames !== undefined) { - res.classList.add(classNames); - } - - if (attributes) { - for (const [k, v] of Object.entries(attributes)) { - res.setAttribute(k, v); - } - } - return res; + /** + * @type {JumpButton[]} + */ + const jumpButtons = []; + for (const id of IDs) { + const btn = document.createElement("button"); + const slave = getSlave(id); + btn.append(SlaveFullName(slave)); + btn.classList.add(getSlaveDevotionClass(slave), getSlaveTrustClass(slave)); + btn.onclick = () => $('html, body').animate({scrollTop: $(`#slave-${id}-${uuid}`).offset().top - 50}, 300); + jumpButtons.push({slave: slave, button: btn}); + indexContainer.append(btn); } - const res = document.createDocumentFragment(); + if (V.useSlaveListInPageJSNavigation === 1) { + App.UI.DOM.elementToggle(toggleButton, [indexSorting, indexContainer]); + } - /* Useful for finding weird combinations — usages of this passage that don't yet generate the quick index. - * <<print 'pass/count/indexed/flag::[' + passageName + '/' + Count + '/' + indexed + '/' + V.SlaveSummaryFiler + ']'>> - */ + return f; - if (IDs.length > 1 && passageName === "Main") { - const buttons = []; - let offset = -50; - if (/Select/i.test(passageName)) { - offset = -25; - } - /* - * we want <button data-quick-index="<<= listID>>">... - */ - const quickIndexBtn = document.createElement("button"); - res.appendChild(quickIndexBtn); - quickIndexBtn.id = `quick-list-toggle${listID}`; - quickIndexBtn.setAttribute('data-quick-index', listID.toString()); - quickIndexBtn.onclick = function(ev) { - let which = /** @type {HTMLElement} */ (ev.target).attributes["data-quick-index"].value; - let quick = $("div#list_index" + which); - quick.toggleClass("ql-hidden"); - }; - /* - * we want <div id="list_index3" class=" hidden">... - */ - const listIndex = makeElement(res, "div", undefined, "ql-hidden"); - listIndex.id = `list_index${listID}`; - - for (const sID of IDs) { - const IndexSlave = slaveStateById(sID); - const indexSlaveName = SlaveFullName(IndexSlave); - const devotionClass = getSlaveDevotionClass(IndexSlave); - const trustClass = getSlaveTrustClass(IndexSlave); - buttons.push({ - "data-name": indexSlaveName, - "data-scroll-to": `#slave-${IndexSlave.ID}`, - "data-scroll-offset": offset, - "data-devotion": IndexSlave.devotion, - "data-trust": IndexSlave.trust, - "class": `${devotionClass} ${trustClass}` - }); - } - if (buttons.length > 0) { - V.sortQuickList = V.sortQuickList || 'Devotion'; - makeElement(listIndex, "em", "Sorting: "); - const qlSort = makeElement(listIndex, "span", V.sortQuickList, "strong"); - qlSort.id = "qlSort"; - listIndex.appendChild(document.createTextNode(". ")); - const linkSortByDevotion = makeElement(listIndex, "a", "Sort by Devotion"); - linkSortByDevotion.onclick = (ev) => { - ev.preventDefault(); - V.sortQuickList = "Devotion"; - $("#qlSort").text(V.sortQuickList); - $("#qlWrapper").removeClass("trust").addClass("devotion"); - sortButtonsByDevotion(); - }; - listIndex.append(" | "); - const linkSortByTrust = makeElement(listIndex, "a", "Sort by Trust"); - linkSortByTrust.onclick = (ev) => { - ev.preventDefault(); - V.sortQuickList = "Trust"; - $("#qlSort").text(V.sortQuickList); - $("#qlWrapper").removeClass("devotion").addClass("trust"); - sortButtonsByTrust(); - }; - makeElement(listIndex, "br"); - const qlWrapper = makeElement(listIndex, "div", undefined, ["quick-list", "devotion"]); - qlWrapper.id = "qlWrapper"; - for (const button of buttons) { - const btn = makeElement(listIndex, 'button', button['data-name'], undefined, button); - btn.onclick = App.UI.quickBtnScrollToHandler; - } + /** + * @param {string} name + * @param {function(FC.SlaveState, FC.SlaveState):number} compareFn + * @param {string} colorClass + */ + function sortButtons(name, compareFn, colorClass) { + $(sortSpan).empty().append(name); + jumpButtons.sort((a, b) => compareFn(a.slave, b.slave)); + $(indexContainer).empty().append(jumpButtons.map(v => v.button)); + if (currentSort) { + indexContainer.classList.remove(currentSort); } + indexContainer.classList.add(colorClass); + currentSort = colorClass; } - return res; } }(); @@ -548,7 +506,8 @@ App.UI.SlaveList.sortingLinks = function(passage) { const textify = string => capFirstChar(string.replace(/([A-Z])/g, " $1")); let span = App.UI.DOM.makeElement("span", "Sort by: "); - let order = ["devotion", "trust", "name", "assignment", "seniority", "actualAge", "visualAge", "physicalAge", "weeklyIncome", "beauty", "health", "weight", "muscles", "intelligence", "sexDrive", "pregnancy", "prestige"]; + let order = ["devotion", "trust", "name", "assignment", "seniority", "actualAge", "visualAge", "physicalAge", + "weeklyIncome", "beauty", "health", "weight", "muscles", "intelligence", "sexDrive", "pregnancy", "prestige"]; const orderMap = order.map(so => { return {key: so, name: capFirstChar(so)}; }); @@ -564,7 +523,9 @@ App.UI.SlaveList.sortingLinks = function(passage) { span = App.UI.DOM.makeElement("span", " Sort direction: "); order = ["descending", "ascending"]; span.append(App.UI.DOM.generateLinksStrip(order.map(so => V.sortSlavesOrder !== so - ? App.UI.DOM.passageLink(textify(so), passage, () => { V.sortSlavesOrder = so; }) : textify(so)))); + ? App.UI.DOM.passageLink(textify(so), passage, () => { + V.sortSlavesOrder = so; + }) : textify(so)))); div.append(span); return div; @@ -1088,7 +1049,9 @@ App.UI.SlaveList.slaveSelectionList = function() { */ let slaveSelectionList = null; - $(document).on(':passageinit', () => { slaveSelectionList = null; }); + $(document).on(':passageinit', () => { + slaveSelectionList = null; + }); return selection; @@ -1100,7 +1063,9 @@ App.UI.SlaveList.slaveSelectionList = function() { * @returns {HTMLElement} */ function selection(filter, interactionLink, experienceChecker, postNote) { - if (experienceChecker === null) { experienceChecker = undefined; } + if (experienceChecker === null) { + experienceChecker = undefined; + } options = { filter: filter, interactionLink: interactionLink, @@ -1180,7 +1145,9 @@ App.UI.SlaveList.slaveSelectionList = function() { if (fr === true || (Array.isArray(fr) && fr.length === 0)) { passingIDs.push(id); } else { - if (Array.isArray(fr)) { rejects.push({id: id, rejects: fr}); } + if (Array.isArray(fr)) { + rejects.push({id: id, rejects: fr}); + } } }); -- GitLab