diff --git a/menu.js b/menu.js index 90487970..588dad7c 100644 --- a/menu.js +++ b/menu.js @@ -335,7 +335,7 @@ function setProxy(item, win) { }); } prompt(options, win) - .then((input) => { + .then(input => { if (input !== null && input !== example) { config.set("options.proxy", input); item.checked = input !== ""; diff --git a/package.json b/package.json index 144ac53f..a856babf 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,6 @@ "browser-id3-writer": "^4.4.0", "custom-electron-titlebar": "^3.2.6", "discord-rpc": "^3.2.0", - "doc-ready": "^1.0.4", "downloads-folder": "^3.0.1", "electron-debug": "^3.2.0", "electron-is": "^3.0.0", diff --git a/providers/prompt/dark-prompt.css b/providers/prompt/dark-prompt.css index 49e0f88e..74fea61e 100644 --- a/providers/prompt/dark-prompt.css +++ b/providers/prompt/dark-prompt.css @@ -45,3 +45,8 @@ body { background-color: rgb(0, 0, 0); color: whitesmoke; } + +.minus, +.plus { + background:rgb(0, 0, 0); +} \ No newline at end of file diff --git a/providers/prompt/index.js b/providers/prompt/index.js index bbba8b78..1c14cfa2 100644 --- a/providers/prompt/index.js +++ b/providers/prompt/index.js @@ -6,7 +6,9 @@ const url = require("url"); const path = require("path"); const DEFAULT_WIDTH = 370; +const DEFAULT_COUNTER_WIDTH = 300; const DEFAULT_HEIGHT = 160; +const DEFAULT_COUNTER_HEIGHT= 150; function electronPrompt(options, parentWindow) { return new Promise((resolve, reject) => { @@ -18,8 +20,6 @@ function electronPrompt(options, parentWindow) { { width: DEFAULT_WIDTH, height: DEFAULT_HEIGHT, - minWidth: DEFAULT_WIDTH, - minHeight: DEFAULT_HEIGHT, resizable: false, title: "Prompt", label: "Please input a value:", @@ -40,6 +40,11 @@ function electronPrompt(options, parentWindow) { options || {} ); + options_.minWidth = options.minWidth || options.width || + options_.type === "counter" ? DEFAULT_COUNTER_WIDTH : DEFAULT_WIDTH; + options_.minHeight = options.minHeight || options.height || + options_.type === "counter" ? DEFAULT_COUNTER_HEIGHT : DEFAULT_HEIGHT; + if (options_.type === "select" && (options_.selectOptions === null || typeof options_.selectOptions !== "object")) { reject(new Error('"selectOptions" must be an object')); return; @@ -136,6 +141,13 @@ function electronPrompt(options, parentWindow) { reject(new Error("prompt.html did-fail-load, log:\n", + log.toString())); }); + const promptUrl = url.format({ + protocol: 'file', + slashes: true, + pathname: path.join(__dirname, 'page', 'prompt.html'), + hash: id + }); + //Finally, load prompt promptWindow.loadURL(promptUrl); }); diff --git a/providers/prompt/page/prompt.css b/providers/prompt/page/prompt.css index c3530e57..10654b8d 100644 --- a/providers/prompt/page/prompt.css +++ b/providers/prompt/page/prompt.css @@ -78,3 +78,35 @@ select#data { background-color: #ddd; color: black; } + +/* Counter mode css */ + +span { + cursor: pointer; +} +.number { + margin: 100px; +} +.minus, +.plus { + user-select: none; + width: 20px; + height: 20px; + background: #f2f2f2; + border-radius: 4px; + padding: 8px 5px 8px 5px; + border: 1px solid #ddd; + display: inline-block; + vertical-align: middle; + text-align: center; +} +.inputt { + height: 34px; + width: 100px; + text-align: center; + font-size: 26px; + border: 1px solid #ddd; + border-radius: 4px; + display: inline-block; + vertical-align: middle; +} diff --git a/providers/prompt/page/prompt.js b/providers/prompt/page/prompt.js index b7a54120..042ba546 100644 --- a/providers/prompt/page/prompt.js +++ b/providers/prompt/page/prompt.js @@ -1,13 +1,13 @@ const fs = require("fs"); const {ipcRenderer} = require("electron"); -const docReady = require("doc-ready"); let promptId = null; let promptOptions = null; +function $(selector) {return document.querySelector(selector)} + +document.addEventListener( 'DOMContentLoaded', promptRegister); -docReady(promptRegister); -//start here function promptRegister() { //get custom session id promptId = document.location.hash.replace("#", ""); @@ -21,18 +21,18 @@ function promptRegister() { //set label if (promptOptions.useHtmlLabel) { - document.querySelector("#label").innerHTML = promptOptions.label; + $("#label").innerHTML = promptOptions.label; } else { - document.querySelector("#label").textContent = promptOptions.label; + $("#label").textContent = promptOptions.label; } //set button label if (promptOptions.buttonLabels && promptOptions.buttonLabels.ok) { - document.querySelector("#ok").textContent = promptOptions.buttonLabels.ok; + $("#ok").textContent = promptOptions.buttonLabels.ok; } if (promptOptions.buttonLabels && promptOptions.buttonLabels.cancel) { - document.querySelector("#cancel").textContent = promptOptions.buttonLabels.cancel; + $("#cancel").textContent = promptOptions.buttonLabels.cancel; } //inject custom stylesheet from options @@ -51,26 +51,40 @@ function promptRegister() { } //add button listeners - document.querySelector("#form").addEventListener("submit", promptSubmit); - document.querySelector("#cancel").addEventListener("click", promptCancel); + $("#form").addEventListener("submit", promptSubmit); + $("#cancel").addEventListener("click", promptCancel); //create input/select - const dataContainerElement = document.querySelector("#data-container"); + const dataContainerElement = $("#data-container"); let dataElement; - if (promptOptions.type === "input") { - dataElement = promptCreateInput(); - } else if (promptOptions.type === "select") { - dataElement = promptCreateSelect(); - } else { - return promptError(`Unhandled input type '${promptOptions.type}'`); - } - dataContainerElement.append(dataElement); + switch (promptOptions.type) { + case "counter": + case "input": + dataElement = promptCreateInput(); + break; + case "select": + dataElement = promptCreateSelect(); + break; + default: + return promptError(`Unhandled input type '${promptOptions.type}'`); + } + if (promptOptions.type === "counter") { + dataElement.classList.add("input"); + dataElement.style.width = "unset"; + dataElement.style["text-align"] = "center"; + //dataElement.style["min-height"] = "1.5em"; + dataContainerElement.append(createMinus(dataElement)); + dataContainerElement.append(dataElement); + dataContainerElement.append(createPlus(dataElement)); + } else { + dataContainerElement.append(dataElement); + } dataElement.setAttribute("id", "data"); dataElement.focus(); - if (promptOptions.type === "input") { + if (promptOptions.type === "input" || promptOptions.type === "counter") { dataElement.select(); } @@ -87,7 +101,8 @@ function promptRegister() { window.addEventListener("error", error => { if (promptId) { - promptError("An error has occured on the prompt window: \n" + error); + promptError("An error has occured on the prompt window: \n" + JSON.stringify(error, ["message", "arguments", "type", "name"]) + ); } }); @@ -107,15 +122,23 @@ function promptCancel() { //transfer input data to back function promptSubmit() { - const dataElement = document.querySelector("#data"); + const dataElement = $("#data"); let data = null; - if (promptOptions.type === "input") { - data = dataElement.value; - } else if (promptOptions.type === "select") { - data = promptOptions.selectMultiple ? - dataElement.querySelectorAll("option[selected]").map(o => o.getAttribute("value")) : - dataElement.value; + switch (promptOptions.type) { + case "input": + data = dataElement.value; + break; + case "counter": + data = validateCounterInput(dataElement.value); + break; + case "select": + data = promptOptions.selectMultiple ? + dataElement.querySelectorAll("option[selected]").map(o => o.getAttribute("value")) : + dataElement.value; + break; + default: //will never happen + return promptError(`Unhandled input type '${promptOptions.type}'`); } ipcRenderer.sendSync("prompt-post-data:" + promptId, data); @@ -127,6 +150,9 @@ function promptCreateInput() { dataElement.setAttribute("type", "text"); if (promptOptions.value) { + if (promptOptions.type === "counter") { + promptOptions.value = validateCounterInput(promptOptions.value); + } dataElement.value = promptOptions.value; } else { dataElement.value = ""; @@ -150,11 +176,11 @@ function promptCreateInput() { } }); - //Confrim on 'Enter' + //Confirm on 'Enter' dataElement.addEventListener("keypress", event => { if (event.key === "Enter") { event.preventDefault(); - document.querySelector("#ok").click(); + $("#ok").click(); } }); @@ -184,5 +210,35 @@ function promptCreateSelect() { return dataElement; } +function createMinus(dataElement) { + const minus = document.createElement("span"); + minus.textContent = "-"; + minus.classList.add("minus"); + minus.onmousedown = () => { + dataElement.value = validateCounterInput(parseInt(dataElement.value) - 1); + }; + return minus; +} +function createPlus(dataElement) { + const plus = document.createElement("span"); + plus.textContent = "+"; + plus.classList.add("plus"); + plus.onmousedown = () => { + dataElement.value = validateCounterInput(parseInt(dataElement.value) + 1); + }; + return plus; +} +//validate counter +function validateCounterInput(input) { + const min = promptOptions.counterOptions?.minimum, + max = promptOptions.counterOptions?.maximum; + if (min !== undefined && input < min) { + return min; + } + if (max !== undefined && input > max) { + return max; + } + return input; +} diff --git a/providers/prompt/readme.md b/providers/prompt/readme.md index 6683aced..eff1f907 100644 --- a/providers/prompt/readme.md +++ b/providers/prompt/readme.md @@ -43,8 +43,9 @@ prompt({ | label | (optional, string) The label which appears on the prompt for the input field. Defaults to 'Please input a value:'. | | buttonLabels | (optional, object) The text for the OK/cancel buttons. Properties are 'ok' and 'cancel'. Defaults to null. | | value | (optional, string) The default value for the input field. Defaults to null. | -| type | (optional, string) The type of input field, either 'input' for a standard text input field or 'select' for a dropdown type input. Defaults to 'input'. | -| inputAttrs | (optional, object) The attributes of the input field, analagous to the HTML attributes: `{type: 'text', required: true}` -> ``. Used if the type is 'input' | +| type | (optional, string) The type of input field, either 'input' for a standard text input field or 'select' for a dropdown type input or 'counter' for a number counter with buttons. Defaults to 'input'. | +| inputAttrs | (optional, object) The attributes of the input field, analagous to the HTML attributes: `{type: 'text', required: true}` -> ``. Used if the type is 'input' +| counterOptions | (optional, object) minimum and maximum of counter in format: `{minimum: %int%, maximum: %int%} ` | | selectOptions | (optional, object) The items for the select dropdown if using the 'select' type in the format 'value': 'display text', where the value is what will be given to the then block and the display text is what the user will see. | | useHtmlLabel | (optional, boolean) Whether the label should be interpreted as HTML or not. Defaults to false. | | width | (optional, integer) The width of the prompt window. Defaults to 370. | diff --git a/yarn.lock b/yarn.lock index f9909214..c969527e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2908,13 +2908,6 @@ dmg-builder@22.9.1: js-yaml "^3.14.0" sanitize-filename "^1.6.3" -doc-ready@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/doc-ready/-/doc-ready-1.0.4.tgz#37f5391969cff994303fdfef2e5d50357f8164d3" - integrity sha1-N/U5GWnP+ZQwP9/vLl1QNX+BZNM= - dependencies: - eventie "^1" - doctrine@1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" @@ -3612,11 +3605,6 @@ esutils@^2.0.2: resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== -eventie@^1: - version "1.0.6" - resolved "https://registry.yarnpkg.com/eventie/-/eventie-1.0.6.tgz#d4ffc8b0c2b5e493c2aa1b22cbe918d3aee74437" - integrity sha1-1P/IsMK15JPCqhsiy+kY067nRDc= - events@^3.0.0: version "3.2.0" resolved "https://registry.yarnpkg.com/events/-/events-3.2.0.tgz#93b87c18f8efcd4202a461aec4dfc0556b639379"