(function () {
const MenuTpl = `
{{{title}}}
{{{subtext}}}
{{#isGrid}}
{{#elements}}
{{#image}}
{{/image}}
{{^image}}
{{{label}}}
{{/image}}
{{/elements}}
{{/isGrid}}
{{^isGrid}}
{{#elements}}
{{#isNotSelectable}}
{{/isNotSelectable}}
{{^isNotSelectable}}
{{/isNotSelectable}}
{{#image}}
{{/image}}
{{#isLabelSlider}}
{{{label}}}
{{{sliderLabel}}}
{{{min}}}
{{{max}}}
{{/isLabelSlider}}
{{^isLabelSlider}}
{{#tickBox}}
{{{label}}}
{{#isTickBoxChecked}}
{{/isTickBoxChecked}}
{{/tickBox}}
{{^tickBox}}
{{{label}}}
{{/tickBox}}
{{/isLabelSlider}}
{{^isLabelSlider}}
{{^isDescSlider}}
{{#isTextSlider}}
{{#enableCursor}}
{{/enableCursor}}
{{^enableCursor}}
{{/enableCursor}}
{{{currentTextLabel}}}
{{#enableCursor}}
{{/enableCursor}}
{{^enableCursor}}
{{/enableCursor}}
{{/isTextSlider}}
{{^isTextSlider}}
{{#isSlider}}
{{#enableCursor}}
{{/enableCursor}}
{{^enableCursor}}
{{/enableCursor}}
{{/isSlider}}
{{{sliderLabel}}}
{{#isSlider}}
{{#enableCursor}}
{{/enableCursor}}
{{^enableCursor}}
{{/enableCursor}}
{{/isSlider}}
{{/isTextSlider}}
{{/isDescSlider}}
{{/isLabelSlider}}
{{/elements}}
{{/isGrid}}
{{#elements}}
{{#selected}}
{{{list_id}}}/{{{list_max}}}
{{#confirmButton}}
{{#enableCursor}}
{{#cancelButton}}
{{/cancelButton}}
{{/enableCursor}}
{{/confirmButton}}
{{^confirmButton}}
{{#cancelButton}}
{{#enableCursor}}
{{/enableCursor}}
{{/cancelButton}}
{{/confirmButton}}
{{{desc}}}
{{#isDescSlider}}
{{#enableCursor}}
{{#hasMultipleSliders}}
{{#processedSliders}}
{{{label}}}
{{{sliderLabel}}}
{{{min}}}
{{{max}}}
{{/processedSliders}}
{{/hasMultipleSliders}}
{{^hasMultipleSliders}}
{{{label}}}
{{{sliderLabel}}}
{{{min}}}
{{{max}}}
{{/hasMultipleSliders}}
{{/enableCursor}}
{{/isDescSlider}}
{{#isMultipleTickBoxes}}
{{#enableCursor}}
{{#processedTickBoxes}}
{{{label}}}
{{#isChecked}}
{{/isChecked}}
{{/processedTickBoxes}}
{{/enableCursor}}
{{/isMultipleTickBoxes}}
{{^descPrice}}
{{#footerText}}
{{{footerText}}}
{{/footerText}}
{{/descPrice}}
{{/selected}}
{{/elements}}
{{#showGlobalDivider}}
{{/showGlobalDivider}}
{{#hasDescPrice}}
{{{descPriceData.text}}}
{{#descPriceData.isMoneyIcon}}
$
{{/descPriceData.isMoneyIcon}}
{{^descPriceData.isMoneyIcon}}
{{/descPriceData.isMoneyIcon}}
{{{descPriceData.amount}}}
{{/hasDescPrice}}
`;
const InputTpl = `
{{{header}}}
{{#description}}
{{{description}}}
{{/description}}
{{^isConfirmation}}
{{#isTextarea}}
{{/isTextarea}}
{{^isTextarea}}
{{#isText}}
{{/isText}}
{{#isNumber}}
{{/isNumber}}
{{#isPassword}}
{{/isPassword}}
{{#isDate}}
{{/isDate}}
{{/isTextarea}}
{{/isConfirmation}}
`;
window.isInputOpen = false;
window.MenuData = {};
const MenuData = window.MenuData; // just for linter
MenuData.ResourceName = GetParentResourceName();
MenuData.opened = {};
MenuData.focus = [];
MenuData.pos = {};
let lastmenu;
let SavedScrollTop = 0;
function scrollToElement(element) {
if (element) {
const menuContainer = document.querySelector(".menu .menu-items");
const elementRect = element.getBoundingClientRect();
const containerRect = menuContainer.getBoundingClientRect();
if (elementRect.bottom > containerRect.bottom) {
menuContainer.scrollTop += elementRect.bottom - containerRect.bottom;
} else if (elementRect.top < containerRect.top) {
menuContainer.scrollTop -= containerRect.top - elementRect.top;
}
}
}
function addMouseEvents(namespace, name, menuElement) {
const menuData = MenuData.opened[namespace][name];
let isDragging = false;
let dragElement = null;
let isDescDragging = false;
let isMultiSliderDragging = false;
$(menuElement).find('.menu-item, .grid-item, .slider-left, .slider-right, .menu-confirm-btn, .menu-cancel-btn, .label-slider-track, .label-slider-thumb, .description-slider-track, .description-slider-thumb, .description-slider-container, .tickbox-item').off();
$(menuElement).find('.menu-item').each(function (index) {
$(this).on('click', function () {
if (isDragging || isDescDragging || isMultiSliderDragging) {
return;
}
const currentSelected = MenuData.pos[namespace][name];
if (index === currentSelected) {
let elem = menuData.elements[index];
if (elem.isDisabled) return;
if (elem.tickBox) {
document.body.style.pointerEvents = 'none';
onData({
ak_menubase_action: 'controlPressed',
ak_menubase_control: 'ENTER'
});
setTimeout(() => {
document.body.style.pointerEvents = '';
}, 100);
return;
}
elem.index = index + 1;
MenuData.submit(namespace, name, elem);
} else {
lastSelectedIndex = index;
MenuData.pos[namespace][name] = index;
for (let i = 0; i < menuData.elements.length; i++) {
menuData.elements[i].selected = (i === index);
}
$(menuElement).find('.menu-item').removeClass('selected');
$(this).addClass('selected');
updateSelectedContent(namespace, name, menuData.elements[index]);
MenuData.change(namespace, name, menuData.elements[index]);
const menuContainer = $(menuElement).find('.menu-items')[0];
SavedScrollTop = menuContainer.scrollTop;
MenuData.render();
const newMenuContainer = document.querySelector(".menu .menu-items");
if (newMenuContainer) {
newMenuContainer.scrollTop = SavedScrollTop;
}
$.post("https://" + MenuData.ResourceName + "/playsound");
}
});
$(this).on('contextmenu', function (e) {
e.preventDefault();
onData({
ak_menubase_action: 'controlPressed',
ak_menubase_control: 'BACKSPACE'
});
});
});
$(menuElement).find('.grid-item').each(function (index) {
$(this).on('click', function () {
if (isDragging || isDescDragging || isMultiSliderDragging) {
return;
}
const currentSelected = MenuData.pos[namespace][name];
if (index === currentSelected) {
let elem = menuData.elements[index];
elem.index = index + 1;
MenuData.submit(namespace, name, elem);
} else {
lastSelectedIndex = index;
MenuData.pos[namespace][name] = index;
for (let i = 0; i < menuData.elements.length; i++) {
menuData.elements[i].selected = (i === index);
}
$(menuElement).find('.grid-item').removeClass('selected');
$(this).addClass('selected');
updateSelectedContent(namespace, name, menuData.elements[index]);
MenuData.change(namespace, name, menuData.elements[index]);
const menuContainer = $(menuElement).find('.menu-items')[0];
const savedScrollTop = menuContainer.scrollTop;
MenuData.render();
const newMenuContainer = document.querySelector(".menu .menu-items");
if (newMenuContainer) {
newMenuContainer.scrollTop = savedScrollTop;
}
}
});
$(this).on('contextmenu', function (e) {
e.preventDefault();
onData({
ak_menubase_action: 'controlPressed',
ak_menubase_control: 'BACKSPACE'
});
});
});
$(menuElement).find('.grid-item').on('mouseenter', function () {
$.post("https://" + MenuData.ResourceName + "/playsound");
});
$(menuElement).find('.slider-left, .text-slider-left').on('click', function (e) {
e.stopPropagation();
const itemIndex = $(this).closest('.menu-item').index();
let elem = menuData.elements[itemIndex];
elem.index = itemIndex + 1;
if (itemIndex !== MenuData.pos[namespace][name]) {
return;
}
if (elem.type === 'slider') {
const min = typeof elem.min == "undefined" ? 0 : elem.min;
if (elem.value > min) {
if (typeof elem.hop != "undefined") {
if (Number.isInteger(elem.hop)) {
elem.value = elem.value - elem.hop;
} else {
elem.value = (Number(elem.value) - Number(elem.hop)).toFixed(1);
}
elem.value = Number(elem.value);
if (elem.value < min)
elem.value = min;
} else {
elem.value--;
}
MenuData.change(namespace, name, elem); // why fire 2 functions it doesnt even make sense with the same params lol ?
MenuData.submit(namespace, name, elem);
}
MenuData.render();
} else if (elem.type === 'text-slider') {
if (elem.textList && elem.textList.length > 0) {
const maxLength = elem.textList.length;
const currentIndex = elem.textIndex ? (elem.textIndex - 1) : 0;
if (currentIndex < 0) {
currentIndex = maxLength;
}
const newIndex = currentIndex - 1;
if (elem.textList[newIndex]) {
elem.value = elem.textList[newIndex].value;
elem.currentTextLabel = elem.textList[newIndex].label;
elem.textIndex = newIndex + 1;
elem.index = elem.pos + 1;
MenuData.submit(namespace, name, elem);
const menuContainer = $(menuElement).find('.menu-items')[0];
const savedScrollTop = menuContainer.scrollTop;
MenuData.render();
const newMenuContainer = document.querySelector(".menu .menu-items");
if (newMenuContainer) {
newMenuContainer.scrollTop = savedScrollTop;
}
$.post("https://" + MenuData.ResourceName + "/playsound");
}
}
}
});
$(menuElement).find('.slider-right, .text-slider-right').on('click', function (e) {
e.stopPropagation();
const itemIndex = $(this).closest('.menu-item').index();
let elem = menuData.elements[itemIndex];
elem.index = itemIndex + 1;
if (itemIndex !== MenuData.pos[namespace][name]) {
return;
}
if (elem.type === 'slider') {
if (typeof elem.options != "undefined" && elem.value < elem.options.length - 1) {
elem.value++;
MenuData.change(namespace, name, elem);// why fire 2 functions it doesnt even make sense with the same params lol ?
MenuData.submit(namespace, name, elem);
}
if (typeof elem.max != "undefined" && elem.value < elem.max) {
if (typeof elem.hop != "undefined") {
const min = typeof elem.min == "undefined" ? 0 : elem.min;
if (min > 0 && min == elem.value)
elem.value = 0;
if (Number.isInteger(elem.hop)) {
elem.value = elem.value + elem.hop;
} else {
elem.value = (Number(elem.value) + Number(elem.hop)).toFixed(1);
}
elem.value = Number(elem.value);
if (elem.value > elem.max)
elem.value = elem.max;
} else {
elem.value++;
}
MenuData.change(namespace, name, elem); // why fire 2 functions it doesnt even make sense with the same params lol ?
MenuData.submit(namespace, name, elem);
}
MenuData.render();
} else if (elem.type === 'text-slider') {
if (elem.textList && elem.textList.length > 0) {
const maxLength = elem.textList.length;
const currentIndex = elem.textIndex ? (elem.textIndex - 1) : 0;
if (currentIndex > maxLength) {
newIndex = maxLength;
}
const newIndex = currentIndex + 1;
if (elem.textList[newIndex]) {
elem.value = elem.textList[newIndex].value;
elem.currentTextLabel = elem.textList[newIndex].label;
elem.textIndex = newIndex + 1;
MenuData.submit(namespace, name, elem);
const menuContainer = $(menuElement).find('.menu-items')[0];
const savedScrollTop = menuContainer.scrollTop;
MenuData.render();
const newMenuContainer = document.querySelector(".menu .menu-items");
if (newMenuContainer) {
newMenuContainer.scrollTop = savedScrollTop;
}
$.post("https://" + MenuData.ResourceName + "/playsound");
}
}
}
});
$(menuElement).find('.menu-confirm-btn, .menu-cancel-btn').on('click', function () {
const buttonValue = $(this).data('value');
const currentIndex = MenuData.pos[namespace][name];
const selectedElement = menuData.elements[currentIndex];
const buttonData = {
buttonType: $(this).hasClass('menu-confirm-btn') ? 'confirm' : 'cancel',
buttonValue: buttonValue,
selectedElement: selectedElement,
selectedIndex: currentIndex + 1,
value: buttonValue
};
MenuData.submit(namespace, name, buttonData);
});
$(menuElement).find('.menu-confirm-btn, .menu-cancel-btn').on('mouseenter', function () {
$.post("https://" + MenuData.ResourceName + "/playsound");
});
$(menuElement).find('.menu-confirm-btn, .menu-cancel-btn').on('mouseleave', function () {
$.post("https://" + MenuData.ResourceName + "/playsound");
});
$(menuElement).find('.tickbox-item').on('click', function (e) {
e.stopPropagation();
const tickboxIndex = parseInt($(this).data('tickbox-index'));
const elementIndex = parseInt($(this).data('element-index'));
if (elementIndex !== MenuData.pos[namespace][name]) {
return;
}
const elem = menuData.elements[elementIndex];
if (elem && elem.type === 'tick-box' && elem.tickBoxes && elem.tickBoxes[tickboxIndex]) {
const tickBox = elem.tickBoxes[tickboxIndex];
tickBox.value = tickBox.value === "ticked" ? "unticked" : "ticked";
const menuContainer = $(menuElement).find('.menu-items')[0];
const savedScrollTop = menuContainer.scrollTop;
const submitData = {
...elem,
tickBoxIndex: tickboxIndex + 1,
index: elementIndex + 1
};
MenuData.submit(namespace, name, submitData);
MenuData.render();
const newMenuContainer = document.querySelector(".menu .menu-items");
if (newMenuContainer) {
newMenuContainer.scrollTop = savedScrollTop;
}
$.post("https://" + MenuData.ResourceName + "/playsound");
}
});
function getBoundingRect(e, track, elem) {
const rect = track.getBoundingClientRect();
const clickX = e.clientX - rect.left;
const trackWidth = rect.width;
const percentage = Math.max(0, Math.min(1, clickX / trackWidth));
const min = typeof elem.min === "undefined" ? 0 : elem.min;
const max = typeof elem.max === "undefined" ? 10 : elem.max;
let newValue = min + percentage * (max - min);
if (typeof elem.hop !== "undefined") {
newValue = Math.round(newValue / elem.hop) * elem.hop;
newValue = Number.isInteger(elem.hop) ? newValue : Number(newValue.toFixed(1));
} else {
newValue = Math.round(newValue);
}
newValue = Math.max(min, Math.min(max, newValue));
return newValue;
}
$(menuElement).find('.label-slider-track').on('click', function (e) {
e.stopPropagation();
const itemIndex = $(this).closest('.menu-item').index();
const elem = menuData.elements[itemIndex];
if (itemIndex !== MenuData.pos[namespace][name]) {
return;
}
if (elem && elem.type === 'label-slider') {
const track = $(this)[0];
newValue = getBoundingRect(e, track, elem);
if (newValue !== elem.value) {
elem.value = newValue;
elem.index = itemIndex + 1;
MenuData.submit(namespace, name, elem);
MenuData.render();
}
}
});
$(menuElement).find('.label-slider-thumb').on('mousedown', function (e) {
e.stopPropagation();
e.preventDefault();
const itemIndex = $(this).closest('.menu-item').index();
if (itemIndex !== MenuData.pos[namespace][name]) {
return;
}
if (isDragging) {
$(document).off('mousemove.slider');
$(document).off('mouseup.slider');
}
isDragging = true;
dragElement = itemIndex;
const dragThumb = $(this);
const dragFill = dragThumb.siblings('.label-slider-fill');
const dragValue = $(this).closest('.menu-item').find('.label-slider-value');
$(document).on('mousemove.slider', function (e) {
if (isDragging && dragElement !== null) {
const elem = menuData.elements[dragElement];
if (elem && elem.type === 'label-slider') {
const track = $(menuElement).find('.menu-item').eq(dragElement).find('.label-slider-track')[0];
newValue = getBoundingRect(e, track, elem);
if (newValue !== elem.value) {
elem.value = newValue;
const min = elem.min !== undefined ? elem.min : 0;
const max = elem.max !== undefined ? elem.max : 10;
const range = max - min;
const visualPercentage = range === 0 ? 0 : Math.round(((elem.value - min) / range) * 100);
dragThumb.css('left', visualPercentage + '%');
dragFill.css('width', visualPercentage + '%');
let displayValue = formatSliderValue(elem.value, elem.hop, elem.options);
dragValue.text(displayValue);
elem.index = dragElement + 1;
MenuData.submit(namespace, name, elem);
}
}
}
});
$(document).on('mouseup.slider', function () {
isDragging = false;
dragElement = null;
$(document).off('mousemove.slider');
$(document).off('mouseup.slider');
MenuData.render();
});
});
$(menuElement).find('.description-slider-track').on('click', function (e) {
e.stopPropagation();
const isMultipleSlider = $(this).closest('[data-slider-index]').length > 0;
if (!isMultipleSlider) {
const selectedIndex = MenuData.pos[namespace][name];
let elem = menuData.elements[selectedIndex];
if (elem && elem.type === 'desc-slider') {
const track = $(this)[0];
newValue = getBoundingRect(e, track, elem);
elem.value = newValue;
elem.index = selectedIndex + 1;
MenuData.submit(namespace, name, elem);
MenuData.render();
}
}
});
$(menuElement).find('.description-slider-thumb').on('mousedown', function (e) {
e.stopPropagation();
e.preventDefault();
if (isDescDragging) {
$(document).off('mousemove.descslider');
$(document).off('mouseup.descslider');
}
isDescDragging = true;
const selectedIndex = MenuData.pos[namespace][name];
const dragThumb = $(this);
const dragFill = dragThumb.siblings('.description-slider-fill');
const dragValue = $(this).closest('.description-slider-container').find('.description-slider-value');
$(document).on('mousemove.descslider', function (e) {
if (isDescDragging) {
const elem = menuData.elements[selectedIndex];
if (elem && elem.type === 'desc-slider') {
const track = dragThumb.closest('.description-slider-container').find('.description-slider-track')[0];
newValue = getBoundingRect(e, track, elem);
if (newValue !== elem.value) {
elem.value = newValue;
const min = elem.min !== undefined ? elem.min : 0;
const max = elem.max !== undefined ? elem.max : 10;
const range = max - min;
const visualPercentage = range === 0 ? 0 : Math.round(((elem.value - min) / range) * 100);
dragThumb.css('left', visualPercentage + '%');
dragFill.css('width', visualPercentage + '%');
let displayValue = formatSliderValue(elem.value, elem.hop, elem.options);
dragValue.text(displayValue);
elem.index = selectedIndex + 1;
MenuData.submit(namespace, name, elem);
}
}
}
});
$(document).on('mouseup.descslider', function () {
isDescDragging = false;
$(document).off('mousemove.descslider');
$(document).off('mouseup.descslider');
MenuData.render();
});
});
$(menuElement).find('.description-slider-container[data-slider-index]').each(function () {
const sliderContainer = $(this);
const elementIndex = parseInt(sliderContainer.data('element-index'));
const sliderIndex = parseInt(sliderContainer.data('slider-index'));
sliderContainer.find('.description-slider-track').on('click', function (e) {
e.stopPropagation();
const elem = menuData.elements[elementIndex];
if (elem && elem.type === 'desc-slider' && elem.sliders && elem.sliders[sliderIndex]) {
const slider = elem.sliders[sliderIndex];
const track = $(this)[0];
newValue = getBoundingRect(e, track, slider);
slider.value = newValue;
let callbackData = JSON.parse(JSON.stringify(elem));
callbackData.index = elementIndex + 1;
callbackData.sliderIndex = sliderIndex + 1;
callbackData.value = newValue;
const currentSlider = elem.sliders[sliderIndex];
for (const key in currentSlider) {
if (key !== "label" && key !== "value" && key !== "min" && key !== "max" && key !== "hop" && key !== "options" && key !== "attributes") {
callbackData[key] = currentSlider[key];
}
}
MenuData.submit(namespace, name, callbackData);
MenuData.render();
}
});
sliderContainer.find('.description-slider-thumb').on('mousedown', function (e) {
e.stopPropagation();
e.preventDefault();
if (isMultiSliderDragging) {
$(document).off('mousemove.multislider');
$(document).off('mouseup.multislider');
}
isMultiSliderDragging = true;
const capturedElementIndex = elementIndex;
const capturedSliderIndex = sliderIndex;
const dragThumb = $(this);
const dragFill = dragThumb.siblings('.description-slider-fill');
const dragValue = sliderContainer.find('.description-slider-value');
$(document).on('mousemove.multislider', function (e) {
if (isMultiSliderDragging && capturedElementIndex !== null && capturedSliderIndex !== null) {
const elem = menuData.elements[capturedElementIndex];
if (elem && elem.type === 'desc-slider' && elem.sliders && elem.sliders[capturedSliderIndex]) {
const slider = elem.sliders[capturedSliderIndex];
const track = dragThumb.closest('.description-slider-container').find('.description-slider-track')[0];
newValue = getBoundingRect(e, track, slider);
if (newValue !== slider.value) {
slider.value = newValue;
const min = slider.min !== undefined ? slider.min : 0;
const max = slider.max !== undefined ? slider.max : 10;
const range = max - min;
const visualPercentage = range === 0 ? 0 : Math.round(((slider.value - min) / range) * 100);
dragThumb.css('left', visualPercentage + '%');
dragFill.css('width', visualPercentage + '%');
let displayValue = formatSliderValue(slider.value, slider.hop, slider.options);
dragValue.text(displayValue);
let callbackData = JSON.parse(JSON.stringify(elem));
callbackData.index = capturedElementIndex + 1;
callbackData.sliderIndex = capturedSliderIndex + 1;
callbackData.value = newValue;
const currentSlider = elem.sliders[capturedSliderIndex];
for (const key in currentSlider) {
if (key !== "label" && key !== "value" && key !== "min" && key !== "max" && key !== "hop" && key !== "options" && key !== "attributes") {
callbackData[key] = currentSlider[key];
}
}
MenuData.submit(namespace, name, callbackData);
}
}
}
});
$(document).on('mouseup.multislider', function () {
isMultiSliderDragging = false;
$(document).off('mousemove.multislider');
$(document).off('mouseup.multislider');
MenuData.render();
});
});
});
menuData.cleanup = function () {
$(document).off('mousemove.slider');
$(document).off('mouseup.slider');
$(document).off('mousemove.descslider');
$(document).off('mouseup.descslider');
$(document).off('mousemove.multislider');
$(document).off('mouseup.multislider');
isDragging = false;
isDescDragging = false;
isMultiSliderDragging = false;
dragElement = null;
};
}
function updateSelectedContent(namespace, name, selectedElement) {
const menuElement = document.querySelector(`#menu_${namespace}_${name}`);
const menuData = MenuData.opened[namespace][name];
if (menuElement && menuData) {
const selectedIndex = MenuData.pos[namespace][name];
const optionsAmount = menuElement.querySelector('.options-amount');
if (optionsAmount)
optionsAmount.textContent = `${selectedIndex + 1}/${menuData.elements.length}`;
const description = menuElement.querySelector('.desciption');
if (description)
description.innerHTML = selectedElement.desc || '';
const footerText = menuElement.querySelector('.footer-text');
if (footerText)
footerText.remove();
if (selectedElement.footerText) {
const newFooterText = document.createElement('div');
newFooterText.className = 'footer-text';
newFooterText.innerHTML = selectedElement.footerText;
menuElement.appendChild(newFooterText);
}
$.post('https://' + MenuData.ResourceName + '/update_last_selected', JSON.stringify({
_namespace: namespace,
_name: name,
selected: selectedIndex
}));
}
}
MenuData.open = function (namespace, name, data) {
lastmenu = data.lastmenu;
if (typeof MenuData.opened[namespace] == "undefined") {
MenuData.opened[namespace] = {};
}
if (typeof MenuData.opened[namespace][name] != "undefined") {
MenuData.close(namespace, name);
}
if (typeof MenuData.pos[namespace] == "undefined") {
MenuData.pos[namespace] = {};
}
for (let i = 0; i < data.elements.length; i++) {
if (typeof data.elements[i].type == "undefined") {
data.elements[i].type = "default";
}
}
data._index = MenuData.focus.length;
data._namespace = namespace;
data._name = name;
for (let i = 0; i < data.elements.length; i++) {
data.elements[i]._namespace = namespace;
data.elements[i]._name = name;
}
let selectedIndex = (typeof MenuData.pos[namespace][name] !== "undefined") ? MenuData.pos[namespace][name] : 0;
for (let i = 0; i < data.elements.length; i++) {
data.elements[i].selected = (i === selectedIndex);
}
MenuData.opened[namespace][name] = data;
MenuData.pos[namespace][name] = 0;
for (let i = 0; i < data.elements.length; i++) {
if (data.elements[i].selected) {
MenuData.pos[namespace][name] = i;
} else {
data.elements[i].selected = false;
}
}
MenuData.focus.push({
namespace: namespace,
name: name,
});
data.displayInput = function (inputConfig, onSubmit, onCancel) {
MenuData.inputCallbacks = {
onSubmit: onSubmit,
onCancel: onCancel
};
MenuData.displayInput(namespace, name, inputConfig);
};
MenuData.render();
if (SavedScrollTop > 0) { // refresh the menu this gets called so we gotta scroll to where we were
requestAnimationFrame(() => {
const menuItems = document.querySelector('.menu .menu-items');
if (menuItems) {
menuItems.scrollTop = SavedScrollTop;
SavedScrollTop = 0;
}
});
}
const selectedElement = $("#menu_" + namespace + "_" + name).find(".menu-item.selected, .grid-item.selected");
if (selectedElement.length > 0) {
scrollToElement(selectedElement[0]);
}
$.post("https://" + MenuData.ResourceName + "/setCursor", JSON.stringify({
enabled: data.enableCursor
}));
};
MenuData.close = function (namespace, name) {
if (MenuData.opened[namespace] && MenuData.opened[namespace][name] && MenuData.opened[namespace][name].cleanup) {
MenuData.opened[namespace][name].cleanup();
}
delete MenuData.opened[namespace][name];
for (let i = 0; i < MenuData.focus.length; i++) {
if (
MenuData.focus[i].namespace == namespace &&
MenuData.focus[i].name == name
) {
MenuData.focus.splice(i, 1);
break;
}
}
MenuData.render();
let cursorEnabled = false;
for (let ns in MenuData.opened) {
for (let nm in MenuData.opened[ns]) {
if (MenuData.opened[ns][nm].enableCursor) {
cursorEnabled = true;
break;
}
}
if (cursorEnabled) break;
}
$.post("https://" + MenuData.ResourceName + "/setCursor", JSON.stringify({
enabled: cursorEnabled
}));
};
function formatSliderValue(value, hop, options) {
if (typeof options !== "undefined") {
return options[value];
}
if (typeof hop !== "undefined" && !Number.isInteger(hop)) {
return Number(value).toFixed(1);
} else {
return Math.floor(value);
}
}
MenuData.render = function () {
const focused = MenuData.getFocused();
$(document).off('mousemove.slider');
$(document).off('mouseup.slider');
$(document).off('mousemove.descslider');
$(document).off('mouseup.descslider');
let cursorEnabled = false;
if (focused && MenuData.opened[focused.namespace] && MenuData.opened[focused.namespace][focused.name]) {
cursorEnabled = (MenuData.opened[focused.namespace][focused.name].enableCursor);
}
$.post("https://" + MenuData.ResourceName + "/setCursor", JSON.stringify({
enabled: cursorEnabled
}));
let menuContainer = document.getElementById("menus");
menuContainer.innerHTML = "";
$(menuContainer).hide();
for (const namespace in MenuData.opened) {
for (const name in MenuData.opened[namespace]) {
const menuData = MenuData.opened[namespace][name];
const view = JSON.parse(JSON.stringify(menuData));
for (let i = 0; i < menuData.elements.length; i++) {
let element = view.elements[i];
switch (element.type) {
case "default":
element.list_id = i + 1;
element.list_max = menuData.elements.length;
if (element.tickBox) {
element.isTickBoxChecked = (element.value === "ticked");
}
break;
case "slider": {
element.isSlider = true;
element.list_id = i + 1;
element.list_max = menuData.elements.length;
element.sliderLabel = formatSliderValue(element.value, element.hop, element.options);
break;
}
case "label-slider": {
element.isLabelSlider = true;
element.list_id = i + 1;
element.list_max = menuData.elements.length;
const min = element.min || 0;
const max = element.max || 100;
let value = element.value !== undefined ? element.value : min;
value = Math.max(min, Math.min(max, value));
element.hasNegativeRange = min < 0 && max > 0;
const range = max - min;
if (range === 0) {
element.sliderPercentage = 0;
} else {
element.sliderPercentage = Math.round(((value - min) / range) * 100);
}
element.sliderLabel = formatSliderValue(value, element.hop, element.options);
let customColors = {};
if (element.attributes) {
customColors = {
trackColor: element.attributes.trackColor || null,
fillColor: element.attributes.fillColor || null,
thumbColor: element.attributes.thumbColor || null
};
}
element.customColors = customColors;
element.min = formatSliderValue(min, element.hop);
element.max = formatSliderValue(max, element.hop);
break;
}
case "desc-slider": {
element.isDescSlider = true;
element.list_id = i + 1;
element.list_max = menuData.elements.length;
if (element.sliders && Array.isArray(element.sliders)) {
element.hasMultipleSliders = true;
element.processedSliders = [];
for (let sliderIndex = 0; sliderIndex < element.sliders.length; sliderIndex++) {
const slider = element.sliders[sliderIndex];
const min = slider.min !== undefined ? slider.min : 0;
const max = slider.max !== undefined ? slider.max : 100;
let value = slider.value !== undefined ? slider.value : min;
value = Math.max(min, Math.min(max, value));
const range = max - min;
let sliderPercentage = 0;
if (range === 0) {
sliderPercentage = 0;
} else {
sliderPercentage = Math.round(((value - min) / range) * 100);
}
let sliderLabel = formatSliderValue(value, slider.hop, slider.options);
let customKey = null;
for (const key in slider) {
if (key !== "label" && key !== "value" && key !== "min" && key !== "max" && key !== "hop" && key !== "options" && key !== "attributes") {
if (!customKey) {
customKey = key;
}
}
}
let customColors = {};
if (slider.attributes) {
customColors = {
trackColor: slider.attributes.trackColor || null,
fillColor: slider.attributes.fillColor || null,
thumbColor: slider.attributes.thumbColor || null
};
}
element.processedSliders.push({
index: sliderIndex,
label: slider.label || `Slider ${sliderIndex + 1}`,
value: value,
min: formatSliderValue(slider.min, slider.hop),
max: formatSliderValue(slider.max, slider.hop),
hop: slider.hop,
options: slider.options,
sliderPercentage: sliderPercentage,
sliderLabel: sliderLabel,
customKey: customKey || `slider${sliderIndex}`,
customColors: customColors,
elementIndex: i
});
}
} else {
element.hasMultipleSliders = false;
const min = element.min !== undefined ? element.min : 0;
const max = element.max !== undefined ? element.max : 10;
let value = element.value !== undefined ? element.value : min;
value = Math.max(min, Math.min(max, value));
element.hasNegativeRange = min < 0 && max > 0;
const range = max - min;
if (range === 0) {
element.sliderPercentage = 0;
} else {
element.sliderPercentage = Math.round(((value - min) / range) * 100);
}
element.sliderLabel = formatSliderValue(value, element.hop, element.options);
element.min = formatSliderValue(min, element.hop);
element.max = formatSliderValue(max, element.hop);
}
element.isSlider = false;
break;
}
case "tick-box": {
element.list_id = i + 1;
element.list_max = menuData.elements.length;
if (element.tickBoxes && Array.isArray(element.tickBoxes)) {
element.isMultipleTickBoxes = true;
element.processedTickBoxes = [];
for (let tickBoxIndex = 0; tickBoxIndex < element.tickBoxes.length; tickBoxIndex++) {
const tickBox = element.tickBoxes[tickBoxIndex];
element.processedTickBoxes.push({
index: tickBoxIndex,
label: tickBox.label || `Option ${tickBoxIndex + 1}`,
value: tickBox.value || "unticked",
isChecked: tickBox.value === "ticked",
elementIndex: i
});
}
} else {
element.isMultipleTickBoxes = false;
element.tickBox = true;
element.isTickBoxChecked = element.value === "ticked";
}
break;
}
case "text-slider": {
element.isSlider = true;
element.isTextSlider = true;
element.list_id = i + 1;
element.list_max = menuData.elements.length;
if (element.textList && Array.isArray(element.textList)) {
const currentIndex = element.textIndex ? (element.textIndex - 1) : 0;
if (element.textList[currentIndex]) {
element.textIndex = currentIndex + 1;
element.currentTextLabel = element.textList[currentIndex].label;
element.maxIndex = element.textList.length - 1;
}
} else {
element.textIndex = 0;
element.currentTextLabel = "none";
element.maxIndex = 0;
}
break;
}
default:
element.list_id = i + 1;
element.list_max = menuData.elements.length;
break;
}
if (i == MenuData.pos[namespace][name]) {
element.selected = true;
}
}
let hasDescPrice = false;
let descPriceData = null;
const selectedIndex = MenuData.pos[namespace][name] || 0;
if (view.elements[selectedIndex] && view.elements[selectedIndex].descPrice) {
hasDescPrice = true;
descPriceData = JSON.parse(JSON.stringify(view.elements[selectedIndex].descPrice));
descPriceData.isMoneyIcon = descPriceData.icon === "money";
}
view.hasDescPrice = hasDescPrice;
view.descPriceData = descPriceData;
view.showGlobalDivider = menuData.divider && !hasDescPrice;
view.enableCursor = menuData.enableCursor;
const menu = $(Mustache.render(MenuTpl, view))[0];
$(menu).hide();
menuContainer.appendChild(menu);
if (menuData.maxVisibleItems && typeof menuData.maxVisibleItems === 'number') {
const wrap = menu.querySelector('.menu-items');
if (wrap) {
if (!menuData._maxVisibleHeight) {
requestAnimationFrame(() => {
const items = wrap.querySelectorAll('.menu-item, .grid-item');
const N = menuData.maxVisibleItems;
if (items.length > N) {
let total = 0;
for (let i = 0; i < N; i++) {
const el = items[i];
const h = el.getBoundingClientRect().height;
const s = getComputedStyle(el);
total += h + parseFloat(s.marginTop) + parseFloat(s.marginBottom);
}
menuData._maxVisibleHeight = total;
wrap.style.height = `${total}px`;