mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
Inline tags display
This commit is contained in:
@ -1475,7 +1475,7 @@
|
|||||||
|
|
||||||
<div id="tags_div">
|
<div id="tags_div">
|
||||||
<div class="margin-bot-10px">Tags</div>
|
<div class="margin-bot-10px">Tags</div>
|
||||||
<input id="tagInput" class="text_pole" placeholder="Search / Create tags" />
|
<input id="tagInput" class="text_pole" placeholder="Search / Create tags" maxlength="50" />
|
||||||
<div id="tagList" class="tags"></div>
|
<div id="tagList" class="tags"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -1820,6 +1820,21 @@
|
|||||||
|
|
||||||
<!-- templates for JS to reuse when needed -->
|
<!-- templates for JS to reuse when needed -->
|
||||||
|
|
||||||
|
<div id="character_template" class="template_element">
|
||||||
|
<div class="character_select" chid="" id="">
|
||||||
|
<div class="avatar" title="">
|
||||||
|
<img src="">
|
||||||
|
</div>
|
||||||
|
<div class="ch_name">
|
||||||
|
<span class="name_text"></span>
|
||||||
|
<i class="ch_fav_icon fa-solid fa-star fa-2xs"></i>
|
||||||
|
</div>
|
||||||
|
<input class="ch_fav" value="" hidden />
|
||||||
|
<div class="tags tags_inline">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div id="tag_template" class="template_element">
|
<div id="tag_template" class="template_element">
|
||||||
<span id="" class="tag">
|
<span id="" class="tag">
|
||||||
<span class="tag_name"></span>
|
<span class="tag_name"></span>
|
||||||
|
@ -93,7 +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";
|
import { tag_map, tags, loadTagsSettings, printTags, isElementTagged, getTagsList, appendTagToList } from "./scripts/tags.js";
|
||||||
|
|
||||||
//exporting functions and vars for mods
|
//exporting functions and vars for mods
|
||||||
export {
|
export {
|
||||||
@ -137,6 +137,7 @@ export {
|
|||||||
getStatus,
|
getStatus,
|
||||||
chat,
|
chat,
|
||||||
this_chid,
|
this_chid,
|
||||||
|
selected_button,
|
||||||
settings,
|
settings,
|
||||||
characters,
|
characters,
|
||||||
online_status,
|
online_status,
|
||||||
@ -664,20 +665,27 @@ function updateSoftPromptsList(soft_prompts) {
|
|||||||
|
|
||||||
function printCharacters() {
|
function printCharacters() {
|
||||||
$("#rm_print_characters_block").empty();
|
$("#rm_print_characters_block").empty();
|
||||||
//console.log('printCharacters() -- sees '+characters.length+' characters.');
|
|
||||||
characters.forEach(function (item, i, arr) {
|
characters.forEach(function (item, i, arr) {
|
||||||
let this_avatar = default_avatar;
|
let this_avatar = default_avatar;
|
||||||
if (item.avatar != "none") {
|
if (item.avatar != "none") {
|
||||||
this_avatar = getThumbnailUrl('avatar', item.avatar);
|
this_avatar = getThumbnailUrl('avatar', item.avatar);
|
||||||
} //RossAscends: changed 'prepend' to 'append' to make alphabetical sorting display correctly.
|
}
|
||||||
$("#rm_print_characters_block").append(
|
// Populate the template
|
||||||
`<div class=character_select chid=${i} id="CharID${i}">
|
const template = $('#character_template .character_select').clone();
|
||||||
<div class=avatar title="${item.avatar}"><img src="${this_avatar}"></div>
|
template.attr({'chid': i, 'id': `CharID${i}` });
|
||||||
<div class=ch_name>${item.name} ${item.fav == "true" ? '<i class="fa-solid fa-star fa-2xs"></i>' : ''}</div>
|
template.find('img').attr('src', this_avatar);
|
||||||
<input class="ch_fav" value=${item.fav} hidden />
|
template.find('.avatar').attr('title', item.avatar);
|
||||||
</div>`
|
template.find('.ch_name .name_text').text(item.name);
|
||||||
);
|
template.find('.ch_fav_icon').css("display", !!item.fav ? '' : 'none');
|
||||||
//console.log('printcharacters() -- printing -- ChID '+i+' ('+item.name+')');
|
template.find('.ch_fav').val(item.fav);
|
||||||
|
|
||||||
|
// Display inline tags
|
||||||
|
const tags = getTagsList(item.avatar);
|
||||||
|
const tagsElement = template.find('.tags');
|
||||||
|
tags.forEach(tag => appendTagToList(tagsElement, tag, {}));
|
||||||
|
|
||||||
|
// Add to the list
|
||||||
|
$("#rm_print_characters_block").append(template);
|
||||||
});
|
});
|
||||||
$("#rm_print_characters_block").prepend(`<hr>`);
|
$("#rm_print_characters_block").prepend(`<hr>`);
|
||||||
printTags();
|
printTags();
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { characters, saveSettingsDebounced, this_chid } from "../script.js";
|
import { characters, saveSettingsDebounced, this_chid, selected_button } from "../script.js";
|
||||||
import { selected_group } from "./group-chats.js";
|
import { selected_group } from "./group-chats.js";
|
||||||
|
|
||||||
export {
|
export {
|
||||||
@ -7,57 +7,19 @@ export {
|
|||||||
loadTagsSettings,
|
loadTagsSettings,
|
||||||
printTags,
|
printTags,
|
||||||
isElementTagged,
|
isElementTagged,
|
||||||
|
getTagsList,
|
||||||
|
appendTagToList,
|
||||||
};
|
};
|
||||||
|
|
||||||
const TAG_COLORS = [
|
|
||||||
|
|
||||||
"",
|
|
||||||
/*
|
|
||||||
"#990099", //--tag-pink
|
|
||||||
"#996600", //--tag-orange
|
|
||||||
"#999900", //--tag-yellow
|
|
||||||
"#009966", //--tag-green
|
|
||||||
"#006699", // --tag-blue
|
|
||||||
"#660099", //--tag-purple
|
|
||||||
|
|
||||||
"#dd0a36", // Red
|
|
||||||
"#ff6633", // Orange
|
|
||||||
"#5f9ea0", // Teal Green
|
|
||||||
"#1e90ff", // Light Blue
|
|
||||||
"#990066", // Plum
|
|
||||||
"#8c00ff", // Fuchsia
|
|
||||||
"#00ffff", // Aqua
|
|
||||||
"#0f4ecc", // Teal
|
|
||||||
"#2f4b1c", // Green
|
|
||||||
"#3366e5", // Dodger Blue
|
|
||||||
"#36c3a1", // Mint Green
|
|
||||||
"#995511", // Terracotta
|
|
||||||
"#ab47bc", // Plum RGBA
|
|
||||||
"#805451", // Mulberry
|
|
||||||
"#ff8c69", // Salmon
|
|
||||||
"#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 */
|
|
||||||
];
|
|
||||||
|
|
||||||
const random_id = () => Math.round(Date.now() * Math.random()).toString();
|
const random_id = () => Math.round(Date.now() * Math.random()).toString();
|
||||||
|
|
||||||
const DEFAULT_TAGS = [
|
const DEFAULT_TAGS = [
|
||||||
{ id: random_id(), name: "Plain Text", color: TAG_COLORS[0] },
|
{ id: random_id(), name: "Plain Text" },
|
||||||
{ id: random_id(), name: "OpenAI", color: TAG_COLORS[1] },
|
{ id: random_id(), name: "OpenAI" },
|
||||||
{ id: random_id(), name: "W++", color: TAG_COLORS[2] },
|
{ id: random_id(), name: "W++" },
|
||||||
{ id: random_id(), name: "Boostyle", color: TAG_COLORS[3] },
|
{ id: random_id(), name: "Boostyle" },
|
||||||
{ id: random_id(), name: "PList", color: TAG_COLORS[4] },
|
{ id: random_id(), name: "PList" },
|
||||||
{ id: random_id(), name: "AliChat", color: TAG_COLORS[5] },
|
{ id: random_id(), name: "AliChat" },
|
||||||
];
|
];
|
||||||
|
|
||||||
let tags = [];
|
let tags = [];
|
||||||
@ -77,12 +39,24 @@ function getTagsList(key) {
|
|||||||
return tag_map[key].map(x => tags.find(y => y.id === x)).filter(x => x);
|
return tag_map[key].map(x => tags.find(y => y.id === x)).filter(x => x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getInlineListSelector() {
|
||||||
|
if (selected_group) {
|
||||||
|
return `.group_select[grid="${selected_group}"] .tags`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this_chid && selected_button !== "create") {
|
||||||
|
return `.character_select[chid="${this_chid}"] .tags`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
function getTagKey() {
|
function getTagKey() {
|
||||||
if (selected_group) {
|
if (selected_group) {
|
||||||
return selected_group;
|
return selected_group;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this_chid) {
|
if (this_chid && selected_button !== "create") {
|
||||||
return characters[this_chid].avatar;
|
return characters[this_chid].avatar;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,8 +116,8 @@ function selectTag(event, ui) {
|
|||||||
|
|
||||||
// add tag to the UI and internal map
|
// add tag to the UI and internal map
|
||||||
appendTagToList("#tagList", tag, { removable: true });
|
appendTagToList("#tagList", tag, { removable: true });
|
||||||
|
appendTagToList(getInlineListSelector(), tag, { removable: false });
|
||||||
addTagToMap(tag.id);
|
addTagToMap(tag.id);
|
||||||
printTags();
|
|
||||||
saveSettingsDebounced();
|
saveSettingsDebounced();
|
||||||
|
|
||||||
// need to return false to keep the input clear
|
// need to return false to keep the input clear
|
||||||
@ -154,17 +128,19 @@ function createNewTag(tagName) {
|
|||||||
const tag = {
|
const tag = {
|
||||||
id: random_id(),
|
id: random_id(),
|
||||||
name: tagName,
|
name: tagName,
|
||||||
color: TAG_COLORS[Math.floor(Math.random() * TAG_COLORS.length)]
|
|
||||||
};
|
};
|
||||||
tags.push(tag);
|
tags.push(tag);
|
||||||
return tag;
|
return tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
function appendTagToList(listSelector, tag, { removable, editable, selectable }) {
|
function appendTagToList(listElement, tag, { removable, editable, selectable }) {
|
||||||
|
if (!listElement) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let tagElement = $('#tag_template .tag').clone();
|
let tagElement = $('#tag_template .tag').clone();
|
||||||
tagElement.attr('id', tag.id);
|
tagElement.attr('id', tag.id);
|
||||||
tagElement.find('.tag_name').text(tag.name);
|
tagElement.find('.tag_name').text(tag.name);
|
||||||
tagElement.css({ 'background-color': tag.color });
|
|
||||||
const removeButton = tagElement.find(".tag_remove");
|
const removeButton = tagElement.find(".tag_remove");
|
||||||
removable ? removeButton.show() : removeButton.hide();
|
removable ? removeButton.show() : removeButton.hide();
|
||||||
|
|
||||||
@ -172,8 +148,7 @@ function appendTagToList(listSelector, tag, { removable, editable, selectable })
|
|||||||
tagElement.on('click', onTagFilterClick);
|
tagElement.on('click', onTagFilterClick);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: handle color change
|
$(listElement).append(tagElement);
|
||||||
$(listSelector).append(tagElement);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function onTagFilterClick() {
|
function onTagFilterClick() {
|
||||||
@ -239,25 +214,31 @@ function onTagInputFocus() {
|
|||||||
$(this).autocomplete('search', $(this).val());
|
$(this).autocomplete('search', $(this).val());
|
||||||
}
|
}
|
||||||
|
|
||||||
$(document).on("click", ".character_select", function () {
|
function onCreateCharacterClick() {
|
||||||
clearTagsFilter();
|
|
||||||
const chid = Number($(this).attr('chid'));
|
|
||||||
const key = characters[chid].avatar;
|
|
||||||
const tags = getTagsList(key);
|
|
||||||
|
|
||||||
$("#tagList").empty();
|
$("#tagList").empty();
|
||||||
|
}
|
||||||
|
|
||||||
for (const tag of tags) {
|
function onCharacterSelectClick() {
|
||||||
appendTagToList("#tagList", tag, { removable: true });
|
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(() => {
|
$(document).ready(() => {
|
||||||
$("#tagInput")
|
$("#tagInput")
|
||||||
.autocomplete({ source: findTag, select: selectTag, minLength: 0, })
|
.autocomplete({ source: findTag, select: selectTag, minLength: 0, })
|
||||||
.focus(onTagInputFocus); // <== show tag list on click
|
.focus(onTagInputFocus); // <== show tag list on click
|
||||||
|
|
||||||
|
$(document).on("click", "#rm_button_create", onCreateCharacterClick);
|
||||||
$(document).on("click", ".tag_remove", onTagRemoveClick);
|
$(document).on("click", ".tag_remove", onTagRemoveClick);
|
||||||
|
$(document).on("click", ".character_select", onCharacterSelectClick);
|
||||||
|
|
||||||
$("#tagInput").on("input", onTagInput);
|
$("#tagInput").on("input", onTagInput);
|
||||||
});
|
});
|
@ -1026,6 +1026,8 @@ input[type=search]:focus::-webkit-search-cancel-button {
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 67px auto;
|
grid-template-columns: 67px auto;
|
||||||
|
position: relative;
|
||||||
|
overflow-y: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.character_select .ch_name {
|
.character_select .ch_name {
|
||||||
@ -1035,6 +1037,9 @@ input[type=search]:focus::-webkit-search-cancel-button {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
align-self: center;
|
align-self: center;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.character_select:hover {
|
.character_select:hover {
|
||||||
@ -2336,7 +2341,6 @@ h5 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.tag.selected {
|
.tag.selected {
|
||||||
|
|
||||||
border-color: var(--white70a);
|
border-color: var(--white70a);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2345,18 +2349,28 @@ h5 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.tags {
|
.tags {
|
||||||
|
margin: 5px 0;
|
||||||
margin: 10px 0;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
/*column-gap: 1rem;
|
|
||||||
row-gap: 0.5rem;
|
|
||||||
*/
|
|
||||||
column-gap: 0.4rem;
|
column-gap: 0.4rem;
|
||||||
row-gap: 0.4rem;
|
row-gap: 0.4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tags.tags_inline {
|
||||||
|
position: absolute;
|
||||||
|
margin: 2px 10px;
|
||||||
|
right: 0;
|
||||||
|
opacity: 0.6;
|
||||||
|
column-gap: 0.2rem;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tags_inline .tag {
|
||||||
|
font-size: calc(var(--mainFontSize) - 15%);
|
||||||
|
padding: 0 0.15rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
#rm_tag_filter {
|
#rm_tag_filter {
|
||||||
|
Reference in New Issue
Block a user