mirror of
https://github.com/th-ch/youtube-music.git
synced 2026-01-10 10:11:46 +00:00
Create readme.md
refactor and css fix xo --fix add inline doc fix typo
This commit is contained in:
18
index.js
18
index.js
@ -110,8 +110,8 @@ function createMainWindow() {
|
||||
titleBarStyle: useInlineMenu
|
||||
? "hidden"
|
||||
: is.macOS()
|
||||
? "hiddenInset"
|
||||
: "default",
|
||||
? "hiddenInset"
|
||||
: "default",
|
||||
autoHideMenuBar: config.get("options.hideMenu"),
|
||||
});
|
||||
if (windowPosition) {
|
||||
@ -156,7 +156,7 @@ function createMainWindow() {
|
||||
|
||||
let createdWindow = false;
|
||||
app.on("browser-window-created", (event, win) => {
|
||||
//Ensure listeners aren't registered when creating input dialog
|
||||
//Ensures listeners are registered only once
|
||||
if (createdWindow) {
|
||||
return;
|
||||
}
|
||||
@ -172,7 +172,7 @@ app.on("browser-window-created", (event, win) => {
|
||||
frameProcessId,
|
||||
frameRoutingId,
|
||||
) => {
|
||||
let log = {
|
||||
const log = {
|
||||
error: "did-fail-load",
|
||||
event,
|
||||
errorCode,
|
||||
@ -183,7 +183,7 @@ app.on("browser-window-created", (event, win) => {
|
||||
frameRoutingId,
|
||||
};
|
||||
if (is.dev()) {
|
||||
console.log(log);
|
||||
console.log(log.toString());
|
||||
}
|
||||
win.webContents.send("log", log);
|
||||
win.webContents.loadFile(path.join(__dirname, "error.html"));
|
||||
@ -306,13 +306,11 @@ app.on("ready", () => {
|
||||
}
|
||||
|
||||
// Optimized for Mac OS X
|
||||
if (is.macOS()) {
|
||||
if (!config.get("options.appVisible")) {
|
||||
app.dock.hide();
|
||||
}
|
||||
if (is.macOS() && !config.get("options.appVisible")) {
|
||||
app.dock.hide();
|
||||
}
|
||||
|
||||
var forceQuit = false;
|
||||
let forceQuit = false;
|
||||
app.on("before-quit", () => {
|
||||
forceQuit = true;
|
||||
});
|
||||
|
||||
9
menu.js
9
menu.js
@ -12,6 +12,7 @@ const pluginEnabledMenu = (win, plugin, label = "", hasSubmenu = false) => ({
|
||||
label: label || plugin,
|
||||
type: "checkbox",
|
||||
checked: config.plugins.isEnabled(plugin),
|
||||
//Submenu check used in in-app-menu
|
||||
hasSubmenu: hasSubmenu || undefined,
|
||||
click: (item) => {
|
||||
if (item.checked) {
|
||||
@ -321,13 +322,13 @@ function setProxy(item, win) {
|
||||
},
|
||||
type: 'input',
|
||||
icon: iconPath,
|
||||
customStylesheet: path.join(__dirname, "providers", "prompt", "darkPrompt.css"),
|
||||
customStylesheet: path.join(__dirname, "providers", "prompt", "dark-prompt.css"),
|
||||
};
|
||||
//TODO: custom bar on prompt need testing on macOS
|
||||
if(!is.macOS()) {
|
||||
Object.assign(options, {
|
||||
frame: false,
|
||||
customScript: path.join(__dirname, "providers", "prompt", "customTitlebar.js"),
|
||||
customScript: path.join(__dirname, "providers", "prompt", "custom-titlebar.js"),
|
||||
enableRemoteModule: true,
|
||||
height: 200,
|
||||
width: 450,
|
||||
@ -337,10 +338,10 @@ function setProxy(item, win) {
|
||||
.then((input) => {
|
||||
if (input !== null && input !== example) {
|
||||
config.set("options.proxy", input);
|
||||
item.checked = (input === "") ? false : true;
|
||||
item.checked = input !== "";
|
||||
} else { //user pressed cancel
|
||||
item.checked = !item.checked; //reset checkbox
|
||||
}
|
||||
})
|
||||
.catch(console.error);
|
||||
}
|
||||
}
|
||||
|
||||
12
package.json
12
package.json
@ -101,6 +101,16 @@
|
||||
"envs": [
|
||||
"node",
|
||||
"browser"
|
||||
]
|
||||
],
|
||||
"rules": {
|
||||
"quotes": [
|
||||
"error",
|
||||
"double",
|
||||
{
|
||||
"avoidEscape": true,
|
||||
"allowTemplateLiterals": true
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,8 +9,6 @@ const { injectCSS } = require("../utils");
|
||||
|
||||
//check that menu doesn't get created twice
|
||||
let calledReadyToShow = false;
|
||||
//check menu state isn't changed twice
|
||||
let calledFinishedLoad = false
|
||||
//tracks menu visibility
|
||||
let visible = true;
|
||||
// win hook for fixing menu
|
||||
@ -37,6 +35,7 @@ module.exports = (winImport) => {
|
||||
if (calledReadyToShow) {
|
||||
return;
|
||||
}
|
||||
|
||||
calledReadyToShow = true;
|
||||
|
||||
setApplicationMenu(win);
|
||||
@ -53,7 +52,7 @@ module.exports = (winImport) => {
|
||||
win.webContents.on("did-finish-load", () => {
|
||||
// fix bug with menu not applying on start when no internet connection available
|
||||
setMenuVisibility(!config.get("options.hideMenu"));
|
||||
})
|
||||
});
|
||||
};
|
||||
|
||||
function switchMenuVisibility() {
|
||||
@ -81,10 +80,10 @@ function updateTemplate(template) {
|
||||
for (let item of template) {
|
||||
// Change onClick of checkbox+radio
|
||||
if ((item.type === "checkbox" || item.type === "radio") && !item.fixed) {
|
||||
let originalOnclick = item.click;
|
||||
const originalOnclick = item.click;
|
||||
item.click = (itemClicked) => {
|
||||
originalOnclick(itemClicked);
|
||||
updateCheckboxesAndRadioButtons(itemClicked, item.type === 'radio', item.hasSubmenu);
|
||||
updateCheckboxesAndRadioButtons(itemClicked, item.type === "radio", item.hasSubmenu);
|
||||
};
|
||||
item.fixed = true;
|
||||
}
|
||||
|
||||
@ -1,11 +1,15 @@
|
||||
const { ipcRenderer } = require("electron");
|
||||
|
||||
function logToString(log) {
|
||||
let string = (typeof log === "string") ? log : log.toString();
|
||||
if (!string || string.includes("[object Object]")) {
|
||||
string = JSON.stringify(log);
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
module.exports = () => {
|
||||
ipcRenderer.on("log", (event, log) => {
|
||||
let string = log || log.toString();
|
||||
if (!string || string === "[object Object]") {
|
||||
string = JSON.stringify(log);
|
||||
}
|
||||
console.log(string);
|
||||
})
|
||||
};
|
||||
ipcRenderer.on("log", (event, log) => {
|
||||
console.log(logToString(log));
|
||||
});
|
||||
};
|
||||
|
||||
14
providers/prompt/custom-titlebar.js
Normal file
14
providers/prompt/custom-titlebar.js
Normal file
@ -0,0 +1,14 @@
|
||||
const customTitlebar = require("custom-electron-titlebar");
|
||||
|
||||
module.exports = () => {
|
||||
const bar = new customTitlebar.Titlebar({
|
||||
backgroundColor: customTitlebar.Color.fromHex("#050505"),
|
||||
minimizable: false,
|
||||
maximizable: false,
|
||||
menu: null
|
||||
});
|
||||
const mainStyle = document.querySelector("#container").style;
|
||||
mainStyle.width = "100%";
|
||||
mainStyle.position = "fixed";
|
||||
mainStyle.border = "unset";
|
||||
};
|
||||
@ -1,19 +0,0 @@
|
||||
const customTitlebar = require("custom-electron-titlebar");
|
||||
|
||||
module.exports = () => {
|
||||
const bar = new customTitlebar.Titlebar({
|
||||
backgroundColor: customTitlebar.Color.fromHex("#050505"),
|
||||
minimizable: false,
|
||||
maximizable: false,
|
||||
unfocusEffect: true,
|
||||
});
|
||||
try {
|
||||
bar.updateMenu(null);
|
||||
} catch (e) {
|
||||
//will always throw type error - null isn't menu, but it works
|
||||
}
|
||||
let container = document.querySelector('#container');
|
||||
container.style.width = '100%';
|
||||
container.style.position = 'fixed';
|
||||
container.style.border = 'unset';
|
||||
}
|
||||
@ -34,7 +34,9 @@ body {
|
||||
}
|
||||
|
||||
#ok:hover,
|
||||
#cancel:hover {
|
||||
#ok:focus,
|
||||
#cancel:hover,
|
||||
#cancel:focus {
|
||||
outline: rgba(60, 0, 0, 0.4) solid 2px;
|
||||
}
|
||||
|
||||
@ -1,17 +1,19 @@
|
||||
const electron = require('electron');
|
||||
const electron = require("electron");
|
||||
|
||||
const BrowserWindow = electron.BrowserWindow || electron.remote.BrowserWindow;
|
||||
const ipcMain = electron.ipcMain || electron.remote.ipcMain;
|
||||
const url = require('url');
|
||||
const path = require('path');
|
||||
const url = require("url");
|
||||
const path = require("path");
|
||||
|
||||
const DEFAULT_WIDTH = 370;
|
||||
const DEFAULT_HEIGHT = 160;
|
||||
|
||||
function electronPrompt(options, parentWindow) {
|
||||
return new Promise((resolve, reject) => {
|
||||
//id used to ensure unique listeners per window
|
||||
const id = `${Date.now()}-${Math.random()}`;
|
||||
|
||||
//custom options override default
|
||||
const options_ = Object.assign(
|
||||
{
|
||||
width: DEFAULT_WIDTH,
|
||||
@ -19,12 +21,12 @@ function electronPrompt(options, parentWindow) {
|
||||
minWidth: DEFAULT_WIDTH,
|
||||
minHeight: DEFAULT_HEIGHT,
|
||||
resizable: false,
|
||||
title: 'Prompt',
|
||||
label: 'Please input a value:',
|
||||
title: "Prompt",
|
||||
label: "Please input a value:",
|
||||
buttonLabels: null,
|
||||
alwaysOnTop: false,
|
||||
value: null,
|
||||
type: 'input',
|
||||
type: "input",
|
||||
selectOptions: null,
|
||||
icon: null,
|
||||
useHtmlLabel: false,
|
||||
@ -38,7 +40,7 @@ function electronPrompt(options, parentWindow) {
|
||||
options || {}
|
||||
);
|
||||
|
||||
if (options_.type === 'select' && (options_.selectOptions === null || typeof options_.selectOptions !== 'object')) {
|
||||
if (options_.type === "select" && (options_.selectOptions === null || typeof options_.selectOptions !== "object")) {
|
||||
reject(new Error('"selectOptions" must be an object'));
|
||||
return;
|
||||
}
|
||||
@ -50,9 +52,9 @@ function electronPrompt(options, parentWindow) {
|
||||
minWidth: options_.minWidth,
|
||||
minHeight: options_.minHeight,
|
||||
resizable: options_.resizable,
|
||||
minimizable: false,
|
||||
fullscreenable: false,
|
||||
maximizable: false,
|
||||
minimizable: !options_.skipTaskbar && !parentWindow && !options_.alwaysOnTop,
|
||||
fullscreenable: options_.resizable,
|
||||
maximizable: options_.resizable,
|
||||
parent: parentWindow,
|
||||
skipTaskbar: options_.skipTaskbar,
|
||||
alwaysOnTop: options_.alwaysOnTop,
|
||||
@ -70,14 +72,11 @@ function electronPrompt(options, parentWindow) {
|
||||
promptWindow.setMenu(null);
|
||||
promptWindow.setMenuBarVisibility(options_.menuBarVisible);
|
||||
|
||||
const getOptionsListener = event => {
|
||||
event.returnValue = JSON.stringify(options_);
|
||||
};
|
||||
|
||||
//called on exit
|
||||
const cleanup = () => {
|
||||
ipcMain.removeListener('prompt-get-options:' + id, getOptionsListener);
|
||||
ipcMain.removeListener('prompt-post-data:' + id, postDataListener);
|
||||
ipcMain.removeListener('prompt-error:' + id, errorListener);
|
||||
ipcMain.removeListener("prompt-get-options:" + id, getOptionsListener);
|
||||
ipcMain.removeListener("prompt-post-data:" + id, postDataListener);
|
||||
ipcMain.removeListener("prompt-error:" + id, errorListener);
|
||||
|
||||
if (promptWindow) {
|
||||
promptWindow.close();
|
||||
@ -85,6 +84,12 @@ function electronPrompt(options, parentWindow) {
|
||||
}
|
||||
};
|
||||
|
||||
///transfer options to front
|
||||
const getOptionsListener = event => {
|
||||
event.returnValue = JSON.stringify(options_);
|
||||
};
|
||||
|
||||
//get input from front
|
||||
const postDataListener = (event, value) => {
|
||||
resolve(value);
|
||||
event.returnValue = null;
|
||||
@ -92,34 +97,46 @@ function electronPrompt(options, parentWindow) {
|
||||
};
|
||||
|
||||
const unresponsiveListener = () => {
|
||||
reject(new Error('Window was unresponsive'));
|
||||
reject(new Error("Window was unresponsive"));
|
||||
cleanup();
|
||||
};
|
||||
|
||||
//get error from front
|
||||
const errorListener = (event, message) => {
|
||||
reject(new Error(message));
|
||||
event.returnValue = null;
|
||||
cleanup();
|
||||
};
|
||||
|
||||
ipcMain.on('prompt-get-options:' + id, getOptionsListener);
|
||||
ipcMain.on('prompt-post-data:' + id, postDataListener);
|
||||
ipcMain.on('prompt-error:' + id, errorListener);
|
||||
promptWindow.on('unresponsive', unresponsiveListener);
|
||||
//attach listeners
|
||||
ipcMain.on("prompt-get-options:" + id, getOptionsListener);
|
||||
ipcMain.on("prompt-post-data:" + id, postDataListener);
|
||||
ipcMain.on("prompt-error:" + id, errorListener);
|
||||
promptWindow.on("unresponsive", unresponsiveListener);
|
||||
|
||||
promptWindow.on('closed', () => {
|
||||
promptWindow.on("closed", () => {
|
||||
promptWindow = null;
|
||||
cleanup();
|
||||
resolve(null);
|
||||
});
|
||||
|
||||
const promptUrl = url.format({
|
||||
protocol: 'file',
|
||||
slashes: true,
|
||||
pathname: path.join(__dirname, 'page', 'prompt.html'),
|
||||
hash: id
|
||||
//should never happen
|
||||
promptWindow.webContents.on("did-fail-load", (
|
||||
event,
|
||||
errorCode,
|
||||
errorDescription,
|
||||
validatedURL,
|
||||
) => {
|
||||
const log = {
|
||||
error: "did-fail-load",
|
||||
errorCode,
|
||||
errorDescription,
|
||||
validatedURL,
|
||||
};
|
||||
reject(new Error("prompt.html did-fail-load, log:\n", + log.toString()));
|
||||
});
|
||||
|
||||
//Finally, load prompt
|
||||
promptWindow.loadURL(promptUrl);
|
||||
});
|
||||
}
|
||||
|
||||
@ -1,126 +1,47 @@
|
||||
const fs = require('fs');
|
||||
const {ipcRenderer} = require('electron');
|
||||
const docReady = require('doc-ready');
|
||||
const fs = require("fs");
|
||||
const {ipcRenderer} = require("electron");
|
||||
const docReady = require("doc-ready");
|
||||
|
||||
let promptId = null;
|
||||
let promptOptions = null;
|
||||
|
||||
function promptError(error) {
|
||||
if (error instanceof Error) {
|
||||
error = error.message;
|
||||
}
|
||||
|
||||
ipcRenderer.sendSync('prompt-error:' + promptId, error);
|
||||
}
|
||||
|
||||
function promptCancel() {
|
||||
ipcRenderer.sendSync('prompt-post-data:' + promptId, null);
|
||||
}
|
||||
|
||||
function promptSubmit() {
|
||||
const dataElement = document.querySelector('#data');
|
||||
let data = null;
|
||||
|
||||
if (promptOptions.type === 'input') {
|
||||
data = dataElement.value;
|
||||
} else if (promptOptions.type === 'select') {
|
||||
if (promptOptions.selectMultiple) {
|
||||
data = dataElement.querySelectorAll('option[selected]').map(o => o.getAttribute('value'));
|
||||
} else {
|
||||
data = dataElement.value;
|
||||
}
|
||||
}
|
||||
|
||||
ipcRenderer.sendSync('prompt-post-data:' + promptId, data);
|
||||
}
|
||||
|
||||
function promptCreateInput() {
|
||||
const dataElement = document.createElement('input');
|
||||
dataElement.setAttribute('type', 'text');
|
||||
|
||||
if (promptOptions.value) {
|
||||
dataElement.value = promptOptions.value;
|
||||
} else {
|
||||
dataElement.value = '';
|
||||
}
|
||||
|
||||
if (promptOptions.inputAttrs && typeof (promptOptions.inputAttrs) === 'object') {
|
||||
for (const k in promptOptions.inputAttrs) {
|
||||
if (!Object.prototype.hasOwnProperty.call(promptOptions.inputAttrs, k)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
dataElement.setAttribute(k, promptOptions.inputAttrs[k]);
|
||||
}
|
||||
}
|
||||
|
||||
dataElement.addEventListener('keyup', event => {
|
||||
if (event.key === 'Escape') {
|
||||
promptCancel();
|
||||
}
|
||||
});
|
||||
|
||||
dataElement.addEventListener('keypress', event => {
|
||||
if (event.key === 'Enter') {
|
||||
event.preventDefault();
|
||||
document.querySelector('#ok').click();
|
||||
}
|
||||
});
|
||||
|
||||
return dataElement;
|
||||
}
|
||||
|
||||
function promptCreateSelect() {
|
||||
const dataElement = document.createElement('select');
|
||||
let optionElement;
|
||||
|
||||
for (const k in promptOptions.selectOptions) {
|
||||
if (!Object.prototype.hasOwnProperty.call(promptOptions.selectOptions, k)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
optionElement = document.createElement('option');
|
||||
optionElement.setAttribute('value', k);
|
||||
optionElement.textContent = promptOptions.selectOptions[k];
|
||||
if (k === promptOptions.value) {
|
||||
optionElement.setAttribute('selected', 'selected');
|
||||
}
|
||||
|
||||
dataElement.append(optionElement);
|
||||
}
|
||||
|
||||
return dataElement;
|
||||
}
|
||||
|
||||
docReady(promptRegister);
|
||||
//start here
|
||||
function promptRegister() {
|
||||
promptId = document.location.hash.replace('#', '');
|
||||
//get custom session id
|
||||
promptId = document.location.hash.replace("#", "");
|
||||
|
||||
//get options from back
|
||||
try {
|
||||
promptOptions = JSON.parse(ipcRenderer.sendSync('prompt-get-options:' + promptId));
|
||||
promptOptions = JSON.parse(ipcRenderer.sendSync("prompt-get-options:" + promptId));
|
||||
} catch (error) {
|
||||
return promptError(error);
|
||||
}
|
||||
|
||||
//set label
|
||||
if (promptOptions.useHtmlLabel) {
|
||||
document.querySelector('#label').innerHTML = promptOptions.label;
|
||||
document.querySelector("#label").innerHTML = promptOptions.label;
|
||||
} else {
|
||||
document.querySelector('#label').textContent = promptOptions.label;
|
||||
document.querySelector("#label").textContent = promptOptions.label;
|
||||
}
|
||||
|
||||
//set button label
|
||||
if (promptOptions.buttonLabels && promptOptions.buttonLabels.ok) {
|
||||
document.querySelector('#ok').textContent = promptOptions.buttonLabels.ok;
|
||||
document.querySelector("#ok").textContent = promptOptions.buttonLabels.ok;
|
||||
}
|
||||
|
||||
if (promptOptions.buttonLabels && promptOptions.buttonLabels.cancel) {
|
||||
document.querySelector('#cancel').textContent = promptOptions.buttonLabels.cancel;
|
||||
document.querySelector("#cancel").textContent = promptOptions.buttonLabels.cancel;
|
||||
}
|
||||
|
||||
//inject custom stylesheet from options
|
||||
if (promptOptions.customStylesheet) {
|
||||
try {
|
||||
const customStyleContent = fs.readFileSync(promptOptions.customStylesheet);
|
||||
if (customStyleContent) {
|
||||
const customStyle = document.createElement('style');
|
||||
customStyle.setAttribute('rel', 'stylesheet');
|
||||
const customStyle = document.createElement("style");
|
||||
customStyle.setAttribute("rel", "stylesheet");
|
||||
customStyle.append(document.createTextNode(customStyleContent));
|
||||
document.head.append(customStyle);
|
||||
}
|
||||
@ -129,28 +50,31 @@ function promptRegister() {
|
||||
}
|
||||
}
|
||||
|
||||
document.querySelector('#form').addEventListener('submit', promptSubmit);
|
||||
document.querySelector('#cancel').addEventListener('click', promptCancel);
|
||||
//add button listeners
|
||||
document.querySelector("#form").addEventListener("submit", promptSubmit);
|
||||
document.querySelector("#cancel").addEventListener("click", promptCancel);
|
||||
|
||||
const dataContainerElement = document.querySelector('#data-container');
|
||||
|
||||
//create input/select
|
||||
const dataContainerElement = document.querySelector("#data-container");
|
||||
let dataElement;
|
||||
if (promptOptions.type === 'input') {
|
||||
if (promptOptions.type === "input") {
|
||||
dataElement = promptCreateInput();
|
||||
} else if (promptOptions.type === 'select') {
|
||||
} else if (promptOptions.type === "select") {
|
||||
dataElement = promptCreateSelect();
|
||||
} else {
|
||||
return promptError(`Unhandled input type '${promptOptions.type}'`);
|
||||
}
|
||||
|
||||
dataContainerElement.append(dataElement);
|
||||
dataElement.setAttribute('id', 'data');
|
||||
dataElement.setAttribute("id", "data");
|
||||
|
||||
dataElement.focus();
|
||||
if (promptOptions.type === 'input') {
|
||||
if (promptOptions.type === "input") {
|
||||
dataElement.select();
|
||||
}
|
||||
|
||||
//load custom script from options
|
||||
if (promptOptions.customScript) {
|
||||
try {
|
||||
const customScript = require(promptOptions.customScript);
|
||||
@ -161,10 +85,104 @@ function promptRegister() {
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener('error', error => {
|
||||
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" + error);
|
||||
}
|
||||
});
|
||||
|
||||
docReady(promptRegister);
|
||||
//send error to back
|
||||
function promptError(error) {
|
||||
if (error instanceof Error) {
|
||||
error = error.message;
|
||||
}
|
||||
|
||||
ipcRenderer.sendSync("prompt-error:" + promptId, error);
|
||||
}
|
||||
|
||||
//send to back: input=null
|
||||
function promptCancel() {
|
||||
ipcRenderer.sendSync("prompt-post-data:" + promptId, null);
|
||||
}
|
||||
|
||||
//transfer input data to back
|
||||
function promptSubmit() {
|
||||
const dataElement = document.querySelector("#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;
|
||||
}
|
||||
|
||||
ipcRenderer.sendSync("prompt-post-data:" + promptId, data);
|
||||
}
|
||||
|
||||
//creates input box
|
||||
function promptCreateInput() {
|
||||
const dataElement = document.createElement("input");
|
||||
dataElement.setAttribute("type", "text");
|
||||
|
||||
if (promptOptions.value) {
|
||||
dataElement.value = promptOptions.value;
|
||||
} else {
|
||||
dataElement.value = "";
|
||||
}
|
||||
|
||||
//insert custom input attributes if in options
|
||||
if (promptOptions.inputAttrs && typeof (promptOptions.inputAttrs) === "object") {
|
||||
for (const k in promptOptions.inputAttrs) {
|
||||
if (!Object.prototype.hasOwnProperty.call(promptOptions.inputAttrs, k)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
dataElement.setAttribute(k, promptOptions.inputAttrs[k]);
|
||||
}
|
||||
}
|
||||
|
||||
//Cancel/Exit on 'Escape'
|
||||
dataElement.addEventListener("keyup", event => {
|
||||
if (event.key === "Escape") {
|
||||
promptCancel();
|
||||
}
|
||||
});
|
||||
|
||||
//Confrim on 'Enter'
|
||||
dataElement.addEventListener("keypress", event => {
|
||||
if (event.key === "Enter") {
|
||||
event.preventDefault();
|
||||
document.querySelector("#ok").click();
|
||||
}
|
||||
});
|
||||
|
||||
return dataElement;
|
||||
}
|
||||
|
||||
//create multiple select
|
||||
function promptCreateSelect() {
|
||||
const dataElement = document.createElement("select");
|
||||
let optionElement;
|
||||
|
||||
for (const k in promptOptions.selectOptions) {
|
||||
if (!Object.prototype.hasOwnProperty.call(promptOptions.selectOptions, k)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
optionElement = document.createElement("option");
|
||||
optionElement.setAttribute("value", k);
|
||||
optionElement.textContent = promptOptions.selectOptions[k];
|
||||
if (k === promptOptions.value) {
|
||||
optionElement.setAttribute("selected", "selected");
|
||||
}
|
||||
|
||||
dataElement.append(optionElement);
|
||||
}
|
||||
|
||||
return dataElement;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
79
providers/prompt/readme.md
Normal file
79
providers/prompt/readme.md
Normal file
@ -0,0 +1,79 @@
|
||||
# Prompt Documentation
|
||||
|
||||
<p align="center"><img width="482" alt="prompt-preview" src="https://user-images.githubusercontent.com/17620180/111753337-09c0c680-8897-11eb-8ce8-43de29c143bd.png"></p>
|
||||
|
||||
## Usage
|
||||
```js
|
||||
prompt([options, parentBrowserWindow]).then(...).catch(...)
|
||||
```
|
||||
Promise resolve returns input
|
||||
|
||||
If user presses cancel/exit window, input = null;
|
||||
|
||||
On error, Prompise reject returns custom error message
|
||||
## Example
|
||||
|
||||
```js
|
||||
const prompt = require('./providers/prompt');
|
||||
|
||||
prompt({
|
||||
title: 'Prompt example',
|
||||
label: 'URL:',
|
||||
value: 'http://example.org',
|
||||
inputAttrs: {
|
||||
type: 'url'
|
||||
},
|
||||
type: 'input'
|
||||
})
|
||||
.then((r) => {
|
||||
if(r === null) {
|
||||
console.log('user cancelled');
|
||||
} else {
|
||||
console.log('result', r);
|
||||
}
|
||||
})
|
||||
.catch(console.error);
|
||||
```
|
||||
|
||||
### Options object (optional)
|
||||
|
||||
| Key | Explanation |
|
||||
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| title | (optional, string) The title of the prompt window. Defaults to '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' |
|
||||
| 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. |
|
||||
| minWidth | (optional, integer) The minimum allowed width for the prompt window. Same default value as width. |
|
||||
| height | (optional, integer) The height of the prompt window. Defaults to 130. |
|
||||
| minHeight | (optional, integer) The minimum allowed height for the prompt window. Same default value as height. |
|
||||
| resizable | (optional, boolean) Whether the prompt window can be resized or not (also sets useContentSize). Defaults to false. |
|
||||
| alwaysOnTop | (optional, boolean) Whether the window should always stay on top of other windows. Defaults to false |
|
||||
| icon | (optional, string) The path to an icon image to use in the title bar. Defaults to null and uses electron's icon. |
|
||||
| customStylesheet | (optional, string) The local path of a CSS file to stylize the prompt window. Defaults to null. |
|
||||
| menuBarVisible | (optional, boolean) Whether to show the menubar or not. Defaults to false. |
|
||||
| skipTaskbar | (optional, boolean) Whether to show the prompt window icon in taskbar. Defaults to true. |
|
||||
| frame | (optional, boolean) Wether to create prompt with frame. Defaults to true. |
|
||||
| customScript | (optional, string) The local path of a JS file to run on preload. Defaults to null. |
|
||||
| enableRemoteModule | (optional, boolean) Wether the prompt window have remote modules activated, Defaults to false. |
|
||||
|
||||
If not supplied, it uses the defaults listed in the table above.
|
||||
|
||||
### parentBrowserWindow (optional)
|
||||
|
||||
The window in which to display the prompt on. If not supplied, the parent window of the prompt will be null.
|
||||
|
||||
### customScript (optional)
|
||||
|
||||
Create the script with the following template:
|
||||
|
||||
```node
|
||||
module.exports = () => {
|
||||
// This function will be called as a preload script
|
||||
// So you can use front features like `document.querySelector`
|
||||
};
|
||||
```
|
||||
Reference in New Issue
Block a user