Add custom context menu for bul edit actions
This commit is contained in:
parent
7d60d65d7e
commit
171c20ee16
|
@ -11,3 +11,34 @@
|
|||
visibility: hidden;
|
||||
height: 0 !important;
|
||||
}
|
||||
|
||||
#character_context_menu.hidden { display: none; }
|
||||
#character_context_menu {
|
||||
position: absolute;
|
||||
padding: 3px;
|
||||
z-index: 10000;
|
||||
background-color: var(--SmartThemeUserMesBlurTintColor);
|
||||
border: 1px solid var(--SmartThemeBorderColor);
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
#character_context_menu ul {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#character_context_menu li {
|
||||
padding: 10px;
|
||||
border-radius: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#character_context_menu .character_context_menu_separator {
|
||||
height: 1px;
|
||||
background-color: var(--SmartThemeBotMesBlurTintColor);
|
||||
}
|
||||
|
||||
#character_context_menu li:hover {
|
||||
background-color: var(--SmartThemeBotMesBlurTintColor);
|
||||
}
|
||||
|
|
|
@ -100,6 +100,17 @@
|
|||
<div id="bg_custom"></div>
|
||||
<div id="bg1"></div>
|
||||
|
||||
<div id="character_context_menu" class="hidden">
|
||||
<ul>
|
||||
<li><a href="">Favorite</a></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>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- top bar central settings buttons -->
|
||||
<div id="top-bar">
|
||||
</div>
|
||||
|
@ -4340,6 +4351,7 @@
|
|||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="character_template" class="template_element">
|
||||
<div class="character_select flex-container wide100p alignitemsflexstart" chid="" id="">
|
||||
<div class="avatar" title="">
|
||||
|
|
|
@ -17,6 +17,8 @@ class State {
|
|||
|
||||
class CharacterGroupOverlay {
|
||||
static containerId = 'rm_print_characters_block';
|
||||
static contextMenuClass = 'character_context_menu';
|
||||
static characterClass = 'character_select';
|
||||
static selectModeClass = 'group_overlay_mode_select';
|
||||
static selectedClass = 'character_selected';
|
||||
|
||||
|
@ -79,12 +81,12 @@ class CharacterGroupOverlay {
|
|||
*/
|
||||
onPageLoad = () => {
|
||||
let touchState = false;
|
||||
const grid = document.getElementById('rm_print_characters_block');
|
||||
const grid = document.getElementById(CharacterGroupOverlay.containerId);
|
||||
|
||||
const sortable = new Sortable(grid, {
|
||||
group: 'shared',
|
||||
animation: 150,
|
||||
sort:false,
|
||||
sort: false,
|
||||
handle: '.character_select',
|
||||
onEnd: (evt) => {
|
||||
if (evt.from !== evt.to) {
|
||||
|
@ -93,18 +95,36 @@ class CharacterGroupOverlay {
|
|||
}
|
||||
});
|
||||
|
||||
const elements = [...document.getElementsByClassName('character_select')];
|
||||
const elements = [...document.getElementsByClassName(CharacterGroupOverlay.characterClass)];
|
||||
|
||||
elements.forEach(element => element.addEventListener('touchstart', this.handleHold));
|
||||
elements.forEach(element => element.addEventListener('mousedown', this.handleHold));
|
||||
|
||||
elements.forEach(element => element.addEventListener('touchend', this._handleLongPressEnd));
|
||||
elements.forEach(element => element.addEventListener('mouseup', this._handleLongPressEnd));
|
||||
elements.forEach(element => element.addEventListener('dragend', this._handleLongPressEnd));
|
||||
elements.forEach(element => element.addEventListener('touchend', this.handleLongPressEnd));
|
||||
elements.forEach(element => element.addEventListener('mouseup', this.handleLongPressEnd));
|
||||
elements.forEach(element => element.addEventListener('dragend', this.handleLongPressEnd));
|
||||
|
||||
grid.addEventListener('click', this.handleCancelClick);
|
||||
}
|
||||
|
||||
/**
|
||||
* Block the browsers native context menu and
|
||||
* set a click event to hide the custom context menu.
|
||||
*/
|
||||
enableContextMenu = () => {
|
||||
document.addEventListener('contextmenu', this.handleContextMenuShow);
|
||||
document.addEventListener('click', this.handleContextMenuHide);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove event listeners, allowing the native browser context
|
||||
* menu to be opened.
|
||||
*/
|
||||
disableContextMenu = () => {
|
||||
document.removeEventListener('contextmenu', this.handleContextMenuShow);
|
||||
document.removeEventListener('click', this.handleContextMenuHide);
|
||||
}
|
||||
|
||||
handleHold = (event) => {
|
||||
this.isLongPress = true;
|
||||
setTimeout(() => {
|
||||
|
@ -114,7 +134,7 @@ class CharacterGroupOverlay {
|
|||
}, 3000);
|
||||
}
|
||||
|
||||
_handleLongPressEnd = () => {
|
||||
handleLongPressEnd = () => {
|
||||
this.isLongPress = false;
|
||||
}
|
||||
|
||||
|
@ -126,16 +146,17 @@ class CharacterGroupOverlay {
|
|||
switch (this.state) {
|
||||
case State.browse:
|
||||
this.container.classList.remove(CharacterGroupOverlay.selectModeClass);
|
||||
[...this.container.getElementsByClassName('character_select')]
|
||||
[...this.container.getElementsByClassName(CharacterGroupOverlay.characterClass)]
|
||||
.forEach(element => element.removeEventListener('click', this.toggleCharacterSelected));
|
||||
this.longPressEndCallbacks.forEach(callback => callback());
|
||||
this.clearSelectedCharacters();
|
||||
this.disableContextMenu();
|
||||
break;
|
||||
case State.select:
|
||||
this.container.classList.add(CharacterGroupOverlay.selectModeClass);
|
||||
[...this.container.getElementsByClassName('character_select')]
|
||||
[...this.container.getElementsByClassName(CharacterGroupOverlay.characterClass)]
|
||||
.forEach(element => element.addEventListener('click', this.toggleCharacterSelected));
|
||||
this.clearSelectedCharacters();
|
||||
this.enableContextMenu();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -154,7 +175,23 @@ class CharacterGroupOverlay {
|
|||
character.classList.add(CharacterGroupOverlay.selectedClass);
|
||||
this.selectCharacter(characterId);
|
||||
}
|
||||
}
|
||||
|
||||
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');
|
||||
}
|
||||
|
||||
handleContextMenuHide = (event) => {
|
||||
document.getElementById(CharacterGroupOverlay.containerId).style.pointerEvents = '';
|
||||
let contextMenu = document.getElementById(CharacterGroupOverlay.contextMenuClass);
|
||||
if (false === contextMenu.contains(event.target)) {
|
||||
contextMenu.classList.add('hidden');
|
||||
}
|
||||
}
|
||||
|
||||
addLongPressEndCallback = callback => this.longPressEndCallbacks.push(callback);
|
||||
|
@ -164,7 +201,7 @@ class CharacterGroupOverlay {
|
|||
dismissCharacter = characterId => this.#selectedCharacters = this.selectedCharacters.filter(item => String(characterId) !== item);
|
||||
|
||||
clearSelectedCharacters = () => {
|
||||
this.selectedCharacters.forEach(characterId => document.querySelector('.character_select[chid="'+characterId+'"]')?.classList.remove(CharacterGroupOverlay.selectedClass))
|
||||
this.selectedCharacters.forEach(characterId => document.querySelector('.character_select[chid="' + characterId + '"]')?.classList.remove(CharacterGroupOverlay.selectedClass))
|
||||
this.selectedCharacters.length = 0;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue