This commit is contained in:
ebolam
2022-07-29 21:44:42 -04:00
parent 468f7a81e4
commit 2b739b6cb8
5 changed files with 265 additions and 74 deletions

View File

@@ -6407,8 +6407,28 @@ def UI_2_change_wi_text(data):
@socketio.on('move_wi')
def UI_2_move_wi(data):
print(data)
koboldai_vars.worldinfo_v2.reorder(int(data['dragged_id']), int(data['drop_id']))
if data['folder'] is None:
koboldai_vars.worldinfo_v2.reorder(int(data['dragged_id']), int(data['drop_id']))
else:
koboldai_vars.worldinfo_v2.set_folder(int(data['dragged_id']), data['folder'], before_uid=int(data['drop_id']))
#==================================================================#
# Event triggered when user moves world info
#==================================================================#
@socketio.on('wi_set_folder')
def UI_2_wi_set_folder(data):
print(data)
koboldai_vars.worldinfo_v2.set_folder(int(data['dragged_id']), data['folder'])
#==================================================================#
# Event triggered when user renames world info folder
#==================================================================#
@socketio.on('Rename_World_Info_Folder')
def UI_2_Rename_World_Info_Folder(data):
print("Rename_World_Info_Folder")
print(data)
koboldai_vars.worldinfo_v2.rename_folder(data['old_folder'], data['new_folder'])
#==================================================================#
# Event triggered to rely a message

View File

@@ -911,8 +911,8 @@ class KoboldWorldInfo(object):
def get_folders(self, ui_version=2):
if ui_version == 1:
return {i: {'collapsed': True, 'name': x} for i, x in enumerate(set([x['folder'] for x in self.world_info]))}
return list(set([x['folder'] for x in self.world_info]))
return {i: {'collapsed': True, 'name': x} for i, x in enumerate(set([self.world_info[x]['folder'] for x in self.world_info]))}
return list(set([self.world_info[x]['folder'] for x in self.world_info]))
def get_folder_items(self, folder):
items = [item.to_dict() for item in self.world_info if item['folder'] == folder]
@@ -929,20 +929,28 @@ class KoboldWorldInfo(object):
self.world_info[uid]['sort'] = before_sort_number
def set_folder(self, uid, folder, before_uid=None):
max_sort = max([x['sort'] for x in self.world_info if x['folder'] == folder])
max_sort = max([self.world_info[x]['sort'] for x in self.world_info if self.world_info[x]['folder'] == folder]+[-1])
old_folder = self.world_info[uid]['folder']
self.world_info[uid]['folder'] = folder
self.world_info[uid]['sort'] = max_sort
self.world_info[uid]['sort'] = max_sort+1
if before_uid is not None:
self.reorder(folder, uid, before_uid)
self.reorder(uid, before_uid)
self.resort(folder)
self.resort(old_folder)
def rename_folder(self, old_folder, new_folder):
while new_folder in self.get_folders():
new_folder = "{}-1".format(new_folder)
for x in self.world_info:
if self.world_info[x]['folder'] == old_folder:
self.world_info[x]['folder'] = new_folder
def resort(self, folder):
for i in range(max([x['sort'] for x in self.world_info if x['folder'] == folder])+1):
if i > len([x['sort'] for x in self.world_info if x['folder'] == folder]):
for i in range(max([self.world_info[x]['sort'] for x in self.world_info if self.world_info[x]['folder'] == folder])+1):
if i > len([self.world_info[x]['sort'] for x in self.world_info if self.world_info[x]['folder'] == folder]):
break
elif i not in [x['sort'] for x in self.world_info if x['folder'] == folder]:
elif i not in [self.world_info[x]['sort'] for x in self.world_info if self.world_info[x]['folder'] == folder]:
for item in world_info:
if item['folder'] == folder and item['sort'] > i:
item['sort'] = item['sort']-1

View File

@@ -404,7 +404,8 @@ td.server_vars {
.world_info_card {
width: 100%;
border: 2px outset var(--wi_card_border_color);
background-color: var(--wi_card_bg_color)
background-color: var(--wi_card_bg_color);
margin-bottom: 10px;
}
.world_info_tag_area {
@@ -423,6 +424,14 @@ td.server_vars {
cursor: pointer;
}
.oi[folder] {
margin-right: 5px;
}
.oi[data-glyph="folder"] {
margin-right: 5px;
}
/* ---------------------------- OVERALL PAGE CONFIG ------------------------------*/
body {
@@ -938,4 +947,5 @@ button.disabled {
.drag-over {
border-top: dashed 3px red;
}
}

View File

@@ -1009,12 +1009,60 @@ function world_info(data) {
folder_item.id = "world_info_folder_"+folder;
folder_item.classList.add("WI_Folder");
title = document.createElement("h2");
title.textContent = folder;
title.addEventListener('dragenter', dragEnter)
title.addEventListener('dragover', dragOver);
title.addEventListener('dragleave', dragLeave);
title.addEventListener('drop', drop);
collapse_icon = document.createElement("span");
collapse_icon.id = "world_info_folder_collapse_"+folder;
collapse_icon.classList.add("oi");
collapse_icon.setAttribute("data-glyph", "chevron-bottom");
collapse_icon.setAttribute("folder", folder);
collapse_icon.onclick = function () {
hide_wi_folder(this.getAttribute("folder"));
document.getElementById('world_info_folder_expand_'+this.getAttribute("folder")).classList.remove('hidden');
this.classList.add("hidden");
};
title.append(collapse_icon);
expand_icon = document.createElement("span");
expand_icon.id = "world_info_folder_expand_"+folder;
expand_icon.classList.add("oi");
expand_icon.setAttribute("data-glyph", "chevron-right");
expand_icon.setAttribute("folder", folder);
expand_icon.onclick = function () {
unhide_wi_folder(this.getAttribute("folder"));
document.getElementById('world_info_folder_collapse_'+this.getAttribute("folder")).classList.remove('hidden');
this.classList.add("hidden");
};
expand_icon.classList.add("hidden");
title.append(expand_icon);
icon = document.createElement("span");
icon.classList.add("oi");
icon.setAttribute("data-glyph", "folder");
title.append(icon);
title_text = document.createElement("span");
title_text.setAttribute("contenteditable", true);
title_text.setAttribute("original_text", folder);
title_text.textContent = folder;
title_text.onblur = function () {
if (this.textContent != this.getAttribute("original_text")) {
//Need to check if the new folder name is already in use
folder_name = this.textContent;
while (folder_name in Array(document.getElementById("story_menu_wi").children).filter(folder => folder.id.replace("world_info_folder_", ""))) {
folder_name = folder_name + " 1";
}
this.parentElement.parentElement.id = "world_info_folder_" + folder_name;
socket.emit("Rename_World_Info_Folder", {"old_folder": this.getAttribute("original_text"), "new_folder": folder_name});
this.setAttribute("original_text", folder_name);
}
}
title.append(title_text);
folder_item.append(title);
world_info_area.append(folder_item);
} else {
folder_item = document.getElementById("world_info_folder_"+folder);
}
world_info_card.setAttribute("folder", folder);
@@ -1224,6 +1272,95 @@ function upload_file(file_box) {
}
//--------------------------------------------General UI Functions------------------------------------
function create_world_info_folder() {
var world_info_area = document.getElementById("story_menu_wi");
var i=0;
while (document.getElementById("world_info_folder_New "+i) != null) {
console.log("New "+i);
console.log(document.getElementById("world_info_folder_New "+i));
i+=1;
}
folder = "New "+i;
//create new folder
var folder_item = document.createElement("span");
folder_item.id = "world_info_folder_"+folder;
folder_item.classList.add("WI_Folder");
title = document.createElement("h2");
title.addEventListener('dragenter', dragEnter)
title.addEventListener('dragover', dragOver);
title.addEventListener('dragleave', dragLeave);
title.addEventListener('drop', drop);
collapse_icon = document.createElement("span");
collapse_icon.id = "world_info_folder_collapse_"+folder;
collapse_icon.classList.add("oi");
collapse_icon.setAttribute("data-glyph", "chevron-bottom");
collapse_icon.setAttribute("folder", folder);
collapse_icon.onclick = function () {
hide_wi_folder(this.getAttribute("folder"));
document.getElementById('world_info_folder_expand_'+this.getAttribute("folder")).classList.remove('hidden');
this.classList.add("hidden");
};
title.append(collapse_icon);
expand_icon = document.createElement("span");
expand_icon.id = "world_info_folder_expand_"+folder;
expand_icon.classList.add("oi");
expand_icon.setAttribute("data-glyph", "chevron-right");
expand_icon.setAttribute("folder", folder);
expand_icon.onclick = function () {
unhide_wi_folder(this.getAttribute("folder"));
document.getElementById('world_info_folder_collapse_'+this.getAttribute("folder")).classList.remove('hidden');
this.classList.add("hidden");
};
expand_icon.classList.add("hidden");
title.append(expand_icon);
icon = document.createElement("span");
icon.classList.add("oi");
icon.setAttribute("data-glyph", "folder");
title.append(icon);
title_text = document.createElement("span");
title_text.setAttribute("contenteditable", true);
title_text.setAttribute("original_text", folder);
title_text.textContent = folder;
title_text.onblur = function () {
if (this.textContent != this.getAttribute("original_text")) {
//Need to check if the new folder name is already in use
folder_name = this.textContent;
while (folder_name in document.getElementById("story_menu_wi").children.filter(animal => folder.id.replace("world_info_folder_", ""))) {
folder_name = folder_name + " 1";
}
this.parentElement.parentElement.id = "world_info_folder_" + folder_name;
socket.emit("Rename_World_Info_Folder", {"old_folder": this.getAttribute("original_text"), "new_folder": folder_name});
this.setAttribute("original_text", folder_name);
}
}
title.append(title_text);
folder_item.append(title);
world_info_area.append(folder_item);
}
function hide_wi_folder(folder) {
if (document.getElementById("world_info_folder_"+folder)) {
folder_item = document.getElementById("world_info_folder_"+folder);
for (card of folder_item.children) {
if (card.tagName != "H2") {
card.classList.add("hidden");
}
}
}
}
function unhide_wi_folder(folder) {
if (document.getElementById("world_info_folder_"+folder)) {
folder_item = document.getElementById("world_info_folder_"+folder);
for (card of folder_item.children) {
if (card.tagName != "H2") {
card.classList.remove("hidden");
}
}
}
}
function create_wi_card(wiid) {
world_info_card = document.createElement("div");
world_info_card.setAttribute("draggable", true);
@@ -1280,9 +1417,12 @@ function dragStart(e) {
}
function find_wi_container(e) {
while (true) {
if (e.parentElement == document) {
return e;
} else if (e.tagName == 'H2') {
return e.parentElement;
} else if (typeof e.id == 'undefined') {
e = e.parentElement;
} else if (e.id.replace(/[^a-z_]/gi, '') == 'world_info_') {
@@ -1318,18 +1458,29 @@ function drop(e) {
// get the draggable element
const id = e.dataTransfer.getData('text/plain');
const draggable = document.getElementById(id);
// add it before the drop target
element = find_wi_container(e.target);
element.parentElement.insertBefore(draggable, element);
// display the draggable element
draggable.classList.remove('hidden');
//send the new order to the backend
dragged_id = draggable.id.split("_").slice(-1)[0];
drop_id = element.id.split("_").slice(-1)[0];
socket.emit("move_wi", {'dragged_id': dragged_id, 'drop_id': drop_id});
// get the drop element
element = find_wi_container(e.target);
//check if we're droping on a folder, and then append it to the folder
if (element.children[0].tagName == "H2") {
element.append(draggable);
socket.emit("wi_set_folder", {'dragged_id': dragged_id, 'folder': drop_id});
} else {
//insert the draggable element before the drop element
element.parentElement.insertBefore(draggable, element);
// display the draggable element
draggable.classList.remove('hidden');
if (element.getAttribute("folder") == draggable.getAttribute("folder")) {
socket.emit("move_wi", {'dragged_id': dragged_id, 'drop_id': drop_id, 'folder': null});
} else {
socket.emit("move_wi", {'dragged_id': dragged_id, 'drop_id': drop_id, 'folder': element.getAttribute("folder")});
}
}
}
function dragend(e) {
@@ -1340,67 +1491,69 @@ function dragend(e) {
function assign_world_info_to_action(wiid=null, action_item=null) {
//console.log(world_info_data);
if (wiid != null) {
var worldinfo_to_check = {};
worldinfo_to_check[wiid] = world_info_data[wiid]
} else {
var worldinfo_to_check = world_info_data;
}
if (action_item != null) {
var actions = [action_item]
} else {
var actions = document.getElementById("Selected Text").children;
}
for (action of actions) {
//First check to see if we have a key in the text
var words = Array.prototype.slice.call( action.children );
words_text = [];
for (word of words) {
words_text.push(word.textContent);
if (world_info_data != {}) {
if (wiid != null) {
var worldinfo_to_check = {};
worldinfo_to_check[wiid] = world_info_data[wiid]
} else {
var worldinfo_to_check = world_info_data;
}
for (const [key, worldinfo] of Object.entries(worldinfo_to_check)) {
//remove any world info tags
for (tag of action.getElementsByClassName("tag_wiid_"+wiid)) {
tag.classList.remove("tag_wiid_"+wiid);
tag.removeAttribute("title");
if (action_item != null) {
var actions = [action_item]
} else {
var actions = document.getElementById("Selected Text").children;
}
for (action of actions) {
//First check to see if we have a key in the text
var words = Array.prototype.slice.call( action.children );
words_text = [];
for (word of words) {
words_text.push(word.textContent);
}
if (('key' in worldinfo) & ('keysecondary' in worldinfo) & ('content' in worldinfo)) {
for (keyword of worldinfo['key']) {
if ((action.textContent.replace(/[^0-9a-z \'\"]/gi, '')).includes(keyword)) {
//Ok we have a key match, but we need to check for secondary keys if applicable
if (worldinfo['keysecondary'].length > 0) {
if ('keysecondary' in worldinfo) {
for (second_key of worldinfo['keysecondary']) {
if (action.textContent.replace(/[^0-9a-z \'\"]/gi, '').includes(second_key)) {
//OK we have the phrase in our action. Let's see if we can identify the word(s) that are triggering
for (var i = 0; i < words.length; i++) {
key_words = keyword.split(" ").length;
var to_check = words_text.slice(i, i+key_words).join("").replace(/[^0-9a-z \'\"]/gi, '').trim();
if (keyword == to_check) {
for (var j = i; j < key_words+i; j++) {
words[j].title = worldinfo['content'];
words[j].classList.add("tag_wiid_"+wiid);
for (const [key, worldinfo] of Object.entries(worldinfo_to_check)) {
//remove any world info tags
for (tag of action.getElementsByClassName("tag_wiid_"+wiid)) {
tag.classList.remove("tag_wiid_"+wiid);
tag.removeAttribute("title");
}
if (('key' in worldinfo) & ('keysecondary' in worldinfo) & ('content' in worldinfo)) {
for (keyword of worldinfo['key']) {
if ((action.textContent.replace(/[^0-9a-z \'\"]/gi, '')).includes(keyword)) {
//Ok we have a key match, but we need to check for secondary keys if applicable
if (worldinfo['keysecondary'].length > 0) {
if ('keysecondary' in worldinfo) {
for (second_key of worldinfo['keysecondary']) {
if (action.textContent.replace(/[^0-9a-z \'\"]/gi, '').includes(second_key)) {
//OK we have the phrase in our action. Let's see if we can identify the word(s) that are triggering
for (var i = 0; i < words.length; i++) {
key_words = keyword.split(" ").length;
var to_check = words_text.slice(i, i+key_words).join("").replace(/[^0-9a-z \'\"]/gi, '').trim();
if (keyword == to_check) {
for (var j = i; j < key_words+i; j++) {
words[j].title = worldinfo['content'];
words[j].classList.add("tag_wiid_"+wiid);
}
}
}
}
}
}
}
} else {
//OK we have the phrase in our action. Let's see if we can identify the word(s) that are triggering
for (var i = 0; i < words.length; i++) {
key_words = keyword.split(" ").length;
var to_check = words_text.slice(i, i+key_words).join("").replace(/[^0-9a-z \'\"]/gi, '').trim();
if (keyword == to_check) {
for (var j = i; j < key_words+i; j++) {
words[j].title = worldinfo['content'];
words[j].classList.add("tag_wiid_"+wiid);
} else {
//OK we have the phrase in our action. Let's see if we can identify the word(s) that are triggering
for (var i = 0; i < words.length; i++) {
key_words = keyword.split(" ").length;
var to_check = words_text.slice(i, i+key_words).join("").replace(/[^0-9a-z \'\"]/gi, '').trim();
if (keyword == to_check) {
for (var j = i; j < key_words+i; j++) {
words[j].title = worldinfo['content'];
words[j].classList.add("tag_wiid_"+wiid);
}
}
}
}
}
}
}
}

View File

@@ -29,7 +29,7 @@
<div id="story_menu_memory" class="story_category_area">
<div id="Memory">
Memory:<br/>
<textarea rows=5 id="memory" class="var_sync_story_memory var_sync_alt_story_memory_length fullwidth" onchange='sync_to_server(this);'></textarea>
<textarea rows=20 id="memory" class="var_sync_story_memory var_sync_alt_story_memory_length fullwidth" onchange='sync_to_server(this);'></textarea>
</div>
</div>
<div id="story_menu_author" class="story_category_area hidden">