Merge pull request #139 from wilfredchen/mark-favorite-filter-by-favorite

Mark character and group favorite and filter by favorite
This commit is contained in:
Cohee
2023-04-22 22:19:55 +03:00
committed by GitHub
7 changed files with 122 additions and 18 deletions

1
.gitignore vendored
View File

@@ -14,3 +14,4 @@ config.conf
public/settings.json public/settings.json
/thumbnails /thumbnails
whitelist.txt whitelist.txt
.vscode

View File

@@ -1415,13 +1415,25 @@
<div title="Token counts may be inaccurate and provided just for reference." id="result_info"></div> <div title="Token counts may be inaccurate and provided just for reference." id="result_info"></div>
</div> </div>
<hr> <hr>
<div id="description_div" class="margin-bot-10px"> <div id="fav_chara_wrap">
Description <div id="fav_chara_label" class="margin-bot-10px">
<a href="/notes/1" class="notes-link" target="_blank"> Favorite
<span class="note-link-span">?</span> <a href="/notes/15" class="notes-link" target="_blank">
</a> <span class="note-link-span">?</span>
</a>
</div>
<div>
<input type="checkbox" id="fav_checkbox" name="fav"/>
</div>
</div>
</div> <div id="description_div" class="margin-bot-10px">
Description
<a href="/notes/1" class="notes-link" target="_blank">
<span class="note-link-span">?</span>
</a>
</div>
<textarea id="description_textarea" placeholder="Describe your character's physical and mental traits here." class="margin-bot-10px" name="description" placeholder=""></textarea> <textarea id="description_textarea" placeholder="Describe your character's physical and mental traits here." class="margin-bot-10px" name="description" placeholder=""></textarea>
<div id="first_message_div" class="margin-bot-10px"> <div id="first_message_div" class="margin-bot-10px">
@@ -1458,6 +1470,10 @@
</div> </div>
<div id="rm_group_buttons"> <div id="rm_group_buttons">
<div class="rm_group_settings"> <div class="rm_group_settings">
<label class="checkbox_label">
<input id="rm_group_fav" type="checkbox" />
Favorite
</label>
<label class="checkbox_label"> <label class="checkbox_label">
<input id="rm_group_allow_self_responses" type="checkbox" /> <input id="rm_group_allow_self_responses" type="checkbox" />
Allow bot responses to self Allow bot responses to self
@@ -1517,6 +1533,8 @@
<div class="fa-solid fa-user-group"></div> <div class="fa-solid fa-user-group"></div>
</div> </div>
<div class="ch_name"></div> <div class="ch_name"></div>
<i class='group_fav_icon fa-solid fa-star fa-2xs'></i>
<input class="ch_fav" value="" hidden />
</div> </div>
</div> </div>
</div> </div>
@@ -1532,6 +1550,7 @@
<div id="rm_button_create" title="Create New Character" class="menu_button fa-solid fa-user-plus "></div> <div id="rm_button_create" title="Create New Character" class="menu_button fa-solid fa-user-plus "></div>
<div id="character_import_button" title="Import Character from File" class="menu_button fa-solid fa-file-arrow-up "></div> <div id="character_import_button" title="Import Character from File" class="menu_button fa-solid fa-file-arrow-up "></div>
<div id="rm_button_group_chats" title="Create New Chat Group" class="menu_button fa-solid fa-users-gear "></div> <div id="rm_button_group_chats" title="Create New Chat Group" class="menu_button fa-solid fa-users-gear "></div>
<div id="filter_by_fav" title="Filter By Favorite" class="menu_button fa-solid fa-star"></div>
</div> </div>
<form id="form_character_search_form" action="javascript:void(null);"> <form id="form_character_search_form" action="javascript:void(null);">
<input id="character_search_bar" class="text_pole" type="search" placeholder="Character search..." maxlength="50" /> <input id="character_search_bar" class="text_pole" type="search" placeholder="Character search..." maxlength="50" />

21
public/notes/15.html Normal file
View File

@@ -0,0 +1,21 @@
<html>
<head>
<title>TavernAI - Note - Favorite Character</title>
<link rel="stylesheet" href="/css/notes.css">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin="">
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&amp;display=swap" rel="stylesheet">
</head>
<body>
<div id="main">
<div id="content">
<h2>Favorite Character</h2>
<p>
Mark character as favorite to quickly filter on the side menu bar by pressing on the star button.
</p>
</div>
</div>
</body>
</html>

View File

@@ -203,6 +203,8 @@ let dialogueResolve = null;
let chat_metadata = {}; let chat_metadata = {};
let streamingProcessor = null; let streamingProcessor = null;
let fav_ch_checked = false;
window.filterByFav = false;
const durationSaveEdit = 200; const durationSaveEdit = 200;
const saveSettingsDebounced = debounce(() => saveSettings(), durationSaveEdit); const saveSettingsDebounced = debounce(() => saveSettings(), durationSaveEdit);
@@ -329,6 +331,7 @@ var menu_type = ""; //what is selected in the menu
var selected_button = ""; //which button pressed var selected_button = ""; //which button pressed
//create pole save //create pole save
var create_save_name = ""; var create_save_name = "";
var create_fav_chara = "";
var create_save_description = ""; var create_save_description = "";
var create_save_personality = ""; var create_save_personality = "";
var create_save_first_message = ""; var create_save_first_message = "";
@@ -634,8 +637,6 @@ function updateSoftPromptsList(soft_prompts) {
} }
function printCharacters() { function printCharacters() {
//console.log('printCharacters() entered');
$("#rm_print_characters_block").empty(); $("#rm_print_characters_block").empty();
//console.log('printCharacters() -- sees '+characters.length+' characters.'); //console.log('printCharacters() -- sees '+characters.length+' characters.');
characters.forEach(function (item, i, arr) { characters.forEach(function (item, i, arr) {
@@ -647,7 +648,8 @@ function printCharacters() {
`<div class=character_select chid=${i} id="CharID${i}"> `<div class=character_select chid=${i} id="CharID${i}">
<div class=avatar><img src="${this_avatar}"></div> <div class=avatar><img src="${this_avatar}"></div>
<div class=ch_name>${item.name}</div> <div class=ch_name>${item.name} ${item.fav == "true" ? '<i class="fa-solid fa-star fa-2xs"></i>' : ''}</div>
<input class="ch_fav" value=${item.fav} hidden />
</div>` </div>`
); );
//console.log('printcharacters() -- printing -- ChID '+i+' ('+item.name+')'); //console.log('printcharacters() -- printing -- ChID '+i+' ('+item.name+')');
@@ -1316,7 +1318,7 @@ class StreamingProcessor {
} }
async function Generate(type, automatic_trigger, force_name2) { async function Generate(type, automatic_trigger, force_name2) {
console.log('Generate entered'); //console.log('Generate entered');
setGenerationProgress(0); setGenerationProgress(0);
tokens_already_generated = 0; tokens_already_generated = 0;
const isImpersonate = type == "impersonate"; const isImpersonate = type == "impersonate";
@@ -3164,6 +3166,9 @@ function select_selected_character(chid) {
if (characters[chid].avatar != "none") { if (characters[chid].avatar != "none") {
this_avatar = getThumbnailUrl('avatar', characters[chid].avatar); this_avatar = getThumbnailUrl('avatar', characters[chid].avatar);
} }
$("#fav_checkbox").prop("checked", characters[chid].fav == "true");
$("#avatar_load_preview").attr("src", this_avatar); $("#avatar_load_preview").attr("src", this_avatar);
$("#name_div").css("display", "none"); $("#name_div").css("display", "none");
@@ -3760,6 +3765,25 @@ $(document).ready(function () {
} }
}); });
$("#filter_by_fav").click(function() {
filterByFav = !filterByFav;
const selector = ['#rm_print_characters_block .character_select', '#rm_print_characters_block .group_select'].join(',');
if(filterByFav){
$(selector).each(function () {
if($(this).children(".ch_fav").length !== 0){
$(this).children(".ch_fav").val().toLowerCase().includes(true)
? $(this).show()
: $(this).hide();
}
});
$("#filter_by_fav").addClass("fav_on");
}else{
$(selector).show();
$("#filter_by_fav").removeClass("fav_on");
}
});
$("#send_but").click(function () { $("#send_but").click(function () {
if (is_send_press == false) { if (is_send_press == false) {
is_send_press = true; is_send_press = true;
@@ -3802,6 +3826,7 @@ $(document).ready(function () {
selected_button = "character_edit"; selected_button = "character_edit";
select_selected_character(this_chid); select_selected_character(this_chid);
} }
$("#character_search_bar").val("").trigger("input");
}); });
$(document).on("click", ".character_select", function () { $(document).on("click", ".character_select", function () {
@@ -3829,7 +3854,6 @@ $(document).ready(function () {
selected_button = "character_edit"; selected_button = "character_edit";
select_selected_character(this_chid); select_selected_character(this_chid);
} }
$("#character_search_bar").val("").trigger("input");
}); });
@@ -4096,6 +4120,7 @@ $(document).ready(function () {
$("#rm_info_avatar").html(""); $("#rm_info_avatar").html("");
let save_name = create_save_name; let save_name = create_save_name;
var formData = new FormData($("#form_create").get(0)); var formData = new FormData($("#form_create").get(0));
formData.set('fav', fav_ch_checked);
if ($("#form_create").attr("actiontype") == "createcharacter") { if ($("#form_create").attr("actiontype") == "createcharacter") {
if ($("#character_name_pole").val().length > 0) { if ($("#character_name_pole").val().length > 0) {
//if the character name text area isn't empty (only posible when creating a new character) //if the character name text area isn't empty (only posible when creating a new character)
@@ -4262,11 +4287,18 @@ $(document).ready(function () {
create_save_scenario = $("#scenario_pole").val(); create_save_scenario = $("#scenario_pole").val();
create_save_mes_example = $("#mes_example_textarea").val(); create_save_mes_example = $("#mes_example_textarea").val();
create_save_first_message = $("#firstmessage_textarea").val(); create_save_first_message = $("#firstmessage_textarea").val();
create_fav_chara = $("#fav_checkbox").val();
} else { } else {
saveCharacterDebounced(); saveCharacterDebounced();
} }
}); });
$("#fav_checkbox").change(function(){
fav_ch_checked = $(this).prop("checked");
if (menu_type != "create") {
saveCharacterDebounced();
}
});
$("#talkativeness_slider").on("input", function () { $("#talkativeness_slider").on("input", function () {
if (menu_type == "create") { if (menu_type == "create") {

View File

@@ -214,7 +214,9 @@ function printGroups() {
const template = $("#group_list_template .group_select").clone(); const template = $("#group_list_template .group_select").clone();
template.data("id", group.id); template.data("id", group.id);
template.attr("grid", group.id); template.attr("grid", group.id);
template.find(".ch_name").text(group.name); template.find(".ch_name").html(group.name);
group.fav ? template.find(".group_fav_icon").show() : template.find(".group_fav_icon").hide();
template.find(".ch_fav").val(group.fav);
$("#rm_print_characters_block").prepend(template); $("#rm_print_characters_block").prepend(template);
updateGroupAvatar(group); updateGroupAvatar(group);
} }
@@ -695,7 +697,6 @@ async function reorderGroupMember(chat_id, groupMember, direction) {
function select_group_chats(chat_id, skipAnimation) { function select_group_chats(chat_id, skipAnimation) {
const group = chat_id && groups.find((x) => x.id == chat_id); const group = chat_id && groups.find((x) => x.id == chat_id);
const groupName = group?.name ?? ""; const groupName = group?.name ?? "";
$("#rm_group_chat_name").val(groupName); $("#rm_group_chat_name").val(groupName);
$("#rm_group_chat_name").off(); $("#rm_group_chat_name").off();
$("#rm_group_chat_name").on("input", async function () { $("#rm_group_chat_name").on("input", async function () {
@@ -753,6 +754,7 @@ function select_group_chats(chat_id, skipAnimation) {
const groupHasMembers = !!$("#rm_group_members").children().length; const groupHasMembers = !!$("#rm_group_members").children().length;
$("#rm_group_submit").prop("disabled", !groupHasMembers); $("#rm_group_submit").prop("disabled", !groupHasMembers);
$("#rm_group_allow_self_responses").prop("checked", group && group.allow_self_responses); $("#rm_group_allow_self_responses").prop("checked", group && group.allow_self_responses);
$("#rm_group_fav").prop("checked", group && group.fav);
// bottom buttons // bottom buttons
if (chat_id) { if (chat_id) {
@@ -774,6 +776,15 @@ function select_group_chats(chat_id, skipAnimation) {
callPopup("<h3>Delete the group?</h3>", "del_group"); callPopup("<h3>Delete the group?</h3>", "del_group");
}); });
$("#rm_group_fav").off();
$("#rm_group_fav").on("input", async function(){
if (group) {
const value = $(this).prop("checked");
group.fav = value;
await editGroup(chat_id);
}
});
$("#rm_group_allow_self_responses").off(); $("#rm_group_allow_self_responses").off();
$("#rm_group_allow_self_responses").on("input", async function () { $("#rm_group_allow_self_responses").on("input", async function () {
if (group) { if (group) {
@@ -829,6 +840,9 @@ $(document).ready(() => {
updateChatMetadata({}, true); updateChatMetadata({}, true);
chat.length = 0; chat.length = 0;
await getGroupChat(id); await getGroupChat(id);
//to avoid the filter being lit up yellow and left at true while the list of character and group reseted.
$("#filter_by_fav").removeClass("fav_on");
filterByFav = false;
} }
select_group_chats(id); select_group_chats(id);
@@ -852,6 +866,7 @@ $(document).ready(() => {
$("#rm_group_submit").click(async function () { $("#rm_group_submit").click(async function () {
let name = $("#rm_group_chat_name").val(); let name = $("#rm_group_chat_name").val();
let allow_self_responses = !!$("#rm_group_allow_self_responses").prop("checked"); let allow_self_responses = !!$("#rm_group_allow_self_responses").prop("checked");
let fav = $("#rm_group_fav").prop("checked");
let activation_strategy = $('input[name="rm_group_activation_strategy"]:checked').val() ?? group_activation_strategy.NATURAL; let activation_strategy = $('input[name="rm_group_activation_strategy"]:checked').val() ?? group_activation_strategy.NATURAL;
const members = $("#rm_group_members .group_member") const members = $("#rm_group_members .group_member")
.map((_, x) => $(x).data("id")) .map((_, x) => $(x).data("id"))
@@ -877,6 +892,7 @@ $(document).ready(() => {
allow_self_responses: allow_self_responses, allow_self_responses: allow_self_responses,
activation_strategy: activation_strategy, activation_strategy: activation_strategy,
chat_metadata: {}, chat_metadata: {},
fav: fav,
}), }),
}); });

View File

@@ -909,6 +909,9 @@ select option:not(:checked) {
cursor: not-allowed; cursor: not-allowed;
} }
.fav_on {
color: #ffff00 !important;
}
#api_url_text, #api_url_text,
#textgenerationwebui_api_url_text { #textgenerationwebui_api_url_text {
@@ -1138,6 +1141,17 @@ input[type=search]:focus::-webkit-search-cancel-button {
margin-bottom: 4px; margin-bottom: 4px;
} }
#fav_chara_wrap{
display: flex;
margin: 5px 0px;
}
#fav_chara {
border: none;
font-size: var(--mainFontSize);
display: flex;
}
#description_div { #description_div {
position: relative; position: relative;
} }
@@ -2484,12 +2498,15 @@ h5 {
} }
.group_select .ch_name { .group_select .ch_name {
flex-grow: 1;
max-width: calc(100% - 100px); max-width: calc(100% - 100px);
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
} }
.group_select .group_fav_icon{
margin-left: 5px;
}
#typing_indicator_template { #typing_indicator_template {
display: none !important; display: none !important;
} }

View File

@@ -681,7 +681,7 @@ function checkServer() {
//***************** Main functions //***************** Main functions
function charaFormatData(data) { function charaFormatData(data) {
var char = { "name": data.ch_name, "description": data.description, "personality": data.personality, "first_mes": data.first_mes, "avatar": 'none', "chat": data.ch_name + ' - ' + humanizedISO8601DateTime(), "mes_example": data.mes_example, "scenario": data.scenario, "create_date": humanizedISO8601DateTime(), "talkativeness": data.talkativeness }; var char = { "name": data.ch_name, "description": data.description, "personality": data.personality, "first_mes": data.first_mes, "avatar": 'none', "chat": data.ch_name + ' - ' + humanizedISO8601DateTime(), "mes_example": data.mes_example, "scenario": data.scenario, "create_date": humanizedISO8601DateTime(), "talkativeness": data.talkativeness, "fav": data.fav};
return char; return char;
} }
app.post("/createcharacter", urlencodedParser, function (request, response) { app.post("/createcharacter", urlencodedParser, function (request, response) {
@@ -735,10 +735,8 @@ app.post("/editcharacter", urlencodedParser, async function (request, response)
var char = charaFormatData(request.body);//{"name": request.body.ch_name, "description": request.body.description, "personality": request.body.personality, "first_mes": request.body.first_mes, "avatar": request.body.avatar_url, "chat": request.body.chat, "last_mes": request.body.last_mes, "mes_example": ''}; var char = charaFormatData(request.body);//{"name": request.body.ch_name, "description": request.body.description, "personality": request.body.personality, "first_mes": request.body.first_mes, "avatar": request.body.avatar_url, "chat": request.body.chat, "last_mes": request.body.last_mes, "mes_example": ''};
char.chat = request.body.chat; char.chat = request.body.chat;
char.create_date = request.body.create_date; char.create_date = request.body.create_date;
char = JSON.stringify(char); char = JSON.stringify(char);
let target_img = (request.body.avatar_url).replace('.png', ''); let target_img = (request.body.avatar_url).replace('.png', '');
try { try {
if (!filedata) { if (!filedata) {
@@ -1761,6 +1759,7 @@ app.post('/creategroup', jsonParser, (request, response) => {
allow_self_responses: !!request.body.allow_self_responses, allow_self_responses: !!request.body.allow_self_responses,
activation_strategy: request.body.activation_strategy ?? 0, activation_strategy: request.body.activation_strategy ?? 0,
chat_metadata: request.body.chat_metadata ?? {}, chat_metadata: request.body.chat_metadata ?? {},
fav: request.body.fav,
}; };
const pathToFile = path.join(directories.groups, `${id}.json`); const pathToFile = path.join(directories.groups, `${id}.json`);
const fileData = JSON.stringify(chatMetadata); const fileData = JSON.stringify(chatMetadata);
@@ -1777,7 +1776,6 @@ app.post('/editgroup', jsonParser, (request, response) => {
if (!request.body || !request.body.id) { if (!request.body || !request.body.id) {
return response.sendStatus(400); return response.sendStatus(400);
} }
const id = request.body.id; const id = request.body.id;
const pathToFile = path.join(directories.groups, `${id}.json`); const pathToFile = path.join(directories.groups, `${id}.json`);
const fileData = JSON.stringify(request.body); const fileData = JSON.stringify(request.body);