mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-03-02 19:07:40 +01:00
Tag Folders: show hidden numbers
- Show hidden counts for folders, and total - Rework resizing of character names to shrink additional data first - Better placement for group numbers
This commit is contained in:
parent
18379ec602
commit
fb97f563b7
@ -5000,10 +5000,9 @@
|
|||||||
<div class="flex-container wide100pLess70px gap5px group_select_container">
|
<div class="flex-container wide100pLess70px gap5px group_select_container">
|
||||||
<div class="wide100p group_name_block character_name_block">
|
<div class="wide100p group_name_block character_name_block">
|
||||||
<div class="ch_name"></div>
|
<div class="ch_name"></div>
|
||||||
<small class="group_select_unit" data="characters">group of</small>
|
<small class="character_version group_select_counter"></small>
|
||||||
<small class="character_version group_select_counter">5</small>
|
|
||||||
<small class="group_select_unit character_unit_name" data="characters">characters</small>
|
|
||||||
</div>
|
</div>
|
||||||
|
<small class="character_name_block_sub_line">in this group</small>
|
||||||
<i class='group_fav_icon fa-solid fa-star'></i>
|
<i class='group_fav_icon fa-solid fa-star'></i>
|
||||||
<input class="ch_fav" value="" hidden />
|
<input class="ch_fav" value="" hidden />
|
||||||
<div class="group_select_block_list"></div>
|
<div class="group_select_block_list"></div>
|
||||||
@ -5020,8 +5019,8 @@
|
|||||||
<div class="wide100p character_name_block">
|
<div class="wide100p character_name_block">
|
||||||
<span class="ch_name"></span>
|
<span class="ch_name"></span>
|
||||||
<small class="character_version bogus_folder_counter"></small>
|
<small class="character_version bogus_folder_counter"></small>
|
||||||
<small class="bogus_folder_unit character_unit_name" data="characters">characters</small>
|
|
||||||
</div>
|
</div>
|
||||||
|
<small class="character_name_block_sub_line bogus_folder_hidden_counter"></small>
|
||||||
<div class="bogus_folder_avatars_block avatars_inline avatars_inline_small tags tags_inline"></div>
|
<div class="bogus_folder_avatars_block avatars_inline avatars_inline_small tags tags_inline"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1175,7 +1175,7 @@ function getEmptyBlock() {
|
|||||||
const texts = ['Here be dragons', 'Otterly empty', 'Kiwibunga', 'Pump-a-Rum', 'Croak it'];
|
const texts = ['Here be dragons', 'Otterly empty', 'Kiwibunga', 'Pump-a-Rum', 'Croak it'];
|
||||||
const roll = new Date().getMinutes() % icons.length;
|
const roll = new Date().getMinutes() % icons.length;
|
||||||
const emptyBlock = `
|
const emptyBlock = `
|
||||||
<div class="empty_block">
|
<div class="text_block empty_block">
|
||||||
<i class="fa-solid ${icons[roll]} fa-4x"></i>
|
<i class="fa-solid ${icons[roll]} fa-4x"></i>
|
||||||
<h1>${texts[roll]}</h1>
|
<h1>${texts[roll]}</h1>
|
||||||
<p>There are no items to display.</p>
|
<p>There are no items to display.</p>
|
||||||
@ -1183,6 +1183,20 @@ function getEmptyBlock() {
|
|||||||
return $(emptyBlock);
|
return $(emptyBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {number} hidden Number of hidden characters
|
||||||
|
*/
|
||||||
|
function getHiddenBlock(hidden) {
|
||||||
|
const hiddenBlick = `
|
||||||
|
<div class="text_block hidden_block">
|
||||||
|
<small>
|
||||||
|
<p>${hidden} ${hidden > 1 ? 'characters' : 'character'} hidden.</p>
|
||||||
|
<div class="fa-solid fa-circle-info opacity50p" data-i18n="[title]Characters and groups hidden by filters or closed folders" title="Characters and groups hidden by filters or closed folders"></div>
|
||||||
|
</small>
|
||||||
|
</div>`;
|
||||||
|
return $(hiddenBlick);
|
||||||
|
}
|
||||||
|
|
||||||
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') {
|
||||||
@ -1261,19 +1275,28 @@ async function printCharacters(fullRefresh = false) {
|
|||||||
if (!data.length) {
|
if (!data.length) {
|
||||||
$(listId).append(getEmptyBlock());
|
$(listId).append(getEmptyBlock());
|
||||||
}
|
}
|
||||||
|
let displayCount = 0;
|
||||||
for (const i of data) {
|
for (const i of data) {
|
||||||
switch (i.type) {
|
switch (i.type) {
|
||||||
case 'character':
|
case 'character':
|
||||||
$(listId).append(getCharacterBlock(i.item, i.id));
|
$(listId).append(getCharacterBlock(i.item, i.id));
|
||||||
|
displayCount++;
|
||||||
break;
|
break;
|
||||||
case 'group':
|
case 'group':
|
||||||
$(listId).append(getGroupBlock(i.item));
|
$(listId).append(getGroupBlock(i.item));
|
||||||
|
displayCount++;
|
||||||
break;
|
break;
|
||||||
case 'tag':
|
case 'tag':
|
||||||
$(listId).append(getTagBlock(i.item, i.entities ?? entities));
|
$(listId).append(getTagBlock(i.item, i.entities, i.hidden));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const hidden = (characters.length + groups.length) - displayCount;
|
||||||
|
if (hidden > 0) {
|
||||||
|
$(listId).append(getHiddenBlock(hidden));
|
||||||
|
}
|
||||||
|
|
||||||
eventSource.emit(event_types.CHARACTER_PAGE_LOADED);
|
eventSource.emit(event_types.CHARACTER_PAGE_LOADED);
|
||||||
},
|
},
|
||||||
afterSizeSelectorChange: function (e) {
|
afterSizeSelectorChange: function (e) {
|
||||||
@ -1327,11 +1350,14 @@ export function getEntitiesList({ doFilter = false, doSort = true } = {}) {
|
|||||||
// For folders, we remember the sub entities so they can be displayed later, even if they might be filtered
|
// For folders, we remember the sub entities so they can be displayed later, even if they might be filtered
|
||||||
// Those sub entities should be filtered and have the search filters applied too
|
// Those sub entities should be filtered and have the search filters applied too
|
||||||
if (entity.type === 'tag') {
|
if (entity.type === 'tag') {
|
||||||
let subEntities = filterByTagState(entities, { subForEntity: entity });
|
let subEntities = filterByTagState(entities, { subForEntity: entity, filterHidden: false });
|
||||||
|
const subCount = subEntities.length;
|
||||||
|
subEntities = filterByTagState(entities, { subForEntity: entity });
|
||||||
if (doFilter) {
|
if (doFilter) {
|
||||||
subEntities = entitiesFilter.applyFilters(subEntities);
|
subEntities = entitiesFilter.applyFilters(subEntities);
|
||||||
}
|
}
|
||||||
entity.entities = subEntities;
|
entity.entities = subEntities;
|
||||||
|
entity.hidden = subCount - subEntities.length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -542,11 +542,8 @@ export function getGroupBlock(group) {
|
|||||||
template.find('.group_fav_icon').css('display', 'none');
|
template.find('.group_fav_icon').css('display', 'none');
|
||||||
template.addClass(group.fav ? 'is_fav' : '');
|
template.addClass(group.fav ? 'is_fav' : '');
|
||||||
template.find('.ch_fav').val(group.fav);
|
template.find('.ch_fav').val(group.fav);
|
||||||
template.find('.group_select_counter').text(count);
|
template.find('.group_select_counter').text(`${count} ${count != 1 ? 'characters' : 'character'}`);
|
||||||
template.find('.group_select_block_list').append(namesList.join(''));
|
template.find('.group_select_block_list').append(namesList.join(''));
|
||||||
if (count == 1) {
|
|
||||||
template.find('.character_unit_name').text('character');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Display inline tags
|
// Display inline tags
|
||||||
const tags = getTagsList(group.id);
|
const tags = getTagsList(group.id);
|
||||||
|
@ -86,9 +86,10 @@ let tag_map = {};
|
|||||||
* @param {Object} param1 Optional parameters, explained below.
|
* @param {Object} param1 Optional parameters, explained below.
|
||||||
* @param {Boolean} [param1.globalDisplayFilters] When enabled, applies the final filter for the global list. Icludes filtering out entities in closed/hidden folders and empty folders.
|
* @param {Boolean} [param1.globalDisplayFilters] When enabled, applies the final filter for the global list. Icludes filtering out entities in closed/hidden folders and empty folders.
|
||||||
* @param {Object} [param1.subForEntity] When given an entity, the list of entities gets filtered specifically for that one as a "sub list", filtering out other tags, elements not tagged for this and hidden elements.
|
* @param {Object} [param1.subForEntity] When given an entity, the list of entities gets filtered specifically for that one as a "sub list", filtering out other tags, elements not tagged for this and hidden elements.
|
||||||
|
* @param {Boolean} [param1.filterHidden] Optional switch with which filtering out hidden items (from closed folders) can be disabled.
|
||||||
* @returns The filtered list of entities
|
* @returns The filtered list of entities
|
||||||
*/
|
*/
|
||||||
function filterByTagState(entities, { globalDisplayFilters = false, subForEntity = undefined } = {}) {
|
function filterByTagState(entities, { globalDisplayFilters = false, subForEntity = undefined, filterHidden = true } = {}) {
|
||||||
const filterData = structuredClone(entitiesFilter.getFilterData(FILTER_TYPES.TAG));
|
const filterData = structuredClone(entitiesFilter.getFilterData(FILTER_TYPES.TAG));
|
||||||
|
|
||||||
entities = entities.filter(entity => {
|
entities = entities.filter(entity => {
|
||||||
@ -108,7 +109,7 @@ function filterByTagState(entities, { globalDisplayFilters = false, subForEntity
|
|||||||
|
|
||||||
entities = entities.filter(entity => {
|
entities = entities.filter(entity => {
|
||||||
// Hide entities that are in a closed folder, unless that one is opened
|
// Hide entities that are in a closed folder, unless that one is opened
|
||||||
if (entity.type !== 'tag' && closedFolders.some(f => entitiesFilter.isElementTagged(entity, f.id) && !filterData.selected.includes(f.id))) {
|
if (filterHidden && entity.type !== 'tag' && closedFolders.some(f => entitiesFilter.isElementTagged(entity, f.id) && !filterData.selected.includes(f.id))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,13 +124,13 @@ function filterByTagState(entities, { globalDisplayFilters = false, subForEntity
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (subForEntity !== undefined && subForEntity.type === 'tag') {
|
if (subForEntity !== undefined && subForEntity.type === 'tag') {
|
||||||
entities = filterTagSubEntities(subForEntity.item, entities);
|
entities = filterTagSubEntities(subForEntity.item, entities, { filterHidden : filterHidden });
|
||||||
}
|
}
|
||||||
|
|
||||||
return entities;
|
return entities;
|
||||||
}
|
}
|
||||||
|
|
||||||
function filterTagSubEntities(tag, entities) {
|
function filterTagSubEntities(tag, entities, { filterHidden = true } = {}) {
|
||||||
const filterData = structuredClone(entitiesFilter.getFilterData(FILTER_TYPES.TAG));
|
const filterData = structuredClone(entitiesFilter.getFilterData(FILTER_TYPES.TAG));
|
||||||
|
|
||||||
const closedFolders = entities.filter(x => x.type === 'tag' && TAG_FOLDER_TYPES[x.item.folder_type] === TAG_FOLDER_TYPES.CLOSED);
|
const closedFolders = entities.filter(x => x.type === 'tag' && TAG_FOLDER_TYPES[x.item.folder_type] === TAG_FOLDER_TYPES.CLOSED);
|
||||||
@ -141,7 +142,7 @@ function filterTagSubEntities(tag, entities) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Hide entities that are in a closed folder, unless the closed folder is opened or we display a closed folder
|
// Hide entities that are in a closed folder, unless the closed folder is opened or we display a closed folder
|
||||||
if (sub.type !== 'tag' && TAG_FOLDER_TYPES[tag.folder_type] !== TAG_FOLDER_TYPES.CLOSED && closedFolders.some(f => entitiesFilter.isElementTagged(sub, f.id) && !filterData.selected.includes(f.id))) {
|
if (filterHidden && sub.type !== 'tag' && TAG_FOLDER_TYPES[tag.folder_type] !== TAG_FOLDER_TYPES.CLOSED && closedFolders.some(f => entitiesFilter.isElementTagged(sub, f.id) && !filterData.selected.includes(f.id))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,7 +199,14 @@ function chooseBogusFolder(source, tagId, remove = false) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTagBlock(item, entities) {
|
/**
|
||||||
|
* Builds the tag block for the specified item.
|
||||||
|
* @param {Object} item The tag item
|
||||||
|
* @param {*} entities The list ob sub items for this tag
|
||||||
|
* @param {*} hidden A count of how many sub items are hidden
|
||||||
|
* @returns The html for the tag block
|
||||||
|
*/
|
||||||
|
function getTagBlock(item, entities, hidden = 0) {
|
||||||
let count = entities.length;
|
let count = entities.length;
|
||||||
|
|
||||||
const tagFolder = TAG_FOLDER_TYPES[item.folder_type];
|
const tagFolder = TAG_FOLDER_TYPES[item.folder_type];
|
||||||
@ -208,11 +216,9 @@ function getTagBlock(item, entities) {
|
|||||||
template.attr({ 'tagid': item.id, 'id': `BogusFolder${item.id}` });
|
template.attr({ 'tagid': item.id, 'id': `BogusFolder${item.id}` });
|
||||||
template.find('.avatar').css({ 'background-color': item.color, 'color': item.color2 }).attr('title', `[Folder] ${item.name}`);
|
template.find('.avatar').css({ 'background-color': item.color, 'color': item.color2 }).attr('title', `[Folder] ${item.name}`);
|
||||||
template.find('.ch_name').text(item.name).attr('title', `[Folder] ${item.name}`);
|
template.find('.ch_name').text(item.name).attr('title', `[Folder] ${item.name}`);
|
||||||
template.find('.bogus_folder_counter').text(count);
|
template.find('.bogus_folder_hidden_counter').text(hidden > 0 ? `${hidden} hidden` : '');
|
||||||
|
template.find('.bogus_folder_counter').text(`${count} ${count != 1 ? 'characters' : 'character'}`);
|
||||||
template.find('.bogus_folder_icon').addClass(tagFolder.fa_icon);
|
template.find('.bogus_folder_icon').addClass(tagFolder.fa_icon);
|
||||||
if (count == 1) {
|
|
||||||
template.find('.character_unit_name').text('character');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fill inline character images
|
// Fill inline character images
|
||||||
buildAvatarList(template.find('.bogus_folder_avatars_block'), entities);
|
buildAvatarList(template.find('.bogus_folder_avatars_block'), entities);
|
||||||
|
@ -1312,19 +1312,26 @@ input[type="file"] {
|
|||||||
align-self: center;
|
align-self: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#rm_print_characters_block .text_block {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
opacity: 0.5;
|
||||||
|
margin: 0 auto 1px auto;
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
#rm_print_characters_block .empty_block {
|
#rm_print_characters_block .empty_block {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
opacity: 0.5;
|
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
margin: 0 auto;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
#rm_print_characters_block .hidden_block p {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
#rm_print_characters_block {
|
#rm_print_characters_block {
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
@ -1626,6 +1633,15 @@ input[type=search]:focus::-webkit-search-cancel-button {
|
|||||||
align-items: baseline;
|
align-items: baseline;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
gap: 5px;
|
gap: 5px;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.character_name_block_sub_line {
|
||||||
|
position: absolute;
|
||||||
|
right: 0px;
|
||||||
|
top: calc(var(--mainFontSize) + 2px);
|
||||||
|
font-size: calc(var(--mainFontSize) * 0.6);
|
||||||
|
color: var(--grey7070a);
|
||||||
}
|
}
|
||||||
|
|
||||||
.ch_avatar_url {
|
.ch_avatar_url {
|
||||||
@ -1651,15 +1667,28 @@ input[type=search]:focus::-webkit-search-cancel-button {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*applies to both groups and solos chars in the char list*/
|
/*applies to both groups and solos chars in the char list*/
|
||||||
|
#rm_print_characters_block .character_select_container,
|
||||||
|
#rm_print_characters_block .group_select_container {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
#rm_print_characters_block .ch_name,
|
#rm_print_characters_block .ch_name,
|
||||||
.avatar-container .ch_name {
|
.avatar-container .ch_name {
|
||||||
flex: 1;
|
flex: 1 1 auto;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
text-wrap: nowrap;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#rm_print_characters_block .character_name_block > :last-child {
|
||||||
|
flex: 0 100000 auto; /* Force shrinking first */
|
||||||
|
overflow: hidden;
|
||||||
|
text-wrap: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
.bogus_folder_select:hover,
|
.bogus_folder_select:hover,
|
||||||
.character_select:hover,
|
.character_select:hover,
|
||||||
.avatar-container:hover {
|
.avatar-container:hover {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user