#21 Add world info export, edit popup and deletion

This commit is contained in:
SillyLossy
2023-02-10 23:26:53 +02:00
parent 1e48220711
commit bea28c1845
3 changed files with 257 additions and 13 deletions

View File

@@ -54,6 +54,7 @@
var is_mes_reload_avatar = false; var is_mes_reload_avatar = false;
var is_advanced_char_open = false; var is_advanced_char_open = false;
var is_world_edit_open = false;
var menu_type = '';//what is selected in the menu var menu_type = '';//what is selected in the menu
var selected_button = '';//which button pressed var selected_button = '';//which button pressed
@@ -108,6 +109,7 @@
var kobold_world_synced = false; var kobold_world_synced = false;
var kobold_sync_failed = false; var kobold_sync_failed = false;
var kobold_is_united = false; var kobold_is_united = false;
var imported_world_name = '';
var max_context = 2048;//2048; var max_context = 2048;//2048;
var rep_pen = 1; var rep_pen = 1;
var rep_pen_size = 100; var rep_pen_size = 100;
@@ -1524,8 +1526,16 @@
} }
}); });
} }
if (popup_type === 'world_imported') { if (popup_type === 'world_imported' && imported_world_name) {
// switch to a new world koboldai_world_names.forEach((item, i) => {
if (item === imported_world_name) {
$('#world_info').val(i).change();
}
})
imported_world_name = '';
}
if (popup_type === 'del_world' && kobold_world) {
deleteWorldInfo(kobold_world);
} }
if(popup_type == 'new_chat' && this_chid != undefined && menu_type != "create"){//Fix it; New chat doesn't create while open create character menu if(popup_type == 'new_chat' && this_chid != undefined && menu_type != "create"){//Fix it; New chat doesn't create while open create character menu
clearChat(); clearChat();
@@ -1558,6 +1568,7 @@
$("#dialogue_popup_ok").css("background-color", "#191b31CC"); $("#dialogue_popup_ok").css("background-color", "#191b31CC");
$("#dialogue_popup_ok").text("Yes"); $("#dialogue_popup_ok").text("Yes");
break; break;
case 'del_world':
default: default:
$("#dialogue_popup_ok").css("background-color", "#791b31"); $("#dialogue_popup_ok").css("background-color", "#791b31");
$("#dialogue_popup_ok").text("Delete"); $("#dialogue_popup_ok").text("Delete");
@@ -1963,6 +1974,7 @@
kobold_world = !isNaN(worldIndex) ? koboldai_world_names[worldIndex] : null; kobold_world = !isNaN(worldIndex) ? koboldai_world_names[worldIndex] : null;
} }
hideWorldEditor();
syncKoboldWorldInfo(true); syncKoboldWorldInfo(true);
saveSettings(); saveSettings();
updateWorldStatus(); updateWorldStatus();
@@ -2085,6 +2097,7 @@
function updateWorldStatus() { function updateWorldStatus() {
if($('#world_info_block').is(':visible') && kobold_world) { if($('#world_info_block').is(':visible') && kobold_world) {
$('#world_info_edit_button').show();
$('#world_status').show(); $('#world_status').show();
if (kobold_world_synced) { if (kobold_world_synced) {
@@ -2109,6 +2122,7 @@
} }
} else { } else {
$('#world_status').hide(); $('#world_status').hide();
$('#world_info_edit_button').hide();
} }
} }
@@ -2140,7 +2154,7 @@
body: JSON.stringify({ "name": kobold_world }) body: JSON.stringify({ "name": kobold_world })
}); });
if (response.ok === true) { if (response.ok) {
const syncData = await response.json(); const syncData = await response.json();
if (syncData.ok) { if (syncData.ok) {
@@ -2327,7 +2341,7 @@
$('#world_info').append(`<option value='${i}'>${item}</option>`); $('#world_info').append(`<option value='${i}'>${item}</option>`);
// preselect world if saved // preselect world if saved
if (item == kobold_world){ if (item == kobold_world){
$(`#world_info option[value=${i}]`).attr('selected', 'true'); $('#world_info').val(i).change();
} }
}); });
// end world info settings // end world info settings
@@ -2921,9 +2935,8 @@
processData: false, processData: false,
success: function(data){ success: function(data){
if (data.name) { if (data.name) {
// TODO reload list of custom worlds to allow selection then offer a popup imported_world_name = data.name;
// popup_type = 'world_imported'; updateWorldInfoList(imported_world_name);
// callPopup('<h3>World imported successfully! Select it now?</h3>');
} }
}, },
error: (jqXHR, exception) => {}, error: (jqXHR, exception) => {},
@@ -2933,6 +2946,104 @@
$('#form_world_import').trigger("reset"); $('#form_world_import').trigger("reset");
}); });
async function updateWorldInfoList(importedWorldName) {
var result = await fetch('/getsettings', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({})
});
if (result.ok) {
var data = await result.json();
koboldai_world_names = data.koboldai_world_names?.length ? data.koboldai_world_names : [];
$('#world_info').find('option[value!="None"]').remove();
koboldai_world_names.forEach((item, i) => {
$('#world_info').append(`<option value='${i}'>${item}</option>`);
});
if (importedWorldName) {
const indexOf = koboldai_world_names.indexOf(kobold_world);
$(`#world_info`).val(indexOf);
popup_type = 'world_imported';
callPopup('<h3>World imported successfully! Select it now?</h3>');
}
}
}
function download(content, fileName, contentType) {
var a = document.createElement("a");
var file = new Blob([content], {type: contentType});
a.href = URL.createObjectURL(file);
a.download = fileName;
a.click();
}
// World Info Editor
async function showWorldEditor() {
is_world_edit_open = true;
$('#world_text_content').val('');
$('#world_popup').css('display', 'flex');
if (kobold_world) {
const response = await fetch("/getworldinfo", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ name: kobold_world })
});
if (response.ok) {
const worldInfoData = await response.text();
$('#world_text_content').val(worldInfoData);
}
}
}
function hideWorldEditor() {
is_world_edit_open = false;
$('#world_popup').css('display', 'none');
$('#world_text_content').val('');
}
async function deleteWorldInfo(worldInfoName) {
if (!koboldai_world_names.includes(worldInfoName)) {
return;
}
const response = await fetch("/deleteworldinfo", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ name: worldInfoName })
});
if (response.ok) {
await updateWorldInfoList();
$('#world_info').val('None').change();
hideWorldEditor();
}
}
$('#world_info_edit_button').click(() => {
is_world_edit_open ? hideWorldEditor() : showWorldEditor();
});
$('#world_popup_export').click(() => {
const jsonValue = $('#world_text_content').val();
if (kobold_world && jsonValue) {
const fileName = `${kobold_world}.json`;
download(jsonValue, fileName, 'application/json');
}
});
$('#world_popup_delete').click(() => {
popup_type = 'del_world';
callPopup('<h3>Delete the World Info?</h3>');
});
$('#world_cross').click(() => {
hideWorldEditor();
});
}); });
    </script>     </script>
<title>Tavern.AI</title> <title>Tavern.AI</title>
@@ -2990,6 +3101,27 @@
<div></div> <div></div>
</div> </div>
<div id="world_popup">
<div id="world_popup_text">
<img id="world_cross" src="img/cross.png">
<div>
<!-- Probably needs a logo (probably) -->
<!-- <img src="img/book2.png" id="world_logo"> -->
<h3>World Info creation</h3>
</div>
</div>
<!-- Placeholder until actual editor is implemented -->
<h4>File content (read-only)</h4>
<textarea id="world_text_content" placeholder="Loading..." form="form_create" disabled></textarea>
<div id="world_popup_bottom_holder">
<div id="world_popup_export" class="menu_button">Export</div>
<div id="world_popup_delete" class="menu_button">Delete</div>
</div>
</div>
<div id="shadow_select_chat_popup"> <div id="shadow_select_chat_popup">
<div id="select_chat_popup"> <div id="select_chat_popup">
<div id="select_chat_popup_text"> <div id="select_chat_popup_text">
@@ -3141,7 +3273,11 @@
<input type="range" id="rep_pen_size" name="volume" min="0" max="2048" step="1"> <input type="range" id="rep_pen_size" name="volume" min="0" max="2048" step="1">
</div> </div>
<div> <div>
<h4 id="world_info_block">World Info</h4><h5>How to use (<a href="/notes/13" target="_blank">?</a>)</h5> <h4 id="world_info_block">
World Info
<div id="world_import_button" class="right_menu_button"><h2>+Import</h2></div>
<h5>How to use (<a href="/notes/13" target="_blank">?</a>)</h5>
</h4>
<div id="rm_world_import" class="right_menu" style="display: none;"> <div id="rm_world_import" class="right_menu" style="display: none;">
<form id="form_world_import" action="javascript:void(null);" method="post" enctype="multipart/form-data"> <form id="form_world_import" action="javascript:void(null);" method="post" enctype="multipart/form-data">
<input type="file" id="world_import_file" accept=".json" name="avatar"> <input type="file" id="world_import_file" accept=".json" name="avatar">
@@ -3150,7 +3286,7 @@
<select id="world_info" class="option_select_right_menu"> <select id="world_info" class="option_select_right_menu">
<option value="None">None</option> <option value="None">None</option>
</select> </select>
<div id="world_import_button" class="right_menu_button"><h2>+Import</h2></div> <input id="world_info_edit_button" type="button" value="Details">
<div id="world_status"> <div id="world_status">
<div id="world_status_indicator"></div><div id="world_status_text"></div> <div id="world_status_indicator"></div><div id="world_status_text"></div>
</div> </div>

View File

@@ -956,12 +956,15 @@ input[type=button] {
#world_info { #world_info {
margin-bottom: 12px; margin-bottom: 12px;
margin-right: 4px;
} }
#world_status{ #world_status{
opacity: 0.5; opacity: 0.5;
margin-top: 2px; margin-top: 2px;
margin-left: 10px; margin-left: 10px;
} }
#world_status_indicator{ #world_status_indicator{
border-radius: 7px; border-radius: 7px;
width: 14px; width: 14px;
@@ -969,21 +972,99 @@ input[type=button] {
background-color: red; background-color: red;
display: inline-block; display: inline-block;
} }
#world_status_text { #world_status_text {
margin-left: 4px; margin-left: 4px;
display: inline-block; display: inline-block;
} }
#world_import_button { #world_import_button {
cursor: pointer; cursor: pointer;
display: inline-block; display: inline-block;
} }
#world_import_button h2 { #world_import_button h2 {
margin-top: auto; margin-top: auto;
margin-bottom: auto; margin-bottom: auto;
font-size: 17px; margin-left: 1rem;
font-size: 16px;
color: rgb(188, 193, 200, 0.5); color: rgb(188, 193, 200, 0.5);
} }
#world_info_edit_button {
cursor: pointer;
color: #ffffffaa;
padding-left: 0.5rem;
padding-right: 0.5rem;
}
#world_popup {
display: none;
flex-direction: column;
max-width: 800px;
height: 83vh;
position: absolute;
z-index: 2060;
background-color: blue;
margin-left: auto;
margin-right: auto;
left: 0;
right: 0;
margin-top: 0px;
box-shadow: 0 0 2px rgba(200, 200, 200, 0.1);
padding: 4px 36px;
background: #191b31F5;
border-radius: 1px;
}
#world_text_content {
margin: 0;
flex-grow: 1;
}
#world_popup_bottom_holder {
padding: 1rem 0;
display: flex;
flex-direction: row;
justify-content: flex-end;
}
#world_popup_bottom_holder div {
margin-left: 1rem;
cursor: pointer;
user-select: none;
}
#world_cross {
position: absolute;
right: 15px;
top: 15px;
width: 20px;
height: 20px;
cursor: pointer;
opacity: 0.6;
}
#world_popup h5 a {
color: #936f4a;
}
#world_popup h5 a:hover {
color: #998e6b;
}
#world_popup h4 a {
color: #936f4a;
}
#world_popup h4 a:hover {
color: #998e6b;
}
#world_popup h5 {
color: #757575;
}
.del_checkbox{ .del_checkbox{
display: none; display: none;
opacity: 0.5; opacity: 0.5;

View File

@@ -709,6 +709,33 @@ app.post('/synckoboldworld', jsonParser, async (request, response) => {
} }
}); });
app.post('/getworldinfo', jsonParser, async (request, response) => {
if (!request.body?.name) {
return response.sendStatus(400);
}
const file = readWorldInfoFile(request.body.name);
return response.send(file.tavernWorldInfo);
});
app.post('/deleteworldinfo', jsonParser, async (request, response) => {
if (!request.body?.name) {
return response.sendStatus(400);
}
const worldInfoName = request.body.name;
const filename = `${worldInfoName}.json`;
const pathToWorldInfo = path.join(directories.worlds, filename);
if (!fs.existsSync(pathToWorldInfo)) {
throw new Error(`World info file ${filename} doesn't exist.`);
}
fs.rmSync(pathToWorldInfo);
return response.sendStatus(200);
});
function getCharaterFile(directories,response,i){ //old need del function getCharaterFile(directories,response,i){ //old need del
if(directories.length > i){ if(directories.length > i){