Allow for adding multiple favorites at once

This commit is contained in:
artisticMink 2023-10-25 17:22:58 +02:00
parent ecb9ac1433
commit 14f03a10a5
3 changed files with 68 additions and 17 deletions

View File

@ -102,12 +102,12 @@
<div id="character_context_menu" class="hidden">
<ul>
<li><a href="">Favorite</a></li>
<li><button id="character_context_menu_favorite">Favorite</button></li>
<li class="character_context_menu_separator"></li>
<li><a href="">Duplicate</a></li>
<li><a href="">Export</a></li>
<li><a href="">To Persona</a></li>
<li><a href="">Delete</a></li>
<li><button id="character_context_menu_duplicate">Duplicate</button></li>
<li><button id="character_context_menu_export">Export</button></li>
<li><button id="character_context_menu_persona">To Persona</button></li>
<li><button id="character_context_menu_delete">Delete</button></li>
</ul>
</div>
@ -5111,4 +5111,4 @@
</script>
</body>
</html>
</html>

View File

@ -185,6 +185,7 @@ import { applyLocale } from "./scripts/i18n.js";
import { getTokenCount, getTokenizerModel, initTokenizers, saveTokenCache } from "./scripts/tokenizers.js";
import { initPersonas, selectCurrentPersona, setPersonaDescription } from "./scripts/personas.js";
import { getBackgrounds, initBackgrounds } from "./scripts/backgrounds.js";
import {CharacterContextMenu, CharacterGroupOverlay} from "./scripts/CharacterGroupOverlay.js";
//exporting functions and vars for mods
export {
@ -314,8 +315,8 @@ eventSource.on(event_types.CHAT_CHANGED, displayOverrideWarnings);
eventSource.on(event_types.MESSAGE_RECEIVED, processExtensionHelpers);
eventSource.on(event_types.MESSAGE_SENT, processExtensionHelpers);
import {CharacterGroupOverlay} from "./scripts/CharacterGroupOverlay.js";
const characterGroupOverlay = new CharacterGroupOverlay();
const characterContextMenu = new CharacterContextMenu(characterGroupOverlay);
eventSource.on(event_types.CHARACTER_PAGE_LOADED, characterGroupOverlay.onPageLoad);
hljs.addPlugin({ "before:highlightElement": ({ el }) => { el.textContent = el.innerText } });
@ -989,7 +990,7 @@ export function getEntitiesList({ doFilter } = {}) {
return entities;
}
async function getOneCharacter(avatarUrl) {
export async function getOneCharacter(avatarUrl) {
const response = await fetch("/getonecharacter", {
method: "POST",
headers: getRequestHeaders(),

View File

@ -1,6 +1,7 @@
"use strict";
import {event_types, eventSource} from "../script.js";
import {characters, event_types, eventSource, getOneCharacter} from "../script.js";
import {favsToHotswap} from "./RossAscends-mods.js";
/**
* Implement a SingletonPattern, allowing access to the group overlay instance
@ -15,9 +16,60 @@ class CharacterGroupOverlayState {
static select = 1;
}
class CharacterContextMenu {
static toggleFavorite = (characterId) => {
const character = CharacterContextMenu.getCharacter(characterId);
const data = {
name: character.name,
avatar: character.avatar,
data: {
extensions: {
fav: !character.data.extensions.fav
}
}
};
jQuery.ajax({
type: "POST",
url: '/v2/editcharacterattribute',
data: JSON.stringify(data),
contentType: "application/json; charset=utf-8",
cache: false,
processData: false,
success: () =>
getOneCharacter(character.avatar)
.then(() =>
favsToHotswap()
.then(() => eventSource.emit(event_types.CHARACTER_EDITED, { detail: { id: character.id, character: characters[character.id] } })
)),
error: response => toastr.error('Character not saved. Error: ' + response.responseJSON?.message),
});
}
static getCharacter = (characterId) => characters[characterId] ?? null;
static show = (positionX, positionY) => {
let contextMenu = document.getElementById(CharacterGroupOverlay.contextMenuId);
contextMenu.style.left = `${positionX}px`;
contextMenu.style.top = `${positionY}px`;
document.getElementById(CharacterGroupOverlay.contextMenuId).classList.remove('hidden');
}
static hide = () => document.getElementById(CharacterGroupOverlay.contextMenuId).classList.add('hidden');
constructor(characterGroupOverlay) {
const contextMenuItems = [
{id: 'character_context_menu_favorite', callback: characterGroupOverlay.handleContextMenuFavorite}
];
contextMenuItems.forEach(contextMenuItem => document.getElementById(contextMenuItem.id).addEventListener('click', contextMenuItem.callback))
}
}
class CharacterGroupOverlay {
static containerId = 'rm_print_characters_block';
static contextMenuClass = 'character_context_menu';
static contextMenuId = 'character_context_menu';
static characterClass = 'character_select';
static selectModeClass = 'group_overlay_mode_select';
static selectedClass = 'character_selected';
@ -124,7 +176,7 @@ class CharacterGroupOverlay {
document.removeEventListener('click', this.handleContextMenuHide);
}
handleHold = (event) => {
handleHold = () => {
this.isLongPress = true;
setTimeout(() => {
if (this.isLongPress) {
@ -149,6 +201,7 @@ class CharacterGroupOverlay {
.forEach(element => element.removeEventListener('click', this.toggleCharacterSelected));
this.clearSelectedCharacters();
this.disableContextMenu();
CharacterContextMenu.hide();
break;
case CharacterGroupOverlayState.select:
this.container.classList.add(CharacterGroupOverlay.selectModeClass);
@ -181,17 +234,14 @@ class CharacterGroupOverlay {
handleContextMenuShow = (event) => {
event.preventDefault();
document.getElementById(CharacterGroupOverlay.containerId).style.pointerEvents = 'none';
let contextMenu = document.getElementById(CharacterGroupOverlay.contextMenuClass);
contextMenu.style.top = `${event.clientY}px`;
contextMenu.style.left = `${event.clientX}px`;
contextMenu.classList.remove('hidden');
CharacterContextMenu.show(event.clientX, event.clientY);
}
handleContextMenuHide = (event) => {
document.getElementById(CharacterGroupOverlay.containerId).style.pointerEvents = '';
let contextMenu = document.getElementById(CharacterGroupOverlay.contextMenuClass);
let contextMenu = document.getElementById(CharacterGroupOverlay.contextMenuId);
if (false === contextMenu.contains(event.target)) {
contextMenu.classList.add('hidden');
CharacterContextMenu.hide();
}
}