Add tags as folders display mode

This commit is contained in:
Cohee 2023-11-10 21:56:25 +02:00
parent abe4bb6d54
commit cb1e254cb9
8 changed files with 219 additions and 62 deletions

View File

@ -167,6 +167,10 @@
box-shadow: none !important; box-shadow: none !important;
} }
.height100p {
height: 100%;
}
.height100pSpaceEvenly { .height100pSpaceEvenly {
align-content: space-evenly; align-content: space-evenly;
height: 100%; height: 100%;
@ -514,4 +518,4 @@ textarea:disabled {
height: 30px; height: 30px;
text-align: center; text-align: center;
padding: 5px; padding: 5px;
} }

View File

@ -2731,6 +2731,10 @@
<input id="hotswapEnabled" type="checkbox" /> <input id="hotswapEnabled" type="checkbox" />
<span data-i18n="Characters Hotswap">Characters Hotswap</span> <span data-i18n="Characters Hotswap">Characters Hotswap</span>
</label> </label>
<label for="bogus_folders" class="checkbox_label">
<input id="bogus_folders" type="checkbox" />
<span data-i18n="Tags as Folders">Tags as Folders</span>
</label>
</div> </div>
<h4><span data-i18n="Miscellaneous">Miscellaneous</span></h4> <h4><span data-i18n="Miscellaneous">Miscellaneous</span></h4>
<div> <div>
@ -4160,6 +4164,22 @@
</div> </div>
</div> </div>
</div> </div>
<div id="bogus_folder_template" class="template_element">
<div class="bogus_folder_select flex-container wide100p alignitemsflexstart">
<div class="avatar flex alignitemscenter textAlignCenter">
<i class="fa-solid fa-folder-open fa-xl"></i>
</div>
<div class="flex-container wide100pLess70px character_select_container">
<div class="wide100p character_name_block">
<span class="ch_name"></span>
</div>
<div class="bogus_folder_counter_block">
<span class="bogus_folder_counter"></span>
<span data="character card(s)">character card(s)</span>
</div>
</div>
</div>
</div>
<div id="hotswap_template" class="template_element"> <div id="hotswap_template" class="template_element">
<div class="hotswapAvatar" title="Add a character/group to favorites to display it here!"> <div class="hotswapAvatar" title="Add a character/group to favorites to display it here!">
<img src="/img/ai4.png"> <img src="/img/ai4.png">

View File

@ -989,6 +989,33 @@ export async function selectCharacterById(id) {
} }
} }
function getTagBlock(item) {
const count = Object.values(tag_map).flat().filter(x => x == item.id).length;
const template = $('#bogus_folder_template .bogus_folder_select').clone();
template.attr({ 'tagid': item.id, 'id': `BogusFolder${item.id}` });
template.find('.avatar').css({'background-color': item.color, 'color': item.color2 });
template.find('.ch_name').text(item.name);
template.find('.bogus_folder_counter').text(count);
template.on('click', () => {
console.log('Bogus folder clicked', item.id);
entitiesFilter.setFilterData(FILTER_TYPES.TAG, { excluded: [], selected: [item.id], bogus: true, });
});
return template;
}
function getEmptyBlock() {
const icons = ['fa-dragon', 'fa-otter', 'fa-kiwi-bird', 'fa-crow', 'fa-frog'];
const texts = ['Here be dragons', 'Otterly empty', 'Kiwibunga', 'Pump-a-Rum', 'Croak it'];
const roll = Math.floor(Math.random() * icons.length);
const emptyBlock = `
<div class="empty_block">
<i class="fa-solid ${icons[roll]} fa-4x"></i>
<h1>${texts[roll]}</h1>
<p>There are no items to display.</p>
</div>`;
return $(emptyBlock);
}
function getCharacterBlock(item, id) { function getCharacterBlock(item, id) {
let this_avatar = default_avatar; let this_avatar = default_avatar;
if (item.avatar != "none") { if (item.avatar != "none") {
@ -1037,6 +1064,12 @@ async function printCharacters(fullRefresh = false) {
saveCharactersPage = 0; saveCharactersPage = 0;
printTagFilters(tag_filter_types.character); printTagFilters(tag_filter_types.character);
printTagFilters(tag_filter_types.group_member); printTagFilters(tag_filter_types.group_member);
const isBogusFolderOpen = !!entitiesFilter.getFilterData(FILTER_TYPES.TAG)?.bogus;
// Return to main list
if (isBogusFolderOpen) {
entitiesFilter.setFilterData(FILTER_TYPES.TAG, { excluded: [], selected: [] });
}
await delay(1); await delay(1);
displayOverrideWarnings(); displayOverrideWarnings();
@ -1065,6 +1098,12 @@ async function printCharacters(fullRefresh = false) {
if (i.type === 'group') { if (i.type === 'group') {
$("#rm_print_characters_block").append(getGroupBlock(i.item)); $("#rm_print_characters_block").append(getGroupBlock(i.item));
} }
if (i.type === 'tag') {
$("#rm_print_characters_block").append(getTagBlock(i.item));
}
}
if (!data.length) {
$("#rm_print_characters_block").append(getEmptyBlock());
} }
eventSource.emit(event_types.CHARACTER_PAGE_LOADED); eventSource.emit(event_types.CHARACTER_PAGE_LOADED);
}, },
@ -1087,6 +1126,10 @@ export function getEntitiesList({ doFilter } = {}) {
entities.push(...characters.map((item, index) => ({ item, id: index, type: 'character' }))); entities.push(...characters.map((item, index) => ({ item, id: index, type: 'character' })));
entities.push(...groups.map((item) => ({ item, id: item.id, type: 'group' }))); entities.push(...groups.map((item) => ({ item, id: item.id, type: 'group' })));
if (power_user.bogus_folders) {
entities.push(...tags.map((item) => ({ item, id: item.id, type: 'tag' })));
}
if (doFilter) { if (doFilter) {
entities = entitiesFilter.applyFilters(entities); entities = entitiesFilter.applyFilters(entities);
} }

View File

@ -1,4 +1,4 @@
import { fuzzySearchCharacters, fuzzySearchGroups, fuzzySearchWorldInfo, power_user } from "./power-user.js"; import { fuzzySearchCharacters, fuzzySearchGroups, fuzzySearchTags, fuzzySearchWorldInfo, power_user } from "./power-user.js";
import { tag_map } from "./tags.js"; import { tag_map } from "./tags.js";
/** /**
@ -148,16 +148,20 @@ export class FilterHelper {
const searchValue = this.filterData[FILTER_TYPES.SEARCH].trim().toLowerCase(); const searchValue = this.filterData[FILTER_TYPES.SEARCH].trim().toLowerCase();
const fuzzySearchCharactersResults = power_user.fuzzy_search ? fuzzySearchCharacters(searchValue) : []; const fuzzySearchCharactersResults = power_user.fuzzy_search ? fuzzySearchCharacters(searchValue) : [];
const fuzzySearchGroupsResults = power_user.fuzzy_search ? fuzzySearchGroups(searchValue) : []; const fuzzySearchGroupsResults = power_user.fuzzy_search ? fuzzySearchGroups(searchValue) : [];
const fuzzySearchTagsResult = power_user.fuzzy_search ? fuzzySearchTags(searchValue) : [];
function getIsValidSearch(entity) { function getIsValidSearch(entity) {
const isGroup = entity.type === 'group'; const isGroup = entity.type === 'group';
const isCharacter = entity.type === 'character'; const isCharacter = entity.type === 'character';
const isTag = entity.type === 'tag';
if (power_user.fuzzy_search) { if (power_user.fuzzy_search) {
if (isCharacter) { if (isCharacter) {
return fuzzySearchCharactersResults.includes(parseInt(entity.id)); return fuzzySearchCharactersResults.includes(parseInt(entity.id));
} else if (isGroup) { } else if (isGroup) {
return fuzzySearchGroupsResults.includes(String(entity.id)); return fuzzySearchGroupsResults.includes(String(entity.id));
} else if (isTag) {
return fuzzySearchTagsResult.includes(String(entity.id));
} else { } else {
return false; return false;
} }

View File

@ -31,6 +31,7 @@ import {
} from "./instruct-mode.js"; } from "./instruct-mode.js";
import { registerSlashCommand } from "./slash-commands.js"; import { registerSlashCommand } from "./slash-commands.js";
import { tags } from "./tags.js";
import { tokenizers } from "./tokenizers.js"; import { tokenizers } from "./tokenizers.js";
import { countOccurrences, debounce, delay, isOdd, resetScrollHeight, sortMoments, stringToRange, timestampToMoment } from "./utils.js"; import { countOccurrences, debounce, delay, isOdd, resetScrollHeight, sortMoments, stringToRange, timestampToMoment } from "./utils.js";
@ -218,6 +219,7 @@ let power_user = {
fuzzy_search: false, fuzzy_search: false,
encode_tags: false, encode_tags: false,
servers: [], servers: [],
bogus_folders: false,
}; };
let themes = []; let themes = [];
@ -486,7 +488,7 @@ async function switchZenSliders() {
$("#clickSlidersTips").hide() $("#clickSlidersTips").hide()
$("#pro-settings-block input[type='number']").hide(); $("#pro-settings-block input[type='number']").hide();
//hide number inputs that are not 'seed' inputs //hide number inputs that are not 'seed' inputs
$(`#textgenerationwebui_api-settings :input[type='number']:not([id^='seed']), $(`#textgenerationwebui_api-settings :input[type='number']:not([id^='seed']),
#kobold_api-settings :input[type='number']:not([id^='seed'])`).hide() #kobold_api-settings :input[type='number']:not([id^='seed'])`).hide()
//hide original sliders //hide original sliders
$(`#textgenerationwebui_api-settings input[type='range'], $(`#textgenerationwebui_api-settings input[type='range'],
@ -1038,7 +1040,14 @@ async function applyTheme(name) {
localStorage.setItem(storage_keys.hotswap_enabled, Boolean(power_user.hotswap_enabled)); localStorage.setItem(storage_keys.hotswap_enabled, Boolean(power_user.hotswap_enabled));
switchHotswap(); switchHotswap();
} }
} },
{
key: 'bogus_folders',
action: async () => {
$('#bogus_folders').prop('checked', power_user.bogus_folders);
await printCharacters(true);
},
},
]; ];
for (const { key, selector, type, action } of themeProperties) { for (const { key, selector, type, action } of themeProperties) {
@ -1203,6 +1212,7 @@ function loadPowerUserSettings(settings, data) {
$("#console_log_prompts").prop("checked", power_user.console_log_prompts); $("#console_log_prompts").prop("checked", power_user.console_log_prompts);
$('#auto_fix_generated_markdown').prop("checked", power_user.auto_fix_generated_markdown); $('#auto_fix_generated_markdown').prop("checked", power_user.auto_fix_generated_markdown);
$('#auto_scroll_chat_to_bottom').prop("checked", power_user.auto_scroll_chat_to_bottom); $('#auto_scroll_chat_to_bottom').prop("checked", power_user.auto_scroll_chat_to_bottom);
$('#bogus_folders').prop("checked", power_user.bogus_folders);
$(`#tokenizer option[value="${power_user.tokenizer}"]`).attr('selected', true); $(`#tokenizer option[value="${power_user.tokenizer}"]`).attr('selected', true);
$(`#send_on_enter option[value=${power_user.send_on_enter}]`).attr("selected", true); $(`#send_on_enter option[value=${power_user.send_on_enter}]`).attr("selected", true);
$("#import_card_tags").prop("checked", power_user.import_card_tags); $("#import_card_tags").prop("checked", power_user.import_card_tags);
@ -1537,6 +1547,22 @@ export function fuzzySearchWorldInfo(data, searchValue) {
return results.map(x => x.item?.uid); return results.map(x => x.item?.uid);
} }
export function fuzzySearchTags(searchValue) {
const fuse = new Fuse(tags, {
keys: [
{ name: 'name', weight: 1},
],
includeScore: true,
ignoreLocation: true,
threshold: 0.2
});
const results = fuse.search(searchValue);
console.debug('Tags fuzzy search results for ' + searchValue, results);
const ids = results.map(x => String(x.item?.id)).filter(x => x);
return ids;
}
export function fuzzySearchGroups(searchValue) { export function fuzzySearchGroups(searchValue) {
const fuse = new Fuse(groups, { const fuse = new Fuse(groups, {
keys: [ keys: [
@ -1664,8 +1690,7 @@ async function saveTheme() {
enableLabMode: power_user.enableLabMode, enableLabMode: power_user.enableLabMode,
hotswap_enabled: power_user.hotswap_enabled, hotswap_enabled: power_user.hotswap_enabled,
custom_css: power_user.custom_css, custom_css: power_user.custom_css,
bogus_folders: power_user.bogus_folders,
}; };
const response = await fetch('/savetheme', { const response = await fetch('/savetheme', {
@ -2790,6 +2815,13 @@ $(document).ready(() => {
switchSimpleMode(); switchSimpleMode();
}); });
$('#bogus_folders').on('input', function() {
const value = !!$(this).prop('checked');
power_user.bogus_folders = value;
saveSettingsDebounced();
printCharacters(true);
});
$(document).on('click', '#debug_table [data-debug-function]', function () { $(document).on('click', '#debug_table [data-debug-function]', function () {
const functionId = $(this).data('debug-function'); const functionId = $(this).data('debug-function');
const functionRecord = debug_functions.find(f => f.functionId === functionId); const functionRecord = debug_functions.find(f => f.functionId === functionId);

View File

@ -6,6 +6,7 @@ import {
menu_type, menu_type,
getCharacters, getCharacters,
entitiesFilter, entitiesFilter,
printCharacters,
} from "../script.js"; } from "../script.js";
import { FILTER_TYPES, FilterHelper } from "./filters.js"; import { FILTER_TYPES, FilterHelper } from "./filters.js";
@ -48,12 +49,12 @@ const InListActionable = {
} }
const DEFAULT_TAGS = [ const DEFAULT_TAGS = [
{ id: uuidv4(), name: "Plain Text" }, { id: uuidv4(), name: "Plain Text", create_date: Date.now() },
{ id: uuidv4(), name: "OpenAI" }, { id: uuidv4(), name: "OpenAI", create_date: Date.now() },
{ id: uuidv4(), name: "W++" }, { id: uuidv4(), name: "W++", create_date: Date.now() },
{ id: uuidv4(), name: "Boostyle" }, { id: uuidv4(), name: "Boostyle", create_date: Date.now() },
{ id: uuidv4(), name: "PList" }, { id: uuidv4(), name: "PList", create_date: Date.now() },
{ id: uuidv4(), name: "AliChat" }, { id: uuidv4(), name: "AliChat", create_date: Date.now() },
]; ];
let tags = []; let tags = [];
@ -208,8 +209,8 @@ function selectTag(event, ui, listSelector) {
const characterIds = characterData ? JSON.parse(characterData).characterIds : null; const characterIds = characterData ? JSON.parse(characterData).characterIds : null;
if (characterIds) { if (characterIds) {
characterIds.forEach((characterId) => addTagToMap(tag.id,characterId)); characterIds.forEach((characterId) => addTagToMap(tag.id, characterId));
} else { } else {
addTagToMap(tag.id); addTagToMap(tag.id);
} }
@ -232,7 +233,6 @@ function getExistingTags(new_tags) {
return existing_tags return existing_tags
} }
async function importTags(imported_char) { async function importTags(imported_char) {
let imported_tags = imported_char.tags.filter(t => t !== "ROOT" && t !== "TAVERN"); let imported_tags = imported_char.tags.filter(t => t !== "ROOT" && t !== "TAVERN");
let existingTags = await getExistingTags(imported_tags); let existingTags = await getExistingTags(imported_tags);
@ -272,13 +272,13 @@ async function importTags(imported_char) {
return false; return false;
} }
function createNewTag(tagName) { function createNewTag(tagName) {
const tag = { const tag = {
id: uuidv4(), id: uuidv4(),
name: tagName, name: tagName,
color: '', color: '',
color2: '', color2: '',
create_date: Date.now(),
}; };
tags.push(tag); tags.push(tag);
return tag; return tag;
@ -477,55 +477,78 @@ export function createTagInput(inputSelector, listSelector) {
function onViewTagsListClick() { function onViewTagsListClick() {
$('#dialogue_popup').addClass('large_dialogue_popup'); $('#dialogue_popup').addClass('large_dialogue_popup');
const list = document.createElement('div'); const list = $(document.createElement('div'));
list.attr('id', 'tag_view_list');
const everything = Object.values(tag_map).flat(); const everything = Object.values(tag_map).flat();
$(list).append('<h3>Tags</h3><i>Click on the tag name to edit it.</i><br>'); $(list).append(`
$(list).append('<i>Click on color box to assign new color.</i><br><br>'); <div class="title_restorable alignItemsBaseline">
<h3>Tag Management</h3>
<div class="menu_button menu_button_icon tag_view_create">
<i class="fa-solid fa-plus"></i>
<span data-i18n="Create">Create</span>
</div>
</div>
<div class="justifyLeft m-b-1">
<small>
Click on the tag name to edit it.<br>
Click on color box to assign new color.
</small>
</div>`);
for (const tag of tags.slice().sort((a, b) => a?.name?.toLowerCase()?.localeCompare(b?.name?.toLowerCase()))) { for (const tag of tags.slice().sort((a, b) => a?.name?.toLowerCase()?.localeCompare(b?.name?.toLowerCase()))) {
const count = everything.filter(x => x == tag.id).length; appendViewTagToList(list, tag, everything);
const template = $('#tag_view_template .tag_view_item').clone();
template.attr('id', tag.id);
template.find('.tag_view_counter_value').text(count);
template.find('.tag_view_name').text(tag.name);
template.find('.tag_view_name').addClass('tag');
template.find('.tag_view_name').css('background-color', tag.color);
template.find('.tag_view_name').css('color', tag.color2);
const colorPickerId = tag.id + "-tag-color";
const colorPicker2Id = tag.id + "-tag-color2";
template.find('.tagColorPickerHolder').html(
`<toolcool-color-picker id="${colorPickerId}" color="${tag.color}" class="tag-color"></toolcool-color-picker>`
);
template.find('.tagColorPicker2Holder').html(
`<toolcool-color-picker id="${colorPicker2Id}" color="${tag.color2}" class="tag-color2"></toolcool-color-picker>`
);
template.find('.tag-color').attr('id', colorPickerId);
template.find('.tag-color2').attr('id', colorPicker2Id);
list.appendChild(template.get(0));
setTimeout(function () {
document.querySelector(`.tag-color[id="${colorPickerId}"`).addEventListener('change', (evt) => {
onTagColorize(evt);
});
}, 100);
setTimeout(function () {
document.querySelector(`.tag-color2[id="${colorPicker2Id}"`).addEventListener('change', (evt) => {
onTagColorize2(evt);
});
}, 100);
$(colorPickerId).color = tag.color;
$(colorPicker2Id).color = tag.color2;
} }
callPopup(list.outerHTML, 'text');
callPopup(list, 'text');
}
function onTagCreateClick() {
const tag = createNewTag('New Tag');
appendViewTagToList($('#tag_view_list'), tag, []);
printCharacters(false);
saveSettingsDebounced();
}
function appendViewTagToList(list, tag, everything) {
const count = everything.filter(x => x == tag.id).length;
const template = $('#tag_view_template .tag_view_item').clone();
template.attr('id', tag.id);
template.find('.tag_view_counter_value').text(count);
template.find('.tag_view_name').text(tag.name);
template.find('.tag_view_name').addClass('tag');
template.find('.tag_view_name').css('background-color', tag.color);
template.find('.tag_view_name').css('color', tag.color2);
const colorPickerId = tag.id + "-tag-color";
const colorPicker2Id = tag.id + "-tag-color2";
template.find('.tagColorPickerHolder').html(
`<toolcool-color-picker id="${colorPickerId}" color="${tag.color}" class="tag-color"></toolcool-color-picker>`
);
template.find('.tagColorPicker2Holder').html(
`<toolcool-color-picker id="${colorPicker2Id}" color="${tag.color2}" class="tag-color2"></toolcool-color-picker>`
);
template.find('.tag-color').attr('id', colorPickerId);
template.find('.tag-color2').attr('id', colorPicker2Id);
list.append(template);
setTimeout(function () {
document.querySelector(`.tag-color[id="${colorPickerId}"`).addEventListener('change', (evt) => {
onTagColorize(evt);
});
}, 100);
setTimeout(function () {
document.querySelector(`.tag-color2[id="${colorPicker2Id}"`).addEventListener('change', (evt) => {
onTagColorize2(evt);
});
}, 100);
$(colorPickerId).color = tag.color;
$(colorPicker2Id).color = tag.color2;
} }
function onTagDeleteClick() { function onTagDeleteClick() {
@ -541,6 +564,7 @@ function onTagDeleteClick() {
tags.splice(index, 1); tags.splice(index, 1);
$(`.tag[id="${id}"]`).remove(); $(`.tag[id="${id}"]`).remove();
$(`.tag_view_item[id="${id}"]`).remove(); $(`.tag_view_item[id="${id}"]`).remove();
printCharacters(false);
saveSettingsDebounced(); saveSettingsDebounced();
} }
@ -559,6 +583,7 @@ function onTagColorize(evt) {
const newColor = evt.detail.rgba; const newColor = evt.detail.rgba;
$(evt.target).parent().parent().find('.tag_view_name').css('background-color', newColor); $(evt.target).parent().parent().find('.tag_view_name').css('background-color', newColor);
$(`.tag[id="${id}"]`).css('background-color', newColor); $(`.tag[id="${id}"]`).css('background-color', newColor);
$(`.bogus_folder_select[tagid="${id}"] .avatar`).css('background-color', newColor);
const tag = tags.find(x => x.id === id); const tag = tags.find(x => x.id === id);
tag.color = newColor; tag.color = newColor;
console.debug(tag); console.debug(tag);
@ -571,6 +596,7 @@ function onTagColorize2(evt) {
const newColor = evt.detail.rgba; const newColor = evt.detail.rgba;
$(evt.target).parent().parent().find('.tag_view_name').css('color', newColor); $(evt.target).parent().parent().find('.tag_view_name').css('color', newColor);
$(`.tag[id="${id}"]`).css('color', newColor); $(`.tag[id="${id}"]`).css('color', newColor);
$(`.bogus_folder_select[tagid="${id}"] .avatar`).css('color', newColor);
const tag = tags.find(x => x.id === id); const tag = tags.find(x => x.id === id);
tag.color2 = newColor; tag.color2 = newColor;
console.debug(tag); console.debug(tag);
@ -597,4 +623,5 @@ $(document).ready(() => {
$(document).on("click", ".tags_view", onViewTagsListClick); $(document).on("click", ".tags_view", onViewTagsListClick);
$(document).on("click", ".tag_delete", onTagDeleteClick); $(document).on("click", ".tag_delete", onTagDeleteClick);
$(document).on("input", ".tag_view_name", onTagRenameInput); $(document).on("input", ".tag_view_name", onTagRenameInput);
$(document).on("click", ".tag_view_create", onTagCreateClick);
}); });

View File

@ -550,7 +550,7 @@ export function timestampToMoment(timestamp) {
return moment.invalid(); return moment.invalid();
} }
// Unix time (legacy TAI) // Unix time (legacy TAI / tags)
if (typeof timestamp === 'number') { if (typeof timestamp === 'number') {
return moment(timestamp); return moment(timestamp);
} }

View File

@ -889,10 +889,20 @@ hr {
box-shadow: 0 0 5px var(--black50a); box-shadow: 0 0 5px var(--black50a);
} }
.bogus_folder_select .avatar,
.character_select .avatar { .character_select .avatar {
flex: unset; flex: unset;
} }
.bogus_folder_select .avatar {
justify-content: center;
background-color: var(--SmartThemeBlurTintColor);
color: var(--SmartThemeBodyColor);
outline-style: solid;
outline-width: 1px;
outline-color: var(--SmartThemeBorderColor);
}
.mes_block { .mes_block {
padding-top: 0; padding-top: 0;
padding-left: 10px; padding-left: 10px;
@ -1213,6 +1223,20 @@ input[type="file"] {
width: calc(100% - 85px); width: calc(100% - 85px);
} }
#rm_print_characters_block .empty_block {
display: flex;
flex-direction: column;
gap: 10px;
flex-wrap: wrap;
text-align: center;
height: 100%;
width: 100%;
opacity: 0.5;
justify-content: center;
margin: 0 auto;
align-items: center;
}
#rm_print_characters_block { #rm_print_characters_block {
overflow-y: auto; overflow-y: auto;
flex-grow: 1; flex-grow: 1;
@ -1479,6 +1503,7 @@ input[type=search]:focus::-webkit-search-cancel-button {
pointer-events: all; pointer-events: all;
} }
.bogus_folder_select,
.character_select { .character_select {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
@ -1505,6 +1530,7 @@ input[type=search]:focus::-webkit-search-cancel-button {
font-style: italic; font-style: italic;
} }
.bogus_folder_select .avatar,
.character_select .avatar { .character_select .avatar {
align-self: center; align-self: center;
} }
@ -1532,6 +1558,7 @@ input[type=search]:focus::-webkit-search-cancel-button {
display: block; display: block;
} }
.bogus_folder_select:hover,
.character_select:hover { .character_select:hover {
background-color: var(--white30a); background-color: var(--white30a);
} }