mirror of
https://github.com/th-ch/youtube-music.git
synced 2026-01-11 10:31:47 +00:00
add prompt with number counter
This commit is contained in:
2
menu.js
2
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 !== "";
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -45,3 +45,8 @@ body {
|
||||
background-color: rgb(0, 0, 0);
|
||||
color: whitesmoke;
|
||||
}
|
||||
|
||||
.minus,
|
||||
.plus {
|
||||
background:rgb(0, 0, 0);
|
||||
}
|
||||
@ -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);
|
||||
});
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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}` -> `<input type="text" required>`. 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}` -> `<input type="text" required>`. 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. |
|
||||
|
||||
12
yarn.lock
12
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"
|
||||
|
||||
Reference in New Issue
Block a user