From 57ae0b2de9a10ed835fe5f90568544e46d9cb277 Mon Sep 17 00:00:00 2001 From: somebody Date: Wed, 31 Aug 2022 20:32:52 -0500 Subject: [PATCH 01/10] Finder barebones --- static/koboldai.css | 62 ++++++++++++++++++++++++++++++++++++++++ templates/index_new.html | 37 ++++++++++++++++++++++++ 2 files changed, 99 insertions(+) diff --git a/static/koboldai.css b/static/koboldai.css index e06ccdb7..7e5784d0 100644 --- a/static/koboldai.css +++ b/static/koboldai.css @@ -1737,6 +1737,68 @@ body { font-size: 50vh; opacity: 0.7; } + +/* Finder */ + +#finder-container { + display: flex; + justify-content: center; + align-items: center; + + position: absolute; + left: 0px; + top: 0px; + + background-color: rgba(0, 0, 0, 0.5); + z-index: 99999999; + + width: 100vw; + height: 100vh; +} + +#finder { + width: 25%; + background-color: var(--flyout_background_pinned); + padding: 10px; + border-radius: 4px; +} + +#finder-input { + width: 100%; + padding: 5px; + border: none; +} + +.finder-result { + display: flex; + flex-direction: row; + justify-content: space-between; + + padding: 3px; + margin-top: 5px; + background-color: var(--input_background); + cursor: pointer; +} + +.finder-result > .result-textblock > span { + display: block; +} + +.result-title { + font-weight: bold; + font-size: 15px; +} + +.result-details { + margin-left: 15px; + opacity: 0.7; +} + +.result-icon { + display: flex !important; + align-items: center; +} + /*---------------------------------- Global ------------------------------------------------*/ .hidden { display: none; diff --git a/templates/index_new.html b/templates/index_new.html index 3b4d77bb..68382680 100644 --- a/templates/index_new.html +++ b/templates/index_new.html @@ -143,5 +143,42 @@ + + \ No newline at end of file From 0d504716336fda76661881203149e1533747cbe2 Mon Sep 17 00:00:00 2001 From: somebody Date: Thu, 1 Sep 2022 06:45:27 -0500 Subject: [PATCH 02/10] Wip search for finder --- static/koboldai.js | 49 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/static/koboldai.js b/static/koboldai.js index f2c1f7df..30554b7a 100644 --- a/static/koboldai.js +++ b/static/koboldai.js @@ -37,6 +37,7 @@ var shift_down = false; var world_info_data = {}; var world_info_folder_data = {}; var saved_settings = {}; +var settings_data = {}; const map1 = new Map() map1.set('Top K Sampling', 0) map1.set('Top A Sampling', 1) @@ -3028,6 +3029,29 @@ async function processDroppedFile(file) { } } +// By p01 - https://gist.github.com/p01/1127070 +function levenshteinDistance(a, b){ + let c,d,e,f,g; + for(d=[e=0];a[e];e++) { + for(c=[f=0];b[++f];) { + g=d[f]= e ? 1+Math.min(d[--f], c[f]-(a[e-1]==b[f]), c[++f]=d[f]) : f; + } + } + return g; +} + +function updateSearchListings() { + let query = this.value.toLowerCase(); + + if (!query) return; + + for (const settingName of Object.keys(settings_data)) { + let compare = settingName.toLowerCase().slice(0, query.length); + let distance = levenshteinDistance(query, compare); + console.log(distance, settingName, query, compare); + } +} + $(document).ready(function(){ create_theming_elements(); document.onkeydown = detect_key_down; @@ -3133,4 +3157,29 @@ $(document).ready(function(){ console.log("end") $("#file-upload-notice")[0].classList.add("hidden"); }); + + // Parse settings for search thingey + for (const el of document.getElementsByClassName("setting_label")) { + let name = el.children[0].innerText; + + let tooltipEl = el.getElementsByClassName("helpicon")[0]; + let tooltip = tooltipEl ? tooltipEl.getAttribute("title") : null; + + settings_data[name] = {tooltip: tooltip, element: el.parentElement} + } + + document.getElementById("finder-input").addEventListener("keyup", updateSearchListings); }); + +document.addEventListener("keydown", function(event) { + if (!event.ctrlKey) return; + + switch (event.key) { + // TODO: Add other shortcuts + case "k": + let finderContainer = document.getElementById("finder-container"); + finderContainer.classList.remove("hidden"); + event.preventDefault(); + break; + } +}); \ No newline at end of file From 9189a56197b78e2084b63fd40fbf22787cec8d83 Mon Sep 17 00:00:00 2001 From: somebody Date: Fri, 2 Sep 2022 07:11:32 -0500 Subject: [PATCH 03/10] More finder work --- static/koboldai.css | 19 ++++- static/koboldai.js | 162 +++++++++++++++++++++++++++++++++++---- templates/index_new.html | 31 -------- 3 files changed, 162 insertions(+), 50 deletions(-) diff --git a/static/koboldai.css b/static/koboldai.css index 7e5784d0..cd484c40 100644 --- a/static/koboldai.css +++ b/static/koboldai.css @@ -1780,11 +1780,13 @@ body { cursor: pointer; } -.finder-result > .result-textblock > span { - display: block; -} +.result-selected { background-color: #273b48; } .result-title { + display: flex !important; + align-items: center; + white-space: pre; + font-weight: bold; font-size: 15px; } @@ -1792,6 +1794,17 @@ body { .result-details { margin-left: 15px; opacity: 0.7; + + /* Limit to 2 lines of text */ + + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + overflow: hidden; +} + +.result-highlight { + background-color: rgb(112, 112, 31); } .result-icon { diff --git a/static/koboldai.js b/static/koboldai.js index 30554b7a..32b53ad5 100644 --- a/static/koboldai.js +++ b/static/koboldai.js @@ -37,7 +37,21 @@ var shift_down = false; var world_info_data = {}; var world_info_folder_data = {}; var saved_settings = {}; -var settings_data = {}; +var finder_selection_index = -1; + +// name, desc, icon, func +const finder_actions = [ + {name: "Load Model", icon: "folder_open", func: function() { socket.emit('load_model_button', {}); }}, + {name: "New Story", icon: "description", func: function() { socket.emit('new_story', ''); }}, + {name: "Load Story", icon: "folder_open", func: function() { socket.emit('load_story_list', ''); }}, + {name: "Save Story", icon: "save", func: function() { socket.emit("save_story", null, (response) => {save_as_story(response);}); }}, + {name: "Download Story", icon: "file_download", func: function() { document.getElementById('download_iframe').src = 'json'; }}, + + // Locations + {name: "Setting Presets", icon: "open_in_new", func: function() { highlightEl(".var_sync_model_selected_preset") }}, + {name: "Phrase Biases", icon: "open_in_new", func: function() { highlightEl("#biasing") }}, +]; + const map1 = new Map() map1.set('Top K Sampling', 0) map1.set('Top A Sampling', 1) @@ -57,6 +71,7 @@ map2.set(6, 'Repetition Penalty') var calc_token_usage_timeout; var game_text_scroll_timeout; var var_processing_time = 0; +var finder_last_input; //-----------------------------------Server to UI Functions----------------------------------------------- function connect() { console.log("connected"); @@ -3029,27 +3044,104 @@ async function processDroppedFile(file) { } } -// By p01 - https://gist.github.com/p01/1127070 -function levenshteinDistance(a, b){ - let c,d,e,f,g; - for(d=[e=0];a[e];e++) { - for(c=[f=0];b[++f];) { - g=d[f]= e ? 1+Math.min(d[--f], c[f]-(a[e-1]==b[f]), c[++f]=d[f]) : f; - } +function highlightEl(element) { + if (typeof element === "string") element = document.querySelector(element); + if (!element) { + console.error("Bad jump!") + return; } - return g; + + console.log("uhoh", element); +} + +function addSearchListing(action, highlight) { + const finder = document.getElementById("finder"); + + let result = document.createElement("div"); + result.classList.add("finder-result"); + + let textblock = document.createElement("div"); + textblock.classList.add("result-textbox"); + result.appendChild(textblock); + + let titleEl = document.createElement("span"); + titleEl.classList.add("result-title"); + titleEl.innerText = action.name; + + // TODO: Sanitation + titleEl.innerHTML = titleEl.innerHTML.replace( + new RegExp(`(${highlight})`, "i"), + '$1' + ); + textblock.appendChild(titleEl); + + if (action.desc) { + let descriptionEl = document.createElement("span"); + descriptionEl.classList.add("result-details"); + descriptionEl.innerText = action.desc; + descriptionEl.innerHTML = descriptionEl.innerHTML.replace( + new RegExp(`(${highlight})`, "i"), + '$1' + ); + + // It can get cut off by CSS, so let's add a tooltip. + descriptionEl.setAttribute("title", action.desc); + textblock.appendChild(descriptionEl); + } + + let icon = document.createElement("span"); + icon.classList.add("result-icon"); + icon.classList.add("material-icons-outlined"); + + // TODO: Change depending on what pressing enter does + icon.innerText = action.icon; + result.appendChild(icon) + + finder.appendChild(result); + + return result; } function updateSearchListings() { + const maxResultCount = 5; + + if (this.value === finder_last_input) return; + finder_last_input = this.value; + finder_selection_index = -1; + let query = this.value.toLowerCase(); + // TODO: Maybe reuse the element? Would it give better performance? + $(".finder-result").remove(); + if (!query) return; - for (const settingName of Object.keys(settings_data)) { - let compare = settingName.toLowerCase().slice(0, query.length); - let distance = levenshteinDistance(query, compare); - console.log(distance, settingName, query, compare); + const actionMatches = {name: [], desc: []}; + + for (const action of finder_actions) { + if (action.name.toLowerCase().includes(query)) { + actionMatches.name.push(action); + } else if (action.desc && action.desc.toLowerCase().includes(query)) { + actionMatches.desc.push(action); + } } + + // Title matches over desc matches + const matchingActions = actionMatches.name.concat(actionMatches.desc); + + + for (let i=0;i= actionsCount) { + future = 0; + } else if (future < 0) { + future = actionsCount - 1; + } + + finder_selection_index = future; + updateFinderSelection(delta); + }); }); document.addEventListener("keydown", function(event) { @@ -3177,8 +3304,11 @@ document.addEventListener("keydown", function(event) { switch (event.key) { // TODO: Add other shortcuts case "k": - let finderContainer = document.getElementById("finder-container"); + const finderContainer = document.getElementById("finder-container"); + const finderInput = document.getElementById("finder-input"); finderContainer.classList.remove("hidden"); + finderInput.focus(); + finder_selection_index = -1; event.preventDefault(); break; } diff --git a/templates/index_new.html b/templates/index_new.html index 68382680..a04ee9d1 100644 --- a/templates/index_new.html +++ b/templates/index_new.html @@ -147,37 +147,6 @@ From 67e8e6b4b73dfb973ed50193423812d813062d21 Mon Sep 17 00:00:00 2001 From: somebody Date: Fri, 2 Sep 2022 17:16:06 -0500 Subject: [PATCH 04/10] Make finder actually jump to things --- static/koboldai.js | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/static/koboldai.js b/static/koboldai.js index 32b53ad5..f13a278d 100644 --- a/static/koboldai.js +++ b/static/koboldai.js @@ -3050,15 +3050,34 @@ function highlightEl(element) { console.error("Bad jump!") return; } + + let settingArea = $(element).closest(".settings_category_area")[0]; + + // HACK: This really sucks, we should probably have an easier way to select tabs. + if (settingArea) { + let tabName = settingArea.id.replace("setting_menu_", ""); + for (const tab of $(".setting_menu_button")) { + if (tab.innerText.toLowerCase() === tabName) { + tab.click(); + break; + } + } + element.scrollIntoView(); + } console.log("uhoh", element); } function addSearchListing(action, highlight) { + const finderContainer = document.getElementById("finder-container"); const finder = document.getElementById("finder"); let result = document.createElement("div"); result.classList.add("finder-result"); + result.addEventListener("click", function(event) { + finderContainer.classList.add("hidden"); + action.func(); + }); let textblock = document.createElement("div"); textblock.classList.add("result-textbox"); @@ -3271,8 +3290,12 @@ $(document).ready(function(){ finderInput.addEventListener("keyup", updateSearchListings); finderInput.addEventListener("keydown", function(event) { let delta = 0; - - if (event.key === "ArrowUp") { + const actions = document.getElementsByClassName("finder-result"); + + if (event.key === "Enter") { + let index = finder_selection_index >= 0 ? finder_selection_index : 0; + actions[index].click(); + } else if (event.key === "ArrowUp") { delta = -1; } else if (event.key === "ArrowDown") { delta = 1 @@ -3282,7 +3305,7 @@ $(document).ready(function(){ return; } - const actionsCount = document.getElementsByClassName("finder-result").length; + const actionsCount = actions.length; let future = finder_selection_index + delta; event.preventDefault(); From b452559105d1aeca849c55cf0f6f9569ee0de7d1 Mon Sep 17 00:00:00 2001 From: somebody Date: Fri, 2 Sep 2022 17:40:27 -0500 Subject: [PATCH 05/10] More work on finder --- static/koboldai.js | 45 ++++++++++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/static/koboldai.js b/static/koboldai.js index f13a278d..c11f5d37 100644 --- a/static/koboldai.js +++ b/static/koboldai.js @@ -49,7 +49,9 @@ const finder_actions = [ // Locations {name: "Setting Presets", icon: "open_in_new", func: function() { highlightEl(".var_sync_model_selected_preset") }}, - {name: "Phrase Biases", icon: "open_in_new", func: function() { highlightEl("#biasing") }}, + + // TODO: Direct theme selection + // {name: "", icon: "palette", func: function() { highlightEl("#biasing") }}, ]; const map1 = new Map() @@ -3052,20 +3054,24 @@ function highlightEl(element) { } let settingArea = $(element).closest(".settings_category_area")[0]; + let area = settingArea ? settingArea : $(element).closest(".story_category_area")[0]; + let classBit = settingArea ? "setting" : "story"; + + if (!area) { + console.error("No error? :^("); + return; + } // HACK: This really sucks, we should probably have an easier way to select tabs. - if (settingArea) { - let tabName = settingArea.id.replace("setting_menu_", ""); - for (const tab of $(".setting_menu_button")) { - if (tab.innerText.toLowerCase() === tabName) { - tab.click(); - break; - } + let tabName = area.id.replace(`${classBit}_menu_`, ""); + for (const tab of $(`.${classBit}_menu_button`)) { + if (tab.innerText.toLowerCase() === tabName) { + tab.click(); + console.log("clicking", tab) + break; } - element.scrollIntoView(); } - - console.log("uhoh", element); + element.scrollIntoView(); } function addSearchListing(action, highlight) { @@ -3270,7 +3276,7 @@ $(document).ready(function(){ }); // Parse settings for search thingey - for (const el of document.getElementsByClassName("setting_label")) { + for (const el of $(".setting_label")) { let name = el.children[0].innerText; let tooltipEl = el.getElementsByClassName("helpicon")[0]; @@ -3281,7 +3287,20 @@ $(document).ready(function(){ desc: tooltip, icon: "open_in_new", func: function () { highlightEl(el.parentElement) }, - }) + }); + } + + for (const el of $(".collapsable_header")) { + // https://stackoverflow.com/a/11347962 + let headerText = $(el.children[0]).contents().filter(function() { + return this.nodeType == 3; + }).text().trim(); + + finder_actions.push({ + name: headerText, + icon: "open_in_new", + func: function () { highlightEl(el) }, + }); } const finderInput = document.getElementById("finder-input"); From 0e549b2f3f175c8a6cd980ce2984f053cfe38e1c Mon Sep 17 00:00:00 2001 From: somebody Date: Fri, 2 Sep 2022 18:06:25 -0500 Subject: [PATCH 06/10] Tab overhaul Makes tabs easy(er) to programatically act upon --- static/koboldai.js | 14 +++++++++++++- templates/settings flyout.html | 23 ++++++---------------- templates/story flyout.html | 35 ++++++++-------------------------- 3 files changed, 27 insertions(+), 45 deletions(-) diff --git a/static/koboldai.js b/static/koboldai.js index c11f5d37..55539d61 100644 --- a/static/koboldai.js +++ b/static/koboldai.js @@ -2963,6 +2963,18 @@ function detect_key_up(e) { } } +function selectTab(tab) { + let tabTarget = document.getElementById(tab.getAttribute("tab-target")); + let tabClass = Array.from(tab.classList).filter((c) => c.startsWith("tab-"))[0]; + let targetClass = Array.from(tabTarget.classList).filter((c) => c.startsWith("tab-target-"))[0]; + + $(`.${tabClass}`).removeClass("selected"); + tab.classList.add("selected"); + + $(`.${targetClass}`).addClass("hidden"); + tabTarget.classList.remove("hidden"); +} + function loadNAILorebook(data, filename) { let lorebookVersion = data.lorebookVersion; let wi_data = {folders: {[filename]: []}, entries: {}}; @@ -3353,5 +3365,5 @@ document.addEventListener("keydown", function(event) { finder_selection_index = -1; event.preventDefault(); break; - } +} }); \ No newline at end of file diff --git a/templates/settings flyout.html b/templates/settings flyout.html index 581a985a..423dbd96 100644 --- a/templates/settings flyout.html +++ b/templates/settings flyout.html @@ -1,14 +1,3 @@ -