mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-02-10 17:10:45 +01:00
add a healthy dose of mobile copium
This commit is contained in:
parent
81f135fa7c
commit
cdbcd6cfb2
@ -102,8 +102,7 @@ function onQuickReplyInput(id) {
|
|||||||
|
|
||||||
function onQuickReplyLabelInput(id) {
|
function onQuickReplyLabelInput(id) {
|
||||||
extension_settings.quickReply.quickReplySlots[id - 1].label = $(`#quickReply${id}Label`).val();
|
extension_settings.quickReply.quickReplySlots[id - 1].label = $(`#quickReply${id}Label`).val();
|
||||||
let quickReplyLabel = extension_settings.quickReply.quickReplySlots[id - 1]?.label || '';
|
addQuickReplyBar();
|
||||||
$(`#quickReply${id}`).text(quickReplyLabel + (extension_settings.quickReply.quickReplySlots[id - 1]?.contextMenu?.length?'…':''));
|
|
||||||
saveSettingsDebounced();
|
saveSettingsDebounced();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -277,10 +276,11 @@ function addQuickReplyBar() {
|
|||||||
for (let i = 0; i < extension_settings.quickReply.numberOfSlots; i++) {
|
for (let i = 0; i < extension_settings.quickReply.numberOfSlots; i++) {
|
||||||
let quickReplyMes = extension_settings.quickReply.quickReplySlots[i]?.mes || '';
|
let quickReplyMes = extension_settings.quickReply.quickReplySlots[i]?.mes || '';
|
||||||
let quickReplyLabel = extension_settings.quickReply.quickReplySlots[i]?.label || '';
|
let quickReplyLabel = extension_settings.quickReply.quickReplySlots[i]?.label || '';
|
||||||
|
let expander = '';
|
||||||
if (extension_settings.quickReply.quickReplySlots[i]?.contextMenu?.length) {
|
if (extension_settings.quickReply.quickReplySlots[i]?.contextMenu?.length) {
|
||||||
quickReplyLabel = `${quickReplyLabel}…`;
|
expander = '<span class="ctx-expander" title="Open context menu">⋮</span>';
|
||||||
}
|
}
|
||||||
quickReplyButtonHtml += `<div title="${quickReplyMes}" class="quickReplyButton" data-index="${i}" id="quickReply${i + 1}">${quickReplyLabel}</div>`;
|
quickReplyButtonHtml += `<div title="${quickReplyMes}" class="quickReplyButton" data-index="${i}" id="quickReply${i + 1}">${quickReplyLabel}${expander}</div>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const quickReplyBarFullHtml = `
|
const quickReplyBarFullHtml = `
|
||||||
@ -297,6 +297,17 @@ function addQuickReplyBar() {
|
|||||||
let index = $(this).data('index');
|
let index = $(this).data('index');
|
||||||
sendQuickReply(index);
|
sendQuickReply(index);
|
||||||
});
|
});
|
||||||
|
$('.quickReplyButton > .ctx-expander').on('click', function (evt) {
|
||||||
|
evt.stopPropagation();
|
||||||
|
let index = $(this.closest('.quickReplyButton')).data('index');
|
||||||
|
const qr = extension_settings.quickReply.quickReplySlots[index];
|
||||||
|
if (qr.contextMenu?.length) {
|
||||||
|
evt.preventDefault();
|
||||||
|
const tree = buildContextMenu(qr);
|
||||||
|
const menu = new ContextMenu(tree.children);
|
||||||
|
menu.show(evt);
|
||||||
|
}
|
||||||
|
})
|
||||||
$('.quickReplyButton').on('contextmenu', function (evt) {
|
$('.quickReplyButton').on('contextmenu', function (evt) {
|
||||||
let index = $(this).data('index');
|
let index = $(this).data('index');
|
||||||
const qr = extension_settings.quickReply.quickReplySlots[index];
|
const qr = extension_settings.quickReply.quickReplySlots[index];
|
||||||
|
@ -1,16 +1,23 @@
|
|||||||
import { MenuItem } from "./MenuItem.js";
|
import { MenuItem } from "./MenuItem.js";
|
||||||
|
|
||||||
export class ContextMenu {
|
export class ContextMenu {
|
||||||
|
/**@type {MenuItem[]}*/ itemList = [];
|
||||||
|
/**@type {Boolean}*/ isActive = false;
|
||||||
|
|
||||||
/**@type {HTMLElement}*/ root;
|
/**@type {HTMLElement}*/ root;
|
||||||
/**@type {HTMLElement}*/ menu;
|
/**@type {HTMLElement}*/ menu;
|
||||||
|
|
||||||
/**@type {MenuItem[]}*/ itemList = [];
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
constructor(/**@type {MenuItem[]}*/items) {
|
constructor(/**@type {MenuItem[]}*/items) {
|
||||||
this.itemList = items;
|
this.itemList = items;
|
||||||
|
items.forEach(item=>{
|
||||||
|
item.onExpand = ()=>{
|
||||||
|
items.filter(it=>it!=item)
|
||||||
|
.forEach(it=>it.collapse());
|
||||||
|
};
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@ -35,12 +42,24 @@ export class ContextMenu {
|
|||||||
|
|
||||||
|
|
||||||
show({clientX, clientY}) {
|
show({clientX, clientY}) {
|
||||||
|
if (this.isActive) return;
|
||||||
|
this.isActive = true;
|
||||||
this.render();
|
this.render();
|
||||||
this.menu.style.bottom = `${window.innerHeight - clientY}px`;
|
this.menu.style.bottom = `${window.innerHeight - clientY}px`;
|
||||||
this.menu.style.left = `${clientX}px`;
|
this.menu.style.left = `${clientX}px`;
|
||||||
document.body.append(this.root);
|
document.body.append(this.root);
|
||||||
}
|
}
|
||||||
hide() {
|
hide() {
|
||||||
|
if (this.root) {
|
||||||
this.root.remove();
|
this.root.remove();
|
||||||
}
|
}
|
||||||
|
this.isActive = false;
|
||||||
|
}
|
||||||
|
toggle(/**@type {PointerEvent}*/evt) {
|
||||||
|
if (this.isActive) {
|
||||||
|
this.hide();
|
||||||
|
} else {
|
||||||
|
this.show(evt);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,15 +1,9 @@
|
|||||||
|
import { MenuItem } from "./MenuItem.js";
|
||||||
import { SubMenu } from "./SubMenu.js";
|
import { SubMenu } from "./SubMenu.js";
|
||||||
|
|
||||||
export class MenuHeader {
|
export class MenuHeader extends MenuItem {
|
||||||
/**@type {String}*/ label;
|
|
||||||
|
|
||||||
/**@type {HTMLElement}*/ root;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
constructor(/**@type {String}*/label) {
|
constructor(/**@type {String}*/label) {
|
||||||
this.label = label;
|
super(label, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -5,9 +5,13 @@ export class MenuItem {
|
|||||||
/**@type {Object}*/ value;
|
/**@type {Object}*/ value;
|
||||||
/**@type {Function}*/ callback;
|
/**@type {Function}*/ callback;
|
||||||
/**@type {MenuItem[]}*/ childList = [];
|
/**@type {MenuItem[]}*/ childList = [];
|
||||||
|
/**@type {SubMenu}*/ subMenu;
|
||||||
|
/**@type {Boolean}*/ isForceExpanded = false;
|
||||||
|
|
||||||
/**@type {HTMLElement}*/ root;
|
/**@type {HTMLElement}*/ root;
|
||||||
|
|
||||||
|
/**@type {Function}*/ onExpand;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -29,15 +33,44 @@ export class MenuItem {
|
|||||||
if (this.callback) {
|
if (this.callback) {
|
||||||
item.addEventListener('click', (evt)=>this.callback(evt, this));
|
item.addEventListener('click', (evt)=>this.callback(evt, this));
|
||||||
}
|
}
|
||||||
|
item.append(this.label);
|
||||||
if (this.childList.length > 0) {
|
if (this.childList.length > 0) {
|
||||||
item.classList.add('ctx-has-children');
|
item.classList.add('ctx-has-children');
|
||||||
const sub = new SubMenu(this.childList);
|
const sub = new SubMenu(this.childList);
|
||||||
item.addEventListener('pointerover', ()=>sub.show(item));
|
this.subMenu = sub;
|
||||||
item.addEventListener('pointerleave', ()=>sub.hide());
|
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());
|
||||||
|
|
||||||
}
|
}
|
||||||
item.append(this.label);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return this.root;
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -47,9 +47,18 @@ export class SubMenu {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
hide() {
|
hide() {
|
||||||
|
if (this.root) {
|
||||||
this.root.remove();
|
this.root.remove();
|
||||||
this.root.style.top = '';
|
this.root.style.top = '';
|
||||||
this.root.style.left = '';
|
this.root.style.left = '';
|
||||||
|
}
|
||||||
this.isActive = false;
|
this.isActive = false;
|
||||||
}
|
}
|
||||||
|
toggle(/**@type {HTMLElement}*/parent) {
|
||||||
|
if (this.isActive) {
|
||||||
|
this.hide();
|
||||||
|
} else {
|
||||||
|
this.show(parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -71,11 +71,25 @@
|
|||||||
.ctx-item {
|
.ctx-item {
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
.ctx-item.ctx-has-children:after {
|
.ctx-expander {
|
||||||
content: " >";
|
border-left: 1px solid;
|
||||||
|
margin-left: 1em;
|
||||||
|
text-align: center;
|
||||||
|
width: 2em;
|
||||||
|
}
|
||||||
|
.ctx-expander:hover {
|
||||||
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
.ctx-sub-menu {
|
.ctx-sub-menu {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 100%;
|
left: 100%;
|
||||||
}
|
}
|
||||||
|
@media screen and (max-width: 1000px) {
|
||||||
|
.ctx-blocker {
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
.list-group .list-group-item.ctx-item {
|
||||||
|
padding: 1em;
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user