mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
Add character tagging (groups pending)
This commit is contained in:
@ -1367,6 +1367,7 @@
|
|||||||
<input id="extensions_url" type="text" class="text_pole" maxlength="250" />
|
<input id="extensions_url" type="text" class="text_pole" maxlength="250" />
|
||||||
<div class="extensions_url_block">
|
<div class="extensions_url_block">
|
||||||
<input id="extensions_connect" class="menu_button" type="submit" value="Connect" />
|
<input id="extensions_connect" class="menu_button" type="submit" value="Connect" />
|
||||||
|
<input id="extensions_details" class="menu_button" type="button" value="Manage extensions" />
|
||||||
<span class="expander"></span>
|
<span class="expander"></span>
|
||||||
<label for="extensions_autoconnect"><input id="extensions_autoconnect" type="checkbox" />
|
<label for="extensions_autoconnect"><input id="extensions_autoconnect" type="checkbox" />
|
||||||
Auto-connect
|
Auto-connect
|
||||||
@ -1379,8 +1380,6 @@
|
|||||||
<h4>Active extensions</h4>
|
<h4>Active extensions</h4>
|
||||||
<ul id="extensions_list">
|
<ul id="extensions_list">
|
||||||
</ul>
|
</ul>
|
||||||
<p>Missing something? Press <a id="extensions_details" href="javascript:void(null);">here</a>
|
|
||||||
for more details!</p>
|
|
||||||
</div>
|
</div>
|
||||||
<div id="extensions_settings">
|
<div id="extensions_settings">
|
||||||
<h3>Extension settings</h3>
|
<h3>Extension settings</h3>
|
||||||
@ -1439,13 +1438,14 @@
|
|||||||
<div id="delete_button" class="menu_button fa-solid fa-trash-can " title="Delete Character"></div>
|
<div id="delete_button" class="menu_button fa-solid fa-trash-can " title="Delete Character"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<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="tags_div" class="margin-bot-10px ui-widget">
|
<div id="tags_div">
|
||||||
<input id="tagInput" class="text_pole margin-bot-10px" />
|
<div class="margin-bot-10px">Tags</div>
|
||||||
<div id="tagList"></div>
|
<input id="tagInput" class="text_pole" placeholder="Search / Create tags" />
|
||||||
|
<div id="tagList" class="tags"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="description_div" class="margin-bot-10px">
|
<div id="description_div" class="margin-bot-10px">
|
||||||
@ -1529,35 +1529,6 @@
|
|||||||
<h3>Members</h3>
|
<h3>Members</h3>
|
||||||
<!-- !!!Don't break line after div!!! -->
|
<!-- !!!Don't break line after div!!! -->
|
||||||
<div id="rm_group_members"></div>
|
<div id="rm_group_members"></div>
|
||||||
|
|
||||||
<div id="group_member_template">
|
|
||||||
<div class="group_member">
|
|
||||||
<div class="avatar">
|
|
||||||
<img alt="Avatar" src="" />
|
|
||||||
</div>
|
|
||||||
<div class="ch_name"></div>
|
|
||||||
<div class="group_member_icon">
|
|
||||||
<div title="Move up" data-action="up" class="right_menu_button fa-solid fa-xl fa-chevron-up"></div>
|
|
||||||
<div title="Move down" data-action="down" class="right_menu_button fa-solid fa-xl fa-chevron-down"></div>
|
|
||||||
<div title="Remove from group" data-action="remove" class="right_menu_button fa-solid fa-2xl fa-xmark"></div>
|
|
||||||
<div title="Add to group" data-action="add" class="right_menu_button fa-solid fa-2xl fa-plus"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="group_list_template">
|
|
||||||
<div class="group_select">
|
|
||||||
<div class="avatar">
|
|
||||||
<img src="">
|
|
||||||
</div>
|
|
||||||
<div class="group_icon">
|
|
||||||
<div class="fa-solid fa-user-group"></div>
|
|
||||||
</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 id="rm_character_import" class="right_menu" style="display: none;">
|
<div id="rm_character_import" class="right_menu" style="display: none;">
|
||||||
@ -1586,6 +1557,9 @@
|
|||||||
<option data-field="chat_size" data-order="asc">Least chatted</option>
|
<option data-field="chat_size" data-order="asc">Least chatted</option>
|
||||||
</select>
|
</select>
|
||||||
</form>
|
</form>
|
||||||
|
<div id="rm_tag_filter" class="tags">
|
||||||
|
|
||||||
|
</div>
|
||||||
<div id="rm_print_characters_block"></div>
|
<div id="rm_print_characters_block"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -1815,7 +1789,14 @@
|
|||||||
|
|
||||||
<!-- templates for JS to reuse when needed -->
|
<!-- templates for JS to reuse when needed -->
|
||||||
|
|
||||||
<div id="openai_logit_bias_template">
|
<div id="tag_template" class="template_element">
|
||||||
|
<span id="" class="tag">
|
||||||
|
<span class="tag_name"></span>
|
||||||
|
<i class="fa-solid fa-circle-xmark tag_remove"></i>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="openai_logit_bias_template" class="template_element">
|
||||||
<div class="openai_logit_bias_form">
|
<div class="openai_logit_bias_form">
|
||||||
<input class="openai_logit_bias_text text_pole" placeholder="type here..." />
|
<input class="openai_logit_bias_text text_pole" placeholder="type here..." />
|
||||||
<input class="openai_logit_bias_value text_pole" type="number" min="-100" value="0" max="100" />
|
<input class="openai_logit_bias_value text_pole" type="number" min="-100" value="0" max="100" />
|
||||||
@ -1823,7 +1804,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="message_template">
|
<div id="message_template" class="template_element">
|
||||||
<div class="mes" mesid="${count_view_mes}" ch_name="${characterName}" is_user="${mes.is_user}" is_system="${mes.is_system}">
|
<div class="mes" mesid="${count_view_mes}" ch_name="${characterName}" is_user="${mes.is_user}" is_system="${mes.is_system}">
|
||||||
<div class="for_checkbox"></div><input type="checkbox" class="del_checkbox">
|
<div class="for_checkbox"></div><input type="checkbox" class="del_checkbox">
|
||||||
<div class="avatar"><img src=""></div>
|
<div class="avatar"><img src=""></div>
|
||||||
@ -1856,7 +1837,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="group_avatars_template">
|
<div id="group_avatars_template" class="template_element">
|
||||||
<div class="avatar avatar_collage collage_1">
|
<div class="avatar avatar_collage collage_1">
|
||||||
<img alt="img1" class="img_1" src="">
|
<img alt="img1" class="img_1" src="">
|
||||||
</div>
|
</div>
|
||||||
@ -1877,8 +1858,37 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="group_member_template" class="template_element">
|
||||||
|
<div class="group_member">
|
||||||
|
<div class="avatar">
|
||||||
|
<img alt="Avatar" src="" />
|
||||||
|
</div>
|
||||||
|
<div class="ch_name"></div>
|
||||||
|
<div class="group_member_icon">
|
||||||
|
<div title="Move up" data-action="up" class="right_menu_button fa-solid fa-xl fa-chevron-up"></div>
|
||||||
|
<div title="Move down" data-action="down" class="right_menu_button fa-solid fa-xl fa-chevron-down"></div>
|
||||||
|
<div title="Remove from group" data-action="remove" class="right_menu_button fa-solid fa-2xl fa-xmark"></div>
|
||||||
|
<div title="Add to group" data-action="add" class="right_menu_button fa-solid fa-2xl fa-plus"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="group_list_template" class="template_element">
|
||||||
|
<div class="group_select">
|
||||||
|
<div class="avatar">
|
||||||
|
<img src="">
|
||||||
|
</div>
|
||||||
|
<div class="group_icon">
|
||||||
|
<div class="fa-solid fa-user-group"></div>
|
||||||
|
</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>
|
||||||
|
|
||||||
<!-- chat and input bar -->
|
<!-- chat and input bar -->
|
||||||
<div id="typing_indicator_template">
|
<div id="typing_indicator_template" class="template_element">
|
||||||
<div class="typing_indicator"><span class="typing_indicator_name">CHAR</span> is typing</div>
|
<div class="typing_indicator"><span class="typing_indicator_name">CHAR</span> is typing</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="sheld">
|
<div id="sheld">
|
||||||
|
@ -93,6 +93,7 @@ import {
|
|||||||
import { debounce, delay } from "./scripts/utils.js";
|
import { debounce, delay } from "./scripts/utils.js";
|
||||||
import { extension_settings, loadExtensionSettings } from "./scripts/extensions.js";
|
import { extension_settings, loadExtensionSettings } from "./scripts/extensions.js";
|
||||||
import { executeSlashCommands, getSlashCommandsHelp } from "./scripts/slash-commands.js";
|
import { executeSlashCommands, getSlashCommandsHelp } from "./scripts/slash-commands.js";
|
||||||
|
import { tag_map, tags, loadTagsSettings, printTags, isElementTagged } from "./scripts/tags.js";
|
||||||
|
|
||||||
//exporting functions and vars for mods
|
//exporting functions and vars for mods
|
||||||
export {
|
export {
|
||||||
@ -277,6 +278,8 @@ const system_messages = {
|
|||||||
'</ol>',
|
'</ol>',
|
||||||
'Type <tt>/?</tt> in any chat to get help on message formatting commands.',
|
'Type <tt>/?</tt> in any chat to get help on message formatting commands.',
|
||||||
'<h3>Still have questions or suggestions left?</h3>',
|
'<h3>Still have questions or suggestions left?</h3>',
|
||||||
|
'<a target="_blank" href="https://discord.gg/RZdyAEUPvj">SillyTavern Community Discord</a>',
|
||||||
|
'<br/>',
|
||||||
'<a target="_blank" href="https://github.com/Cohee1207/SillyTavern/issues">Post a GitHub issue.</a>',
|
'<a target="_blank" href="https://github.com/Cohee1207/SillyTavern/issues">Post a GitHub issue.</a>',
|
||||||
'<br/>',
|
'<br/>',
|
||||||
'<a target="_blank" href="https://github.com/Cohee1207/SillyTavern#questions-or-suggestions">Contact the developers.</a>'
|
'<a target="_blank" href="https://github.com/Cohee1207/SillyTavern#questions-or-suggestions">Contact the developers.</a>'
|
||||||
@ -667,9 +670,8 @@ function printCharacters() {
|
|||||||
this_avatar = getThumbnailUrl('avatar', item.avatar);
|
this_avatar = getThumbnailUrl('avatar', item.avatar);
|
||||||
} //RossAscends: changed 'prepend' to 'append' to make alphabetical sorting display correctly.
|
} //RossAscends: changed 'prepend' to 'append' to make alphabetical sorting display correctly.
|
||||||
$("#rm_print_characters_block").append(
|
$("#rm_print_characters_block").append(
|
||||||
|
|
||||||
`<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 title="${item.avatar}"><img src="${this_avatar}"></div>
|
||||||
<div class=ch_name>${item.name} ${item.fav == "true" ? '<i class="fa-solid fa-star fa-2xs"></i>' : ''}</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 />
|
<input class="ch_fav" value=${item.fav} hidden />
|
||||||
</div>`
|
</div>`
|
||||||
@ -677,6 +679,7 @@ function printCharacters() {
|
|||||||
//console.log('printcharacters() -- printing -- ChID '+i+' ('+item.name+')');
|
//console.log('printcharacters() -- printing -- ChID '+i+' ('+item.name+')');
|
||||||
});
|
});
|
||||||
$("#rm_print_characters_block").prepend(`<hr>`);
|
$("#rm_print_characters_block").prepend(`<hr>`);
|
||||||
|
printTags();
|
||||||
printGroups();
|
printGroups();
|
||||||
sortCharactersList();
|
sortCharactersList();
|
||||||
}
|
}
|
||||||
@ -2825,6 +2828,8 @@ async function getSettings(type) {
|
|||||||
// Load power user settings
|
// Load power user settings
|
||||||
loadPowerUserSettings(settings, data);
|
loadPowerUserSettings(settings, data);
|
||||||
|
|
||||||
|
// Load- character tags
|
||||||
|
loadTagsSettings(settings);
|
||||||
|
|
||||||
//Enable GUI deference settings if GUI is selected for Kobold
|
//Enable GUI deference settings if GUI is selected for Kobold
|
||||||
if (main_api === "kobold") {
|
if (main_api === "kobold") {
|
||||||
@ -2918,10 +2923,12 @@ async function saveSettings(type) {
|
|||||||
power_user: power_user,
|
power_user: power_user,
|
||||||
poe_settings: poe_settings,
|
poe_settings: poe_settings,
|
||||||
extension_settings: extension_settings,
|
extension_settings: extension_settings,
|
||||||
|
tags: tags,
|
||||||
|
tag_map: tag_map,
|
||||||
...nai_settings,
|
...nai_settings,
|
||||||
...kai_settings,
|
...kai_settings,
|
||||||
...oai_settings,
|
...oai_settings,
|
||||||
}),
|
}, null, 4),
|
||||||
beforeSend: function () {
|
beforeSend: function () {
|
||||||
//console.log('saveSettings() -- active_character -- '+active_character);
|
//console.log('saveSettings() -- active_character -- '+active_character);
|
||||||
if (type == "change_name") {
|
if (type == "change_name") {
|
||||||
@ -3811,16 +3818,38 @@ $(document).ready(function () {
|
|||||||
$("#character_search_bar").on("input", function () {
|
$("#character_search_bar").on("input", function () {
|
||||||
const selector = ['#rm_print_characters_block .character_select', '#rm_print_characters_block .group_select'].join(',');
|
const selector = ['#rm_print_characters_block .character_select', '#rm_print_characters_block .group_select'].join(',');
|
||||||
const searchValue = $(this).val().trim().toLowerCase();
|
const searchValue = $(this).val().trim().toLowerCase();
|
||||||
|
const selectedTagId = $('#rm_tag_filter .tag.selected').attr('id');
|
||||||
|
|
||||||
if (!searchValue) {
|
if (!searchValue) {
|
||||||
$(selector).show();
|
$(selector).each(function () {
|
||||||
|
if (selectedTagId && !isElementTagged(this, selectedTagId)) {
|
||||||
|
$(this).hide();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$(this).show();
|
||||||
|
}
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
$(selector).each(function () {
|
$(selector).each(function () {
|
||||||
$(this).children(".ch_name").text().toLowerCase().includes(searchValue)
|
const isValidSearch = $(this).children(".ch_name").text().toLowerCase().includes(searchValue);
|
||||||
? $(this).show()
|
|
||||||
: $(this).hide();
|
if (isValidSearch) {
|
||||||
|
if (selectedTagId && !isElementTagged(this, selectedTagId)) {
|
||||||
|
$(this).hide();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$(this).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$(this).hide();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (selectedTagId) {
|
||||||
|
applyFilterToList(selectedTagId)
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$("#filter_by_fav").click(function () {
|
$("#filter_by_fav").click(function () {
|
||||||
|
@ -1,49 +1,253 @@
|
|||||||
|
import { characters, saveSettingsDebounced, this_chid } from "../script.js";
|
||||||
|
import { selected_group } from "./group-chats.js";
|
||||||
|
|
||||||
|
export {
|
||||||
|
tags,
|
||||||
|
tag_map,
|
||||||
|
loadTagsSettings,
|
||||||
|
printTags,
|
||||||
|
isElementTagged,
|
||||||
|
};
|
||||||
|
|
||||||
const TAG_COLORS = [
|
const TAG_COLORS = [
|
||||||
'#FFB6C1', // Light Pink
|
"#dd0a36", // Red
|
||||||
'#FFECB3', // Light Yellow
|
"#ff6633", // Orange
|
||||||
'#FFE4B5', // Cream
|
"#5f9ea0", // Teal Green
|
||||||
'#B2EBF2', // Powder Blue
|
"#1e90ff", // Light Blue
|
||||||
'#E0FFFF', // Light Sky Blue
|
"#990066", // Plum
|
||||||
'#FBB4B9', // Lavender
|
"#8c00ff", // Fuchsia
|
||||||
'#FFF9C4', // Floral White
|
"#00ffff", // Aqua
|
||||||
'#DDA0DD', // Plum
|
"#0f4ecc", // Teal
|
||||||
'#DA70D6', // Orchid
|
"#2f4b1c", // Green
|
||||||
'#D2B48C', // Tan
|
"#3366e5", // Dodger Blue
|
||||||
'#FAEBD7', // Antique White
|
"#36c3a1", // Mint Green
|
||||||
'#FFEFD5', // Papaya Whip
|
"#995511", // Terracotta
|
||||||
'#CD853F', // Peru
|
"#ab47bc", // Plum RGBA
|
||||||
'#B2DFEE', // Sky Blue
|
"#805451", // Mulberry
|
||||||
'#FFFFC2', // Parchment
|
"#ff8c69", // Salmon
|
||||||
'#FDF5E6', // Old Lace
|
"#ba55d3", // Magenta
|
||||||
|
"#b3ffba", // Mint RGBA
|
||||||
|
"#bae7b3", // Sea Green
|
||||||
|
"#b5d6fd", // Light Sky Blue
|
||||||
|
"#d9ecf1", // Mint Green RGBA
|
||||||
|
"#ffe6e6", // Light Pink
|
||||||
|
"#dcd0c8", // Linen
|
||||||
|
"#bed3f3", // Lavender Blush
|
||||||
|
"#ffe9f3", // Sand RGBA
|
||||||
|
"#333366", // Violet
|
||||||
|
"#993333", // Red Violet
|
||||||
|
"#3399ff", // Sky Blue
|
||||||
];
|
];
|
||||||
|
|
||||||
let tags = [
|
const random_id = () => Math.round(Date.now() * Math.random()).toString();
|
||||||
{ name: "tag1", color: "blue" },
|
|
||||||
{ name: "tag2", color: "green" }
|
const DEFAULT_TAGS = [
|
||||||
|
{ id: random_id(), name: "Plain Text", color: TAG_COLORS[0] },
|
||||||
|
{ id: random_id(), name: "OpenAI", color: TAG_COLORS[1] },
|
||||||
|
{ id: random_id(), name: "W++", color: TAG_COLORS[2] },
|
||||||
|
{ id: random_id(), name: "Boostyle", color: TAG_COLORS[3] },
|
||||||
|
{ id: random_id(), name: "PList", color: TAG_COLORS[4] },
|
||||||
|
{ id: random_id(), name: "AliChat", color: TAG_COLORS[5] },
|
||||||
];
|
];
|
||||||
|
|
||||||
$(document).ready(() => {
|
let tags = [];
|
||||||
$("#tagInput").autocomplete({
|
let tag_map = {};
|
||||||
source: tags.map(t => t.name),
|
|
||||||
select: function(event, ui) {
|
function loadTagsSettings(settings) {
|
||||||
|
tags = settings.tags !== undefined ? settings.tags : DEFAULT_TAGS;
|
||||||
|
tag_map = settings.tag_map !== undefined ? settings.tag_map : Object.create(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTagsList(key) {
|
||||||
|
if (!Array.isArray(tag_map[key])) {
|
||||||
|
tag_map[key] = [];
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return tag_map[key].map(x => tags.find(y => y.id === x)).filter(x => x);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTagKey() {
|
||||||
|
if (selected_group) {
|
||||||
|
return selected_group;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this_chid) {
|
||||||
|
return characters[this_chid].avatar;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function addTagToMap(tagId) {
|
||||||
|
const key = getTagKey();
|
||||||
|
|
||||||
|
if (!key) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Array.isArray(tag_map[key])) {
|
||||||
|
tag_map[key] = [tagId];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
tag_map[key].push(tagId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeTagFromMap(tagId) {
|
||||||
|
const key = getTagKey();
|
||||||
|
|
||||||
|
if (!key) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Array.isArray(tag_map[key])) {
|
||||||
|
tag_map[key] = [];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const indexOf = tag_map[key].indexOf(tagId);
|
||||||
|
tag_map[key].splice(indexOf, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function findTag(request, resolve) {
|
||||||
|
const skipIds = [...($("#tagList").find(".tag").map((_, el) => $(el).attr("id")))];
|
||||||
|
const haystack = tags.filter(t => !skipIds.includes(t.id)).map(t => t.name).sort();
|
||||||
|
const needle = request.term.toLowerCase();
|
||||||
|
const result = haystack.filter(x => x.toLowerCase().includes(needle));
|
||||||
|
resolve(result.length !== 0 ? result : [request.term]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectTag(event, ui) {
|
||||||
let tagName = ui.item.value;
|
let tagName = ui.item.value;
|
||||||
let tag = tags.find(t => t.name === tagName);
|
let tag = tags.find(t => t.name === tagName);
|
||||||
|
|
||||||
|
// create new tag if it doesn't exist
|
||||||
if (!tag) {
|
if (!tag) {
|
||||||
tag = {
|
tag = createNewTag(tagName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// unfocus and clear the input
|
||||||
|
$(this).val("").blur();
|
||||||
|
|
||||||
|
// add tag to the UI and internal map
|
||||||
|
appendTagToList("#tagList", tag, { removable: true });
|
||||||
|
addTagToMap(tag.id);
|
||||||
|
printTags();
|
||||||
|
saveSettingsDebounced();
|
||||||
|
|
||||||
|
// need to return false to keep the input clear
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createNewTag(tagName) {
|
||||||
|
const tag = {
|
||||||
|
id: random_id(),
|
||||||
name: tagName,
|
name: tagName,
|
||||||
color: TAG_COLORS[Math.floor(Math.random() * colors.length)]
|
color: TAG_COLORS[Math.floor(Math.random() * TAG_COLORS.length)]
|
||||||
};
|
};
|
||||||
tags.push(tag);
|
tags.push(tag);
|
||||||
|
return tag;
|
||||||
}
|
}
|
||||||
let tagElement = $(`<span class="tag" style="background-color: ${tag.color}">${tag.name}</span>`);
|
|
||||||
$("#tagList").append(tagElement);
|
|
||||||
$(this).val("");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#tagInput").on("input", function(event) {
|
function appendTagToList(listSelector, tag, { removable, editable, selectable }) {
|
||||||
|
let tagElement = $('#tag_template .tag').clone();
|
||||||
|
tagElement.attr('id', tag.id);
|
||||||
|
tagElement.find('.tag_name').text(tag.name);
|
||||||
|
tagElement.css({ 'background-color': tag.color });
|
||||||
|
const removeButton = tagElement.find(".tag_remove");
|
||||||
|
removable ? removeButton.show() : removeButton.hide();
|
||||||
|
|
||||||
|
if (selectable) {
|
||||||
|
tagElement.on('click', onTagFilterClick);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: handle color change
|
||||||
|
$(listSelector).append(tagElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onTagFilterClick() {
|
||||||
|
const wasSelected = $(this).hasClass('selected');
|
||||||
|
clearTagsFilter();
|
||||||
|
|
||||||
|
if (wasSelected) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const tagId = $(this).attr('id');
|
||||||
|
$(this).addClass('selected');
|
||||||
|
$('#rm_print_characters_block > div').each((_, element) => applyFilterToElement(tagId, element));
|
||||||
|
}
|
||||||
|
|
||||||
|
function applyFilterToElement(tagId, element) {
|
||||||
|
const isTagged = isElementTagged(element, tagId);
|
||||||
|
$(element).css('display', !isTagged ? 'none' : '');
|
||||||
|
}
|
||||||
|
|
||||||
|
function isElementTagged(element, tagId) {
|
||||||
|
const isGroup = $(element).hasClass('group_select');
|
||||||
|
const isCharacter = $(element).hasClass('character_select');
|
||||||
|
const idAttr = isGroup ? 'grid' : 'chid';
|
||||||
|
const elementId = $(element).attr(idAttr);
|
||||||
|
const lookupValue = isCharacter ? characters[elementId].avatar : elementId;
|
||||||
|
const isTagged = Array.isArray(tag_map[lookupValue]) && tag_map[lookupValue].includes(tagId);
|
||||||
|
return isTagged;
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearTagsFilter() {
|
||||||
|
$('#rm_tag_filter .tag').removeClass('selected');
|
||||||
|
$('#rm_print_characters_block > div').css('display', '');
|
||||||
|
}
|
||||||
|
|
||||||
|
function printTags() {
|
||||||
|
$('#rm_tag_filter').empty();
|
||||||
|
const characterTagIds = Object.values(tag_map).flat();
|
||||||
|
const tagsToDisplay = tags.filter(x => characterTagIds.includes(x.id));
|
||||||
|
|
||||||
|
for (const tag of tagsToDisplay) {
|
||||||
|
appendTagToList('#rm_tag_filter', tag, { removable: false, editable: false, selectable: true, });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onTagRemoveClick(event) {
|
||||||
|
event.stopPropagation();
|
||||||
|
const tag = $(this).closest(".tag");
|
||||||
|
const tagId = tag.attr("id");
|
||||||
|
tag.remove();
|
||||||
|
removeTagFromMap(tagId);
|
||||||
|
printTags();
|
||||||
|
saveSettingsDebounced();
|
||||||
|
}
|
||||||
|
|
||||||
|
function onTagInput(event) {
|
||||||
let val = $(this).val();
|
let val = $(this).val();
|
||||||
if (tags.find(t => t.name === val)) return;
|
if (tags.find(t => t.name === val)) return;
|
||||||
$(this).autocomplete("search", val);
|
$(this).autocomplete("search", val);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onTagInputFocus() {
|
||||||
|
$(this).autocomplete('search', $(this).val());
|
||||||
|
}
|
||||||
|
|
||||||
|
$(document).on("click", ".character_select", function () {
|
||||||
|
clearTagsFilter();
|
||||||
|
const chid = Number($(this).attr('chid'));
|
||||||
|
const key = characters[chid].avatar;
|
||||||
|
const tags = getTagsList(key);
|
||||||
|
|
||||||
|
$("#tagList").empty();
|
||||||
|
|
||||||
|
for (const tag of tags) {
|
||||||
|
appendTagToList("#tagList", tag, { removable: true });
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$(document).ready(() => {
|
||||||
|
$("#tagInput")
|
||||||
|
.autocomplete({ source: findTag, select: selectTag, minLength: 0, })
|
||||||
|
.focus(onTagInputFocus); // <== show tag list on click
|
||||||
|
|
||||||
|
$(document).on("click", ".tag_remove", onTagRemoveClick);
|
||||||
|
|
||||||
|
$("#tagInput").on("input", onTagInput);
|
||||||
});
|
});
|
@ -439,11 +439,6 @@ code {
|
|||||||
background-color: var(--SmartThemeEmColor);
|
background-color: var(--SmartThemeEmColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#message_template {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.auto_hide {
|
.auto_hide {
|
||||||
content-visibility: auto;
|
content-visibility: auto;
|
||||||
}
|
}
|
||||||
@ -2323,11 +2318,39 @@ h5 {
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
border-color: var(--black30a);
|
border-color: var(--black30a);
|
||||||
padding: 0.2rem 0.3rem;
|
padding: 0.2rem 0.3rem;
|
||||||
font-size: calc(var(--mainFontSize) * 1.1);
|
font-size: calc(var(--mainFontSize) + 5%);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
width: fit-content;
|
||||||
}
|
}
|
||||||
|
|
||||||
#tagList {
|
.tag.selected {
|
||||||
margin-top: 10px;
|
font-weight: 500;
|
||||||
|
filter: brightness(125%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag_remove {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tags {
|
||||||
|
margin: 10px 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: flex-start;
|
||||||
|
column-gap: 1rem;
|
||||||
|
row-gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#rm_tag_filter {
|
||||||
|
justify-content: space-evenly;
|
||||||
|
}
|
||||||
|
|
||||||
|
#rm_tag_filter .tag {
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
body .ui-front {
|
body .ui-front {
|
||||||
@ -2519,11 +2542,6 @@ body .ui-widget-content {
|
|||||||
padding: 0px;
|
padding: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#group_member_template,
|
|
||||||
#group_list_template {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.group_select {
|
.group_select {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
@ -2553,10 +2571,6 @@ body .ui-widget-content {
|
|||||||
margin-left: 5px;
|
margin-left: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#typing_indicator_template {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.typing_indicator {
|
.typing_indicator {
|
||||||
position: sticky;
|
position: sticky;
|
||||||
bottom: 10px;
|
bottom: 10px;
|
||||||
@ -2600,10 +2614,6 @@ body .ui-widget-content {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#group_avatars_template {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.avatar_collage {
|
.avatar_collage {
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
position: relative;
|
position: relative;
|
||||||
@ -2950,6 +2960,7 @@ label[for="extensions_autoconnect"] {
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
gap: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.extensions_url_block h4 {
|
.extensions_url_block h4 {
|
||||||
@ -3271,8 +3282,8 @@ toolcool-color-picker {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
#openai_logit_bias_template {
|
.template_element {
|
||||||
display: none;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.openai_logit_bias_text,
|
.openai_logit_bias_text,
|
||||||
|
Reference in New Issue
Block a user