diff --git a/kits/ActionEditorModal.js b/kits/ActionEditorModal.js new file mode 100644 index 0000000..e69de29 diff --git a/kits/ActionModules.js b/kits/ActionModules.js new file mode 100644 index 0000000..b633cd2 --- /dev/null +++ b/kits/ActionModules.js @@ -0,0 +1,586 @@ +function newObject(type) { + createCheckpoint({ + recacheFolders: true + }); + if (type == 1) { + let additionalData = { + channel: { + type: 'id', + value: '' + } + }; + + let highlightedGroupType = 'event' + if (botData.commands[lastObj].type == 'action') { + highlightedGroupType = botData.commands[lastObj].trigger + } + + if (highlightedGroupType == 'slashCommand') { + additionalData = { + channel: { + type: "commandInteraction", + value: "" + } + } + } else if (highlightedGroupType != 'event') { + } + customIDsCalculated++ + let newAct = { + name: "Send Message", + file: "sendmessage.js", + data: { + "name": "Send Message", + "messageContent": "Hello World!", + "actionRows": [], + "embeds": [], + channel: { + type: "command", + value: "" + }, + replyToInteraction: true, + storeAs: { + value: "", + type: "temporary" + } + }, + id: customIDsCalculated + new Date().getTime() + }; + + botData.commands[lastObj].actions.splice(((lastAct != undefined) ? Number(lastAct) : 0) + 1, 0, newAct) + botData.commands[lastObj].actions.filter( + (e) => e != undefined || e != null, + ); + lastAct = botData.commands[lastObj].actions.length; + saveLocally(); + refreshActions(true); + document.getElementById(`${lastObj}Groupcount`).innerHTML = lastAct; + + if (editorSettings.editActionsOnCreation) { + highlight(document.getElementById(`Action${botData.commands[lastObj].actions.length - 1}`)).then(() => { + editAction({ picker: true }); + }) + } + } else { + let type = "action"; + let trigger; + let extra = {}; + if (selectedGroupType == "command") { + trigger = "textCommand"; + switch (settings.defaultCommandType) { + case 'Slash': + trigger = 'slashCommand'; + break + + case 'Message': + trigger = 'messageContent' + break + + case 'Message Command': + trigger = 'message' + break + + case 'User Command': + trigger = 'user' + break + } + extra = { boundary: { worksIn: "guild", limits: [] }, parameters: [], description: "No Description" }; + } + if (selectedGroupType == "event") { + extra = { eventFile: "message_create.js", eventData: ["", ""] }; + + type = "event"; + trigger = "event"; + } + + let newGroup = { + name: "", + type: type, + trigger, + actions: [], + customId: new Date().getTime(), + ...extra, + folder: [lastFolder] + }; + + // if (lastFolder && !cachedFolders[lastFolder].closed) { + // botData.commands.splice(cachedFolders[lastFolder].last + 1, 0, newGroup); + // } else { + // botData.commands.splice(Number(lastObj || cachedFolders[lastFolder]?.last || botData.commands.length) + 1, 0, newGroup); + // newGroup.folder = null; + // } + botData.commands.push(newGroup) + + const folderUsed = lastFolder; + + lastObj = botData.commands.length; + saveLocally(); + recacheFolders(); + refreshGroups(true); + + + setTimeout(async () => { + await highlight(document.getElementById(`Group${folderUsed ? cachedFolders[folderUsed].last : botData.commands.length - 1}`)); + }, 10); + } + checkSaveStatus() +} + +async function deleteFolder(folderID) { + let keepGoing = false; + if (editorSettings.commandDeletionScreening) { + try { + keepGoing = await awaitIPCResponse({ channel: "deleteScreening", content: getString(strings.editor.folder_deletion_confirmation, [cachedFolders[lastFolder].name]) }, 'deletionModalInteraction'); + if (!keepGoing) return; + } catch (error) { + keepGoing = true; + } + } + + createCheckpoint({ recacheFolders: true }); + delete botData.folders[folderID]; + + await recacheFolders(); await refreshGroups(); + + setTimeout(() => { + highlight(document.getElementById('Group0')); + }, 100); +} + +function duplicateGroup(index) { + createCheckpoint(); + botData.commands.splice(parseFloat(index) + 1, 0, JSON.parse(JSON.stringify(botData.commands[index]))) + + botData.commands[parseFloat(index) + 1].customId = new Date().getTime() + saveLocally(); + + recacheFolders(); + refreshGroups(); +} + +async function deleteCommand(index) { + if (editorSettings.commandDeletionScreening) { + let keepGoing = await awaitIPCResponse({ channel: "deleteScreening", content: getString(botData.commands[index].type == 'action' ? strings.editor.command_deletion_confirmation : strings.editor.event_deletion_confirmation, [botData.commands[index].name]) }, 'deletionModalInteraction'); + if (!keepGoing) return; + } + await new Promise(res => { + document.getElementById(`Group${index}`).style.transition = `all 0.${editorSettings.fastAnimation}s ease` + + document.getElementById(`Group${index}`).style.opacity = '0' + document.getElementById(`Group${index}`).style.height = '0' + document.getElementById(`Group${index}`).style.paddingTop = '0' + document.getElementById(`Group${index}`).style.paddingBottom = '0' + document.getElementById(`Group${index}`).style.marginTop = '0' + document.getElementById(`Group${index}`).style.marginBottom = '0' + + setTimeout(() => { + res() + }, editorSettings.fastAnimation * 100); + }) + + try { + createCheckpoint(); + botData.commands.splice(index, 1); + saveLocally(); + recacheFolders(); + refreshGroups(); + } catch (err) { console.error(err) } + + if (selectedGroupType == 'slash') { + setHighlightedGroup(2) + } else if (selectedGroupType == 'text') { + setHighlightedGroup(1) + } else if (selectedGroupType == 'event') { + setHighlightedGroup(3) + } + document.getElementById('actionbar').innerHTML = '' + + refreshGroups(); +} + +async function deleteAction(index) { + if (editorSettings.actionDeletionScreening) { + let keepGoing = await awaitIPCResponse({ channel: "deleteScreening", content: `Are you sure you want to delete ${botData.commands[lastObj].actions[index].name}?` }, 'deletionModalInteraction'); + if (!keepGoing) return; + } + + + await new Promise(res => { + document.getElementById(`Action${index}`).style.transition = `all 0.${editorSettings.fastAnimation}s ease` + + document.getElementById(`Action${index}`).style.opacity = '0' + document.getElementById(`Action${index}`).style.height = '0' + document.getElementById(`Action${index}`).style.paddingTop = '0' + document.getElementById(`Action${index}`).style.paddingBottom = '0' + document.getElementById(`Action${index}`).style.marginTop = '0' + document.getElementById(`Action${index}`).style.marginBottom = '0' + + setTimeout(() => { + res() + }, editorSettings.fastAnimation * 100); + }) + createCheckpoint() + let deserializedAction = botData.commands[lastObj].actions[index]; + botData.commands[lastObj].actions.splice(index, 1); + saveLocally(); + refreshActions(); + document.getElementById(`${lastObj}Groupcount`).innerHTML = botData.commands[lastObj].actions.length; +} + +let timing; + +var draggedGroup; +var draggedOverGroup; +var draggedOverFolder; +var lastDraggedOverFolder; +var stillOverFolder = {} +var stillOver = false; +var lastDraggedOverThing; +var draggedFolder; + +function handleFolderDragStart(folder) { + timing = new Date().getTime(); + draggedFolder = folder; +} + +function handleFolderDragEnd() { + if (new Date().getTime() - timing < 100) return; + createCheckpoint({ recacheFolders: true }); + let folder = cachedFolders[draggedFolder]; + + let transferredGroups = 0; + + let newPosition = parseFloat(draggedOverGroup); + let toTransfer; + + if (folder.last == folder.first) { + toTransfer = 1; + } else { + toTransfer = Number(folder.last + 1) - folder.first + } + + let folderArray = [draggedFolder]; + + if (draggedOverFolder) { + folderArray = [draggedOverFolder, ...folderArray]; + } + + while (transferredGroups < toTransfer) { + botData.commands[folder.first].folder = folderArray; + transferredGroups++ + + botData.commands = moveArrayElement(botData.commands, folder.first, newPosition); + + if (newPosition < folder.first) { + newPosition++ + folder.first = folder.first + 1; + } + } + + recacheFolders(); + saveLocally(); + + refreshGroups(); + + draggedFolder = undefined; +} + +function handleGroupDrag(group) { + timing = new Date().getTime(); + draggedGroup = group.id.split("Group")[1]; +} +function groupDragOverHandle(event, group) { + group.classList.add("goofyhovereffectlite"); + /* + placeholderGroup = document.createElement('div') + placeholderGroup.style.animationName = 'fade' + placeholderGroup.style.marginTop = '41px' + placeholderGroup.style.marginBottom = '-35px' + */ + + event.preventDefault(); + draggedOverGroup = group.id.split("Group")[1]; + group.style.animationName = ""; + group.style.animationDuration = ""; + group.style.animationDelay = ""; + lastDraggedOverThing = 1; +} + +function handleGroupDragEnd(group) { + group.classList.remove("goofyhovereffectlite"); +} + +function handleGroupDrop(group) { + createCheckpoint({ recacheFolders: true }); + refreshGroups(); + if (new Date().getTime() - timing < 100) return; + let oldPosition = parseFloat(draggedGroup); + let newPosition = parseFloat(draggedOverGroup); + let newFolder = null; + + if (draggedOverGroup && draggedOverFolder) { + botData.commands[oldPosition].folder = botData.commands[newPosition].folder; + } else { + botData.commands[oldPosition].folder = null; + } + + lastObj = newPosition; + botData.commands = moveArrayElement( + botData.commands, + oldPosition, + newPosition, + ); + + saveLocally(); + recacheFolders(); + refreshGroups(); + checkSaveStatus(); + + draggedOverFolder = undefined; + lastDraggedOverFolder = undefined; + stillOver = false; +} + +var draggedAction; +var draggedOverAction; +function handleActionDrag(action) { + timing = new Date().getTime(); + draggedAction = action.id.split("Action")[1]; +} +function actionDragOverHandle(event, action) { + action.classList.add("flash"); + action.style.animationName = ""; + action.style.animationDuration = ""; + action.style.animationDuration = '0.6s'; + action.style.animationDelay = ""; + event.preventDefault(); + draggedOverAction = action.id.split("Action")[1]; +} +function handleActionDragEnd(action) { + action.classList.remove("flash"); +} +function moveArrayElement(arr, old_index, new_index) { + const element = arr[old_index]; + arr.splice(old_index, 1); + arr.splice(new_index, 0, element); + + return arr; +} +function handleActionDrop(action) { + refreshActions(); + createCheckpoint(); + if (new Date().getTime() - timing < 100) return; + + let oldPosition = parseFloat(draggedAction); + let newPosition = parseFloat(draggedOverAction); + lastType = 1; + + botData.commands[lastObj].actions = moveArrayElement( + botData.commands[lastObj].actions, + oldPosition, + newPosition, + ); + saveLocally(); + refreshActions(); + checkSaveStatus() +} + +refreshGroups() + +function setHighlightedGroup(type) { + let oldGroupType; + let trigger = 'action' + if (selectedGroupType == "command") { + oldGroupType = 1; + } + if (selectedGroupType == "event") { + oldGroupType = 3; + } + + if (type == 1 || type == 2) { + selectedGroupType = "command"; + prioritizeCommandOptions(); + document.getElementById('types-EVENTS').style.background = '' + document.getElementById('types-COMMANDS').style.background = 'var(--accent)' + } + + if (type == 3) { + trigger = 'event' + prioritizeEvents(); + selectedGroupType = "event"; + document.getElementById('types-COMMANDS').style.background = '' + document.getElementById('types-EVENTS').style.background = 'var(--accent)' + } + + refreshGroups(); +} + +if (!Array.isArray(botData.commands)) { + transferProject(); + + location.reload(); +} +function transferProject() { + botData.commands = Object.values(botData.commands); + saveLocally(); + for (let command in botData.commands) { + botData.commands[command].actions = Object.values( + botData.commands[command].actions, + ); + console.log(botData.commands[command].actions); + saveLocally(); + for (let action of botData.commands[command].actions) { + try { + let actionBase = require(`${processPath}/AppData/Actions/${action.file}`); + for (let UIelement in actionBase.UI) { + if (UIelement.startsWith("actions")) { + action.data[actionBase.UI[UIelement]] = Object.values( + action.data[actionBase.UI[UIelement]], + ); + saveLocally(); + } + } + } catch (err) { } + } + } +} + +function storeCaretPosition(element) { + let selection = window.getSelection(); + if (selection.rangeCount > 0) { + let range = selection.getRangeAt(0); + let preSelectionRange = range.cloneRange(); + preSelectionRange.selectNodeContents(element); + preSelectionRange.setEnd(range.startContainer, range.startOffset); + let caretOffset = preSelectionRange.toString().length; + + element.dataset.caretOffset = caretOffset; + } +} + +function restoreCaretPosition(element) { + let caretOffset = parseInt(element.dataset.caretOffset) || 0; + let textNode = element.firstChild; + + if (textNode && textNode.nodeType === Node.TEXT_NODE) { + let range = document.createRange(); + range.setStart(textNode, Math.min(caretOffset, textNode.length)); + range.setEnd(textNode, Math.min(caretOffset, textNode.length)); + + let selection = window.getSelection(); + selection.removeAllRanges(); + selection.addRange(range); + } +} + +function validateInputSpaces(div) { + storeCaretPosition(div); + + var sanitizedText = div.innerText.replaceAll('\n', '') + + sanitizedText = sanitizedText.substr(0, 32); + + div.innerHTML = sanitizedText; + restoreCaretPosition(div); +} + +let isTypeManagerOpen = false; +function dropTypes() { + if (isTypeManagerOpen) { + return + } + var element = document.getElementById('edutor'); + element.scrollTop = element.scrollHeight; + + isTypeManagerOpen = true; + let typeManager = document.getElementById('typeOfGroup'); + // typeManager.classList.remove('hoverable') + let types = { + messageContent: "Message Content", + textCommand: "Text Command", + slashCommand: "Slash Command", + message: "Message Command", + user: "User Command" + } + let commandType = botData.commands[lastObj].trigger + typeManager.onclick = () => { + isTypeManagerOpen = false; + + typeManager.onclick = () => { + dropTypes(); + } + + const innerHeight = typeManager.clientHeight; + typeManager.style.animationDuration = ""; + typeManager.style.setProperty("--inner-height", innerHeight + "px"); + typeManager.style.animationName = "shrink"; + typeManager.style.animationDuration = "200ms"; + setTimeout(() => { + typeManager.innerHTML = `${types[botData.commands[lastObj].trigger]}` + // typeManager.classList.add('hoverable') + setTimeout(() => { + typeManager.style.animationName = 'unset' + typeManager.style.height = '' + + highlight(document.getElementById(`Group${lastObj}`)) + saveLocally(); + }, 80); + }, 100); + } + + for (let type in types) { + if (type != commandType) { + typeManager.innerHTML += ` + + ` + } + } +} + +function declareAsRunningInFolder(event) { + if (!lastFolder) return; + event.preventDefault() + document.getElementById('actionbar').firstElementChild.style.opacity = '0'; + document.getElementById('actionbar').firstElementChild.style.scale = '0.5'; + document.getElementById('actionbar').firstElementChild.style.filter = 'blur(12px)'; + document.getElementById('actionbar').firstElementChild.style.transition = `all var(--commonAnimation) var(--ease-strong)` + setTimeout(() => { + document.getElementById('actionbar').firstElementChild.style.display = 'none' + let element = document.createElement('btext'); + element.style.opacity = '0'; + element.style.margin = 'auto'; + element.style.scale = '1.2'; + element.style.filter = 'blur(12px)'; + element.style.transition = `all var(--commonAnimation) var(--ease-strong)` + element.innerHTML = getString(strings.editor.release_to_add_to_folder, [cachedFolders[lastFolder].name]); + document.getElementById('actionbar').appendChild(element); + + draggedOverFolder = lastFolder; + draggedOverGroup = cachedFolders[lastFolder].last + 1; + + setTimeout(() => { + element.style.scale = '1'; + element.style.opacity = '1'; + element.style.filter = 'blur(0px)'; + }, editorSettings.fastAnimation * 30); + }, editorSettings.commonAnimation * 100); +} + +function declareAsNotRunningInFolder(event) { + if (!lastFolder) return; + event.preventDefault(); + document.getElementById('actionbar').firstElementChild.nextElementSibling.style.scale = '1.2'; + document.getElementById('actionbar').firstElementChild.nextElementSibling.style.opacity = '0'; + document.getElementById('actionbar').firstElementChild.nextElementSibling.style.filter = 'blur(12px)'; + + setTimeout(() => { + document.getElementById('actionbar').firstElementChild.style.display = ''; + setTimeout(() => { + document.getElementById('actionbar').firstElementChild.nextElementSibling.remove(); + document.getElementById('actionbar').firstElementChild.style.opacity = '' + document.getElementById('actionbar').firstElementChild.style.scale = ''; + document.getElementById('actionbar').firstElementChild.style.filter = ''; + }, editorSettings.fastAnimation * 30); + }, editorSettings.commonAnimation * 100); + + draggedOverFolder = undefined; +} \ No newline at end of file diff --git a/kits/EditorBones.js b/kits/EditorBones.js new file mode 100644 index 0000000..07263d7 --- /dev/null +++ b/kits/EditorBones.js @@ -0,0 +1,1909 @@ + +let version = `4.22.0 SNAP 1 BETA`; +const strings = getStrings(); +let loadedAutomations = []; + + +const { app, ipcRenderer } = require("electron"); +let selectedGroupType = "slash"; +let copiedAction; +let isBotOn; +let lastFolder; +let globalVars = {}; +let selectedActions = []; +let serverVars = {}; +const fs = require("fs"); +setInterval(() => { + checkSaveStatus(); +}, 5000); + +const steamworks = require('steamworks.js'); + +let client; +try { + client = steamworks.init(appID); + // console.log('making') + // client.workshop.createItem(appID).then(e => { + // client.workshop.updateItem(e.itemId, { + // changeNote: "Create this", + // title: "Test Thing Yk", + // contentPath: "./Workshop_Items/Command" + // }).then(e => { + // console.log(e); + // client.workshop.getItem(e.itemId).then(aaaaaaaaaa => { + // console.log(aaaaaaaaaa) + // }) + // }) + // }).catch(err => console.log(err)); +} catch (error) { + console.log(error) + setTimeout(() => { + // notify('Unable to connect to steam, achievements & steam cloud will be unavailable') + }, 1000); +} + +ipcRenderer.on('backupClose', () => { + document.body.style.opacity = 1; +}); + +let cachedActions = {}; + +fs.readdirSync(`${processPath}/AppData/Actions`).forEach(act => { + try { + cachedActions[act] = require(`${processPath}/AppData/Actions/${act}`); + } catch (e) { } +}); + + + +ipcRenderer.on("botWindowStatus", (event, botOn) => { + if (botOn == false || botOn == true) { + isBotOn = true; + document.getElementById("botStatus").innerHTML = strings.editor.bot_states_short[1]; + document.getElementById("turnBotOn").innerHTML = strings.editor.bot_states[0]; + } else { + isBotOn = false; + document.getElementById("botStatus").innerHTML = strings.editor.bot_states_short[0]; + document.getElementById("turnBotOn").innerHTML = strings.editor.bot_states[1]; + } +}); + +ipcRenderer.on('aliases', (event, newAliases) => { + createCheckpoint(); + botData.commands[lastObj].aliases = newAliases; + saveLocally(); +}) + +ipcRenderer.on("eventSave", (event, eventData) => { + createCheckpoint(); + botData.commands[lastObj].eventFile = eventData.file; + botData.commands[lastObj].eventData = eventData.data; + highlight(document.getElementById(`Group${lastObj}`)); + checkSaveStatus(); +}); + +function toggleBotStatus() { + if (!isBotOn) { + ipcRenderer.send("runBot"); + } else { + ipcRenderer.send("shutdownBot"); + } +} + +function editAction(options) { + createCheckpoint(); + checkSaveStatus(); + + let commandVars = []; + + let variables = { temporary: [] }; + let actionType = "text"; + if (botData.commands[lastObj].type == "event") { + actionType = "event"; + try { + let event = require(processPath + + "/AppData/Events/" + + botData.commands[lastObj].eventFile); + for (let eventVariableStorageName in event.nameSchemes) { + if ( + event.preventStorage && + event.preventStorage.includes( + event.nameSchemes[eventVariableStorageName] + ) + ) { + } else { + commandVars.push( + botData.commands[lastObj].eventData[eventVariableStorageName] + ); + } + } + } catch (err) { } + } else { + if (botData.commands[lastObj].trigger == "slashCommand") { + actionType = "slash"; + if (botData.commands[lastObj].parameters) { + for (let parameterI in botData.commands[lastObj].parameters) { + let parameter = botData.commands[lastObj].parameters[parameterI]; + commandVars.push(parameter.storeAs); + } + } + } else if (botData.commands[lastObj].trigger == 'user') { + actionType = "user"; + } else if (botData.commands[lastObj].trigger == 'message') { + actionType = "message"; + } + } + + let endGlobal = []; + let endServer = []; + let thisGlobal = []; + let thisServer = []; + + for (let cmd in globalVars) { + endGlobal = globalVars[cmd] || []; + } + + for (let cmd in serverVars) { + endServer = serverVars[cmd] || []; + } + + variables.global = endGlobal; + variables.server = endServer; + + for (let action in botData.commands[lastObj].actions) { + let act = botData.commands[lastObj].actions[action]; + + if (action != lastAct) { + try { + let result = scrapeVars(cachedActions[act.file].UI, act.data); + commandVars = [...commandVars, ...result.temporary]; + variables.global = [...variables.global, ...endGlobal, ...result.global]; + variables.server = [...variables.server, ...endServer, ...result.server]; + } catch (error) { console.log(error) } + } else { + try { + let result = scrapeVars(cachedActions[act.file].UI, act.data); + variables.temporary = result.temporary; + thisGlobal = [...thisGlobal, ...result.global]; + thisServer = [...thisServer, ...result.server]; + } catch (error) { console.log(error) } + } + } + + variables.commandVars = commandVars; + variables.thisServer = thisServer; + variables.thisGlobal = thisGlobal; + + ipcRenderer.send("editAction", { + action: lastAct, + actions: botData.commands[lastObj].actions, + variables: variables, + actionType: actionType, + options: (options || { picker: false }) + }); +} + +ipcRenderer.on("childSave", (event, data, copied) => { + createCheckpoint() + + botData.commands[lastObj].actions[lastAct] = data; + saveLocally(); + refreshActions(); + copiedAction = copied; + + globalVars[botData.commands[lastObj].customId] = []; + serverVars[botData.commands[lastObj].customId] = []; + + for (let act in botData.commands[lastObj].actions) { + let action = botData.commands[lastObj].actions[act]; + try { + let UI = cachedActions[action.file].UI; + scrapeForVariables(UI, action.data, botData.commands[lastObj].customId); + } catch (err) { } + } + checkSaveStatus(); +}); + +function openParameters() { + if (!botData.commands[lastObj].description) { + botData.commands[lastObj].description = "No Description"; + } + ipcRenderer.send("editParameters", { + parameters: botData.commands[lastObj].parameters || [], + name: botData.commands[lastObj].name, + description: botData.commands[lastObj].description, + }); +} + +ipcRenderer.on("parametersSave", (event, data) => { + createCheckpoint(); + botData.commands[lastObj].parameters = data.parameters; + saveLocally(); + checkSaveStatus(); + highlight(document.getElementById(`Group${lastObj}`)); +}); + +ipcRenderer.on("childClose", () => { + document.body.style.opacity = "100%"; +}); + +let lastHovered; +let menu = null; +let errorPending = false; +var botData = JSON.parse(fs.readFileSync("./AppData/data.json", 'utf8')); +let lastType = 0; // 0 = Command; 1 = Actions; +let lastObj = 0; +let lastAct = 0; +let lastHighlighted; +let themeColor = botData.color; +if (ownSettings.theme == 'default') { + document.body.style.background = `linear-gradient(130deg, ${ownSettings.firstColor || `rgb(0, 0, 0)`}, ${ownSettings.secondColor || `rgb(18, 18, 18)`})`; +} else { + document.body.style.background = `var(--main-background)`; +} +document.onkeydown = function (event) { + handleKeybind(event); +}; +if (editorSettings.focus) { + if (botData.colorsVisibility) { + toggleColorsVisibility() + } +} +document.documentElement.style.setProperty("--highlight-color", botData.color); +let customIDsCalculated = 0; +let alreadyUsedIDs = {}; +let scrapeForVariables = (UI, data, cID) => { + for (let i in UI) { + try { + let element = UI[i]; + if (typeof element != "string") { + if ( + element.element == "storageInput" || + element.element == "storage" || + element.element == "store" + ) { + if (data[element.storeAs].type == "global") { + if (!globalVars[cID]) { + globalVars[cID] = []; + } + globalVars[cID].push(data[element.storeAs].value); + } else if (data[element.storeAs].type == "server") { + if (!serverVars[cID]) { + serverVars[cID] = []; + } + + serverVars[cID].push(data[element.storeAs].value); + } + } + if (element.element == "menu") { + for (let menu in data[element.storeAs]) { + let elm = data[element.storeAs][data[element.storeAs][menu].type]; + scrapeForVariables( + element.UItypes[data[element.storeAs][menu].type].UI, + data[element.storeAs][menu].data, + cID + ); + } + } + + if (element.element == "case" || element.element == "condition") { + if (data[element.storeAs].type == "runActions") { + for (let i in data[element.storeActionsAs]) { + let action = data[element.storeActionsAs][i]; + if (!action.id || alreadyUsedIDs[action.id]) { + action.id = new Date().getTime() + customIDsCalculated; + customIDsCalculated++ + } + alreadyUsedIDs[action.id] = true; + try { + let act = cachedActions[action.file]; + scrapeForVariables(act.UI, action.data, cID); + } catch (err) { } + } + } + } + + if (element.element == "actions") { + for (let i in data[element.storeAs]) { + let action = data[element.storeAs][i]; + if (!action.id || alreadyUsedIDs[action.id]) { + action.id = new Date().getTime() + customIDsCalculated; + customIDsCalculated++ + } + alreadyUsedIDs[action.id] = true; + try { + let act = cachedActions[action.file]; + scrapeForVariables(act.UI, action.data, cID); + } catch (err) { } + } + } + } + } catch (err) { + } + } +}; + + +let scrapeVars = (UI, data) => { + let toReturn = { + temporary: [], + server: [], + global: [] + }; + for (let i in UI) { + try { + let element = UI[i]; + if (typeof element != "string") { + if ( + element.element == "storageInput" || + element.element == "storage" || + element.element == "store" + ) { + if (data[element.storeAs].type == "temporary") { + toReturn.temporary = [...toReturn.temporary, data[element.storeAs].value]; + } + if (data[element.storeAs].type == "server") { + toReturn.server = [...toReturn.server, data[element.storeAs].value]; + } + if (data[element.storeAs].type == "global") { + toReturn.global = [...toReturn.global, data[element.storeAs].value]; + } + } + if (element.element == "menu") { + for (let menu in data[element.storeAs]) { + let result = scrapeVars(element.UItypes[data[element.storeAs][menu].type].UI, data[element.storeAs][menu].data); + toReturn.temporary = [...toReturn.temporary, ...result.temporary]; + toReturn.server = [...toReturn.server, ...result.server]; + toReturn.global = [...toReturn.global, ...result.global]; + } + } + + if (element.element == "case" || element.element == "condition") { + if (data[element.storeAs].type == "runActions") { + for (let i in data[element.storeActionsAs]) { + let action = data[element.storeActionsAs][i]; + try { + let act = cachedActions[action.file]; + let result = scrapeVars(act.UI, action.data); + toReturn.temporary = [...toReturn.temporary, ...result.temporary]; + toReturn.server = [...toReturn.server, ...result.server]; + toReturn.global = [...toReturn.global, ...result.global]; + } catch (err) { console.log(err) } + } + } + } + + if (element.element == "actions") { + for (let i in data[element.storeAs]) { + let action = data[element.storeAs][i]; + try { + let act = cachedActions[action.file]; + let result = scrapeVars(act.UI, action.data); + toReturn.temporary = [...toReturn.temporary, ...result.temporary]; + toReturn.server = [...toReturn.server, ...result.server]; + toReturn.global = [...toReturn.global, ...result.global]; + } catch (err) { console.log(err) } + } + } + } + } catch (err) { + } + } + return toReturn +}; + +for (let cmd in botData.commands) { + let command = botData.commands[cmd]; + for (let i in command.actions) { + let action = command.actions[i]; + if (!action.id || alreadyUsedIDs[action.id]) { + action.id = new Date().getTime() + customIDsCalculated; + customIDsCalculated++ + } + alreadyUsedIDs[action.id] = true; + + try { + let act = cachedActions[action.file]; + scrapeForVariables(act.UI, action.data, command.customId); + } catch (err) { } + } +} + + +let clicks = 0; +try { + clicks = settingsFS.readFileSync('./clicks', 'utf8'); +} catch (error) { } + +try { + setInterval(() => { + if (new Date().getHours() == 0) { + client.achievement.activate('MIDNIGHT') + } + if (botData.commands.length > 40) { + client.achievement.activate('ON_FIRE') + } + }, 60000); +} catch (error) { } +document.addEventListener('mousedown', () => { + clicks = Number(clicks); + if (clicks > 1250) { + client.achievement.activate('MADMAN') + } + if (clicks > 7500) { + client.achievement.activate('GRASS') + } + if (clicks > 20000) { + client.achievement.activate('TIMELESS') + } + + clicks++ + + settingsFS.writeFileSync('./clicks', clicks.toString()) +}); + + +saveLocally() + +function refreshActions(fadeLast, dontUpdate, commandOverwrite) { + const toReplaceWith = lastObj; + lastObj = commandOverwrite || lastObj; + + if (!dontUpdate) { + selectedActions = []; + document.getElementById("actionbar").innerHTML = ""; + } + botData.commands[lastObj].actions = botData.commands[lastObj].actions.filter( + (action) => action != null + ); + saveLocally(); + + let endHTML = ""; + let endActions = []; + + for (let a in botData.commands[lastObj].actions) { + let action = botData.commands[lastObj].actions[a]; + let actionData; + let endAction = { + subtitle: "", + found: false, + file: action.file, + borderType: "bordercentere", + }; + try { + actionData = cachedActions[action.file]; + } catch (err) { } + + // if (botData.commands[lastObj].actions[parseFloat(a) - 1] == undefined) { + // endAction.borderType = "borderbottom"; + // } else if (botData.commands[lastObj].actions[parseFloat(a) + 1] == undefined) { + // endAction.borderType = "bordertop"; + // } + + if (actionData) { + endAction.found = true; + endAction.name = action.name; + try { + if (actionData.subtitle) { + if (typeof actionData.subtitle == "function") { + endAction.subtitle = actionData.subtitle(action.data, { + user: (user) => { + let translations = { + author: "Command Author", + mentioned: "Mentioned User", + user: "Command User", + messageAuthor: "Message Author", + + id: "ID", + + tempVar: "Temporary Variable", + serverVar: "Server Variable", + globVar: "Global Variable", + }; + + let disabledInputTypes = ["mentioned", "author", "user", "messageAuthor"]; + if (!disabledInputTypes.includes(user.type)) { + return `${translations[user.type]} (${user.value || "Blank" + })`; + } else { + return `${translations[user.type]}`; + } + }, + channel: (channel) => { + let translations = { + id: "Channel ID", + userID: "User ID", + command: "Command Channel", + user: "Command User", + commandAuthor: "Command Author", + mentionedChannel: "Mentioned Channel", + mentionedUser: "Mentioned User", + + tempVar: "Temporary Variable", + serverVar: "Server Variable", + globVar: "Global Variable", + }; + + let disabledInputTypes = [ + "command", + "commandAuthor", + "mentionedUser", + "mentionedChannel", + "user" + ]; + if (!disabledInputTypes.includes(channel.type)) { + return `${translations[channel.type]} (${channel.value || "Blank" + })`; + } else { + return `${translations[channel.type]}`; + } + }, + role: (role) => { + let translations = { + id: "ID", + mentioned: "Mentioned Role", + tempVar: "Temporary Variable", + serverVar: "Server Variable", + globVar: "Global Variable", + }; + + let disabledInputTypes = ["mentioned"]; + if (!disabledInputTypes.includes(role.type)) { + return `${translations[role.type]} (${role.value || "Blank" + })`; + } else { + return `${translations[role.type]}`; + } + }, + guild: (guild) => { + let translations = { + current: "Current", + id: "ID", + tempVar: "Temporary Variable", + serverVar: "Server Variable", + globVar: "Global Variable", + }; + + let disabledInputTypes = ["current"]; + if (!disabledInputTypes.includes(guild.type)) { + return `${translations[guild.type]} (${guild.value || "Blank"})`; + } else { + return `${translations[guild.type]}`; + } + }, + message: (message) => { + let translations = { + commandMessage: "Command Message", + interactionReply: "Command Reply", + tempVar: "Temporary Variable", + serverVar: "Server Variable", + globVar: "Global Variable", + }; + + let disabledInputTypes = ["commandMessage", "interactionReply"]; + if (!disabledInputTypes.includes(message.type)) { + return `${translations[message.type]} (${message.value || "Blank" + })`; + } else { + return `${translations[message.type]}`; + } + }, + interaction: (interaction) => { + let translations = { + commandInteraction: "Command Interaction", + tempVar: "Temporary Variable", + serverVar: "Server Variable", + globVar: "Global Variable", + }; + + let disabledInputTypes = ["commandInteraction"]; + if (!disabledInputTypes.includes(interaction.type)) { + return `${translations[interaction.type]} (${interaction.value || "Blank" + })`; + } else { + return `${translations[interaction.type]}`; + } + }, + image: (image) => { + let translations = { + file: "File", + url: "URL", + tempVar: "Temporary Variable", + serverVar: "Server Variable", + globVar: "Global Variable", + }; + + let disabledInputTypes = []; + if (!disabledInputTypes.includes(image.type)) { + return `${translations[image.type]} (${image.value || "Blank" + })`; + } else { + return `${translations[image.type]}`; + } + }, + variable: (variables) => { + let translations = { + tempVar: "Temporary Variable", + serverVar: "Server Variable", + globVar: "Global Variable", + temporary: "Temporary Variable", + server: "Server Variable", + global: "Global Variable", + }; + return `${translations[variables.type]} (${variables.value || "Blank" + })`; + }, + }, actionData); + } else { + let actionSubtitle = actionData.subtitle; + const subtitleRegex = /(\$\[.*?\]\$)/g; + endAction.subtitle = actionSubtitle.replace( + subtitleRegex, + (match, key) => { + let dataName = key + .split("$[")[1] + .split("]$")[0] + .replaceAll("*", ""); + return action.data[dataName]; + } + ); + } + } + } catch (err) { } + } else { + endAction.name = action.name; + } + + endAction.subtitle = endAction.subtitle?.replaceAll("<", "<​"); + + endActions.push(endAction); + } + + let leftSeparatorDisplay, rightSeparatorDisplay, subtitlePosition; + + switch (editorSettings.subtitlePosition) { + case "left": + leftSeparatorDisplay = "none"; + rightSeparatorDisplay = "inherit; margin-left: 5px !important;"; + subtitlePosition = "margin-left: 5px !important; margin-right: auto;"; + break; + case "right": + rightSeparatorDisplay = "none"; + leftSeparatorDisplay = + "inherit; margin-right: 5px !important; margin-left: 10px !important;"; + subtitlePosition = "margin-right: 0; margin-left: auto;"; + deleteButtonStyling = "margin-left: 5px;"; + break; + case "center": + rightSeparatorDisplay = "inherit"; + leftSeparatorDisplay = "inherit; margin-left: 5px !important;"; + subtitlePosition = "margin-right: 5px; margin-left: 5px;"; + break; + } + + if (editorSettings.focus) { + rightSeparatorDisplay = 'none' + leftSeparatorDisplay = 'none' + } + + for (let index in endActions) { + let action = endActions[index]; + let errors = ""; + + if (action.found == false) { + errors = ` +
Action Not Found!
+ `; + } + endHTML += ` +
+ + ${editorSettings.focus ? "" : "#"}${parseFloat(index) + 1} +
${action.name.substring(0, 256)}
+ ${errors} +
+
+
+
${action.subtitle.replaceAll("", "​")}
+
+
+
+ +
+
+ `; + } + + if (!dontUpdate) { + document.getElementById("actionbar").innerHTML = endHTML; + + highlight(document.getElementById(`Action${lastAct}`)); + } else { + return endHTML; + } + lastObj = toReplaceWith; +} + +function hideAliases() { + let aliasBox = document.getElementById('Command_Name').nextElementSibling; + let commandNameBox = document.getElementById('Command_Name'); + commandNameBox.classList.remove('rounded_less_right') + + commandNameBox.style.marginRight = '' + commandNameBox.style.width = '100%' + aliasBox.style.display = 'none' +} + +function showAliases() { + let aliasBox = document.getElementById('Command_Name').nextElementSibling; + let commandNameBox = document.getElementById('Command_Name'); + + commandNameBox.classList.add('rounded_less_right') + + commandNameBox.style.width = 'var(--alias-shown-input-width)' + commandNameBox.style.marginRight = '0px' + + aliasBox.style.width = '35px' + aliasBox.style.display = '' +} + +let undoList = []; + +let redoList = []; + +function createCheckpoint(options) { + const newUndoStuff = { + JSON: JSON.stringify(botData.commands), + folders: JSON.stringify(botData.folders), + createdAt: Date.now(), + }; + + if (newUndoStuff.JSON == undoList[0]?.JSON) return + + undoList.unshift(newUndoStuff); + redoList = []; + + if (undoList.length > 200) { + undoList.splice(undoList.length - 1, 2) + } +} + +function undo() { + if (areSettingsOpen) return; + let undoElement = undoList[0]; + + undoElement.JSON; + + redoList.splice(0, 0, { + JSON: JSON.stringify(botData.commands), + folders: JSON.stringify(botData.folders), + createdAt: Date.now() + }); + + botData.commands = JSON.parse(undoElement.JSON); + botData.folders = JSON.parse(undoElement.folders); + undoList.splice(0, 1); + recacheFolders(); + refreshGroups(); + saveLocally(); + checkSaveStatus(); +} + +function redo() { + if (areSettingsOpen) return; + + let redoElement = redoList[0]; + let oldJSON = JSON.stringify(botData.commands); + let oldFolders = JSON.stringify(botData.folders); + botData.commands = JSON.parse(redoElement.JSON); + botData.folders = JSON.parse(redoElement.folders); + + redoElement.JSON = oldJSON; + redoElement.folders = oldFolders; + + redoList.splice(0, 1); + undoList.splice(0, 0, redoElement); + + recacheFolders(); + refreshGroups(); + saveLocally(); + checkSaveStatus(); +} + +function newFolder() { + createCheckpoint(); + const folderID = Number(`${new Date().getTime()}`); + let newFolder = { + name: "Folder", + color: null, + }; + + botData.folders[folderID] = newFolder; + if (Array.isArray(botData.commands[lastObj].folder)) { + botData.commands[lastObj].folder.push(folderID) + } else { + botData.commands[lastObj].folder = [folderID] + } + + + saveLocally(); + recacheFolders(); + refreshGroups(); +} +let closedFolders = {}; +let cachedFolders = {}; + +function hideEditorSpecifics() { + document.getElementById("infoTile").style.height = "0px"; + document.getElementById("infoTile").style.paddingTop = "0px"; + document.getElementById("infoTile").style.paddingBottom = "0px"; + document.getElementById("infoTile").style.overflow = "hidden"; + document.getElementById("infoTile").style.marginTop = "0"; + document.getElementById('edutor').firstElementChild.classList.remove('borderbottomz') +} +function showEditorSpecifics(event) { + document.getElementById("infoTile").style.paddingTop = "0px"; + document.getElementById("infoTile").style.paddingBottom = "0px"; + document.getElementById("infoTile").style.marginTop = "4px"; + document.getElementById("infoTile").style.height = "32px"; + + document.getElementById('edutor').firstElementChild.classList.add('borderbottomz') + + if (event) { + hideTypeDropdown() + } else { + showTypeDropdown() + } +} + +function hideTypeDropdown() { + let dropdownContainer = document.getElementById('typeDropdownContainer'); + dropdownContainer.style.width = '0%' + dropdownContainer.style.display = 'none' + let inputContainer = document.getElementById('nameContainer'); + inputContainer.style.width = '100%' +} +function showTypeDropdown() { + let dropdownContainer = document.getElementById('typeDropdownContainer'); + dropdownContainer.style.width = '50%' + dropdownContainer.style.display = '' + let inputContainer = document.getElementById('nameContainer'); + inputContainer.style.width = '50%' +} + +function recacheFolders() { + if (!botData.folders) { + botData.folders = {}; + saveLocally(); + } + + cachedFolders = {}; + for (let f in botData.folders) { + let folder = botData.folders[f]; + closedFolders[f] = folder.closed + cachedFolders[f] = { + ...folder, + id: f, + last: [], + first: [] + }; + } + + let knownFoldersPlacement = {}; + + botData.commands.forEach((command, index) => { + if (!Array.isArray(command.folder) && command.folder) { + command.folder = [command.folder]; + } + + command.folder = Array.from(new Set(command.folder)) + if (command.folder?.length > 10) { + let folder = command.folder; + command.folder = [folder[0], folder[1], folder[2], folder[3], folder[4], folder[5], folder[6], folder[7], folder[8], folder[9]] + } + for (let i in command.folder) { + if (!botData.folders[command.folder[i]]) { + command.folder.splice(i, 1); + saveLocally(); + } else { + if (cachedFolders[command.folder[i]]) { + let commandFolder = command.folder[i]; + if (!knownFoldersPlacement[commandFolder]) { + knownFoldersPlacement[commandFolder] = {}; + } + + if (knownFoldersPlacement[commandFolder].first == undefined) { + knownFoldersPlacement[commandFolder].first = index; + } else { + knownFoldersPlacement[commandFolder].last = index; + } + } + } + } + }); + + for (let f in cachedFolders) { + if (knownFoldersPlacement[f] && knownFoldersPlacement[f].first != undefined) { + if (knownFoldersPlacement[f] && knownFoldersPlacement[f].last == undefined) { + knownFoldersPlacement[f].last = knownFoldersPlacement[f]?.first; + } + cachedFolders[f] = { ...cachedFolders[f], ...knownFoldersPlacement[f] }; + } else { + delete cachedFolders[f]; + delete botData.folders[f]; + saveLocally(); + } + } +} + +setTimeout(() => { + recacheFolders(); + refreshGroups(); +}, 150); + +function refreshGroups(fadeLast, dontUpdate) { + let firstOnScreen = true; + let endHTML = ""; + if (!dontUpdate) { + document.getElementById("commandbar").innerHTML = ""; + } + + let firstCompatibleGroup; + + for (let cmd in botData.commands) { + if (!firstCompatibleGroup) { + try { + let command = botData.commands[cmd]; + + if (command.type == "action" && selectedGroupType == "command") { + firstCompatibleGroup = cmd; + } else if (command.type == "event" && selectedGroupType == "event") { + firstCompatibleGroup = cmd; + } + } catch (error) { } + } + } + + let firstGroup; + var delay = 0; + + for (let cmd in botData.commands) { + try { + if (!firstCompatibleGroup) { + document.getElementById("actionbar").innerHTML = ""; + } + let groupType = botData.commands[cmd].type; + let endType; + if (groupType == "action") { + endType = "command"; + } else { + endType = "event"; + } + + if (endType == selectedGroupType) { + if (!firstGroup) { + firstGroup = cmd; + } + + let additional = ""; + let endAdditional = ""; + let folderNesting = false; + if (Array.isArray(botData.commands[cmd].folder)) { + for (let f in botData.commands[cmd].folder) { + if (cachedFolders[botData.commands[cmd].folder[f]]?.first == cmd) { + if (botData.commands[cmd].folder[f] != botData.commands[cmd].folder[0]) { + folderNesting = true; + } else { + folderNesting = false; + } + + let folder = botData.commands[cmd].folder[f]; + additional += ` +
+
+
+ ${cachedFolders[folder].name.replaceAll("<", "<​")} +
+
+
+
+ `; + marginTop = "0px"; + firstOnScreen = false; + } + + if (cachedFolders[botData.commands[cmd].folder[f]]?.last == cmd) { + endAdditional += `
`; + firstOnScreen = false; + } + } + } + + delay++; + let preDeco = ``; + + if (!editorSettings.hideCommandInvokers) { + let commandTriggerMap = { + textCommand: botData.prefix, + slashCommand: "/", + } + + preDeco = commandTriggerMap[botData.commands[cmd].trigger] || `
`; + } + + let groupDecoration = ``; + endHTML += ` + ${additional} +
+ ${preDeco} +
+ ${botData.commands[cmd].name.substring(0, 24)}${botData.commands[cmd].name.length > 23 ? "..." : ""} +
${botData.commands[cmd].actions.length} Actions ${groupDecoration}
+
+ ${endAdditional} + `; + } + } catch (error) { + botData.commands.splice(cmd, 1); + } + } + + if (!dontUpdate) { + document.getElementById("commandbar").innerHTML = endHTML; + } else { + return endHTML; + } + + let editor = document.getElementById("edutor"); + if (delay == 0) { + editor.style.scale = "0.3"; + editor.style.opacity = "0"; + setTimeout(() => { + editor.style.scale = "0"; + }, 150); + } else { + editor.style.scale = "1"; + setTimeout(() => { + editor.style.scale = "1"; + }, 150); + editor.style.opacity = "1"; + } + + if (document.getElementById(`Group${lastObj}`)) { + try { + highlight(document.getElementById(`Group${lastObj}`)); + } catch (err) { + highlight(document.getElementById(`Group${firstCompatibleGroup}`)); + } + } else { + highlight(document.getElementById(`Group${firstCompatibleGroup}`)); + } +} + +function recalculateFolderHeight(starterID, repeated) { + if (Array.isArray(botData.commands[cachedFolders[starterID].first].folder)) { + botData.commands[cachedFolders[starterID].first].folder.forEach((id) => { + if (id != starterID) return; + let folder = document.getElementById(`${id}`); + let folderContent = document.getElementById(`${id}content`); + + if (closedFolders[id]) { + let height = folderContent.clientHeight; + folderContent.style.height = height + 'px'; + folderContent.style.overflow = 'hidden'; + folderContent.classList.add('closedFolder') + + + setTimeout(() => { + folderContent.style.height = '0px' + }, 10); + } else { + let heightGuesser = document.createElement('div'); + heightGuesser.innerHTML = folderContent.innerHTML; + heightGuesser.style.opacity = '0'; + document.body.appendChild(heightGuesser); + let height = heightGuesser.clientHeight; + folderContent.classList.remove('closedFolder') + heightGuesser.remove(); + + setTimeout(() => { + folderContent.style.height = (height + 0) + 'px'; + setTimeout(() => { + folderContent.style.height = 'auto' + }, editorSettings.commonAnimation * 100); + }, 10); + } + }) + } + + setTimeout(() => { + if (repeated) return; + recalculateFolderHeight(id, true) + }, 30); +} + +function toggleFolderVisibility(id, button) { + createCheckpoint({ recacheFolders: true }); + if (!closedFolders[id]) { + botData.folders[id].closed = true; + closedFolders[id] = true; + + setTimeout(() => { + button.style.transition = 'all 0.5s cubic-bezier(.41,-0.58,.48,1.53)' + button.style.rotate = '180deg' + saveLocally(); + checkSaveStatus(); + }, 10); + } else { + botData.folders[id].closed = false; + closedFolders[id] = false; + + setTimeout(() => { + button.style.rotate = '359deg' + }, 10); + setTimeout(() => { + button.style.transition = 'all 0s ease' + setTimeout(() => { + button.style.rotate = '0deg' + setTimeout(() => { + button.style.transition = 'all 0.5s cubic-bezier(.41,-0.58,.48,1.53)' + }, 10); + }, 10); + }, 500); + + setTimeout(() => { + saveLocally(); + checkSaveStatus(); + }, editorSettings.commonAnimation * 100); + } + + recalculateFolderHeight(id); +} + +function highlightFolder(id) { + hideTypeDropdown(); + lastType = 2; + hideAliases() + hideEditorSpecifics(); + try { + document.getElementById(`Group${lastObj}`).classList.remove('highlighted') + if (botData.commands[lastObj].color != undefined) { + document.getElementById(`Group${lastObj}`).style.background = botData.commands[lastObj].color.split(")") + " 0.09)"; + } else { + document.getElementById(`Group${lastObj}`).style.background = ""; + } + } catch (err) { } + lastObj = undefined; + if (editorSettings.focus) { + document.getElementById('actionsOf').innerHTML = `` + document.getElementById('actionbar').innerHTML = '' + } else { + document.getElementById('actionsOf').innerHTML = strings.editor.folder_no_actions; + document.getElementById('actionbar').classList.add('flexbox') + document.getElementById('actionbar').innerHTML = ` +
+ ` + } + + if (lastFolder) { + document.getElementById(lastFolder).classList.remove('highlighted') + if (cachedFolders[lastFolder]?.color) { + let color = cachedFolders[lastFolder].color.split(")"); + document.getElementById(lastFolder).style.background = `${color} 0.10)`; + } else { + document.getElementById(lastFolder).style.background = ``; + } + } + + lastFolder = id; + document.getElementById(lastFolder).classList.add('highlighted') + + if (cachedFolders[id].color) { + let color = cachedFolders[lastFolder].color.split(")"); + document.getElementById(id).style.background = `${color} 0.15)`; + } else { + document.getElementById(id).style.background = `var(--accent)`; + } + + document.getElementById("Command_Description").value = botData.folders[id].description || ""; + + lastHighlightedType = 2; + + document.getElementById("groupType").innerText = strings.editor.command_name_labels.folder; + document.getElementById("Command_Name").innerText = cachedFolders[lastFolder].name; + document.getElementById('actionbar').style.background = '' + document.getElementById('actiontoolbar').style.background = '' +} + +function colorize(element, at, type) { + let color; + if (element.id.startsWith("Group")) { + if (!botData.commands[at].color) return; + color = botData.commands[at].color.split(")"); + } else { + if (!cachedFolders[at]?.color) return; + color = cachedFolders[at].color.split(")"); + } + + let intensity; + + if (element.id.startsWith("Group")) { + switch (type) { + case 1: + intensity = '0.18' + break + + case 2: + if (lastObj == at) { + intensity = '0.15' + } else { + intensity = '0.09' + } + break + + case 3: + intensity = '0.20' + break + + case 4: + if (lastObj == at) { + intensity = '0.17' + } else { + intensity = '0.9' + } + break + } + element.style.background = `${color} ${intensity})`; + } else { + switch (type) { + default: + // hover + intensity = "0.15"; + break; + + case 2: + // hover leave + if (lastFolder == at) { + intensity = "0.20"; + } else { + intensity = "0.1"; + } + break; + + case 3: + intensity = "0.25"; + break; + + case 4: + intensity = "0.10"; + break; + } + element.style.background = `${color} ${intensity})`; + } + +} + +let commandParameters = document.getElementById("commandParameters"); +let groupOptions = document.getElementById("commandOptions"); +let groupEvents = document.getElementById("groupEvents"); +function resetElements() { + groupOptions.style.width = ``; + groupOptions.style.opacity = ``; + groupOptions.style.padding = ``; + + groupEvents.style.padding = "0px"; + groupEvents.style.opacity = "0%"; + groupEvents.style.width = "0%"; + groupEvents.innerHTML = ``; + + commandParameters.style.padding = ``; + commandParameters.style.width = ``; + commandParameters.style.marginRight = ``; + commandParameters.style.opacity = ``; +} + +resetElements(); + +function prioritizeCommandOptions() { + resetElements(); + + commandParameters.style.width = `0%`; + commandParameters.style.padding = `0px`; + commandParameters.style.opacity = `0%`; + commandParameters.style.marginRight = "0px"; + + groupOptions.style.width = "calc(100% - 4px)"; + groupOptions.style.marginRight = `0px`; +} + +function prioritizeEvents() { + resetElements(); + + groupOptions.style.width = `0%`; + groupOptions.style.paddingTop = `0px`; + groupOptions.style.paddingBottom = `0px`; + groupOptions.style.opacity = `0%`; + groupOptions.style.marginRight = `0px`; + commandParameters.style.width = `0%`; + commandParameters.style.padding = `0px`; + commandParameters.style.opacity = `0%`; + commandParameters.style.marginRight = "0px"; + + groupEvents.style.padding = ""; + groupEvents.style.width = "calc(100% - 4px)"; + groupEvents.style.opacity = ""; + + try { + groupEvents.innerHTML = ` +
${getString(strings.editor.event, [require(`${processPath}/AppData/Events/${botData.commands[lastObj].eventFile}`).name])}
+
+ ` + } catch (err) { + groupEvents.innerHTML = `
${getString(strings.editor.event, [strings.editor.none])}
`; + } +} + +function returnToNormal() { + resetElements(); +} + +let lastHighlightedType = 0; // 0 = Group - 1 = Action - 2 = Folder + +let isHoldingCTRL = false; + +document.addEventListener('keydown', (key) => { + isHoldingCTRL = key.ctrlKey +}) +document.addEventListener('keyup', (key) => { + isHoldingCTRL = key.ctrlKey +}) + +async function highlight(element) { + if (lastFolder) { + showTypeDropdown() + document.getElementById('actionbar').classList.remove('flexbox'); + try { + if (cachedFolders[lastFolder].color) { + let color = cachedFolders[lastFolder].color.split(")"); + document.getElementById(lastFolder).style.background = `${color} 0.10)`; + } else { + document.getElementById(lastFolder).style.background = ""; + } + document.getElementById(lastFolder).classList.remove('highlighted'); + } catch (err) { } + lastFolder = undefined; + } + try { + if (element.id.startsWith("Group")) { + selectedActions = [] + lastType = 0; + setTimeout(() => { + lastHighlightedType = 0; + }, 1500); + + showEditorSpecifics( + botData.commands[element.id.split("Group")[1]].type == "event" + ); + try { + document.getElementById(`Group${lastObj}`).classList.remove('highlighted'); + + if (botData.commands[lastObj].color != undefined) { + document.getElementById(`Group${lastObj}`).style.background = botData.commands[lastObj].color.split(")") + " 0.09)"; + } else { + document.getElementById(`Group${lastObj}`).style.background = ""; + } + } catch (err) { } + + element.style.background = "var(--accent)"; + lastObj = element.id.split("Group")[1]; + + document.getElementById("Command_Name").innerText = botData.commands[lastObj].name; + document.getElementById("Command_Description").value = botData.commands[lastObj].description || ""; + + if (!editorSettings.focus) { + document.getElementById("actionsOf").innerHTML = getString(strings.editor.actions_of, [botData.commands[lastObj].name]); + } else { + document.getElementById("actionsOf").innerHTML = `${botData.commands[lastObj].name}`; + } + + + if (botData.commands[lastObj].color != undefined) { + element.style.background = botData.commands[lastObj].color.split(")") + " 0.15)"; + } + + refreshActions(); + let group = botData.commands[lastObj]; + + if (botData.commands[lastObj].type == "action") { + if (botData.commands[lastObj].trigger != 'slashCommand') { + prioritizeCommandOptions(); + } + + document.getElementById('requiredPermissions').innerHTML = group.boundary?.limits.length || strings.misc.none; + + switch (botData.commands[lastObj].trigger) { + case "slashCommand": + resetElements(); + hideAliases(); + document.getElementById('parameterCount').innerHTML = group.parameters?.length || strings.misc.none; + break; + case "textCommand": + showAliases(); + break; + case "messageContent": + showAliases(); + break; + case "message": + hideAliases(); + break + case "user": + hideAliases(); + break + } + } else { + prioritizeEvents(); + hideAliases(); + } + + document.getElementById("groupType").innerText = strings.editor.command_name_labels[botData.commands[lastObj].trigger]; + + if (editorSettings.groupColorAppliesToActions == 'On') { + if (!botData.commands[lastObj].color) { + document.getElementById('actionbar').style.background = '' + document.getElementById('actiontoolbar').style.background = '' + } else { + document.getElementById('actionbar').style.background = `${botData.commands[lastObj].color.split(')')} 0.10)` + document.getElementById('actiontoolbar').style.background = `${botData.commands[lastObj].color.split(')')} 0.08)` + } + } + + let typeManager = document.getElementById("typeOfGroup"); + let types = { + messageContent: "Message Content", + textCommand: "Text Command", + slashCommand: "Slash Command", + message: "Message Command", + user: "User Command" + }; + + if (isTypeManagerOpen) { + typeManager.onclick(); + } else { + typeManager.onclick = () => { + dropTypes(); + }; + } + + typeManager.innerHTML = `${types[botData.commands[lastObj].trigger] || "No Type Available"}` + + lastHighlightedType = 0; + + let r, g, b; + + let command = botData.commands[lastObj]; + document.getElementById(`Group${lastObj}`).classList.add('highlighted'); + } else { + lastHighlightedType = 1; + lastType = 1; + try { + if (!isHoldingCTRL) { + document.getElementById(`Action${lastAct}`).style.background = ""; + document.getElementById(`Action${lastAct}`).classList.remove('highlighted'); + } + } catch (err) {} + + if (isHoldingCTRL && lastAct != element.id.split("Action")[1] && selectedActions.length == 0) { + selectedActions.push(lastAct) + } + + lastAct = element.id.split("Action")[1]; + + if (!isHoldingCTRL) { + if (selectedActions.length != 0) { + refreshActions() + } + selectedActions = []; + document.getElementById(`Action${lastAct}`).classList.add('highlighted'); + } else { + let eID = element.id.split("Action")[1]; + if (selectedActions.length == 0 && eID != lastAct) { + selectedActions.push(lastAct) + } + if (selectedActions.includes(eID)) { + element.classList.remove('highlighted'); + selectedActions.splice(selectedActions.indexOf(eID), 1) + } else { + selectedActions.push(eID); + document.getElementById(`Action${lastAct}`).classList.add('highlighted'); + } + } + } + } catch (err) {} +} + +(Element.prototype.appendBefore = function (element) { + element.parentNode.insertBefore(this, element); +}), + false; +(Element.prototype.appendAfter = function (element) { + element.parentNode.insertBefore(this, element.nextSibling); +}), + false; + +let timesSaved = 0; + +function setCommandColor(r, g, b) { + client.achievement.activate('RAINBOWS') + if (lastFolder) { + if (r == '255' && g == '255' && b == '255') { + botData.folders[lastFolder].color = null + cachedFolders[lastFolder].color = null + } else { + botData.folders[lastFolder].color = `rgb(${r}, ${g}, ${b})` + cachedFolders[lastFolder].color = `rgb(${r}, ${g}, ${b})` + } + saveLocally(); + checkSaveStatus(); + colorize(document.getElementById(lastFolder), lastFolder, 1); + } else { + if (r == '255' && g == '255' && b == '255') { + botData.commands[lastObj].color = null + } else { + botData.commands[lastObj].color = `rgb(${r}, ${g}, ${b})` + } + saveLocally(); + checkSaveStatus(); + + colorize(document.getElementById(`Group${lastObj}`), lastObj, 1); + } +} + +function savePrj() { + timesSaved++ + try { + fs.writeFileSync( + botData.prjSrc + "/AppData/data.json", + JSON.stringify(botData, null, 2) + ); + } catch (err) { } + + + document.getElementById("saveStatus").style.filter = `blur(12px)` + + setTimeout(() => { + document.getElementById("saveStatus").innerText = strings.editor.save_states[1]; + document.getElementById("saveStatus").style.filter = `blur(0px)` + }, editorSettings.fastAnimation * 100); + lastKnownStatus = true; + + document.getElementById("saveIcon").style.transform = ''; + + saveLocally(); + if (timesSaved > 40) { + client.achievement.activate('SAFETY_FIRST'); + } + + if (ownSettings.restartOnSave != 'Off' && isBotOn) { + toggleBotStatus() + setTimeout(() => { + toggleBotStatus() + }, 500); + } +} + +let lastKnownStatus; +function checkSaveStatus() { + document.getElementById("saveStatus").style.transition = `all 0.${editorSettings.fastAnimation}s ease` + + if (fs.readFileSync("./AppData/data.json", "utf8") == fs.readFileSync(`${botData.prjSrc}/AppData/data.json`, "utf8")) { + document.getElementById("saveIcon").style.transform = ''; + if (lastKnownStatus == true) return true; + + lastKnownStatus = true + + document.getElementById("saveStatus").style.filter = `blur(12px)` + + setTimeout(() => { + document.getElementById("saveStatus").innerText = strings.editor.save_states[1]; + document.getElementById("saveStatus").style.filter = `blur(0px)` + }, editorSettings.fastAnimation * 100); + + return true; + } else { + document.getElementById("saveIcon").style.transform = 'translateY(12px)'; + if (lastKnownStatus == false) return false; + lastKnownStatus = false; + document.getElementById("saveStatus").style.filter = `blur(12px)` + + setTimeout(() => { + document.getElementById("saveStatus").innerText = strings.editor.save_states[0]; + document.getElementById("saveStatus").style.filter = `blur(0px)` + }, editorSettings.fastAnimation * 100); + + return false; + } +} + + +function openEvent() { + try { + ipcRenderer.send("editEvent", { + name: require(processPath + + "/AppData/Events/" + + botData.commands[lastObj].eventFile).name, + event: botData.commands[lastObj].eventFile, + data: botData.commands[lastObj].eventData, + }); + } catch (err) { + ipcRenderer.send("editEvent", { + name: "Bot Ready", + event: "bot_ready.js", + data: [""], + }); + } +} + +function openPermissionEditor() { + ipcRenderer.send("openPerms", botData.commands[lastObj]); + ipcRenderer.once("boundaryData", (event, data) => { + createCheckpoint() + botData.commands[lastObj].boundary = data; + highlight(document.getElementById(`Group${lastObj}`)); + }); +} + +function setGroupColor(elm) { + + createCheckpoint(); + if (lastFolder) { + if (elm == null) { + botData.folders[lastFolder].color = null; + cachedFolders[lastFolder].color = null; + saveLocally(); + document.getElementById(lastFolder).classList.remove('coloredAction') + document.getElementById(lastFolder).classList.add('action') + document.getElementById(lastFolder).style.background = `#ffffff25` + return; + } + let color = elm.style.background; + cachedFolders[lastFolder].color = color; + botData.folders[lastFolder].color = color; + document.getElementById(lastFolder).classList.remove('action') + document.getElementById(lastFolder).classList.add('coloredAction') + saveLocally(); + + document.getElementById(lastFolder).style.background = `${cachedFolders[lastFolder].color.split(')')} 0.20`; + recacheFolders() + } else { + const last = `${lastObj}`; + if (elm == null) { + botData.commands[lastObj].color = undefined; + refreshGroups(); + return; + } + let color = elm.style.background; + botData.commands[lastObj].color = color; + refreshGroups(); + saveLocally(); + } + + if (editorSettings.focus) { + toggleColorsVisibility() + } + + client.achievement.activate('RAINBOWS'); +} + +function toggleColorsVisibility() { + return + if (botData.colorsVisibility == undefined) { + botData.colorsVisibility = false; + } + if (botData.colorsVisibility == true) { + document.getElementById("colorsSelector").style.width = "0%"; + document.getElementById("colorsSelector").style.marginLeft = "-10px"; + document.getElementById("colorsSelector").style.paddingLeft = "0px"; + document.getElementById("colorsSelector").style.paddingRight = "0px"; + + setTimeout(() => { + document.getElementById("colorsSelector").style.marginLeft = ""; + }, 250); + botData.colorsVisibility = false; + } else { + document.getElementById("colorsSelector").style.marginLeft = ""; + document.getElementById("colorsSelector").style.width = "calc(100% - 55px)"; + document.getElementById("colorsSelector").style.paddingLeft = "3px"; + document.getElementById("colorsSelector").style.paddingRight = "3px"; + setTimeout(() => { + document.getElementById("colorsSelector").style.width = "calc(100% - 55px - 10px)"; + }, 250); + botData.colorsVisibility = true; + } + saveLocally(); +} + +function saveLocally() { + fs.writeFileSync( + "./AppData/data.json", + JSON.stringify(botData, null, 2) + ); + + + document.getElementById("saveStatus").innerText = "Saved"; + document.getElementById("saveIcon").style.transform = ''; +} + +let lastNotification; +let handlingLastNotification = false; + +async function notify(text) { + if (lastNotification) { + await new Promise(res => { + lastNotification.style.opacity = '0' + lastNotification.style.scale = '2.2' + res(); + + setTimeout(() => { + lastNotification.remove(); + }, 100); + }) + } + let popup = document.createElement('div') + popup.style.position = 'fixed' + document.body.appendChild(popup); + + popup.innerHTML = `${text}`; + popup.style.marginTop = '' + popup.style.marginRight = '-100vw' + popup.style.padding = '10px' + popup.style.borderRadius = '9px' + popup.style.transition = 'all 0.2s ease, margin-top 0.3s cubic-bezier(.4,.16,.14,1.4), margin-left 0.3s cubic-bezier(.4,.16,.14,1.4), height 0.3s ease, scale 0.4s cubic-bezier(.4,.16,.14,1.4)' + popup.style.backdropFilter = 'blur(12px)' + popup.style.background = '#ffffff10' + popup.style.scale = '0.2' + + setTimeout(() => { + popup.style.scale = '1' + lastNotification = popup; + }, 100); + + + setTimeout(() => { + popup.style.opacity = '0' + popup.style.scale = '2.2' + setTimeout(() => { + popup.remove() + }, 300); + }, 4000); + + return popup +} + +let usedCustomIds = []; +for (let command in botData.commands) { + if (botData.commands[command]) { + if (usedCustomIds.includes(botData.commands[command].customId)) { + botData.commands[command].customId = + parseFloat(new Date().getTime()) + parseFloat(usedCustomIds.length); + } else { + usedCustomIds.push(botData.commands[command].customId); + } + } +} +saveLocally(); + +async function closeEditor() { + if (checkSaveStatus() == false) { + let keepGoing = await awaitIPCResponse({ channel: "deleteScreening", content: strings.editor.exit_unsaved_confirmation }, 'deletionModalInteraction'); + if (!keepGoing) return; + } + ipcRenderer.send("close"); +} + + +async function uploadToWorkshop(content, type) { + if (type == 0) { + const customId = botData.commands[content].customId; + let keepGoing = await awaitIPCResponse({ channel: "deleteScreening", content: `Are you sure you want to upload ${botData.commands[content].name} to the Steam Workshop?` }, 'deletionModalInteraction'); + if (!keepGoing) return; + + client.workshop.createItem(appID).then(e => { + client.workshop.updateItem(e.itemId, { + changeNote: "Add content", + title: `${botData.commands[lastObj].name} (${botData.commands[lastObj].type == 'action' ? "command" : "event"})`, + contentPath: "./Workshop_Items/Command" + }).then(e => { + console.log(e); + client.workshop.getItem(e.itemId).then(aaaaaaaaaa => { + console.log(aaaaaaaaaa) + }) + }) + }).catch(err => console.log(err)); + + const fse = require('fs-extra'); + + try { + if (!fs.existsSync(`./Workshop_Items/${customId}`)) { + fse.copySync('./Workshop_Items/Command', `./Workshop_Items/${customId}`) + } + } catch (error) { + return notify('Something went wrong, sorry!'); + } + + try { + client.workshop.createItem().then(workshopItem => { + console.log('created!') + client.workshop.updateItem(workshopItem.itemId, { + contentPath: `./Workshop_Items/${customId}`, + tags: ["383217"] + }) + }); + } catch (error) { + console.log(error); + notify('Upload Failed..'); + } + } +} + +function resizeCommands() { + let ids = ['commandbar', 'edutor', 'actionbar', 'toggleSizing']; + ids.forEach(id => { + document.getElementById(id).style.transition = `all 0.${editorSettings.commonAnimation}s cubic-bezier(.17,.67,0,1.38)` + }) + + if (!botData.collapsed) { + document.getElementById('commandbar').style.height = 'var(--collapsedCommandContainerHeight)' + document.getElementById('actionbar').style.height = 'var(--expandedActionContainerHeight)' + document.getElementById('toggleSizing').style.rotate = '90deg' + botData.collapsed = true; + } else { + document.getElementById('commandbar').style.height = 'var(--commandContainerHeight)' + document.getElementById('actionbar').style.height = 'var(--actionContainerHeight)' + document.getElementById('edutor').style.height = '' + document.getElementById('edutor').style.width = '' + document.getElementById('edutor').style.marginBottom = '' + botData.collapsed = false; + document.getElementById('toggleSizing').style.rotate = '-90deg' + } + saveLocally(); + checkSaveStatus(); +} + +resizeCommands(); +resizeCommands(); + +// document.getElementById('windowControls').appendBefore(document.getElementById('logo_toolbar')) \ No newline at end of file diff --git a/kits/EditorComponents.js b/kits/EditorComponents.js new file mode 100644 index 0000000..2366b31 --- /dev/null +++ b/kits/EditorComponents.js @@ -0,0 +1,836 @@ +let lastHoveredContainer; +let draggedOverMenu, draggedPosition, draggedOverPosition; +let timing; +let customIDsCalculated = 0; + +function addObjectToMenu(element, option, hlLast) { + setTimeout(() => { + document.getElementById(actionUI[element].storeAs).classList.remove('flexbox'); + }, editorSettings.commonAnimation * 100); + + if (actionUI[element].max > action.data[actionUI[element].storeAs].length) { + action.data[actionUI[element].storeAs].push({ + type: option, + data: actionUI[element].UItypes[option].data, + }); + } + refreshMenuItems(element, true, hlLast ? true : false); + document.getElementById(`${element}AddButton`).style.transition = `all 0.${editorSettings.commonAnimation}s ease` + + if (actionUI[element].max != 1) { + document.getElementById(`${element}AddButton`).style.transform = "rotate(360deg)"; + setTimeout(() => { + document.getElementById(`${element}AddButton`).style.transform = "rotate(0deg)"; + document.getElementById(`${element}AddButton`).style.transition = `all 0s ease` + }, editorSettings.commonAnimation * 200); + } + + if (editorSettings.editMenusOnCreation) { + openPopupOption(action.data[actionUI[element].storeAs].length - 1, element, { picker: true }); + } +} + +function recacheOwnVariables() { + let rescraped = scrapeForVariables(actionUI, action.data, true); + + tempVars = rescraped.temp; + thisGlobal = rescraped.global; + thisServer = rescraped.server; +} + +let scrapeForVariables = (UI, data, pullTemp) => { + let localGlobal = []; + let localServer = []; + let localTemp = []; + + try { + for (let i in UI) { + let element = UI[i]; + if (element.element == 'storageInput' || element.element == 'storage' || element.element == 'store') { + if (data[element.storeAs].type == 'global') { + localGlobal.push(data[element.storeAs].value); + } else if (data[element.storeAs].type == 'server') { + localServer.push(data[element.storeAs].value); + } else if (data[element.storeAs].type == 'temporary' && (pullTemp == undefined || pullTemp == true)) { + localTemp.push(data[element.storeAs].value); + } + } + + if (element.element == 'menu') { + for (let menu in data[element.storeAs]) { + let scraped = scrapeForVariables(element.UItypes[data[element.storeAs][menu].type].UI, data[element.storeAs][menu].data, element.UItypes[data[element.storeAs][menu].type].pullVariables); + localTemp = [...localTemp, ...scraped.temp] + localServer = [...localServer, ...scraped.server] + localGlobal = [...localGlobal, ...scraped.global] + } + } + + if (element.element == "case" || element.element == "condition") { + if (data[element.storeAs].type == "runActions") { + for (let i in data[element.storeActionsAs]) { + let action = data[element.storeActionsAs][i]; + try { + let act = allActions[action.file]; + let scraped = scrapeForVariables(act.UI, action.data); + localTemp = [...localTemp, ...scraped.temp] + localServer = [...localServer, ...scraped.server] + localGlobal = [...localGlobal, ...scraped.global] + } catch (err) { } + } + } + } + + if (element.element == 'actions') { + for (let i in data[element.storeAs]) { + let action = data[element.storeAs][i]; + try { + let act = allActions[action.file]; + let scraped = scrapeForVariables(act.UI, action.data); + localTemp = [...localTemp, ...scraped.temp] + localServer = [...localServer, ...scraped.server] + localGlobal = [...localGlobal, ...scraped.global] + } catch (err) { } + } + } + } + } catch (err) { } + return { global: localGlobal, server: localServer, temp: localTemp } +} + + +function openPopupOption(object, index) { + let vars = scrapeForVariables(actionUI[index].UItypes[action.data[actionUI[index].storeAs][object].type].UI, action.data[actionUI[index].storeAs][object].data, true); + + let data = action.data[actionUI[index].storeAs][object].data; + if (actionUI[index].UItypes[action.data[actionUI[index].storeAs][object].type].inheritData == true) { + data = action.data; + } + + ipcRenderer.send(`${time}`, { + event: "openCustom", + data, + UI: actionUI[index].UItypes[action.data[actionUI[index].storeAs][object].type].UI, + name: actionUI[index].UItypes[action.data[actionUI[index].storeAs][object].type].name, + variables: { + commandVars: [...commandVars, ...tempVars], + temporary: vars.temp, + server: [...serverVars], + global: [...globalVars], + thisGlobal: vars.global, + thisServer: vars.server + }, + actionType: actionType, + }); + + ipcRenderer.once("menuData", (event, data, copied) => { + if (actionUI[index].UItypes[action.data[actionUI[index].storeAs][object].type].inheritData) { + action.data = data; + } else { + action.data[actionUI[index].storeAs][object].data = data; + } + recacheOwnVariables(); + refreshMenuItems(index); + }); +} + + +function editAction(at, actionNumber, options) { + let vars = scrapeForVariables(ipcActionCache[action.data[at][actionNumber].file].UI, action.data[at][actionNumber]); + let customId = new Date().getTime(); + ipcRenderer.send("editAction", { + event: "openAction", + variables: { + commandVars: vars.temp, + temporary: [...commandVars, ...tempVars], + server: [...thisServer, ...serverVars], + global: [...thisGlobal, ...globalVars], + thisGlobal: vars.global, + thisServer: vars.server + }, + actionType: actionType, + customId: `${customId}`, + actions: action.data[at], + action: actionNumber, + options: (options || { picker: false }) + }); + function storeActionData() { + ipcRenderer.once(`childSave${customId}`, (event, data, copied) => { + action.data[at][actionNumber] = data; + storeActionData(); + recacheOwnVariables(); + + refreshActions(at); + }); + } + storeActionData(); +} + +recacheOwnVariables(); + + +function handleOptionDrag(position, menu) { + draggedPosition = position; + draggedOverMenu = menu; +} + +function dragPositionOver(position, menu, event) { + if (draggedOverMenu == menu) event.preventDefault() + + draggedOverPosition = position; +} + +function handleDragOptionEnd() { + console.log(actionUI[draggedOverMenu], draggedOverMenu) + action.data[actionUI[draggedOverMenu].storeAs] = moveArrayElement(action.data[actionUI[draggedOverMenu].storeAs], draggedPosition, draggedOverPosition); + refreshMenuItems(draggedOverMenu) + draggedOverMenu = undefined; +} + + +async function refreshMenuItems(menu, fade, fadeLast) { + + let leftSeparatorDisplay, rightSeparatorDisplay, subtitlePosition; + + switch (editorSettings.subtitlePosition) { + case "left": + leftSeparatorDisplay = "none"; + rightSeparatorDisplay = "inherit; margin-left: 5px !important;"; + subtitlePosition = "margin-left: 5px !important; margin-right: auto;"; + break; + case "right": + rightSeparatorDisplay = "none"; + leftSeparatorDisplay = + "inherit; margin-right: 5px !important; margin-left: 10px !important;"; + subtitlePosition = "margin-right: 0; margin-left: auto;"; + deleteButtonStyling = "margin-left: 5px;"; + break; + case "center": + rightSeparatorDisplay = "inherit"; + leftSeparatorDisplay = "inherit; margin-left: 5px !important;"; + subtitlePosition = "margin-right: 5px; margin-left: 5px;"; + break; + } + + if (editorSettings.focus) { + rightSeparatorDisplay = 'none' + leftSeparatorDisplay = 'none' + } + + + await new Promise(res => { + if (document.getElementById(`${actionUI[menu].storeAs}_Options`)) { + document.getElementById(`${actionUI[menu].storeAs}_Options`).style.opacity = '0' + setTimeout(() => { + res() + }, editorSettings.fastAnimation * 100); + } else { + res() + } + }); + + let menuObject = actionUI[menu]; + let menuElement = document.getElementById(menuObject.storeAs); + + + if (menuObject.max != 1) { + if (!action.data[menuObject.storeAs].length) { + menuElement.style.height = "37px"; + } else { + menuElement.style.height = "150px"; + } + + if (!highlights[menuObject.storeAs]) { + highlights[menuObject.storeAs] = { highlighted: 0, menu, selected: [], type: 2 } + } + + if (!action.data[menuObject.storeAs][highlights[menuObject.storeAs].highlighted] && highlights[menuObject.storeAs].highlighted != 0) { + highlights[menuObject.storeAs].highlighted = 0; + } + + let endOptions = ``; + + for (let object in action.data[menuObject.storeAs]) { + let option = action.data[menuObject.storeAs][object]; + let typeName = actionUI[menu].UItypes[option.type].name; + + let preview = ''; + try { + if (actionUI[menu].UItypes[option.type].preview) { + preview = eval(actionUI[menu].UItypes[option.type].preview) + } + } catch (err) { } + + let previewText = ''; + let previewLength = 0; + + previewText.replaceAll('<', '<​') + + let deco = `` + + if (action.data[menuObject.storeAs][Number(object) + 1] && actionUI[menu].path) { + deco = ` +
+ ` + } + + let additionalClass = `` + if (highlights[menuObject.storeAs]?.highlighted == object) { + additionalClass = `highlighted` + } + + let fadeNow = false; + + if (fade && !fadeLast) { + fadeNow = true; + } else if (fade && fadeLast) { + fadeNow = action.data[menuObject.storeAs].length - 1 == object; + } + + + + endOptions += ` + + ${deco} + ` + } + setTimeout(() => { + menuElement.innerHTML = `
${endOptions}
`; + if (!endOptions) { + menuElement.innerHTML = ` + + No ${menuObject.name} Yet +
+
` + } + }, editorSettings.commonAnimation * 50); + document.getElementById(`${menu}AddButton`).style.transform = "rotate(0deg)"; + + setTimeout(() => { + document.getElementById(`${menu}AddButton`).style.transition = ""; + document.getElementById(`${menu}AddButton`).style.transition = `all 0.${editorSettings.commonAnimation}s cubic-bezier(.17,.67,.6,1.34)` + document.getElementById(`${menu}AddButton`).parentElement.onclick = () => { + addObjectToCustomMenu(menu, true); + }; + }, editorSettings.commonAnimation * 50); + } else { + if (action.data[menuObject.storeAs][0]) { + let UItype = Object.keys(menuObject.UItypes)[0]; + let previewText = `` + + try { + let preview = ''; + let data = action.data[menuObject.storeAs][0]; + + + try { + if (actionUI[menu].UItypes[UItype].preview) { + let option = { data } + preview = eval(actionUI[menu].UItypes[UItype].preview); + } + } catch (err) { } + + let previewLength = 0; + + if (preview.length > 35) { + for (let character of preview.split('')) { + if (previewLength < 35) { + const opacity = 100 - (previewLength - 25) * 10; + previewText += `${character}`; + previewLength++ + } + } + } else { + previewText = preview; + } + + previewText.replaceAll('<', '<​') + } catch (error) { } + + menuElement.innerHTML = ` + + ` + document.getElementById(`${menu}AddButton`).parentElement.onclick = () => { + deleteMenuOption(0, menu, true); + }; + document.getElementById(`${menu}AddButton`).style.rotate = "225deg"; + } else { + document.getElementById(`${menu}AddButton`).style.rotate = "0deg"; + + menuElement.innerHTML = ` + + No ${menuObject.name} Yet +
+
` + document.getElementById(`${menu}AddButton`).parentElement.onclick = () => { + addObjectToCustomMenu(menu, true); + }; + } + } +} + +async function highlightMenu(menu, object) { + let rawMenu = actionUI[menu]; + lastContainer = rawMenu.storeAs; + + let currentSelection = []; + let skipBackgroundAddition = false; + + if (highlights[rawMenu.storeAs]) { + currentSelection = highlights[rawMenu.storeAs].selected; + if (currentSelection.length != 0) { + if (!isHoldingCTRL) { + highlights[rawMenu.storeAs].highlighted = object; + currentSelection = []; + await refreshMenuItems(menu); + } else { + if (currentSelection.includes(object)) { + let lastHighlightedMenu = document.getElementById(`menu${menu}object${object}`); + lastHighlightedMenu.classList.remove('highlighted') + skipBackgroundAddition = true; + currentSelection.splice(currentSelection.indexOf(object), 1); + return + } + } + } else { + if (!isHoldingCTRL) { + let oldMenu = highlights[rawMenu.storeAs]; + try { + let lastHighlightedMenu = document.getElementById(`menu${oldMenu.menu}object${oldMenu.highlighted}`); + lastHighlightedMenu.classList.remove('highlighted') + } catch (error) { } + } + } + } + + if (isHoldingCTRL) { + if (currentSelection.length == 0 && highlights[rawMenu.storeAs].highlighted != object) { + currentSelection.push(highlights[rawMenu.storeAs].highlighted) + } + currentSelection.push(object) + } + + if (!skipBackgroundAddition) { + let newMenu = document.getElementById(`menu${menu}object${object}`); + newMenu.classList.add('highlighted') + } + + + highlights[rawMenu.storeAs] = { highlighted: object, selected: currentSelection, type: 2, menu }; +} + +function createAction(at) { + customIDsCalculated++ + let newAct = { + name: "Send Message", + file: "sendmessage.js", + data: { + "name": "Send Message", + "messageContent": "Hello World!", + "actionRows": [], + "embeds": [], + channel: { + type: "command", + value: "" + }, + storeAs: { + value: "", + type: "temporary" + }, + replyToInteraction: true + }, + id: customIDsCalculated + new Date().getTime() + }; + + action.data[at].push(newAct); + refreshActions(at); + + if (editorSettings.editActionsOnCreation) { + editAction(at, action.data[at].length - 1, { picker: true }); + } +} + + +function refreshActions(at) { + if (!highlights[at]) { + highlights[at] = { highlighted: 0, selected: [], type: 1 }; + } + action.data[at] = action.data[at].filter(action => action != null) + + document.getElementById(at).innerHTML = ""; + let endHTML = ''; + let endActions = [] + + for (let a in action.data[at]) { + let Action = action.data[at][a]; + let actionData; + let endAction = { + subtitle: '', + found: false, + file: Action.file, + borderType: 'bordercentere' + } + try { + actionData = require(`${processPath}/AppData/Actions/${Action.file}`); + } catch (err) { } + + // if (action.data[at][parseFloat(a) - 1] == undefined) { + // endAction.borderType = "bordertop"; + // } else if (action.data[at][parseFloat(a) + 1] == undefined) { + // endAction.borderType = "bordertop"; + // } + + + + if (actionData) { + endAction.found = true; + endAction.name = Action.name; + try { + if (actionData.subtitle) { + if (typeof actionData.subtitle == 'function') { + endAction.subtitle = actionData.subtitle(Action.data, { + user: (user) => { + let translations = { + author: "Command Author", + mentioned: "Mentioned User", + user: "Command User", + messageAuthor: "Message Author", + + id: "ID", + + tempVar: "Temporary Variable", + serverVar: "Server Variable", + globVar: "Global Variable", + }; + + let disabledInputTypes = ["mentioned", "author", "user", "messageAuthor"]; + if (!disabledInputTypes.includes(user.type)) { + return `${translations[user.type]} (${user.value || "Blank" + })`; + } else { + return `${translations[user.type]}`; + } + }, + channel: (channel) => { + let translations = { + id: "Channel ID", + userID: "User ID", + command: "Command Channel", + user: "Command User", + commandAuthor: "Command Author", + mentionedChannel: "Mentioned Channel", + mentionedUser: "Mentioned User", + + tempVar: "Temporary Variable", + serverVar: "Server Variable", + globVar: "Global Variable", + }; + + let disabledInputTypes = [ + "command", + "commandAuthor", + "mentionedUser", + "mentionedChannel", + "user" + ]; + if (!disabledInputTypes.includes(channel.type)) { + return `${translations[channel.type]} (${channel.value || "Blank" + })`; + } else { + return `${translations[channel.type]}`; + } + }, + role: (role) => { + let translations = { + id: "ID", + mentioned: "Mentioned Role", + tempVar: "Temporary Variable", + serverVar: "Server Variable", + globVar: "Global Variable", + }; + + let disabledInputTypes = ["mentioned"]; + if (!disabledInputTypes.includes(role.type)) { + return `${translations[role.type]} (${role.value || "Blank" + })`; + } else { + return `${translations[role.type]}`; + } + }, + guild: (guild) => { + let translations = { + current: "Current", + id: "ID", + tempVar: "Temporary Variable", + serverVar: "Server Variable", + globVar: "Global Variable", + }; + + let disabledInputTypes = ["current"]; + if (!disabledInputTypes.includes(guild.type)) { + return `${translations[guild.type]} (${guild.value || "Blank"})`; + } else { + return `${translations[guild.type]}`; + } + }, + message: (message) => { + let translations = { + commandMessage: "Command Message", + interactionReply: "Command Reply", + tempVar: "Temporary Variable", + serverVar: "Server Variable", + globVar: "Global Variable", + }; + + let disabledInputTypes = ["commandMessage", "interactionReply"]; + if (!disabledInputTypes.includes(message.type)) { + return `${translations[message.type]} (${message.value || "Blank" + })`; + } else { + return `${translations[message.type]}`; + } + }, + interaction: (interaction) => { + let translations = { + commandInteraction: "Command Interaction", + tempVar: "Temporary Variable", + serverVar: "Server Variable", + globVar: "Global Variable", + }; + + let disabledInputTypes = ["commandInteraction"]; + if (!disabledInputTypes.includes(interaction.type)) { + return `${translations[interaction.type]} (${interaction.value || "Blank" + })`; + } else { + return `${translations[interaction.type]}`; + } + }, + image: (image) => { + let translations = { + file: "File", + url: "URL", + tempVar: "Temporary Variable", + serverVar: "Server Variable", + globVar: "Global Variable", + }; + + let disabledInputTypes = []; + if (!disabledInputTypes.includes(image.type)) { + return `${translations[image.type]} (${image.value || "Blank" + })`; + } else { + return `${translations[image.type]}`; + } + }, + variable: (variables) => { + let translations = { + tempVar: "Temporary Variable", + serverVar: "Server Variable", + globVar: "Global Variable", + temporary: "Temporary Variable", + server: "Server Variable", + global: "Global Variable", + }; + return `${translations[variables.type]} (${variables.value || "Blank" + })`; + }, + }, actionData); + } else { + let actionSubtitle = actionData.subtitle; + const subtitleRegex = /(\$\[.*?\]\$)/g; + endAction.subtitle = actionSubtitle.replace( + subtitleRegex, + (match, key) => { + let dataName = key + .split("$[")[1] + .split("]$")[0] + .replaceAll("*", ""); + return Action.data[dataName]; + }, + ); + } + } + } catch (err) { } + } else { + endAction.name = Action.name + } + + endAction.subtitle = endAction.subtitle?.replaceAll('<', '<​') + + endActions.push(endAction) + } + + let leftSeparatorDisplay, rightSeparatorDisplay, subtitlePosition; + + switch (editorSettings.subtitlePosition) { + case "left": + leftSeparatorDisplay = "none"; + rightSeparatorDisplay = "inherit; margin-left: 5px !important;"; + subtitlePosition = "margin-left: 5px !important; margin-right: auto;"; + break; + case "right": + rightSeparatorDisplay = "none"; + leftSeparatorDisplay = + "inherit; margin-right: 5px !important; margin-left: 10px !important;"; + subtitlePosition = "margin-right: 0; margin-left: auto;"; + deleteButtonStyling = "margin-left: 5px;"; + break; + case "center": + rightSeparatorDisplay = "inherit"; + leftSeparatorDisplay = "inherit; margin-left: 5px !important;"; + subtitlePosition = "margin-right: 5px; margin-left: 5px;"; + break; + } + + if (editorSettings.focus) { + rightSeparatorDisplay = 'none' + leftSeparatorDisplay = 'none' + } + + endActions.forEach((Action, index) => { + let errors = '' + + if (Action.found == false) { + errors = ` +
Action Not Found!
+ ` + } + endHTML += ` +
+ + ${editorSettings.focus ? "" : "#"}${parseFloat(index) + 1} +
${Action.name.substring(0, 256)}
+ ${errors} +
+
+ ${Action.subtitle.replaceAll("", "​")} +
+
+ +
+
+ ` + }); + + document.getElementById(at).innerHTML = endHTML; + highlights[at].selected = [] +} + +function highlightAction(container, index) { + lastContainer = container; + let selected = []; + if (highlights[container].selected) { + selected = highlights[container].selected; + } + if (!isHoldingCTRL && selected.length != 0) { + highlights[container].selected = []; + selected = []; + refreshActions(container); + } + + let newAction = document.getElementById(`${container}Action${index}`) + + try { + if (!isHoldingCTRL) { + let oldAction = document.getElementById(`${container}Action${highlights[container].highlighted}`) + oldAction.style.background = '' + } else { + if (selected.includes(index)) { + selected.splice(selected.indexOf(index), 1) + newAction.style.background = '' + return; + } else { + if (selected.length == 0) { + if (highlights[container].highlighted != index) { + selected.push(highlights[container].highlighted); + } + } + selected.push(index) + } + } + } catch (e) { } + + highlights[container] = { highlighted: index, type: 1, selected }; + + newAction.style.background = `var(--accent)` +} + +function deleteAction(at, number) { + action.data[at].splice(number, 1); + refreshActions(at); +} +var actionParent; +var draggedAction; +var draggedOverAction; +function handleActionDrag(at, actionNumber) { + draggedAction = actionNumber; + actionParent = at; + timing = new Date().getTime(); +} +function actionDragOverHandle(event, at, actionNumber) { + if (at != actionParent) return; + event.preventDefault(); + draggedOverAction = actionNumber; +} + +function handleActionDragEnd() { } + +function moveArrayElement(arr, old_index, new_index) { + const element = arr[old_index]; + arr.splice(old_index, 1); + arr.splice(new_index, 0, element); + + return arr; +} +function handleActionDrop(at) { + if (new Date().getTime() - timing < 100) return; + + let oldPosition = parseFloat(draggedAction); + let newPosition = parseFloat(draggedOverAction); + lastType = 1; + + let modifiedActions = moveArrayElement( + action.data[at], + oldPosition, + newPosition, + ); + + action.data[at] = modifiedActions; + refreshActions(at); +} \ No newline at end of file diff --git a/kits/EditorScripts.js b/kits/EditorScripts.js new file mode 100644 index 0000000..b9c0689 --- /dev/null +++ b/kits/EditorScripts.js @@ -0,0 +1,538 @@ +let kindOf; +let highlights = {}; +let lastContainer; +let lastHoveredMenu; +let lastHovered; +let isHoldingCTRL = false; +let lastActionContainer; + +let lastOpenedMenu = {} + +let cancelMenu = false; + +(Element.prototype.appendBefore = function (element) { + element.parentNode.insertBefore(this, element); +}), + false; +(Element.prototype.appendAfter = function (element) { + element.parentNode.insertBefore(this, element.nextSibling); +}), + false; + +window.oncontextmenu = function (event) { + if (menu) { + menu.style.transition = "all 0.2s ease"; + } + showCustomMenu(event.clientX, event.clientY); + return false; // cancel default menu +}; + +async function addObjectToCustomMenu(element) { + if (document.getElementById(actionUI[element].storeAs)?.getElementsByClassName('backArrow').length) { + document.getElementById(actionUI[element].storeAs).getElementsByClassName('backArrow')[0].parentElement.style.opacity = '0' + } + + if (document.getElementById(`addButtonOf${element}`)?.previousElementSibling.getElementsByClassName('backArrow').length) { + document.getElementById(`addButtonOf${element}`).previousElementSibling.getElementsByClassName('backArrow')[0].parentElement.style.opacity = '0' + } + + let targetField = document.getElementById(actionUI[element].storeAs); + targetField.style.transition = `all 0.${editorSettings.fastAnimation}s ease` + + let animationDelay = 0 + + if (actionUI[element].max > action.data[actionUI[element].storeAs].length) { + if (Object.keys(actionUI[element].types).length > 1) { + await new Promise(res => { + action.data[actionUI[element].storeAs].forEach((e, index) => { + try { + document.getElementById(`menu${element}object${index}`).style.transition = `all 0.${editorSettings.fastAnimation}s ease` + document.getElementById(`menu${element}object${index}`).style.opacity = '0' + } catch (error) { } + }) + + setTimeout(() => { + res() + }, editorSettings.fastAnimation * 100); + }) + document.getElementById(`${element}AddButton`).style.transition = `all 0.${editorSettings.commonAnimation}s ease` + + document.getElementById(`${element}AddButton`).style.transform = + "rotate(135deg)"; + document.getElementById(`${element}AddButton`).parentElement.onclick = () => { + refreshMenuItems(`${element}`, true); + + setTimeout(() => { + targetField.classList.remove('flexbox'); + }, editorSettings.commonAnimation * 100); + }; + + let endHTML = ""; + for (let option in actionUI[element].types) { + if (animationDelay != 9) { + animationDelay++ + } + endHTML = `${endHTML} + + ${actionUI[element].types[option]} + + `; + } + + targetField.classList.add('flexbox') + targetField.style.height = "170px"; + + setTimeout(() => { + targetField.innerHTML = ` +
+
${!editorSettings.focus ? `${actionUI[element].name} have different types, select one!` : `${actionUI[element].name} Types`}
+
+ ${endHTML} +
+
+ `; + }, editorSettings.fastAnimation * 100); + } else { + addObjectToMenu(`${element}`, Object.keys(actionUI[element].types)[0], true); + } + } +} + +function deleteMenuOption(position, menu, skipAnimations) { + action.data[actionUI[menu].storeAs].splice(position, 1); + + document.getElementById(`menu${menu}object${position}`).style.transition = `all 0.${editorSettings.commonAnimation}s ease` + document.getElementById(`${menu}AddButton`).style.transition = `all 0.${editorSettings.commonAnimation}s ease` + + setTimeout(() => { + refreshMenuItems(menu); + }, editorSettings.commonAnimation * 100); + + setTimeout(() => { + document.getElementById(`menu${menu}object${position}`).style.opacity = '0%' + + if (!skipAnimations) { + document.getElementById(`menu${menu}object${position}`).style.height = '0px' + document.getElementById(`menu${menu}object${position}`).style.paddingTop = '0px' + document.getElementById(`menu${menu}object${position}`).style.paddingBottom = '0px' + document.getElementById(`menu${menu}object${position}`).style.marginBottom = '0px' + document.getElementById(`menu${menu}object${position}`).style.marginTop = '0px' + } + }, editorSettings.commonAnimation); +} + +function fuzzyMatch(str, pattern, accuracy) { + pattern = pattern.replace(/[-\\\/^$*+?.()|[\]{}]/g, "\\$&"); + pattern = pattern.split("").reduce((a, b) => a + `.*${b}`, ""); + + const regex = new RegExp(pattern, "i"); + const matchScore = str.match(regex) ? str.match(regex)[0].length : 0; + const requiredScore = str.length * accuracy; + + return matchScore >= requiredScore; +} + +let folders; + +async function viewAllActions() { + let ind = -1; + try { + document.getElementById('searchResults').innerHTML = '' + if (!folders) { + folders = {}; + for (let action of cachedActions) { + ind++ + if (!folders[action.category]) { + folders[action.category] = '' + } + folders[action.category] += ` +
${action.name}${action.mod ? ` MOD` : ""}
+ ` + }; + + folders = Object.fromEntries(Object.entries(folders).sort()) + } + + for (let f in folders) { + let folder = folders[f]; + document.getElementById('searchResults').innerHTML += ` +
+
+ ${f}
+
+ ${folder} +
` + } + } catch (err) { console.log(err) } +} + +let isSearchOpen = false; +async function startSearch() { + if (isSearchOpen) return; + isSearchOpen = true; + let cache; + if (!Array.isArray(cachedActions)) { + cache = new Promise(resolve => { + ipcRenderer.send(`${time}`, { + event: "askForCache" + }); + + ipcRenderer.on('actionCache', (e, actionCache) => { + cachedActions = actionCache.cachedActions; + resolve() + }) + }); + } + + document.getElementById('searchIcon').style.transition = `all 0.${editorSettings.commonAnimation}s ease`; + + document.getElementById('searchIcon').style.rotate = '360deg'; + document.getElementById('searchIcon').style.scale = '0.6'; + + setTimeout(() => { + document.getElementById('searchIcon').style.scale = '1' + }, editorSettings.commonAnimation * 30); + + await cache; + document.getElementById('actionSearchButton').onclick = () => { closeSearch() } + const container = document.getElementById('editorContent'); + container.style.transition = `all 0.${editorSettings.fastAnimation}s ease`; + + const search = document.getElementById('search'); + search.style.height = 'calc(100vh - var(--toolbar-height))' + search.style.transition = `all 0.${editorSettings.fastAnimation}s ease, opacity 0.${editorSettings.commonAnimation == '0' ? '1' : '5'}s ease` + search.style.opacity = '1' + + if (!document.getElementById('searchResults')) { + search.innerHTML = ` +
+ +
+
` + viewAllActions(); + }; + + container.style.borderRadius = 'var(--round-strong)' + container.style.scale = '0.9' + container.style.marginRight = '-296.475px'; + search.style.width = '296.475px'; + search.style.overflow = 'hidden'; + + document.getElementById('search').firstElementChild.firstElementChild.focus(); +} + +function actionSearch(query) { + cachedResults = undefined; + if (query == "") { + viewAllActions(); + return; + } + query = query.replaceAll(' ', '') + + let endFolders = {}; + let overwrittenFolders = {}; + let count = 0; + + document.getElementById("searchResults").innerHTML = ""; + for (let action in cachedActions) { + if (fuzzyMatch(cachedActions[action].name, query, 0.02)) { + count++ + if (!endFolders[cachedActions[action].category]) { + endFolders[cachedActions[action].category] = '' + } + endFolders[cachedActions[action].category] += ` +
${cachedActions[action].name}${cachedActions[action].mod ? ` MOD` : ""}
` + } + } + + for (let folder in folders) { + if (fuzzyMatch(folder, query, 0.02)) { + overwrittenFolders[folder] = true; + endFolders[folder] = folders[folder]; + } + } + + endFolders = Object.fromEntries(Object.entries(endFolders).sort()); + + let initialKeys = []; + let leftoverKeys = []; + for (let folder in endFolders) { + if (overwrittenFolders[folder]) { + initialKeys.push([folder, endFolders[folder]]) + } else { + leftoverKeys.push([folder, endFolders[folder]]) + } + } + let endKeys = [...initialKeys, ...leftoverKeys] + endFolders = Object.fromEntries(endKeys) + + for (let folderName in endFolders) { + let decoration = `` + if (overwrittenFolders[folderName]) { + decoration = ` +
+
+
+
+ ` + } else { + decoration = ` +
+ ` + } + + document.getElementById("searchResults").innerHTML += ` +
+
+ ${decoration} + ${folderName} +
+ ${endFolders[folderName]} +
+ ` + } +} + +async function closeSearch() { + searchResultSelected = 0; + document.getElementById('searchIcon').style.rotate = '0deg' + document.getElementById('searchIcon').style.scale = '0.6'; + + setTimeout(() => { + document.getElementById('searchIcon').style.scale = '1' + isSearchOpen = false; + }, editorSettings.commonAnimation * 30); + + document.getElementById('actionSearchButton').onclick = () => { startSearch() } + + const container = document.getElementById('editorContent'); + container.style.scale = '1' + container.style.borderRadius = '0px' + container.style.marginRight = '0'; + + const search = document.getElementById('search'); + search.style.width = '0'; + search.style.opacity = '0' +} + +function switchOutAction(file) { + let newAction = require(`${processPath}/AppData/Actions/${file}`); + actionFile = newAction; + action.data = newAction.data; + action.name = newAction.data.name; + action.file = file; + actionUI = newAction.UI; + actions[actionNumber].data = action.data; + document.getElementById("editorContent").innerHTML = ""; + document.getElementById("editorContent").innerHTML = getUIelements(newAction.UI); + + closeSearch(); + updateTopBarContent(`${action.name}`, 'action-name'); + + recacheThisVariables(); +} + +function openHalfDropdown(storedAs, index) { + document.getElementById(storedAs).onclick = () => { + closeHalfDropdown(storedAs, index) + } + + document.getElementById(storedAs).style.zIndex = '1000' + document.getElementById(storedAs).parentElement.style.zIndex = '1000' + + for (let choiceIndex in actionUI[index].choices) { + let choice = actionUI[index].choices[choiceIndex] + if (choice.name != action.data[storedAs]) { + document.getElementById(storedAs).innerHTML += ` + + ` + } + } +} + +function setHalfDropdownType(storedAs, choice, index) { + let foundChoice; + for (let option of actionUI[index].choices) { + if (option.name == action.data[actionUI[index].storeAs]) { + foundChoice = option; + } + } + if (foundChoice.placeholder) { + document.getElementById(`${storedAs}input`).ariaPlaceholder = foundChoice.placeholder + } else { + document.getElementById(`${storedAs}input`).ariaPlaceholder = '' + } + + let input = document.getElementById(`${storedAs}input`) + + if (foundChoice.field && !actionUI[index].choices[choice].field) { + let dropdown = document.getElementById(storedAs) + + dropdown.parentElement.style.marginRight = '0' + + dropdown.classList.remove('borderright'); + dropdown.style.width = 'calc(var(--width-in-editor) - 12px)' + + input.style.width = '0px' + input.style.setProperty('padding', '0px') + input.style.height = '0px' + } else if (!foundChoice.field && actionUI[index].choices[choice].field) { + let dropdown = document.getElementById(storedAs) + + dropdown.parentElement.style.marginRight = 'var(--dropdown-paddingLeft)' + + dropdown.classList.add('borderright'); + dropdown.style.width = 'var(--width-in-otherhalf-dropdown)' + + input.style.width = 'calc(var(--width-in-editor) - var(--width-in-half-dropdown))' + input.style.setProperty('padding', '') + input.style.height = '30.8px' + } + + input.placeholder = actionUI[index].choices[choice].placeholder ? actionUI[index].choices[choice].placeholder : '' + + action.data[storedAs] = actionUI[index].choices[choice].name; + + emitChange(storedAs) +} + +function closeHalfDropdown(s, i) { + let element = document.getElementById(s); + element.style.animationName = ""; + const innerHeight = element.clientHeight; + element.style.animationDuration = ""; + element.style.setProperty("--inner-height", innerHeight + "px"); + element.style.animationName = "shrink"; + element.style.animationDuration = "300ms"; + element.style.zIndex = '' + element.parentElement.style.zIndex = '' + + + setTimeout(() => { + element.onclick = () => { + openHalfDropdown(s, i) + }; + element.innerHTML = action.data[s]; + }, 70); +} + +function openTypedDropdown(storedAs, index, types, toRun) { + document.getElementById(storedAs).style.zIndex = '1000' + document.getElementById(storedAs).parentElement.style.zIndex = '1000' + + document.getElementById(storedAs).onclick = () => { + closeTypedDropdown(storedAs, index, types, toRun) + } + + for (let translation in types) { + if (translation != action.data[storedAs].type) { + let option = document.createElement('div') + option.className = 'dropdown_option' + option.onclick = () => { + setTypedType(storedAs, { ...types[translation], type: translation }, index) + } + option.innerHTML = types[translation].name; + document.getElementById(storedAs).appendChild(option) + } + } +} + +function setTypedType(storedAs, translation, i, toRun) { + if (!translation.field) { + let dropdown = document.getElementById(storedAs) + let input = document.getElementById(`${storedAs}input`) + + dropdown.parentElement.style.marginRight = '0' + + dropdown.classList.remove('borderright'); + dropdown.style.width = 'calc(var(--width-in-editor) - 12px)' + + input.style.width = '0px' + input.style.setProperty('padding', '0px') + input.style.height = '0px' + } else { + let dropdown = document.getElementById(storedAs) + let input = document.getElementById(`${storedAs}input`) + + dropdown.parentElement.style.marginRight = 'var(--dropdown-paddingLeft)' + + dropdown.classList.add('borderright'); + dropdown.style.width = 'var(--width-in-otherhalf-dropdown)' + + input.style.width = 'calc(var(--width-in-editor) - var(--width-in-half-dropdown))' + input.style.setProperty('padding', '') + input.style.height = '30.8px' + } + + action.data[storedAs].type = translation.type; +} + +function closeTypedDropdown(s, i, types, toRun) { + let element = document.getElementById(s); + element.style.animationName = ""; + const innerHeight = element.clientHeight; + element.style.animationDuration = ""; + element.style.setProperty("--inner-height", innerHeight + "px"); + element.style.animationName = "shrink"; + element.style.animationDuration = "300ms"; + element.style.zIndex = '' + element.parentElement.style.zIndex = '' + + if (toRun) { + toRun(action.data[s], i); + } + + setTimeout(() => { + element.onclick = () => { + openTypedDropdown(s, i, types, toRun) + }; + element.innerHTML = types[action.data[s].type].name; + }, 70); +} + +function openActionFolder(folder_bar) { + let element = folder_bar.nextElementSibling; + let heightGuesser = document.createElement('div'); + heightGuesser.innerHTML = element.innerHTML; + heightGuesser.style.width = element.clientWidth; + heightGuesser.classList.add('search_action'); + heightGuesser.style.padding = '0px' + element.style.marginTop = '4px'; + document.body.appendChild(heightGuesser); + setTimeout(() => { + let height = heightGuesser.clientHeight; + element.style.paddingTop = '4px'; + element.style.height = height; + folder_bar.classList.add('rounded_top'); + element.classList.add('rounded_bottom'); + heightGuesser.remove(); + }, 10); + + folder_bar.onclick = () => { + closeActionFolder(folder_bar) + } +} + +function toggleDropdownContainer(dataset, i) { + let actionContainer = document.getElementById(actionUI[i].storeActionsAs); + if (dataset.type == 'runActions') { + actionContainer.classList.remove('closedActions'); + actionContainer.previousElementSibling.classList.remove('closedActions'); + } else { + actionContainer.classList.add('closedActions'); + actionContainer.previousElementSibling.classList.add('closedActions'); + } +} + +function closeActionFolder(folder_bar) { + folder_bar.classList.remove('rounded_top'); + let element = folder_bar.nextElementSibling; + element.classList.remove('rounded_bottom') + element.style.height = '0px' + element.style.paddingBottom = '0px'; + element.style.paddingTop = '0px'; + element.style.marginTop = '0px'; + folder_bar.onclick = () => { + openActionFolder(folder_bar) + } +} \ No newline at end of file diff --git a/kits/Loader.js b/kits/Loader.js new file mode 100644 index 0000000..68c4863 --- /dev/null +++ b/kits/Loader.js @@ -0,0 +1,17 @@ +var fs = require("fs"); +let lastButton; +let menu; + +function closeContextmenu() { + if (menu && !mOpened) { + menu.style.scale = "0"; + setTimeout(() => { + menu.remove(); + menu = undefined; + }, 200); + } +} + +document.onclick = () => { + closeContextmenu() +}; diff --git a/kits/MiscScripts.js b/kits/MiscScripts.js new file mode 100644 index 0000000..36fecee --- /dev/null +++ b/kits/MiscScripts.js @@ -0,0 +1,1080 @@ +let areSettingsOpen; +let preventClose; +function array_move(arr, old_index, new_index) { + if (new_index >= arr.length) { + var k = new_index - arr.length + 1; + while (k--) { + arr.push(undefined); + } + } + arr.splice(new_index, 0, arr.splice(old_index, 1)[0]); + return arr; // for testing +} + +let settings; +try { + settings = JSON.parse( + fs.readFileSync(path + "/EditorSettings.json", "utf8"), + ); +} catch (err) { } + +if (!settings) { + fs.writeFileSync(path + "/EditorSettings.json", "{}"); + settings = JSON.parse( + fs.readFileSync(path + "/EditorSettings.json", "utf8"), + ); +} + +function saveLocally() { + fs.writeFileSync( + "./AppData/data.json", + JSON.stringify(botData, null, 2), + ); +} + +let lastRow; +let lastDraggedComponent; + +window.oncontextmenu = function (event) { + showCustomMenu(event.clientX, event.clientY); + return false; +}; + +function copyAction(id) { + if (selectedActions.length == 0) { + ipcRenderer.send('copiedAction', botData.commands[lastObj].actions[id]) + } else { + ipcRenderer.send('copiedAction', selectedActions.map(action => botData.commands[lastObj].actions[action])) + } +} + +function toHex(rgb) { + try { + let parts = rgb.replace('rgb(', '').replace(')', '').split(','); + + // Convert each part to an integer, then to a hex string and pad with zeros if necessary + let r = parseInt(parts[0]).toString(16).padStart(2, '0'); + let g = parseInt(parts[1]).toString(16).padStart(2, '0'); + let b = parseInt(parts[2]).toString(16).padStart(2, '0'); + + // Concatenate the hex strings and prepend with '#' + return `${r}${g}${b}`; + } catch (error) { + return `#000000` + } +} + + + + +/** + * + * @param {*} x + * @param {*} y + * @param {HTMLDivElement} target + */ +function showCustomMenu(x, y, target) { + if (!menu) { + menu = document.createElement("div"); + document.body.appendChild(menu); + menu.className = 'right_click_menu' + menu.id = "customMenu"; + } + + + // Calculate the maximum allowed coordinates based on window dimensions + const windowWidth = window.innerWidth; + const windowHeight = window.innerHeight; + const menuWidth = menu.offsetWidth; + const menuHeight = menu.offsetHeight; + const maxX = windowWidth - menuWidth; + const maxY = windowHeight - menuHeight; + + let adjustedX = x; + let adjustedY = y; + if (x > maxX) { + adjustedX = maxX; + } + if (y > maxY) { + adjustedY = maxY - 48; + } + + menu.style.top = adjustedY + "px"; + menu.style.left = adjustedX + "px"; + menu.style.width = ""; + + menu.style.position = 'relative'; + menu.style.zIndex = '5000' + menu.style.scale = 1; + menu.style.opacity = 1; + menu.innerHTML = ``; + if (lastHovered) { + if (lastHovered.id.startsWith("Group")) { + menu.innerHTML += ` +
Duplicate
+
Edit Data
+ +
Delete
+
Copy ID
+
+
${strings.editor.upload_workshop}
+ +
${strings.editor.reset_command_color}
+
+
+ `; + } + + if (lastHovered.id.startsWith("Action")) { + ipcRenderer.send('getCopiedAction'); + ipcRenderer.once('copiedAction', (e, action) => { + menu.innerHTML += ` +
Copy
+ ` + if (action) { + menu.innerHTML += `
Paste + ${Array.isArray(action) ? (`${action.length} Action${action.length != 1 ? "s" : ""}`) : (action.name)} +
` + }; + menu.innerHTML += ` + +
Delete
+
Copy ID
+
`; + }) + + } + if (lastHovered.id == 'folder') { + let folderID = lastHovered.specifically; + menu.innerHTML += ` +
${closedFolders[folderID] ? "Open" : "Close"}
+ +
Delete
+
Copy ID
+
+ `; + } + } +} +function getCaretPosition(element) { + var caretPos = 0; + var sel; + var range; + var clonedRange; + + if (window.getSelection) { + sel = window.getSelection(); + if (sel.rangeCount) { + range = sel.getRangeAt(0); + clonedRange = range.cloneRange(); + clonedRange.selectNodeContents(element); + clonedRange.setEnd(range.endContainer, range.endOffset); + caretPos = clonedRange.toString().length; + } + } else if (document.selection && document.selection.type !== "Control") { + range = document.selection.createRange(); + clonedRange = range.duplicate(); + clonedRange.moveToElementText(element); + clonedRange.setEndPoint("EndToEnd", range); + caretPos = clonedRange.text.length; + } + + return caretPos; +} + +function setCaretPosition(element, caretPos) { + let range; + let offset = caretPos; + let found = false; + + if (document.createRange) { + range = document.createRange(); + for (const node of element.childNodes) { + if (node.nodeType === Node.TEXT_NODE) { + if (offset <= node.textContent.length) { + range.setStart(node, offset); + found = true; + break; + } else { + offset -= node.textContent.length; + } + } + } + + if (!found) { + range.setStart(element, element.childNodes.length); + } + + range.collapse(true); + + const sel = window.getSelection(); + sel.removeAllRanges(); + sel.addRange(range); + } else if (document.selection) { + range = document.body.createTextRange(); + range.moveToElementText(element); + range.moveStart("character", caretPos); + range.collapse(true); + range.select(); + } +} + +function editRawData(group) { + if (areSettingsOpen) return + document.getElementById('titlebar1').style.transition = `all 0.${editorSettings.fastAnimation}s ease` + + areSettingsOpen = true; + menu.remove(); + + setTimeout(() => { + document.getElementById('titlebar1').style.marginTop = '-37px' + }, 100); + document.body.innerHTML += ` +
+ +
+
+
+
${strings.dismissible_content.rawdata_editor_new}
+ Dismiss +
+
${strings.dismissible_content.rawdata_editor_new_subtitle}
+
+
+
+ ${getString(strings.editor.rawdata_editor.folder_id, [botData.commands[group].folder || "null"]?.join(', ') || "")} + + ${strings.misc.copy} + +
+ ${getString(strings.editor.rawdata_editor.id, [botData.commands[group].customId])} + + ${strings.misc.copy} + +
+
+ ${getString(strings.editor.rawdata_editor.description, [botData.commands[group].description])} +
+ ${getString(strings.editor.rawdata_editor.permissions, [botData.commands[group].boundary?.limits || "Unset"])} +
+ ${getString(strings.editor.rawdata_editor.nsfw, [botData.commands[group].boundary?.nsfw || "false"])} +
+ ${getString(strings.editor.rawdata_editor.installable, [botData.commands[group].boundary?.installable || "false"])} + +
+
+
${strings.misc.exit}
+
+
${strings.editor.rawdata_editor.serialized_upload}
+
${strings.editor.rawdata_editor.deserialized_upload}
+
+
+
+
+ ` +} + +function pasteActionTo(index) { + ipcRenderer.send('getCopiedAction') + + ipcRenderer.once('copiedAction', (e, action) => { + if (action) { + createCheckpoint(); + if (Array.isArray(action)) { + let pasteIndex = Number(index) + 1; + action.forEach(act => { + botData.commands[lastObj].actions.splice(pasteIndex, 0, act); + pasteIndex++ + }); + saveLocally(); + refreshActions(); + } else { + botData.commands[lastObj].actions.push(action); + botData.commands[lastObj].actions = moveArrayElement( + botData.commands[lastObj].actions, + botData.commands[lastObj].actions.length - 1, + parseFloat(index) + 1, + ); + saveLocally(); + refreshActions(); + } + } + }) + +} + +window.oncontextmenu = function (event) { + showCustomMenu(event.clientX, event.clientY, event.target); + return false; +}; + +window.addEventListener("click", function (event) { + if (menu && !preventClose) { + menu.style.scale = "var(--menu-initial-scale)"; + menu.style.opacity = "var(--menu-initial-opacity)"; + setTimeout(() => { + menu.remove(); + menu = null; + }, editorSettings.commonAnimation * 100); + } +}); + +function getOffset(el) { + const rect = el.getBoundingClientRect(); + return { + left: rect.left + window.scrollX, + top: rect.top + window.scrollY, + }; +} + +async function handleKeybind(keyEvent) { + if (keyEvent.key == 'Enter' && searchBar) { + document.getElementById('searchResults').firstElementChild.nextElementSibling.onclick() + } + if (keyEvent.key.toLowerCase() == keybinds.search.key && keyEvent[keybinds.modifier] == true && keyEvent.repeat == false) { + toggleSearch() + } + + if (Number(keyEvent.key) != NaN && keyEvent[keybinds.modifier]) { + if (lastHighlightedType == 1) { + if (isHoldingCTRL && !keyEvent.shiftKey) { + isHoldingCTRL = false; + await highlight(document.getElementById(`Action${keyEvent.key - 1}`)); + isHoldingCTRL = true; + } + } + } + + if (keyEvent.key.toLowerCase() == keybinds.save.key && keyEvent[keybinds.modifier] == true) { + saveLocally(); + savePrj(); + } + + if (keyEvent.key.toLowerCase() == keybinds.newAction.key && keyEvent[keybinds.modifier] == true) { + newObject(1) + } + + if (keyEvent.key.toLowerCase() == keybinds.newCommand.key && keyEvent[keybinds.modifier] == true) { + newObject(0) + } + + + + if (keyEvent.key == 'Escape') { + if (searchBar) { + toggleSearch(); + } + } + + if (document.activeElement.tagName != "BODY") return; + + if (keyEvent.key.toLowerCase() == "d" && keyEvent[keybinds.modifier] == true) { + duplicateGroup(lastObj) + return + } + + if (keyEvent.key == 'ArrowUp') { + if (lastHighlightedType == 1) { + highlight(document.getElementById(`Action${Number(lastAct) - 1}`)); + } + if (lastHighlightedType == 0) { + await highlight(document.getElementById(`Group${Number(lastObj) - 1}`)); + if (botData.folders[botData.commands[lastObj].folder].closed) { + toggleFolderVisibility(botData.commands[lastObj].folder, document.getElementById(`${botData.commands[lastObj].folder}closebutton`)) + saveLocally(); + recacheFolders(); + } + } + } + + if (keyEvent.key.toLowerCase() == 'a' && keyEvent[keybinds.modifier] && document.activeElement.tagName == 'BODY') { + if (lastHighlightedType == 1) { + selectedActions = []; + + highlight(document.getElementById(`Action0`)); + botData.commands[lastObj].actions.forEach((act, index) => { + if (index != 0) { + highlight(document.getElementById(`Action${index}`)) + } + }); + selectedActions.sort((a, b) => a - b) + } + } + + let symbolsToNumbers = { + "!": "1", + "@": "2", + "#": "3", + "$": "4", + "%": "5", + "^": "6", + "&": "7", + "*": "8", + "(": "9", + ")": "10" + }; + + if (keyEvent.shiftKey && symbolsToNumbers[keyEvent.key] && !keyEvent[keybinds.modifier]) { + isHoldingCTRL = true; + await highlight(document.getElementById(`Action${Number(symbolsToNumbers[keyEvent.key]) - 1}`)); + isHoldingCTRL = false; + } + + if (keyEvent.key == 'ArrowDown') { + if (lastHighlightedType == 1) { + highlight(document.getElementById(`Action${Number(lastAct) + 1}`)); + } + if (lastHighlightedType == 0) { + await highlight(document.getElementById(`Group${Number(lastObj) + 1}`)); + if (botData.folders[botData.commands[lastObj].folder].closed) { + toggleFolderVisibility(botData.commands[lastObj].folder, document.getElementById(`${botData.commands[lastObj].folder}closebutton`)) + saveLocally(); + recacheFolders(); + } + } + } + + if (keyEvent.key == 'Enter') { + createCheckpoint({ recacheFolders: true }); + + if (lastHighlightedType == 1) { + highlight(document.getElementById(`Action${lastAct}`)); + editAction(lastAct); + } + if (lastHighlightedType == 0) { + lastHighlightedType = 1; + } + if (lastHighlightedType == 2) { + toggleFolderVisibility(lastFolder, document.getElementById(`${lastFolder}closebutton`)) + saveLocally(); + recacheFolders(); + } + } + + if (keyEvent.key.toLowerCase() == 'c' && keyEvent[keybinds.modifier] == true && !keyEvent.repeat) { + if (lastHighlightedType == 0) { + document.getElementById(`Group${lastObj}`).style.rotate = '-2deg' + setTimeout(() => { + document.getElementById(`Group${lastObj}`).style.rotate = '2deg' + setTimeout(() => { + document.getElementById(`Group${lastObj}`).style.rotate = '0deg' + }, 100); + }, 100); + + ipcRenderer.send('copiedAction', botData.commands[lastObj].actions); + notify('Copied ' + botData.commands[lastObj].actions.length + ' Actions!') + } + + if (lastHighlightedType == 1) { + if (selectedActions.length != 0) { + notify('Copied ' + selectedActions.length + ` Action${selectedActions.length == 1 ? "" : "s"}`); + + let toSend = []; + + selectedActions.forEach(action => { + toSend.push(botData.commands[lastObj].actions[action]) + }) + + ipcRenderer.send('copiedAction', toSend); + } else { + ipcRenderer.send('copiedAction', botData.commands[lastObj].actions[lastAct]); + } + } + + if (lastHighlightedType == 2) { + document.getElementById(`${lastFolder}`).style.rotate = '-2deg' + setTimeout(() => { + document.getElementById(`${lastFolder}`).style.rotate = '2deg' + setTimeout(() => { + document.getElementById(`${lastFolder}`).style.rotate = '' + }, 100); + }, 100); + + let copiedActions = []; + let totalActions = 0; + + let folder = cachedFolders[lastFolder]; + let commandsArray = []; + + botData.commands.forEach((value, index) => { + if (index >= folder.first && index <= folder.last) { + commandsArray.push(value) + } + }); + + commandsArray.map(command => command.actions).forEach(actions => { + actions.forEach(action => { + copiedActions.push(action); + totalActions++ + }) + }); + + ipcRenderer.send('copiedAction', copiedActions); + + notify('Copied ' + copiedActions.length + ` Action${totalActions == 1 ? "" : "s"}`); + } + } + + if (keyEvent.key.toLowerCase() == 'v' && keyEvent[keybinds.modifier] == true && !keyEvent.repeat) { + if (lastHighlightedType != 2) { + let toInsertAt = lastAct; + toInsertAt++ + ipcRenderer.send('getCopiedAction'); + + ipcRenderer.once('copiedAction', (event, actions) => { + createCheckpoint() + if (Array.isArray(actions)) { + actions.forEach(action => { + botData.commands[lastObj].actions.splice(toInsertAt, 0, action); + toInsertAt++ + }) + } else { + botData.commands[lastObj].actions.splice(Number(lastAct) + 1, 0, actions) + } + refreshGroups(); + saveLocally(); + }) + } + } + + if (keyEvent.key == 'Delete') { + if (document.activeElement.tagName != 'BODY') return + if (lastHighlightedType == 1 && (selectedActions.length != 0 || botData.commands[lastObj]?.actions[lastAct])) { + createCheckpoint({ recacheFolders: false }); + + if (selectedActions.length != 0) { + if (editorSettings.actionDeletionScreening) { + let keepGoing = await awaitIPCResponse({ channel: "deleteScreening", content: `Are you sure you want to delete ${selectedActions.length} actions?` }, 'deletionModalInteraction'); + if (!keepGoing) return; + } + + let endActions = []; + for (let action in botData.commands[lastObj].actions) { + if (!selectedActions.includes(`${action}`)) { + endActions.push(botData.commands[lastObj].actions[action]) + } + } + botData.commands[lastObj].actions = endActions; + } else { + deleteAction(lastAct); + } + refreshActions(); + saveLocally(); + } + + if (lastHighlightedType == 0) { + createCheckpoint({ recacheFolders: true }); + deleteCommand(lastObj) + } + + if (lastHighlightedType == 2) { + createCheckpoint({ recacheFolders: true }); + deleteFolder(lastFolder) + } + } + + if (keyEvent.key.toLowerCase() == 'z' && keyEvent[keybinds.modifier] == true) { + undo(); + } + + if (keyEvent.key.toLowerCase() == 'y' && keyEvent[keybinds.modifier] == true) { + redo(); + } + + if (keyEvent.key.toLowerCase() == 'q' && keyEvent[keybinds.modifier] == true) { + toggleBotStatus('shutdownBot'); + } + + if (keyEvent.key.toLowerCase() == keybinds.create.key && keyEvent[keybinds.modifier] == true) { + newAction(); + } + + if (keyEvent.key.toLowerCase() == keybinds.toggle.key && keyEvent[keybinds.modifier] == true) { + resizeCommands(); + } +} + +let searchBar; + +function fuzzyMatch(str, pattern, accuracy) { + pattern = pattern.replace(/[-\\\/^$*+?.()|[\]{}]/g, "\\$&"); + pattern = pattern.split("").reduce((a, b) => a + `.*${b}`, ""); + + const regex = new RegExp(pattern, "i"); + const matchScore = str.match(regex) ? str.match(regex)[0].length : 0; + const requiredScore = str.length * accuracy; + + return matchScore >= requiredScore; +} + +function toggleSearch(preview) { + if (searchBar == undefined) { + if (searchBar == undefined && areSettingsOpen) return; + document.getElementById('searchIcon').style.rotate = '360deg' + areSettingsOpen = true; + searchBar = document.createElement('div'); + searchBar.className = 'search' + searchBar.style.zIndex = '2147483647' + searchBar.style.position = 'relative' + + document.body.appendChild(searchBar); + searchBar.innerHTML = ` + +
+ Start your search with : to search within ${botData.commands[lastObj]?.name || "nothing"}'s actions, ! to search for a(n) ${selectedGroupType} and / to search through available automations. + ` + + setTimeout(() => { + searchBar.firstElementChild.focus(); + searchBar.style.opacity = '1'; + searchBar.style.scale = '1'; + searchBar.style.filter = 'unset' + }, 30); + } else { + document.getElementById('searchIcon').style.rotate = '0deg' + areSettingsOpen = false; + searchBar.style.scale = '' + searchBar.style.opacity = '' + searchBar.style.filter = '' + const cachedsearchbar = searchBar; + searchBar = undefined; + setTimeout(() => { + cachedsearchbar.remove(); + }, editorSettings.commonAnimation * 100); + } +} + +if (botData.openThemesAtLaunch) { + botData.openThemesAtLaunch = false; + saveLocally(); + + toggleSearch(); + + let themes = []; + + fs.readdirSync('./Themes').forEach(themeFolder => { + try { + let themeData = require(`${processPath}/Themes/${themeFolder}/data.json`); + themes.push({ ...themeData, folder: themeFolder }) + } catch (error) { } + }) + + searchBar.style.height = 'fit-content' + searchBar.style.paddingBottom = '5px' + searchBar.style.maxHeight = '500px' + searchBar.innerHTML = ` + ${studioUI.dropdown({ + name: 'Theme', + options: [{ name: "Default", value: "default" }, ...themes.map((theme) => { return { name: theme.name, value: theme.folder } })], + currentChoice: settings.theme, + onclick: "pickTheme(this.parentElement.dataset.chosen)", + forcePush: true, + style: "width: 98.5% !important;" + })} + + ${strings.misc.done} + ` +} + +function pickTheme(theme) { + settings.theme = theme; + saveSettings(); + + try { + let themeCss = fs.readFileSync(`./Themes/${theme}/theme.css`, 'utf8'); + + if (document.getElementById('theme_container')) { + document.getElementById('theme_container').innerHTML = themeCss + } else { + let styleSheet = document.createElement('style'); + styleSheet.id = 'theme_container'; + styleSheet.innerHTML = themeCss; + document.body.appendChild(styleSheet) + } + document.body.style.background = 'var(--editor-background)' + } catch (error) { + document.getElementById('theme_container').innerHTML = '' + setColor({ style: { background: botData.color || "rgb(0, 0, 0)" } }); + } +} + + +try { + pickTheme(settings.theme) +} catch (error) { + pickTheme('default') +} + +async function search(query) { + await new Promise(res => { + res() + if (loadedAutomations.length == 0) { + fs.readdirSync('./Automations').forEach((folderName) => { + try { + loadedAutomations.push({ + ...require(`${process.cwd()}/Automations/${folderName}/data.json`), ...{ + id: folderName + } + }); + } catch (error) { } + }) + } + }) + + + let results = document.getElementById('searchResults') + results.innerHTML = '' + if (query == '') { + searchBar.style.marginTop = '' + setTimeout(() => { + results.style.height = '0px' + }, 10); + return + } else { + searchBar.style.marginTop = '2vh' + } + + let queryTypes = { + '/': "automations", + '!': "commands", + ':': "actions", + } + + let queryType = [queryTypes[query[0]]]; + if (!queryType[0]) { + queryType = ["actions", "automations", "commands"]; + } else { + query = query.substring(1) + } + + + let actions = botData.commands[lastObj].actions; + + let resultsFound = 0; + + let endResults = { + actions: [], + automations: [], + commands: [] + } + + queryType.forEach((type) => { + if (type == 'actions') { + actions.forEach((action, index) => { + if (fuzzyMatch(action.name.toLowerCase().replaceAll(' ', ''), query.toLowerCase().replaceAll(' ', ''), 0.12) || Number(query.replaceAll('#', '')) - 1 == index) { + endResults[type].push({ + indicator: `#${index + 1}`, + label: action.name, + actions: [ + { label: "Higlight", onclick: `highlight(document.getElementById('Action${index}'))` }, + { label: "Edit", onclick: `editAction(${index})` }, + ] + }) + } + }); + } else if (type == 'commands') { + botData.commands.forEach((command, index) => { + if (!((command.type == (selectedGroupType == "command" ? "action" : "event")) && command.name.replaceAll(' ', '') != '')) return; + if (!editorSettings.hideCommandInvokers) { + let commandTriggerMap = { + textCommand: botData.prefix, + slashCommand: "/", + } + + preDeco = commandTriggerMap[command.trigger] || `
`; + } + + if (fuzzyMatch(command.name.toLowerCase().replaceAll(' ', ''), query.toLowerCase().replaceAll(' ', ''), 0.12)) { + endResults[type].push({ + label: command.name, + indicator: preDeco, + actions: [ + { label: "Higlight", onclick: `highlight(document.getElementById('Group${index}'))` } + ] + }) + } + }) + } else if (type == 'automations') { + loadedAutomations.forEach((automation) => { + if (fuzzyMatch(automation.name, query.toLowerCase().replaceAll(' ', ''), 0.12)) { + endResults[type].push({ + label: automation.name, + indicator: `
`, + onclick: 0, + actions: [ + { label: "Run", onclick: `runAutomation('${automation.id}')` } + ] + }) + } + }) + } + }) + + + let leftSeparatorDisplay, rightSeparatorDisplay, subtitlePosition; + + switch (editorSettings.subtitlePosition) { + case "left": + leftSeparatorDisplay = "none"; + rightSeparatorDisplay = "inherit; margin-left: 5px !important;"; + subtitlePosition = "margin-left: 5px !important; margin-right: auto;"; + break; + case "right": + rightSeparatorDisplay = "none"; + leftSeparatorDisplay = + "inherit; margin-right: 5px !important; margin-left: 10px !important;"; + subtitlePosition = "margin-right: 0; margin-left: auto;"; + deleteButtonStyling = "margin-left: 5px;"; + break; + case "center": + rightSeparatorDisplay = "inherit"; + leftSeparatorDisplay = "inherit; margin-left: 5px !important;"; + subtitlePosition = "margin-right: 5px; margin-left: 5px;"; + break; + } + + if (editorSettings.focus) { + rightSeparatorDisplay = 'none' + leftSeparatorDisplay = 'none' + } + + let toHTML = (data) => { + return ` +
+ ${data.indicator ? `${data.indicator}` : ""} +
${data.label}
+ +
+ ${data.subtitle ? `${data.subtitle}` : ""} +
+ ${data.actions?.map((i) => { + return ` + ${i.label} + ` + }).join('')} +
+ ` + } + + queryType.forEach((type) => { + if (!endResults[type]?.length) return + resultsFound++ + results.innerHTML += ` + Results for ${type} + ${endResults[type].map(i => toHTML(i)).join('')} +
+ ` + }) + + if (resultsFound == 0) { + results.innerHTML = ` + Oof.. nothing to see here + ` + } + setTimeout(() => { + results.style.height = '270px' + }, 30); +} + + +function refreshIntents() { + return + if (!botData.intents) { + botData.intents = ["all"] + saveLocally() + } + + document.getElementById('intents').innerHTML = '' + + let intents = { + all: "All", + guildMessages: "Guild Messages", + messageContent: "Messages Content", + guilds: "Guilds", + guildExpressions: "Guild Expressions", + directMessages: "Direct Messages", + guildIntegrations: "Guild Integrations", + guildMembers: "Guild Members", + guildInvites: "Guild Invites", + guildPresence: "Guild Presences", + guildModeration: "Guild Moderation", + typingMessages: "Guild Message Typing", + } + + for (let i in intents) { + let intent = intents[i] + document.getElementById('intents').innerHTML += `
${intent}
` + } +} + +function toggleIntent(intent, e) { + if (botData.intents.includes(intent)) { + e.style.background = '' + for (let i in botData.intents) { + if (botData.intents[i] == intent) { + botData.intents.splice(i, 1) + saveLocally() + } + } + } else { + botData.intents.push(intent) + e.style.background = 'var(--accent)' + saveLocally() + } +} + +function dupe(from, target) { + fs.writeFileSync(from, fs.readFileSync(target, 'utf8')) +} + +function saveSettings() { + fs.writeFileSync( + path + "/EditorSettings.json", + JSON.stringify(settings), + ); +} + + + +if (settings.lastVersionOpened != version) { + // toggleSearch(); + // searchBar.style.height = '500px' + // searchBar.style.padding = '12px' + + // let endHTML = `` + + // if (changelog.actions) { + // let end = ` + // New Actions + // ` + // changelog.actions.forEach(act => { + // let action = require(`${process.cwd()}/AppData/Actions/${act}`); + // end += ` + //
+ // See In Action + // ${action.data.name} + //
+ //
${action.category || "Uncategorized"}
+ //
+ // ` + // }); + + // endHTML += `${end}
` + // } + + // if (changelog.updatedActions) { + // let end = ` + // Updated Actions + // ` + // changelog.updatedActions.forEach(act => { + // let action = require(`${process.cwd()}/AppData/Actions/${act.action}`); + // end += ` + //
+ // ${action.data.name} + // + // ${act.update} + //
+ // ` + // }); + + // endHTML += `${end}
` + // } + + // if (changelog.updatedEditor) { + // let end = ` + // Editor Updates + // ` + // changelog.updatedEditor.forEach(update => { + // end += ` + //
+ // ${update.type.toUpperCase()} + // ${update.name} + // ${update.description} + //
+ // ` + // }); + + // endHTML += `${end}
` + // } + + // searchBar.innerHTML = ` + // Just Updated - What's New? Dismiss + //
+ //
+ // ${endHTML} + //
+ // ` +} + +function countUppercaseLetters(str) { + let count = 0; + + for (let i = 0; i < str.length; i++) { + if (str[i] >= 'A' && str[i] <= 'Z') { + count++; + } + } + return count; +} + +function runAutomation(automationID) { + let search = document.getElementsByClassName('search')[0]; + + let automation = require(`./Automations/${automationID}/main.js`); + let automationData = require(`./Automations/${automationID}/data.json`); + + automation.run({ + showInterface: (UI, data) => { + ipcRenderer.send(`openCustom`, { + data: data || { name: automationData.name }, + UI, + name: automationData.name, + actionType: 'text', + }); + + return new Promise((res) => { + ipcRenderer.once('menuData', (event, data) => { + setTimeout(() => { + res(data); + }, 10); + }) + }) + }, + eval, + burstInform: (message) => { + search.innerHTML = ` + ${message} + ` + }, + result: (message) => { + search.style.opacity = 0; + search.style.padding = '0px' + setTimeout(() => { + search.style.padding = '15px' + search.innerHTML = ` + ${message} + ` + setTimeout(() => { + if (searchBar) { + toggleSearch() + } + }, 3000); + + search.style.opacity = 1; + }, editorSettings.commonAnimation * 100); + + } + }); + + search.style.opacity = 0; + setTimeout(() => { + search.style.padding = '15px' + search.innerHTML = ` + ${automationData.name} is running... + ` + search.style.opacity = 1; + }, editorSettings.commonAnimation * 100); +} \ No newline at end of file diff --git a/kits/PopupModalHandler.js b/kits/PopupModalHandler.js new file mode 100644 index 0000000..5281d8e --- /dev/null +++ b/kits/PopupModalHandler.js @@ -0,0 +1 @@ +// don't ask what this is \ No newline at end of file diff --git a/kits/Toolkit/botInit.js b/kits/Toolkit/botInit.js new file mode 100644 index 0000000..cbd4850 --- /dev/null +++ b/kits/Toolkit/botInit.js @@ -0,0 +1,78 @@ +const runCmd = require("node-run-cmd"); +const customFs = require("fs"); + +const filePath = "./bot.js"; +function consoleLog(log) { + document.getElementById( + "console", + ).innerHTML += `
${ansiToHtml( + log, + )}
`; +} + +let ranbot = false; + +const fs = require("fs"); +const { exec } = require("child_process"); +const os = require("os"); + +exec("node -v", (error, stdout, stderr) => { + if (error) { + consoleLog( + "Node.js is not installed. Downloading now... (This will take a while..)", + ); + const platform = os.platform(); + + if (platform === "win32") { + exec( + "winget install --accept-source-agreements --accept-package-agreements nodeJS", + (error, stdout, stderr) => { + if (error) { + consoleLog( + `Error occured whilst downloading Node.JS, please visit the support guild or download Node.JS manually`, + ); + return; + } + consoleLog( + `Finished downloading Node.js! Studio Bot Maker will close in order to comply with the new changes. Please reopen it afterwards!`, + ); + + setTimeout(() => { + require("electron").ipcRenderer.send("restart", true); + }, 7500); + }, + ); + } else { + consoleLog( + "winget is only available on Windows. Please download it manually", + ); + } + } else { + consoleLog(`Node.JS ${stdout} is already installed, jumping directly to Startup.`); + consoleLog(`Checking NPM modules.. This might take a bit`); + + exec("npm i oceanic.js@1.8.0", (err) => { + runBot() + }); + exec("npm i @oceanicjs/builders"); + exec("npm i discord-api-types"); + } +}); + +async function runBot() { + if (ranbot == true) return; + ranbot = true; + customFs.writeFileSync( + "bot.js", + customFs.readFileSync("./AppData/bot.js", "utf8"), + ); + runCmd + .run(`node ${filePath}`, { onData: consoleLog, onError: consoleLog, oncancel: cancelWindow }) + .catch((error) => { + consoleLog(`Error executing bot.js: ${error}`); + }); +} + +let cancelWindow = () => { + ipcRenderer.send('') +} \ No newline at end of file diff --git a/kits/Toolkit/interactionTools.js b/kits/Toolkit/interactionTools.js new file mode 100644 index 0000000..79a37d9 --- /dev/null +++ b/kits/Toolkit/interactionTools.js @@ -0,0 +1,22 @@ +module.exports = { + stopExecution(uID) { + var tempVars = JSON.parse(fs.readFileSync("./tempVars.json", "utf8")); + + tempVars[uID][`${uID}_stop`] = true; + fs.writeFileSync("./tempVars.json", JSON.stringify(tempVars)); + }, + async runCommand(id, actionRunner, uID, client, message) { + const datjson = require("../data.json"); + for (let command in datjson.commands) { + if (datjson.commands[command].customId == id) { + await actionRunner(command, message, client, uID); + } + } + }, + preventDeletion(uID) { + return; + }, + leak(uID, customTimestamp) { + return; + }, +}; diff --git a/kits/Toolkit/storedData.json b/kits/Toolkit/storedData.json new file mode 100644 index 0000000..08ae05c --- /dev/null +++ b/kits/Toolkit/storedData.json @@ -0,0 +1,7 @@ +{ + "users": { }, + "guilds": {}, + "members": {}, + "channels": {}, + "lists": {} +} diff --git a/kits/Toolkit/variableTools.js b/kits/Toolkit/variableTools.js new file mode 100644 index 0000000..1ff2962 --- /dev/null +++ b/kits/Toolkit/variableTools.js @@ -0,0 +1,31 @@ +module.exports = { + transf(text, variables) { + try { + const tempVars = (variable) => { + if (typeof variables[variable] == 'string' || variables[variable] == undefined || typeof variables[variable] == 'number') { + return variables[variable]; + } else { + try { + if (variables[variable].userID) { + return `<@${variables[variable].user.id}>` + } else if (variables[variable].topic && variables[variable].guildID) { + return `<#${variables[variable].id}>` + } else if (variables[variable].publicFlags) { + return `<@${variables[variable].id}>` + } else if (typeof variables[variable].hoist == "boolean") { + return `<@&${variables[variable].id}>` + } + } catch (err) {return variables[variable]} + } + }; + + let formattedText = text; + if (formattedText.includes("`")) { + formattedText = formattedText.replace(/`/g, "/`"); + } + + const evaluatedText = eval("`" + formattedText + "`"); + return evaluatedText; + } catch (err) {return ''} + }, +}; \ No newline at end of file diff --git a/kits/botLoader.js b/kits/botLoader.js new file mode 100644 index 0000000..8fe72f3 --- /dev/null +++ b/kits/botLoader.js @@ -0,0 +1,2 @@ +var Convert = require("ansi-to-html"); +var convert = new Convert(); diff --git a/kits/flex.js b/kits/flex.js new file mode 100644 index 0000000..da9e4d7 --- /dev/null +++ b/kits/flex.js @@ -0,0 +1,814 @@ +let variableInsertionData = {} + +const EventEmitter = require('events'); + +let actionEvents = new EventEmitter(); + +function refreshUI() { + document.getElementById('editorContent').innerHTML = getUIelements(actionUI, false, true) +} + +function emitChange(changed) { + actionEvents.emit('change', { + data: action.data, + type: actionType, + UI: actionUI, + document: document, + events: actionEvents, + changed, + extra: globalData || null, + updateUI: refreshUI + }) +} + +function createDropdown(element, hasField, translations, index, defaultName, toRun) { + return ` + ${element.name ? element.name : defaultName} +
+
+ +
+ +
+ ` +} + +function getUIelements(UI, excludeTitle, excludeScript, options) { + let additional = '' + let indexOffset = 0; + + let endHTML = ` +
+ ${action.name} + ${additional} + +
+ `; + + if (excludeTitle == true) { + endHTML = '' + } else { + endHTML += '
' + } + let pendingMenus = []; + let pendingActions = []; + let pendingTabs = []; + + for (let index in UI) { + let realIndex = Number(index) + let element = UI[index]; + + if (typeof UI[index] == 'string') { + if (UI[index] == '' || UI[index] == 'sep' || UI[index] == 'sepbar' || UI[index] == '-') { + endHTML += '
' + } + if (UI[index] == '_') { + endHTML += `
` + } + } else { + if (options?.starterIndex) { + index = index + (options.starterIndex || 0); + } + + index = Number(index) + indexOffset; + + try { + if (element.element == 'input') { + element.type = undefined; + if (!action.data[element.storeAs]) { + action.data[element.storeAs] = '' + } + + endHTML += `${element.name}` + } + + if (element.element == 'largeInput') { + if (!action.data[element.storeAs]) { + action.data[element.storeAs] = '' + } + endHTML += `${element.name}` + } + + + if (element.element == 'inputGroup') { + if (!action.data[element.storeAs[0]]) { + action.data[element.storeAs[0]] = '' + } + + if (!action.data[element.storeAs[1]]) { + action.data[element.storeAs[1]] = '' + } + + endHTML += ` +
+
+ ${element.nameSchemes[0]} + +
+
+ ${element.nameSchemes[1]} + +
+
+ ` + } + + if (element.element == 'toggle') { + if (!action.data[element.storeAs]) { + action.data[element.storeAs] = false + } + + endHTML += studioUI.toggle({ state: (action.data[element.storeAs] == true || action.data[element.storeAs] == 'true') ? true : false, true: element.true, false: element.false, name: element.name }, `action.data['${element.storeAs}'] = (this.dataset.state == 'true')`) + } + + if (element.element == 'toggleGroup') { + if (!action.data[element.storeAs[0]]) { + action.data[element.storeAs[0]] = false + } + if (!action.data[element.storeAs[1]]) { + action.data[element.storeAs[1]] = false + } + + let leftWidth = `(var(--width-in-editor) / 2 + 4px)`; + let rightWidth = `(var(--width-in-editor) / 2 + 4px)`; + + if (element.prefer == 0) { + leftWidth = `((var(--width-in-editor) / 1.6) - 13.5px)` + rightWidth = `((var(--width-in-editor) / 2.4) - 13.5px)` + } + if (element.prefer == 1) { + rightWidth = `((var(--width-in-editor) / 1.6) - 13.5px)` + leftWidth = `((var(--width-in-editor) / 2.4) - 13.5px)` + } + + endHTML += ` +
+ ${studioUI.toggle({ style: `width: calc(${leftWidth} - var(--padding-super)); margin-right: 2px !important; margin-bottom: 0px; margin-top: 0px !important;`, state: (action.data[element.storeAs[0]] == true || action.data[element.storeAs[0]] == 'true') ? true : false, true: element.true ? element?.true[0] : null, false: element.false ? element?.false[0] : null, name: element?.nameSchemes[0] }, `action.data['${element.storeAs[0]}'] = (this.dataset.state == 'true')`)} + ${studioUI.toggle({ style: `width: calc(${rightWidth} - var(--padding-super)); margin-left: 2px !important; margin-bottom: 0px; margin-top: 0px !important;`, state: (action.data[element.storeAs[1]] == true || action.data[element.storeAs[1]] == 'true') ? true : false, true: element.true ? element?.true[1] : null, false: element.false ? element?.false[1] : null, name: element?.nameSchemes[1] }, `action.data['${element.storeAs[1]}'] = (this.dataset.state == 'true')`)} +
` + } + + if (element.element == 'storageInput' || element.element == 'storage' || element.element == 'store') { + let translations = { + temporary: { name: "Temporary Variable", field: true }, + server: { name: "Server Variable", field: true }, + global: { name: "Global Variable", field: true } + } + + if (element.optional) { + translations.none = { name: "None", field: false } + } + + if (!action.data[element.storeAs]) { + if (element.optional) { + action.data[element.storeAs] = { type: "none", value: "" } + } else { + action.data[element.storeAs] = { type: "temporary", value: "" } + } + } + + if (!translations[action.data[element.storeAs].type]) { + if (element.optional) { + action.data[element.storeAs].type = 'none' + } else { + action.data[element.storeAs].type = 'temporary' + } + } + + + let hasField = translations[action.data[element.storeAs].type].field; + + endHTML += createDropdown(element, hasField, translations, index, 'Store As', { onblur: "recacheOwnVariables()" }) + } + + if (element.element == 'memberInput' || element.element == 'userInput' || element.element == 'member' || element.element == 'user') { + let translations = {} + + if (actionType == 'text') { + translations.mentioned = { name: "Mentioned User", field: false } + translations.author = { name: "Command Author", field: false } + } else if (actionType == 'slash') { + translations.author = { name: "Command Author", field: false } + } else if (actionType == 'message') { + translations.author = { name: "Command Author", field: false } + translations.messageAuthor = { name: "Message Author", field: false } + } else if (actionType == 'user') { + translations.author = { name: "Command Author", field: false } + translations.user = { name: "Command User", field: false } + } + + translations.id = { name: "User ID", field: true }; + + if (element.also) { + for (let o in element.also) { + let also = element.also[o]; + translations[o] = { name: also, field: true } + } + } + + if (element.and) { + for (let o in element.and) { + if (translations[o]) { + let and = element.and[o]; + translations[o].field = and; + } + } + } + + if (element.additionalOptions) { + translations = { + ...element.additionalOptions, + ...translations + } + } + + translations.tempVar = { name: "Temporary Variable", field: true } + translations.serverVar = { name: "Server Variable", field: true } + translations.globVar = { name: "Global Variable", field: true } + + if (!action.data[element.storeAs]) { + let type = 'id'; + + if (actionType == 'text' || actionType == 'slash' || actionType == 'message' || actionType == 'user') { + type = 'author' + } + + action.data[element.storeAs] = { + type, + value: "" + } + } + + if (!translations[action.data[element.storeAs].type]) { + action.data[element.storeAs].type = 'id' + } + + let hasField = translations[action.data[element.storeAs].type].field; + + endHTML += createDropdown(element, hasField, translations, index, 'User') + } + + if (element.element == 'halfDropdown' || element.element == 'dropdown') { + let foundChoice; + + if (!element.preventRecovery) { + if (!action.data[element.storeAs]) { + action.data[element.storeAs] = element.choices[0].name; + } + + if (!action.data[element.extraField] && element.extraField) { + action.data[element.extraField] = ''; + } + + for (let choice of element.choices) { + if (choice.name == action.data[element.storeAs]) { + foundChoice = choice; + } + } + + if (!foundChoice) { + action.data[element.storeAs] = element.choices[0].name + foundChoice = element.choices[0] + } + } else { + foundChoice = { + name: action.data[element.storeAs] || element.choices[0].name + } + } + + let text = `${element.name}` + if (!element.name) { + text = '' + } + endHTML += ` + ${text} +
+
+ +
+ +
+ ` + } + + if (element.element == 'typedDropdown' || element.element == 'typed') { + let translations = element.choices; + + if (!action.data[element.storeAs]) { + let type = translations[0]; + + action.data[element.storeAs] = { + type, + value: "" + } + } + + if (!translations[action.data[element.storeAs].type]) { + action.data[element.storeAs].type = Object.keys(translations)[0]; + } + + let hasField = translations[action.data[element.storeAs].type].field; + + endHTML += createDropdown(element, hasField, translations, index, element.name || "") + } + + if (element.element == 'channelInput' || element.element == 'channel') { + let translations = {} + + if (element.optional) { + translations.none = { name: "None", field: false } + } + + if (actionType == 'text' || actionType == 'message') { + translations.command = { name: "Command Channel", field: false } + translations.mentionedChannel = { name: "Mentioned Channel", field: false } + + + if (!element.excludeUsers) { + translations.commandAuthor = { name: "Command Author", field: false } + translations.mentionedChannel = { name: "Mentioned User", field: false } + if (actionType == 'message') { + translations.user = { name: "Message Author", field: false } + } + } + } else if (actionType == 'slash') { + translations.command = { name: "Command Channel", field: false } + + if (!element.excludeUsers) { + translations.commandAuthor = { name: "Command Author", field: false } + } + } else if (actionType == 'user') { + if (!element.excludeUsers) { + translations.commandAuthor = { name: "Command Author", field: false } + translations.user = { name: "Command User", field: false } + } + } + + translations.id = { name: "Channel ID", field: true } + + if (!element.excludeUsers) { + translations.userID = { name: "User ID", field: true } + } + + if (element.also) { + for (let o in element.also) { + let also = element.also[o]; + translations[o] = { name: also, field: true } + } + } + + if (element.and) { + for (let o in element.and) { + if (translations[o]) { + let and = element.and[o]; + translations[o].field = and; + } + } + } + + if (element.additionalOptions) { + translations = { + ...element.additionalOptions, + ...translations + } + } + + translations.tempVar = { name: "Temporary Variable", field: true } + translations.serverVar = { name: "Server Variable", field: true } + translations.globVar = { name: "Global Variable", field: true } + + if (!action.data[element.storeAs]) { + if (element.optional) { + action.data[element.storeAs] = { + type: "none", + value: "" + } + } else { + let type = 'id'; + + if (actionType == 'text' || actionType == 'slash' || actionType == 'message') { + type = 'command' + } + + action.data[element.storeAs] = { + type, + value: "" + } + } + } + + if (!translations[action.data[element.storeAs].type]) { + if (element.optional) { + action.data[element.storeAs].type = 'none' + } else { + action.data[element.storeAs].type = 'id' + } + } + + let hasField = translations[action.data[element.storeAs].type].field; + + endHTML += createDropdown(element, hasField, translations, index, 'Channel') + } + + if (element.element == 'image' || element.element == 'imageInput') { + let translations = { + none: { name: "None", field: false }, + file: { name: "File", field: true }, + url: { name: "URL", field: true }, + } + + if (!action.data[element.storeAs]) { + if (element.optional) { + action.data[element.storeAs] = { type: 'none', value: '' } + } else { + action.data[element.storeAs] = { type: 'file', value: '' } + } + } + + if (element.also) { + for (let o in element.also) { + let also = element.also[o]; + translations[o] = { name: also, field: true } + } + } + + if (element.and) { + for (let o in element.and) { + if (translations[o]) { + let and = element.and[o]; + translations[o].field = and; + } + } + } + + if (element.additionalOptions) { + translations = { + ...element.additionalOptions, + ...translations + } + } + + translations = { + ...translations, + tempVar: { name: "Temporary Variable", field: true }, + serverVar: { name: "Server Variable", field: true }, + globVar: { name: "Global Variable", field: true } + } + + if (!translations[action.data[element.storeAs].type]) { + if (element.optional) { + action.data[element.storeAs].type = 'none' + } else { + action.data[element.storeAs].type = 'file' + } + } + + let hasField = translations[action.data[element.storeAs].type].field; + + endHTML += createDropdown(element, hasField, translations, index, 'Image') + } + + if (element.element == 'actions') { + pendingActions.push(element); + if (action.data[element.storeAs] == undefined || (typeof action.data[element.storeAs] == 'object' && !Array.isArray(action.data[element.storeAs]))) { + action.data[element.storeAs] = []; + } + + endHTML = `${endHTML} + + +
+
`; + } + + if (element.element == 'menu') { + if (action.data[element.storeAs] == undefined) { + action.data[element.storeAs] = []; + if (element.required) { + action.data[element.storeAs].push({ + type: Object.keys(element.UItypes)[0], + data: undefined + }) + } + } + + if (element.max == 1) { + endHTML += ` +
+ +
+ ` + } else { + endHTML = `${endHTML} +
+ +
+
+
+ + `; + } + + pendingMenus.push(index); + } + + if (element.element == 'text') { + endHTML += `${element.text}` + } + + if (element.element == 'case' || element.element == 'condition') { + if (action.data[element.storeAs] == undefined) { + action.data[element.storeAs] = { + type: 'continue', + value: '' + } + action.data[element.storeActionsAs] = [] + } + + let translations = { + continue: { name: "Continue Actions", field: false }, + stop: { name: "Stop Actions", field: false }, + runActions: { name: "Run Actions", field: false }, + skip: { name: "Skip # Actions", field: true }, + jump: { name: "Jump To Action #", field: true }, + anchorJump: { name: "Jump To Anchor", field: true }, + callAnchor: { name: "Call Anchor", field: true }, + } + let hasField = translations[action.data[element.storeAs].type].field; + + endHTML += createDropdown(element, hasField, translations, index, '', 'toggleDropdownContainer') + + pendingActions.push({ storeAs: element.storeActionsAs }); + endHTML += ` + +
+
+ ` + } + + if (element.element == 'variableInsertion' || element.element == 'var' || element.element == 'variable') { + let translations = { + tempVar: { name: "Temporary Variable", field: true }, + serverVar: { name: "Server Variable", field: true }, + globVar: { name: "Global Variable", field: true } + } + + if (element.optional) { + translations.none = { name: "None", field: false } + } + + if (element.also) { + for (let o in element.also) { + let also = element.also[o]; + translations[o] = { name: also, field: true } + } + } + + if (element.and) { + for (let o in element.and) { + let and = element.and[o]; + translations[o].field = and; + } + } + + if (element.additionalOptions) { + translations = { + ...element.additionalOptions, + ...translations + } + } + + if (!action.data[element.storeAs]) { + if (element.optional) { + action.data[element.storeAs] = { type: "none", value: "" } + } else { + action.data[element.storeAs] = { type: 'tempVar', value: '' } + } + } + + if (!translations[action.data[element.storeAs].type]) { + if (element.optional) { + action.data[element.storeAs].type = 'none' + } else { + action.data[element.storeAs].type = 'tempVar' + } + } + + + let hasField = translations[action.data[element.storeAs].type].field; + + endHTML += createDropdown(element, hasField, translations, index, 'Variable') + } + + if (element.element == 'interaction') { + let translations = {} + + if (actionType == 'slash' || actionType == 'message' || actionType == 'user') { + translations.commandInteraction = { name: "Command Interaction", field: false }; + } + + if (!action.data[element.storeAs]) { + if (actionType == 'slash' || actionType == 'message' || actionType == 'user') { + action.data[element.storeAs] = { type: "commandInteraction", value: "" } + } else { + action.data[element.storeAs] = { type: "tempVar", value: "" } + } + } + + if (!translations[action.data[element.storeAs].type]) { + action.data[element.storeAs].type = 'tempVar' + } + + translations = { + ...translations, + tempVar: { name: "Temporary Variable", field: true }, + serverVar: { name: "Server Variable", field: true }, + globVar: { name: "Global Variable", field: true } + } + + + let hasField = translations[action.data[element.storeAs].type].field; + + endHTML += createDropdown(element, hasField, translations, index, 'Interaction') + } + + if (element.element == 'message' || element.element == 'messageDropdown') { + let translations = {}; + if (element.optional) { + translations.none = { name: "None", field: false } + } + + translations = { + ...translations, + tempVar: { name: "Temporary Variable", field: true }, + serverVar: { name: "Server Variable", field: true }, + globVar: { name: "Global Variable", field: true } + } + + if (actionType == 'text' || actionType == 'message') { + translations.commandMessage = { name: "Command Message", field: false } + } else if (actionType == 'slash') { + translations.interactionReply = { name: "Command Reply", field: false } + } + + if (!action.data[element.storeAs]) { + if (element.optional) { + action.data[element.storeAs] = { type: 'none', value: "" } + } else if (actionType == 'text' || actionType == 'message') { + action.data[element.storeAs] = { type: "commandMessage", value: "" } + } else if (actionType == 'slash') { + action.data[element.storeAs] = { type: "interactionReply", value: "" } + } else { + action.data[element.storeAs] = { type: "tempVar", value: "" } + } + } + + if (!translations[action.data[element.storeAs].type]) { + action.data[element.storeAs].type = element.optional ? 'none' : 'tempVar' + } + + let hasField = translations[action.data[element.storeAs].type].field; + + endHTML += createDropdown(element, hasField, translations, index, 'Message') + } + + if (element.element == 'role' || element.element == 'roleInput') { + let translations = { + id: { name: "ID", field: true }, + } + + if (actionType == 'text' || actionType == 'message') { + translations.mentioned = { name: "Mentioned Role", field: false } + } + + if (!action.data[element.storeAs]) { + action.data[element.storeAs] = { type: "id", value: "" } + } + + if (!translations[action.data[element.storeAs].type]) { + action.data[element.storeAs].type = 'tempVar' + } + + translations = { + ...translations, + tempVar: { name: "Temporary Variable", field: true }, + serverVar: { name: "Server Variable", field: true }, + globVar: { name: "Global Variable", field: true } + } + + let hasField = translations[action.data[element.storeAs].type].field; + + endHTML += createDropdown(element, hasField, translations, index, 'Role') + } + + if (element.element == 'html') { + endHTML += element.html + } + + if (element.element == 'category' || element.element == 'guild') { + let translations = { + id: { name: "ID", field: true } + } + + if (element.element == 'guild') { + translations.current = { name: "Current", field: false } + } + + + if (element.optional) { + translations.none = { name: "None", field: false } + } + + if (!action.data[element.storeAs]) { + if (!element.optional) { + if (translations.current) { + action.data[element.storeAs] = { type: "current", value: "" } + } else { + action.data[element.storeAs] = { type: "id", value: "" } + } + } else { + action.data[element.storeAs] = { type: "none", value: "" } + } + } + + translations = { + ...translations, + tempVar: { name: "Temporary Variable", field: true }, + serverVar: { name: "Server Variable", field: true }, + globVar: { name: "Global Variable", field: true } + } + + if (!translations[action.data[element.storeAs].type]) { + if (!element.optional) { + action.data[element.storeAs].type = 'tempVar' + } else { + action.data[element.storeAs].type = 'none' + } + } + + let hasField = translations[action.data[element.storeAs].type].field; + + endHTML += createDropdown(element, hasField, translations, index, element.element == 'category' ? "Category" : "Server") + } + } catch (err) { console.log(err) } + } + } + + if (options?.returnInstead) { + return endHTML + } + + try { + return endHTML + "
"; + } finally { + setTimeout(() => { + for (let menu in pendingMenus) { + refreshMenuItems(pendingMenus[menu], true); + } + for (let action in pendingActions) { + refreshActions(pendingActions[action].storeAs); + } + + if (actionFile.script && !excludeScript) { + actionFile.script({ + data: action.data, + type: actionType, + UI: actionUI, + document: document, + events: actionEvents, + extra: globalData || null, + updateUI: refreshUI + }) + + emitChange(null); + } + }, 15); + } +} \ No newline at end of file diff --git a/kits/settings.js b/kits/settings.js new file mode 100644 index 0000000..9050583 --- /dev/null +++ b/kits/settings.js @@ -0,0 +1,619 @@ +let settingsFS = require('fs'); +const appID = Number('2592170'); + +let path = 'C:/ProgramData/Bot-Maker-For-Discord' + +if (require('os').platform == 'linux') { + path = './linux-data' +} +if (require('os').platform == 'darwin') { + path = './mac-data' +} + +let ownSettings = { theme: "default", translation: "default" }; +try { + ownSettings = JSON.parse( + settingsFS.readFileSync(path + "/EditorSettings.json", "utf8"), + ); +} catch (err) { + console.log(err); +} + +let editorSettings = { + deletionScreening: true, + focus: ownSettings.focus == 'On' ? true : false, +}; + +switch (ownSettings.bigBrain) { + case 'On': + var sheet = document.styleSheets[1]; + sheet.insertRule(":root{--smallBrainDisplay: none}"); + editorSettings.bigBrain = true; + break + default: + var sheet = document.styleSheets[1]; + editorSettings.bigBrain = false; + sheet.insertRule(":root{--bigBrainDisplay: none}"); + break +} + +switch (ownSettings.preffered) { + default: + editorSettings.groupPaneHeight = "inherit"; + editorSettings.actionPaneHeight = "inherit"; + break; + case "Group Pane": + editorSettings.actionPaneHeight = "calc(35.5vh - 12px)"; + editorSettings.groupPaneHeight = "calc(44.5vh - 12px)"; + break; + case "Action Pane": + editorSettings.groupPaneHeight = "calc(35vh - 12px)"; + editorSettings.actionPaneHeight = "calc(45vh - 12px)"; + break; +} +switch (ownSettings.actionPreviewPosition) { + default: + editorSettings.subtitlePosition = "center"; + break; + case "Right": + editorSettings.subtitlePosition = "right"; + break; + case "Left": + editorSettings.subtitlePosition = "left"; + break; +} +switch (ownSettings.animations) { + case "Slow": + editorSettings.commonAnimation = 6; + editorSettings.fastAnimation = 4; + editorSettings.reallyFast = 1; + break; + case "Relaxed": + editorSettings.commonAnimation = 4; + editorSettings.fastAnimation = 3; + editorSettings.reallyFast = 0.5; + break; + case "Fast": + editorSettings.commonAnimation = 2; + editorSettings.fastAnimation = 1; + editorSettings.reallyFast = 0.01; + break; + case "Off": + editorSettings.commonAnimation = 0; + editorSettings.fastAnimation = 0; + editorSettings.reallyFast = 0; + break; + default: + editorSettings.commonAnimation = 3; + editorSettings.fastAnimation = 2; + editorSettings.reallyFast = 0.16; + break; +} +var sheet = document.styleSheets[0]; +sheet.insertRule(`:root{--commonAnimation: 0.${editorSettings.commonAnimation}s}`); +sheet.insertRule(`:root{--fastAnimation: 0.${editorSettings.fastAnimation}s}`); +sheet.insertRule(`:root{--reallyFast: ${editorSettings.reallyFast}s}`); + + +switch (ownSettings.scaleEffects) { + case '1.2': + var sheet = document.styleSheets[0]; + sheet.insertRule(":root{--scale: 1.1}"); + break + + case '0.8': + var sheet = document.styleSheets[0]; + sheet.insertRule(":root{--scale: 0.95}"); + break +} + +switch (ownSettings.varStyle) { + case "Floating Window": + editorSettings.oldVariableInsertion = true; +} + +switch (ownSettings.scrolling) { + default: + var sheet = document.styleSheets[0]; + window.addEventListener("mousedown", function (event) { + if (event.button === 1) { + event.preventDefault(); + } + }); + sheet.insertRule(":root{--scrollbar: hidden}"); + sheet.insertRule(":root{--scrw: 0px}"); + break + + case "On": + var sheet = document.styleSheets[document.styleSheets.length - 1]; + sheet.insertRule(":root{--scrollbar: overlay}"); + sheet.insertRule(":root{--scrw: 7px}"); + break +} + +switch (ownSettings.pointer) { + default: + var sheet = document.styleSheets[0]; + sheet.insertRule(":root{--pointer: pointer}"); + break + + case 'Arrow': + var sheet = document.styleSheets[0]; + sheet.insertRule(":root{--pointer: default}"); + break +} + +switch (ownSettings.deletionScreening) { + default: + editorSettings.actionDeletionScreening = true; + editorSettings.commandDeletionScreening = true; + break + + case 'Off': + break + + case 'Commands Only': + editorSettings.commandDeletionScreening = true; + break + + case 'Actions Only': + editorSettings.actionDeletionScreening = true; + break +} + +switch (ownSettings.actionButtons) { + case "Left": + editorSettings.leftActionPlacement = false; + break; + default: + editorSettings.leftActionPlacement = true; + break +} + + +switch (ownSettings.editOnCreation) { + case "Just Actions": + editorSettings.editActionsOnCreation = true; + break; + case "Just Menus": + editorSettings.editMenusOnCreation = true; + break; + case "On": + editorSettings.editMenusOnCreation = true; + editorSettings.editActionsOnCreation = true; + break; +} + +editorSettings.animation = ownSettings.windowAnimation + +if (ownSettings.theme == undefined) { + ownSettings.theme = 'default'; +} + +// window.addEventListener('keydown', function(event) { +// if ((event.ctrlKey || event.metaKey) && (event.key === '+' || event.key === '-')) { +// event.preventDefault(); +// } +// }); + + +/** + * @type {{ button: (options: any) => string; toggle: (options: any, onclick: any) => string; toggleSwitch: (element: HTMLDivElement) => void; }} + */ +let studioUI = { + toggle: (options, onclick) => { + return ` +
+ ${options.name} + ${options.false ? options.false : "No"} +
+ ${options.true ? options.true : "Yes"} +
+ ` + }, + + + toggleSwitch: (element) => { + let toggle = element.getElementsByClassName('toggle_bar')[0].getElementsByClassName('toggle_tail')[0] + toggle.style.transition = `all 0.${editorSettings.commonAnimation}s ease`; + toggle.parentElement.style.transition = `all 0.${editorSettings.commonAnimation}s ease`; + + if (element.dataset.state == 'false') { + element.dataset.state = 'true' + + if (ownSettings.highlightToggles == 'On') { + element.classList.add('selected') + } + + toggle.classList.add('toggle_button_animation_false_to_true'); + toggle.classList.add('toggle_button_false_pre'); + toggle.classList.remove('toggle_button_true_pre'); + toggle.classList.remove('toggle_button_true'); + toggle.parentElement.classList.add('toggle_tail_animation_true_to_false'); + + setTimeout(() => { + toggle.classList.remove('toggle_button_animation_false_to_true'); + toggle.parentElement.classList.remove('toggle_tail_animation_true_to_false'); + toggle.classList.add('toggle_button_false'); + }, editorSettings.commonAnimation * 50); + + } else { + element.dataset.state = 'false' + + toggle.classList.remove('toggle_button_false_pre'); + toggle.classList.remove('toggle_button_false'); + toggle.classList.add('toggle_button_true_pre'); + toggle.parentElement.classList.add('toggle_tail_animation_false_to_true'); + element.classList.remove('selected'); + + toggle.classList.add('toggle_button_animation_true_to_false'); + + setTimeout(() => { + toggle.classList.remove('toggle_button_animation_true_to_false'); + toggle.classList.add('toggle_button_true'); + toggle.parentElement.classList.remove('toggle_tail_animation_false_to_true'); + }, editorSettings.commonAnimation * 50); + } + }, + + dropdown: (options) => { + let choices = options.options; + let foundChoice; + choices.forEach(choice => { + if (choice.value == options.currentChoice) { + foundChoice = choice; + } + }); + + if (!foundChoice) { + foundChoice = choices[0]; + } + + return `
+ +
` + }, + + openDropdown: (element, bound) => { + element.style.zIndex = '1000' + element.parentElement.style.zIndex = '1000' + + element.onclick = () => { + studioUI.closeTypedDropdown(element, bound) + } + + let types = JSON.parse(element.parentElement.dataset.options) + + for (let translation of types) { + if (translation.value != element.parentElement.dataset.chosen) { + let option = document.createElement('div') + option.style = '' + option.className = 'dropdown_option' + option.onclick = () => { + studioUI.selectDropdownOption(element, bound, translation); + } + option.innerHTML = translation.name; + element.appendChild(option); + } + } + }, + + selectDropdownOption: (element, bound, translation) => { + element.parentElement.dataset.chosen = translation.value; + + bound(); + }, + + closeTypedDropdown: (element, bound) => { + element.style.animationName = ""; + const innerHeight = element.clientHeight; + element.style.animationDuration = ""; + element.style.setProperty("--inner-height", innerHeight + "px"); + element.style.animationName = "shrink"; + element.style.animationDuration = "300ms"; + element.style.zIndex = '' + element.parentElement.style.zIndex = '' + + setTimeout(() => { + element.onclick = () => { + studioUI.openDropdown(element, bound) + }; + element.innerHTML = JSON.parse(element.parentElement.dataset.options).find(opt => opt.value == element.parentElement.dataset.chosen).name; + }, 70); + }, + + getColors: () => { + return ["rgb(255, 255, 255)", "rgb(255, 0, 0)", "rgb(255, 106, 0)", "rgb(255, 200, 0)", "rgb(187, 255, 0)", "rgb(51, 255, 0)", "rgb(0, 255, 213)", "rgb(0, 132, 255)", "rgb(0, 90, 255)", "rgb(72, 0, 255)", "rgb(119, 0, 255)", "rgb(195, 0, 255)", "rgb(255, 0, 225)"] + }, + + colorPicker: (style, onclick, rgb, realStyle) => { + return ` +
+
+ +
+
+ + ${studioUI.getColors().map((color) => { + return `
` + }).join('')} +
+ ` + }, + + colorSlider: (options, style) => { + return ` + + ${options.inbetween || ""} + + ` + }, + + + colorChange: (slider) => { + var val = slider.value; + var val2 = slider.nextElementSibling.value; + slider.style.setProperty('--chosenColor', `hsl(${val}, 100%, ${val2 * 100}%)`) + slider.nextElementSibling.style.setProperty('--chosenColor', `rgb(${opposite(val2) * 255}, ${opposite(val2) * 255}, ${opposite(val2) * 255})`) + }, + + togglePicker: (element) => { + let sibling = element; + if (sibling.style.width == '33px') { + sibling.style.width = '518.4px' + setTimeout(() => { + sibling.style.overflow = 'visible' + }, editorSettings.commonAnimation * 100); + } else { + sibling.style.width = '33px' + sibling.style.overflow = 'hidden' + } + }, + + colorPickerToggle: (id, constant) => { + document.getElementById(`${constant}red`).style.width = '0%' + document.getElementById(`${constant}red`).style.opacity = '0%' + document.getElementById(`${constant}red`).style.height = '0px' + document.getElementById(`${constant}green`).style.width = '0%' + document.getElementById(`${constant}green`).style.opacity = '0%' + document.getElementById(`${constant}green`).style.height = '0px' + document.getElementById(`${constant}blue`).style.width = '0%' + document.getElementById(`${constant}blue`).style.opacity = '0%' + document.getElementById(`${constant}blue`).style.height = '0px' + + setTimeout(() => { + if (resolvedToggles[constant] != id) { + document.getElementById(id).style.width = '100%' + document.getElementById(id).style.opacity = '1' + document.getElementById(id).style.height = '30px' + resolvedToggles[constant] = id; + } else { + resolvedToggles[constant] = undefined; + } + }, resolvedToggles[constant] ? editorSettings.commonAnimation * 100 : 1); + }, +} + +function opposite(number) { + return (-number) + 1; +} + + + +let resolvedToggles = {}; + +async function awaitIPCResponse(send, receive) { + return new Promise(resolve => { + ipcRenderer.send(send.channel, send.content); + + ipcRenderer.once(receive, (event, data) => { + resolve(data) + }) + }) +} + +let keybindOverwrites = {} + + +if (ownSettings.keybindOverwrites) { + for (let key in ownSettings.keybindOverwrites) { + let kbd = ownSettings.keybindOverwrites[key]; + keybindOverwrites[key] = kbd; + } +} + +let keybinds = { + save: { display: `CTRL+${(keybindOverwrites.save || "s").toUpperCase()}`, key: (keybindOverwrites.save || "s") }, + save_exit: { display: `CTRL+${(keybindOverwrites.save_exit || "q").toUpperCase()}`, key: (keybindOverwrites.save_exit || "q") }, + search: { display: `CTRL+${(keybindOverwrites.search || "k").toUpperCase()}`, key: (keybindOverwrites.search || "k") }, + done: { display: `CTRL+${(keybindOverwrites.done || "q").toUpperCase()}`, key: (keybindOverwrites.done || "q") }, + create: { display: `CTRL+${(keybindOverwrites.create || "d").toUpperCase()}`, key: (keybindOverwrites.create || "d") }, + toggle: { display: `CTRL+${(keybindOverwrites.resize || "`").toUpperCase()}`, key: (keybindOverwrites.resize || "`") }, + toggleState: { display: `CTRL+${(keybindOverwrites.resize || "`").toUpperCase()}`, key: (keybindOverwrites.resize || "`") }, + newAction: { display: `CTRL+${(keybindOverwrites.newAction || "n").toUpperCase()}`, key: (keybindOverwrites.resize || "n") }, + newCommand: { display: `CTRL+${(keybindOverwrites.newCommand || "j").toUpperCase()}`, key: (keybindOverwrites.resize || "j") }, + exit: { display: `CTRL+TAB`, key: "tab" }, + modifier: "ctrlKey", + modifier_readable: "CTRL", +} + +const keybindElements = { + 'keybind-save': keybinds.save.display, + 'keybind-save-exit': keybinds.save_exit.display, + 'keybind-exit': keybinds.exit.display, + 'keybind-search': keybinds.search.display, + 'keybind-done': keybinds.done.display, + 'keybind-create': keybinds.create.display +}; + +for (const [className, displayText] of Object.entries(keybindElements)) { + for (const element of document.getElementsByClassName(className)) { + element.innerHTML = displayText; + } +} + + +try { + var datjson = JSON.parse(settingsFS.readFileSync("./AppData/data.json")); +} catch (error) { + var datjson = {} +} +function finishEverything(cb) { + if (ownSettings.theme == 'default' || ownSettings.theme == undefined) { + document.getElementById("everything_container").style.background = `linear-gradient(130deg, ${ownSettings.firstColor || `rgb(0, 0, 0)`}, ${ownSettings.secondColor || `rgb(18, 18, 18)`})`; + } else { + document.getElementById("everything_container").style.background = `var(--window-background)`; + try { + document.getElementById('everything_container_2').style.backgroundColor = 'unset' + } catch (error) { } + } + + let easingFunction = 'ease' + + if (editorSettings.animation == 'Push' || !editorSettings.animation) { + document.getElementById("everything_container").style.transform = "rotate3d(12, 0, 0, -90deg)"; + document.getElementById("everything_container").style.scale = "0"; + // easingFunction = 'ease-in-out' + } else if (editorSettings.animation == 'Simple') { + document.getElementById("everything_container").style.scale = "1"; + document.getElementById("everything_container").style.opacity = "0"; + document.getElementById("everything_container").style.filter = "blur(0px)"; + } + + + setTimeout(() => { + document.body.style.transition = `all 0.${editorSettings.commonAnimation}s ${easingFunction}`; + document.body.style.backgroundColor = "#FFFFFF00"; + document.getElementById("everything_container").style.transition = `all 0.${editorSettings.commonAnimation}s ${easingFunction}`; + document.getElementById("everything_container").style.transform = "rotate3d(12, 0, 0, 0deg)"; + document.getElementById("everything_container").style.scale = "1"; + document.getElementById("everything_container").style.opacity = "1"; + document.getElementById("everything_container").style.filter = "blur(0px)"; + if (cb) { + setTimeout(() => { + cb() + }, editorSettings.commonAnimation * 100); + } + }, 20); +} + +async function unfinishEverything(callback) { + if (editorSettings.animation == 'Simple') { + document.getElementById("everything_container").style.opacity = "0"; + } else if (editorSettings.animation == 'Expand') { + document.getElementById("everything_container").style.scale = "0"; + document.getElementById("everything_container").style.filter = "blur(40px)"; + } else { + document.getElementById("everything_container").style.transform = "rotate3d(100, 0, 0, 90deg)"; + document.getElementById("everything_container").style.scale = "0"; + document.getElementById("everything_container").style.filter = "blur(40px)"; + } + + setTimeout(() => { + callback(); + }, editorSettings.commonAnimation * 100); +} + +try { + let themeCss = settingsFS.readFileSync(`./Themes/${ownSettings.theme}/theme.css`, 'utf8'); + + let styleSheet = document.createElement('style'); + styleSheet.id = 'theme_container'; + styleSheet.innerHTML = themeCss; + document.body.appendChild(styleSheet); +} catch (error) { + let styleSheet = document.createElement('style'); + styleSheet.id = 'theme_container'; + styleSheet.innerHTML = ''; + document.body.appendChild(styleSheet); +} + + +let cachedStrings; + +function getStrings() { + try { + if (cachedStrings) return cachedStrings; + let result; + let strings = require(`${process.cwd()}/cachedStrings.json`); + cachedStrings = strings; + return result; + } catch (error) { } +} +getStrings() + + +function getString(string, replacements) { + for (let i in replacements) { + string = string.replace(`+${Number(i) + 1}`, replacements[i]) + } + + return string; +} + +function dismissContent(content) { + if (!settingsFS.existsSync('./Dismissed Content')) { + settingsFS.mkdirSync('./Dismissed Content') + } + + settingsFS.writeFileSync(`./Dismissed Content/${content}`, '1') +} +function isDismissed(content) { + return settingsFS.existsSync(`./Dismissed Content/${content}`, () => { }) +} + +function clipboardCopy(toCopy) { + navigator.clipboard.writeText(toCopy) +} + +function updateTopBarContent(updated, specifity) { + let element = specifity ? document.getElementById(specifity) : document.getElementsByClassName('editor_toolbar')[0].getElementsByTagName('btext')[0] + element.style.transition = `all 0.${editorSettings.commonAnimation}s cubic-bezier(.47,.75,.36,1.54), blur ease var(--commonAnimation), var(--ease-strong) var(--commonAnimation)` + + setTimeout(() => { + element.style.scale = '0.7'; + element.style.opacity = '0'; + element.style.filter = 'blur(12px)'; + setTimeout(() => { + element.innerHTML = updated; + }, editorSettings.commonAnimation * 100); + setTimeout(() => { + element.style.scale = '1'; + element.style.opacity = '1'; + element.style.filter = ''; + }, editorSettings.commonAnimation * 110); + }, 10); +} + +var processPath = require('process').cwd(); + +if (datjson.structureType != '1') { + processPath = processPath + `/Legacy`; +} + +for (let i in document.getElementsByTagName('translation')) { + let element = document.getElementsByTagName('translation')[i]; + element.innerHTML = eval(`cachedStrings.${element.id}`); +} + +const hexToRGB = (hex) => { + const r = parseInt(hex.slice(1, 3), 16); + const g = parseInt(hex.slice(3, 5), 16); + const b = parseInt(hex.slice(5, 7), 16); + + return `rgb(${r}, ${g}, ${b})`; +} + +function componentToHex(c) { + var hex = c.toString(16); + return hex.length == 1 ? "0" + hex : hex; +} + +function rgbToHEX(rgb) { + let rgbSeparated = rgb.replaceAll('rgb(', '').replaceAll(')', '').split(', '); + let r = rgbSeparated[0]; + let g = rgbSeparated[1]; + let b = rgbSeparated[2]; + console.log(r, g, b, rgbSeparated) + return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b); +} diff --git a/kits/temp.js b/kits/temp.js new file mode 100644 index 0000000..e69de29 diff --git a/kits/variableInsertion.js b/kits/variableInsertion.js new file mode 100644 index 0000000..fc8bcbd --- /dev/null +++ b/kits/variableInsertion.js @@ -0,0 +1,530 @@ +window.oncontextmenu = function (event) { + if (!menu) { + setTimeout(() => { + showCustomMenu(event.clientX, event.clientY); + }, 200); + } + showCustomMenu(event.clientX, event.clientY); + return false; +}; +let mOpened = false; + +function getVars(type, eID) { + foundVarType = [...commandVars, ...tempVars] + if (type == 'server') { + foundVarType = [...thisServer, ...serverVars] + } else if (type == 'global') { + foundVarType = [...thisGlobal, ...globalVars] + } + + let used = []; + let endHTML = '' + if (type == 'command') { + let rawVariables = ownSettings.commandVariables; + let variables = {} + + for (let variable in rawVariables) { + if (!rawVariables[variable].commandTypeLimits.length || rawVariables[variable].commandTypeLimits.includes(actionType)) { + variables[variable] = rawVariables[variable] + } + } + + for (let type in variables) { + endHTML += ` +
+ ${type} +
+ `; + } + } else { + for (let variable in foundVarType) { + try { + if (foundVarType[variable].trim() != "" && !used.includes(foundVarType[variable])) { + used.push(foundVarType[variable]) + endHTML += ` +
${foundVarType[variable]}
+ `; + } + } catch (err) { console.error(err) } + } + } + + setTimeout(() => { + document.getElementById('vars-temporary').classList.remove('highlighted') + document.getElementById('vars-server').classList.remove('highlighted') + document.getElementById('vars-global').classList.remove('highlighted') + try { + document.getElementById('vars-command').classList.remove('highlighted') + } catch (error) { } + document.getElementById(`vars-${type}`).classList.add('highlighted') + }, 100); + + return (endHTML || `Your variables will appear here!`) +} + +function showCustomMenu(x, y) { + let computedHeight = 'auto' + if (!menu) { + menu = document.createElement("div"); + document.body.appendChild(menu); + menu.className = "right_click_menu"; + } + // Calculate the maximum allowed coordinates based on window dimensions + const windowWidth = window.innerWidth; + const windowHeight = window.innerHeight; + const menuWidth = menu.offsetWidth; + const menuHeight = menu.offsetHeight; + const maxX = windowWidth - menuWidth; + const maxY = windowHeight - menuHeight; + let adjustedScale = 1; + // Adjust the menu position if it exceeds the window boundaries + let adjustedX = x; + let adjustedY = y; + if (x > maxX) { + adjustedX = maxX; + } + if (y > maxY) { + adjustedY = maxY - 48; + } + + menu.style.top = adjustedY + "px"; + menu.style.left = adjustedX + "px"; + menu.style.maxHeight = '400px' + + menu.style.scale = adjustedScale; + menu.style.opacity = `1`; + + let type = 'indirect' + menu.onmouseenter = () => { + mOpened = true; + } + menu.onmouseleave = () => { + setTimeout(() => { + mOpened = false; + }, 20); + } + + if (actionType != 'event') { + menu.innerHTML = ` +
+
Command
+
Temporary
+
Server
+
Global
+
+ +
+
+
+ `; + } else { + menu.innerHTML = ` +
+
Temporary
+
Server
+
Global
+
+ +
+
+ `; + } + + + setTimeout(() => { + document.getElementById('VARINSMENU').innerHTML = getVars('temporary', `${document.activeElement.id}`) + }, 10); + + if (document.activeElement.tagName.toLowerCase() == 'input' || document.activeElement.tagName.toLowerCase() == 'textarea') { + menu.style.width = '348px' + if (variableInsertionData.type) { + type = variableInsertionData.type; + } else if (variableInsertionData.accept == false || variableInsertionData.accept) { + type = variableInsertionData.accept ? 'indirect' : 'off' + } else if (variableInsertionData.direct) { + type = 'direct' + } else if (variableInsertionData.custom) { + let direct = ['tempVar', 'cmdVar', 'serverVar', 'globVar']; + + let UIelement = actionUI[variableInsertionData.elementIndex]; + if (direct.includes(action.data[UIelement.storeAs].type)) { + type = action.data[UIelement.storeAs].type + } + } + } else { + menu.style.width = '' + menu.innerHTML = ``; + if (lastHovered != undefined) { + menu.innerHTML += ` +
Copy
+ `; + } + + if (lastActionContainer) { + ipcRenderer.send('getCopiedAction'); + ipcRenderer.once('copiedAction', (event, Action) => { + if (Action) { + menu.innerHTML += ` +
+ Paste + ${Array.isArray(Action) ? `${Action.length} Action${Action.length != 1 ? "s" : ""}` : Action.name} +
+ `; + } + + menu.innerHTML += ` + +
Delete
+
Copy ID
+
` + }); + } + + if (lastHoveredContainer) { + if (highlights[lastHoveredContainer].type == 2) { + if (lastHoveredMenu) { + menu.innerHTML += ` +
Copy
+ ` + } + ipcRenderer.send('getCopiedMenu'); + ipcRenderer.once('copiedMenu', (event, Menu) => { + if (Menu) { + menu.innerHTML += ` +
Paste ${Array.isArray(Menu) ? Menu.length : "1"} Element${(Array.isArray(Menu) ? Menu.length : 1) != 1 ? "s" : ""}
` + if (action.data[highlights[lastHoveredContainer].menu]) { + menu.innerHTML += ` +
Copy
` + } + } + if (lastHoveredMenu) { + if (actionUI[lastHoveredMenu.menu].max != action.data[actionUI[lastHoveredMenu.menu].storeAs].length) { + menu.innerHTML += ` +
Delete
+ ` + + } + } + }) + } + } + + } +} + +function closeContextmenu(force) { + if (menu && !mOpened || force) { + menu.style.scale = ""; + menu.style.opacity = ""; + setTimeout(() => { + menu.remove(); + menu = undefined; + }, 200); + } +} + +function copyAction(Action, container) { + if (highlights[container].selected.length != 0) { + ipcRenderer.send('copiedAction', highlights[container].selected.map((value) => action.data[container][value])); + } else { + ipcRenderer.send('copiedAction', action.data[`${container}`][`${Action}`]); + } + closeContextmenu(true) +} + +function pasteCopiedIn(container, Action) { + ipcRenderer.send('getCopiedAction'); + ipcRenderer.once('copiedAction', (event, _Action) => { + let pasteIndex = action.data[container].length - 1; + if (action.data[container][Action]) { + pasteIndex = Number(Action) + 1; + } + + if (_Action) { + if (Array.isArray(_Action)) { + _Action.forEach(act => { + action.data[container].splice(pasteIndex, 0, act); + pasteIndex++ + }); + } else { + action.data[container].splice(Number(highlights[container].highlighted) + 1, 0, _Action) + } + } + refreshActions(container) + }); + + closeContextmenu(true) +} + +function pasteMenuIn(container, menu) { + ipcRenderer.send('getCopiedMenu'); + ipcRenderer.once('copiedMenu', (event, unhandledMenu) => { + if (!unhandledMenu) return + if (document.getElementById(actionUI[highlights[container].menu].storeAs).getElementsByClassName('backArrow').length) { + document.getElementById(actionUI[highlights[container].menu].storeAs).getElementsByClassName('backArrow')[0].parentElement.style.opacity = '0' + } + + let Menu; + + let menuObject = actionUI[highlights[container].menu] + let max = menuObject.max; + let current = action.data[container].length; + + if (Array.isArray(unhandledMenu)) { + Menu = [] + + unhandledMenu.forEach(item => { + if (Object.keys(menuObject.types).includes(item.type)) { + current++ + if (current < max) { + Menu.push(item) + } + } + }) + } else { + if (Object.keys(menuObject.types).includes(unhandledMenu.type)) { + Menu = unhandledMenu; + } + } + + let pasteIndex = action.data[container].length - 1; + if (action.data[container][menu]) { + pasteIndex = Number(menu) + 1; + } + + if (Menu) { + if (Array.isArray(Menu)) { + Menu.forEach(_menu => { + action.data[container].splice(pasteIndex, 0, _menu); + pasteIndex++ + }); + } else { + if (current != max) { + action.data[container].push(Menu) + } + } + } + + refreshMenuItems(highlights[container].menu, action.data[container].length != 1, action.data[container].length == 1) + }); + + closeContextmenu(true) +} + + +document.addEventListener('keydown', (key) => { + if (document.activeElement.tagName != "BODY") return; + + if (key.ctrlKey) { + isHoldingCTRL = true; + let offListener = (key) => { + if (key.ctrlKey) return; + isHoldingCTRL = false; + document.removeEventListener('keyup', offListener) + }; + document.addEventListener('keyup', offListener) + } + + if (key.key.toLowerCase() == 'a' && key.ctrlKey) { + if (document.activeElement.tagName != 'BODY') return; + if (highlights[lastContainer].type == 1) { + refreshActions(lastContainer); + + setTimeout(() => { + const initiallySelected = highlights[lastContainer].highlighted + action.data[lastContainer].forEach((value, index) => { + if (index == initiallySelected) return; + isHoldingCTRL = true; + highlightAction(lastContainer, index); + }); + isHoldingCTRL = false; + highlights[lastContainer].selected = highlights[lastContainer].selected.sort((a, b) => a - b) + }, 10); + } + } + + if (key.key.toLowerCase() == 'c' && key.ctrlKey == true) { + let highlighted = highlights[lastContainer]; + + let sendChannel = highlighted.type == 1 ? "copiedAction" : "copiedMenu" + ipcRenderer.send(sendChannel, highlighted.selected.length != 0 ? highlighted.selected.map((value) => action.data[lastContainer][value]) : action.data[lastContainer][highlighted.highlighted]) + } + + if (key.key.toLowerCase() == 'v' && key.ctrlKey == true) { + if (lastContainer) { + if (highlights[lastContainer].type == 1) { + pasteCopiedIn(lastContainer) + } else { + pasteMenuIn(lastContainer) + } + } + else { + if (!editorSettings.experiments) return; + ipcRenderer.send('getCopiedAction'); + ipcRenderer.once('copiedAction', (event, Action) => { + let containers = 0; + actionUI.forEach(element => { + let container; + if (element.element == 'actions') { + container = document.getElementById(element.storeAs) + containers++ + } else if (element.element == 'case' || element.element == 'condition') { + if (action.data[element.storeAs].type == 'runActions') { + container = document.getElementById(element.storeActionsAs) + containers++ + } + } + + if (container) { + container.previousElementSibling.style.scale = 0 + setTimeout(() => { + container.style.height = '14vh' + container.style.filter = 'blur(12px)' + setTimeout(() => { + container.innerHTML = ` +
+ Pasting ${Action.name} +
+ Paste Here +
CTRL+${containers}
+
+
Cancel +
CTRL+E
+
+
+ ` + }, 100); + setTimeout(() => { + container.style.filter = 'blur(0px)' + }, 200); + }, 200); + } + }); + }); + } + } +}) + + +function setVariableIn(type, varName, elementId) { + closeContextmenu() + + if (type == 'temporary') { + insertTextAtCaret("${tempVars('" + varName + "')}", elementId); + } else if (type == 'server') { + insertTextAtCaret("${serverVars('" + varName + "')}", elementId); + } else if (type == 'global') { + insertTextAtCaret("${globalVars('" + varName + "')}", elementId); + } else { + insertTextAtCaret(varName, elementId); + } + + setTimeout(() => { + mOpened = false; + closeContextmenu() + }, 150) +} + +function insertTextAtCaret(text, elementId) { + var element = document.getElementById(elementId); + element.blur() + if (element && (element.tagName.toLowerCase() === 'textarea' || element.tagName.toLowerCase() === 'input')) { + var start = element.selectionStart; + var end = element.selectionEnd; + var newValue = element.value.substring(0, start) + text + element.value.substring(end); + element.value = newValue; + } + element.blur() + element.focus() +} + +function varTool(elm, index) { + let element = actionUI[index] + let validTypes = { + tempVar: "Temporary Variable", + serverVar: "Server Variable", + globVar: "Global Variable" + } + if (!validTypes[action.data[element.storeAs].type]) { + return + } + let parent = elm; + if (elm?.parentElement?.id) { + parent = elm.parentElement + } + + let selectorParent = document.createElement('div'); + selectorParent.style.width = '100%'; + selectorParent.style.height = '0px'; + selectorParent.style.transition = 'height 0.2s ease' + + let selector = document.createElement('div'); + selectorParent.appendChild(selector); + selector.classList.add('variableInsertion') + + setTimeout(() => { + selector.style.scale = '1' + selector.style.opacity = '1' + elm.style.borderBottomRightRadius = '0px' + }, 10); + elm.onblur = () => { + elm.style.borderBottomRightRadius = '' + action.data[actionUI[index].storeAs].value = elm.value; + selector.style.opacity = '' + selector.style.scale = '' + + setTimeout(() => { + selector.style.height = '0vh' + selector.style.padding = '0px' + }, editorSettings.commonAnimation * 100); + setTimeout(() => { + selector.remove() + selectorParent.remove() + }, editorSettings.commonAnimation * 200); + } + selectorParent.appendAfter(parent); + + let displayType = 'Temporary'; + + let localVariables = [...commandVars, ...tempVars]; + + switch (action.data[element.storeAs].type) { + case 'serverVar': + localVariables = [...thisServer, ...serverVars]; + displayType = 'Server' + break + case 'globVar': + localVariables = [...thisGlobal, ...globalVars]; + displayType = 'Global' + break + } + + elm.oninput = () => { + var endVars = '' + var includedVars = []; + + let query = elm.value; + let results = 0; + for (var varIndex in localVariables) { + var variable = localVariables[varIndex]; + if (variable.trim() != '' && !includedVars.includes(variable) && (fuzzyMatch(variable.toLowerCase().replaceAll('', ' '), query.toLowerCase().replaceAll(' ', ''), 0.01) || variable.toLowerCase().replaceAll(' ', '').includes(query.toLowerCase().replaceAll(' ', '')))) { + results++ + includedVars.push(variable) + endVars += ` +
+ ${displayType} +
+ ${variable} +
+
+ ` + } + }; + + selector.innerHTML = endVars; + } + + elm.oninput() +} \ No newline at end of file