mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
clean out QR extension
This commit is contained in:
@ -1,49 +0,0 @@
|
|||||||
<div id="quickReply_contextMenuEditor_template">
|
|
||||||
<div class="quickReply_contextMenuEditor">
|
|
||||||
<h3><strong>Context Menu Editor</strong></h3>
|
|
||||||
<div id="quickReply_contextMenuEditor_content">
|
|
||||||
<template id="quickReply_contextMenuEditor_itemTemplate">
|
|
||||||
<div class="quickReplyContextMenuEditor_item flex-container alignitemscenter" data-order="0">
|
|
||||||
<span class="drag-handle ui-sortable-handle">☰</span>
|
|
||||||
<select class="quickReply_contextMenuEditor_preset"></select>
|
|
||||||
<label class="flex-container" title="When enabled, the current Quick Reply will be sent together with (before) the clicked QR from the context menu.">
|
|
||||||
Chaining:
|
|
||||||
<input type="checkbox" class="quickReply_contextMenuEditor_chaining">
|
|
||||||
</label>
|
|
||||||
<span class="quickReply_contextMenuEditor_remove menu_button menu_button_icon fa-solid fa-trash-can" title="Remove entry"></span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
<div class="quickReply_contextMenuEditor_actions">
|
|
||||||
<span id="quickReply_contextMenuEditor_addPreset" class="menu_button menu_button_icon fa-solid fa-plus" title="Add preset to context menu"></span>
|
|
||||||
</div>
|
|
||||||
<h3><strong>Auto-Execute</strong></h3>
|
|
||||||
<div class="flex-container flexFlowColumn">
|
|
||||||
<label class="checkbox_label" for="quickReply_hidden">
|
|
||||||
<input type="checkbox" id="quickReply_hidden" >
|
|
||||||
<span><i class="fa-solid fa-fw fa-eye-slash"></i> Invisible (auto-execute only)</span>
|
|
||||||
</label>
|
|
||||||
<label class="checkbox_label" for="quickReply_autoExecute_appStartup">
|
|
||||||
<input type="checkbox" id="quickReply_autoExecute_appStartup" >
|
|
||||||
<span><i class="fa-solid fa-fw fa-rocket"></i> Execute on app startup</span>
|
|
||||||
</label>
|
|
||||||
<label class="checkbox_label" for="quickReply_autoExecute_userMessage">
|
|
||||||
<input type="checkbox" id="quickReply_autoExecute_userMessage" >
|
|
||||||
<span><i class="fa-solid fa-fw fa-user"></i> Execute on user message</span>
|
|
||||||
</label>
|
|
||||||
<label class="checkbox_label" for="quickReply_autoExecute_botMessage">
|
|
||||||
<input type="checkbox" id="quickReply_autoExecute_botMessage" >
|
|
||||||
<span><i class="fa-solid fa-fw fa-robot"></i> Execute on AI message</span>
|
|
||||||
</label>
|
|
||||||
<label class="checkbox_label" for="quickReply_autoExecute_chatLoad">
|
|
||||||
<input type="checkbox" id="quickReply_autoExecute_chatLoad" >
|
|
||||||
<span><i class="fa-solid fa-fw fa-message"></i> Execute on opening chat</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<h3><strong>UI Options</strong></h3>
|
|
||||||
<div class="flex-container flexFlowColumn">
|
|
||||||
<label for="quickReply_ui_title">Title (tooltip, leave empty to show the message or /command)</label>
|
|
||||||
<input type="text" class="text_pole" id="quickReply_ui_title">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
File diff suppressed because it is too large
Load Diff
@ -6,6 +6,6 @@
|
|||||||
"js": "index.js",
|
"js": "index.js",
|
||||||
"css": "style.css",
|
"css": "style.css",
|
||||||
"author": "RossAscends#1779",
|
"author": "RossAscends#1779",
|
||||||
"version": "1.0.0",
|
"version": "2.0.0",
|
||||||
"homePage": "https://github.com/SillyTavern/SillyTavern"
|
"homePage": "https://github.com/SillyTavern/SillyTavern"
|
||||||
}
|
}
|
||||||
|
@ -1,67 +0,0 @@
|
|||||||
/**
|
|
||||||
* @typedef {import('./MenuItem.js').MenuItem} MenuItem
|
|
||||||
*/
|
|
||||||
|
|
||||||
export class ContextMenu {
|
|
||||||
/**@type {MenuItem[]}*/ itemList = [];
|
|
||||||
/**@type {Boolean}*/ isActive = false;
|
|
||||||
|
|
||||||
/**@type {HTMLElement}*/ root;
|
|
||||||
/**@type {HTMLElement}*/ menu;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
constructor(/**@type {MenuItem[]}*/items) {
|
|
||||||
this.itemList = items;
|
|
||||||
items.forEach(item => {
|
|
||||||
item.onExpand = () => {
|
|
||||||
items.filter(it => it != item)
|
|
||||||
.forEach(it => it.collapse());
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
if (!this.root) {
|
|
||||||
const blocker = document.createElement('div'); {
|
|
||||||
this.root = blocker;
|
|
||||||
blocker.classList.add('ctx-blocker');
|
|
||||||
blocker.addEventListener('click', () => this.hide());
|
|
||||||
const menu = document.createElement('ul'); {
|
|
||||||
this.menu = menu;
|
|
||||||
menu.classList.add('list-group');
|
|
||||||
menu.classList.add('ctx-menu');
|
|
||||||
this.itemList.forEach(it => menu.append(it.render()));
|
|
||||||
blocker.append(menu);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this.root;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
show({ clientX, clientY }) {
|
|
||||||
if (this.isActive) return;
|
|
||||||
this.isActive = true;
|
|
||||||
this.render();
|
|
||||||
this.menu.style.bottom = `${window.innerHeight - clientY}px`;
|
|
||||||
this.menu.style.left = `${clientX}px`;
|
|
||||||
document.body.append(this.root);
|
|
||||||
}
|
|
||||||
hide() {
|
|
||||||
if (this.root) {
|
|
||||||
this.root.remove();
|
|
||||||
}
|
|
||||||
this.isActive = false;
|
|
||||||
}
|
|
||||||
toggle(/**@type {PointerEvent}*/evt) {
|
|
||||||
if (this.isActive) {
|
|
||||||
this.hide();
|
|
||||||
} else {
|
|
||||||
this.show(evt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
import { MenuItem } from './MenuItem.js';
|
|
||||||
|
|
||||||
export class MenuHeader extends MenuItem {
|
|
||||||
constructor(/**@type {String}*/label) {
|
|
||||||
super(label, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
render() {
|
|
||||||
if (!this.root) {
|
|
||||||
const item = document.createElement('li'); {
|
|
||||||
this.root = item;
|
|
||||||
item.classList.add('list-group-item');
|
|
||||||
item.classList.add('ctx-header');
|
|
||||||
item.append(this.label);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this.root;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,76 +0,0 @@
|
|||||||
import { SubMenu } from './SubMenu.js';
|
|
||||||
|
|
||||||
export class MenuItem {
|
|
||||||
/**@type {String}*/ label;
|
|
||||||
/**@type {Object}*/ value;
|
|
||||||
/**@type {Function}*/ callback;
|
|
||||||
/**@type {MenuItem[]}*/ childList = [];
|
|
||||||
/**@type {SubMenu}*/ subMenu;
|
|
||||||
/**@type {Boolean}*/ isForceExpanded = false;
|
|
||||||
|
|
||||||
/**@type {HTMLElement}*/ root;
|
|
||||||
|
|
||||||
/**@type {Function}*/ onExpand;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
constructor(/**@type {String}*/label, /**@type {Object}*/value, /**@type {function}*/callback, /**@type {MenuItem[]}*/children = []) {
|
|
||||||
this.label = label;
|
|
||||||
this.value = value;
|
|
||||||
this.callback = callback;
|
|
||||||
this.childList = children;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
render() {
|
|
||||||
if (!this.root) {
|
|
||||||
const item = document.createElement('li'); {
|
|
||||||
this.root = item;
|
|
||||||
item.classList.add('list-group-item');
|
|
||||||
item.classList.add('ctx-item');
|
|
||||||
item.title = this.value;
|
|
||||||
if (this.callback) {
|
|
||||||
item.addEventListener('click', (evt) => this.callback(evt, this));
|
|
||||||
}
|
|
||||||
item.append(this.label);
|
|
||||||
if (this.childList.length > 0) {
|
|
||||||
item.classList.add('ctx-has-children');
|
|
||||||
const sub = new SubMenu(this.childList);
|
|
||||||
this.subMenu = sub;
|
|
||||||
const trigger = document.createElement('div'); {
|
|
||||||
trigger.classList.add('ctx-expander');
|
|
||||||
trigger.textContent = '⋮';
|
|
||||||
trigger.addEventListener('click', (evt) => {
|
|
||||||
evt.stopPropagation();
|
|
||||||
this.toggle();
|
|
||||||
});
|
|
||||||
item.append(trigger);
|
|
||||||
}
|
|
||||||
item.addEventListener('mouseover', () => sub.show(item));
|
|
||||||
item.addEventListener('mouseleave', () => sub.hide());
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this.root;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
expand() {
|
|
||||||
this.subMenu?.show(this.root);
|
|
||||||
if (this.onExpand) {
|
|
||||||
this.onExpand();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
collapse() {
|
|
||||||
this.subMenu?.hide();
|
|
||||||
}
|
|
||||||
toggle() {
|
|
||||||
if (this.subMenu.isActive) {
|
|
||||||
this.expand();
|
|
||||||
} else {
|
|
||||||
this.collapse();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,66 +0,0 @@
|
|||||||
/**
|
|
||||||
* @typedef {import('./MenuItem.js').MenuItem} MenuItem
|
|
||||||
*/
|
|
||||||
|
|
||||||
export class SubMenu {
|
|
||||||
/**@type {MenuItem[]}*/ itemList = [];
|
|
||||||
/**@type {Boolean}*/ isActive = false;
|
|
||||||
|
|
||||||
/**@type {HTMLElement}*/ root;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
constructor(/**@type {MenuItem[]}*/items) {
|
|
||||||
this.itemList = items;
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
if (!this.root) {
|
|
||||||
const menu = document.createElement('ul'); {
|
|
||||||
this.root = menu;
|
|
||||||
menu.classList.add('list-group');
|
|
||||||
menu.classList.add('ctx-menu');
|
|
||||||
menu.classList.add('ctx-sub-menu');
|
|
||||||
this.itemList.forEach(it => menu.append(it.render()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this.root;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
show(/**@type {HTMLElement}*/parent) {
|
|
||||||
if (this.isActive) return;
|
|
||||||
this.isActive = true;
|
|
||||||
this.render();
|
|
||||||
parent.append(this.root);
|
|
||||||
requestAnimationFrame(() => {
|
|
||||||
const rect = this.root.getBoundingClientRect();
|
|
||||||
console.log(window.innerHeight, rect);
|
|
||||||
if (rect.bottom > window.innerHeight - 5) {
|
|
||||||
this.root.style.top = `${window.innerHeight - 5 - rect.bottom}px`;
|
|
||||||
}
|
|
||||||
if (rect.right > window.innerWidth - 5) {
|
|
||||||
this.root.style.left = 'unset';
|
|
||||||
this.root.style.right = '100%';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
hide() {
|
|
||||||
if (this.root) {
|
|
||||||
this.root.remove();
|
|
||||||
this.root.style.top = '';
|
|
||||||
this.root.style.left = '';
|
|
||||||
}
|
|
||||||
this.isActive = false;
|
|
||||||
}
|
|
||||||
toggle(/**@type {HTMLElement}*/parent) {
|
|
||||||
if (this.isActive) {
|
|
||||||
this.hide();
|
|
||||||
} else {
|
|
||||||
this.show(parent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,114 +0,0 @@
|
|||||||
#quickReplyBar {
|
|
||||||
outline: none;
|
|
||||||
/*
|
|
||||||
padding: 5px 0;
|
|
||||||
border-bottom: 1px solid var(--SmartThemeBorderColor);
|
|
||||||
*/
|
|
||||||
margin: 0;
|
|
||||||
transition: 0.3s;
|
|
||||||
opacity: 0.7;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
width: 100%;
|
|
||||||
display: none;
|
|
||||||
max-width: 100%;
|
|
||||||
overflow-x: auto;
|
|
||||||
order: 1;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
#quickReplies {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
gap: 5px;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#quickReplyPopoutButton {
|
|
||||||
position: absolute;
|
|
||||||
right: 5px;
|
|
||||||
top: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#quickReplies div {
|
|
||||||
color: var(--SmartThemeBodyColor);
|
|
||||||
background-color: var(--black50a);
|
|
||||||
border: 1px solid var(--SmartThemeBorderColor);
|
|
||||||
border-radius: 10px;
|
|
||||||
padding: 3px 5px;
|
|
||||||
margin: 3px 0;
|
|
||||||
/* width: min-content; */
|
|
||||||
cursor: pointer;
|
|
||||||
transition: 0.3s;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
#quickReplies div:hover {
|
|
||||||
opacity: 1;
|
|
||||||
filter: brightness(1.2);
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.ctx-blocker {
|
|
||||||
/* backdrop-filter: blur(1px); */
|
|
||||||
/* background-color: rgba(0 0 0 / 10%); */
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
position: fixed;
|
|
||||||
right: 0;
|
|
||||||
top: 0;
|
|
||||||
z-index: 999;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ctx-menu {
|
|
||||||
position: absolute;
|
|
||||||
overflow: visible;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-group .list-group-item.ctx-header {
|
|
||||||
font-weight: bold;
|
|
||||||
cursor: default;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ctx-item+.ctx-header {
|
|
||||||
border-top: 1px solid;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ctx-item {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ctx-expander {
|
|
||||||
border-left: 1px solid;
|
|
||||||
margin-left: 1em;
|
|
||||||
text-align: center;
|
|
||||||
width: 2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ctx-expander:hover {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ctx-sub-menu {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: 1000px) {
|
|
||||||
.ctx-blocker {
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-group .list-group-item.ctx-item {
|
|
||||||
padding: 1em;
|
|
||||||
}
|
|
||||||
}
|
|
Reference in New Issue
Block a user