Allow for adding multiple favorites at once
This commit is contained in:
parent
ecb9ac1433
commit
14f03a10a5
|
@ -102,12 +102,12 @@
|
||||||
|
|
||||||
<div id="character_context_menu" class="hidden">
|
<div id="character_context_menu" class="hidden">
|
||||||
<ul>
|
<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 class="character_context_menu_separator"></li>
|
||||||
<li><a href="">Duplicate</a></li>
|
<li><button id="character_context_menu_duplicate">Duplicate</button></li>
|
||||||
<li><a href="">Export</a></li>
|
<li><button id="character_context_menu_export">Export</button></li>
|
||||||
<li><a href="">To Persona</a></li>
|
<li><button id="character_context_menu_persona">To Persona</button></li>
|
||||||
<li><a href="">Delete</a></li>
|
<li><button id="character_context_menu_delete">Delete</button></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -185,6 +185,7 @@ import { applyLocale } from "./scripts/i18n.js";
|
||||||
import { getTokenCount, getTokenizerModel, initTokenizers, saveTokenCache } from "./scripts/tokenizers.js";
|
import { getTokenCount, getTokenizerModel, initTokenizers, saveTokenCache } from "./scripts/tokenizers.js";
|
||||||
import { initPersonas, selectCurrentPersona, setPersonaDescription } from "./scripts/personas.js";
|
import { initPersonas, selectCurrentPersona, setPersonaDescription } from "./scripts/personas.js";
|
||||||
import { getBackgrounds, initBackgrounds } from "./scripts/backgrounds.js";
|
import { getBackgrounds, initBackgrounds } from "./scripts/backgrounds.js";
|
||||||
|
import {CharacterContextMenu, CharacterGroupOverlay} from "./scripts/CharacterGroupOverlay.js";
|
||||||
|
|
||||||
//exporting functions and vars for mods
|
//exporting functions and vars for mods
|
||||||
export {
|
export {
|
||||||
|
@ -314,8 +315,8 @@ eventSource.on(event_types.CHAT_CHANGED, displayOverrideWarnings);
|
||||||
eventSource.on(event_types.MESSAGE_RECEIVED, processExtensionHelpers);
|
eventSource.on(event_types.MESSAGE_RECEIVED, processExtensionHelpers);
|
||||||
eventSource.on(event_types.MESSAGE_SENT, processExtensionHelpers);
|
eventSource.on(event_types.MESSAGE_SENT, processExtensionHelpers);
|
||||||
|
|
||||||
import {CharacterGroupOverlay} from "./scripts/CharacterGroupOverlay.js";
|
|
||||||
const characterGroupOverlay = new CharacterGroupOverlay();
|
const characterGroupOverlay = new CharacterGroupOverlay();
|
||||||
|
const characterContextMenu = new CharacterContextMenu(characterGroupOverlay);
|
||||||
eventSource.on(event_types.CHARACTER_PAGE_LOADED, characterGroupOverlay.onPageLoad);
|
eventSource.on(event_types.CHARACTER_PAGE_LOADED, characterGroupOverlay.onPageLoad);
|
||||||
|
|
||||||
hljs.addPlugin({ "before:highlightElement": ({ el }) => { el.textContent = el.innerText } });
|
hljs.addPlugin({ "before:highlightElement": ({ el }) => { el.textContent = el.innerText } });
|
||||||
|
@ -989,7 +990,7 @@ export function getEntitiesList({ doFilter } = {}) {
|
||||||
return entities;
|
return entities;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getOneCharacter(avatarUrl) {
|
export async function getOneCharacter(avatarUrl) {
|
||||||
const response = await fetch("/getonecharacter", {
|
const response = await fetch("/getonecharacter", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: getRequestHeaders(),
|
headers: getRequestHeaders(),
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
"use strict";
|
"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
|
* Implement a SingletonPattern, allowing access to the group overlay instance
|
||||||
|
@ -15,9 +16,60 @@ class CharacterGroupOverlayState {
|
||||||
static select = 1;
|
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 {
|
class CharacterGroupOverlay {
|
||||||
static containerId = 'rm_print_characters_block';
|
static containerId = 'rm_print_characters_block';
|
||||||
static contextMenuClass = 'character_context_menu';
|
static contextMenuId = 'character_context_menu';
|
||||||
static characterClass = 'character_select';
|
static characterClass = 'character_select';
|
||||||
static selectModeClass = 'group_overlay_mode_select';
|
static selectModeClass = 'group_overlay_mode_select';
|
||||||
static selectedClass = 'character_selected';
|
static selectedClass = 'character_selected';
|
||||||
|
@ -124,7 +176,7 @@ class CharacterGroupOverlay {
|
||||||
document.removeEventListener('click', this.handleContextMenuHide);
|
document.removeEventListener('click', this.handleContextMenuHide);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleHold = (event) => {
|
handleHold = () => {
|
||||||
this.isLongPress = true;
|
this.isLongPress = true;
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (this.isLongPress) {
|
if (this.isLongPress) {
|
||||||
|
@ -149,6 +201,7 @@ class CharacterGroupOverlay {
|
||||||
.forEach(element => element.removeEventListener('click', this.toggleCharacterSelected));
|
.forEach(element => element.removeEventListener('click', this.toggleCharacterSelected));
|
||||||
this.clearSelectedCharacters();
|
this.clearSelectedCharacters();
|
||||||
this.disableContextMenu();
|
this.disableContextMenu();
|
||||||
|
CharacterContextMenu.hide();
|
||||||
break;
|
break;
|
||||||
case CharacterGroupOverlayState.select:
|
case CharacterGroupOverlayState.select:
|
||||||
this.container.classList.add(CharacterGroupOverlay.selectModeClass);
|
this.container.classList.add(CharacterGroupOverlay.selectModeClass);
|
||||||
|
@ -181,17 +234,14 @@ class CharacterGroupOverlay {
|
||||||
handleContextMenuShow = (event) => {
|
handleContextMenuShow = (event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
document.getElementById(CharacterGroupOverlay.containerId).style.pointerEvents = 'none';
|
document.getElementById(CharacterGroupOverlay.containerId).style.pointerEvents = 'none';
|
||||||
let contextMenu = document.getElementById(CharacterGroupOverlay.contextMenuClass);
|
CharacterContextMenu.show(event.clientX, event.clientY);
|
||||||
contextMenu.style.top = `${event.clientY}px`;
|
|
||||||
contextMenu.style.left = `${event.clientX}px`;
|
|
||||||
contextMenu.classList.remove('hidden');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
handleContextMenuHide = (event) => {
|
handleContextMenuHide = (event) => {
|
||||||
document.getElementById(CharacterGroupOverlay.containerId).style.pointerEvents = '';
|
document.getElementById(CharacterGroupOverlay.containerId).style.pointerEvents = '';
|
||||||
let contextMenu = document.getElementById(CharacterGroupOverlay.contextMenuClass);
|
let contextMenu = document.getElementById(CharacterGroupOverlay.contextMenuId);
|
||||||
if (false === contextMenu.contains(event.target)) {
|
if (false === contextMenu.contains(event.target)) {
|
||||||
contextMenu.classList.add('hidden');
|
CharacterContextMenu.hide();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue