move prompt to provide

This commit is contained in:
Araxeus
2021-04-05 04:21:52 +03:00
parent 106e461beb
commit 6d44a579a4
7 changed files with 12 additions and 7 deletions

View File

@ -0,0 +1,19 @@
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';
}

View File

@ -0,0 +1,45 @@
body {
background-color: rgba(0, 0, 0, 0.3);
background-image: linear-gradient(315deg, #200000 0%, #13253a 74%);
color: whitesmoke;
}
#label {
text-align: center;
}
#container {
background: rgba(0, 0, 0, 0.7);
box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
border-radius: 10px;
border: 1px solid rgba(80, 0, 0, 0.4);
overflow: hidden;
}
#data {
background: unset;
color: whitesmoke;
border: 1px solid rgb(54, 54, 54);
}
#data:hover {
border: 1px solid rgb(85, 85, 85);
}
#data:focus {
outline: unset;
border: 1px solid rgb(85, 85, 85);
}
#ok:hover,
#cancel:hover {
outline: rgba(60, 0, 0, 0.4) solid 2px;
}
#ok,
#cancel {
background-color: rgb(0, 0, 0);
color: whitesmoke;
}

127
providers/prompt/index.js Normal file
View File

@ -0,0 +1,127 @@
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 DEFAULT_WIDTH = 370;
const DEFAULT_HEIGHT = 160;
function electronPrompt(options, parentWindow) {
return new Promise((resolve, reject) => {
const id = `${Date.now()}-${Math.random()}`;
const options_ = Object.assign(
{
width: DEFAULT_WIDTH,
height: DEFAULT_HEIGHT,
minWidth: DEFAULT_WIDTH,
minHeight: DEFAULT_HEIGHT,
resizable: false,
title: 'Prompt',
label: 'Please input a value:',
buttonLabels: null,
alwaysOnTop: false,
value: null,
type: 'input',
selectOptions: null,
icon: null,
useHtmlLabel: false,
customStylesheet: null,
menuBarVisible: false,
skipTaskbar: true,
frame: true,
customScript: null,
enableRemoteModule: false
},
options || {}
);
if (options_.type === 'select' && (options_.selectOptions === null || typeof options_.selectOptions !== 'object')) {
reject(new Error('"selectOptions" must be an object'));
return;
}
let promptWindow = new BrowserWindow({
frame: options_.frame,
width: options_.width,
height: options_.height,
minWidth: options_.minWidth,
minHeight: options_.minHeight,
resizable: options_.resizable,
minimizable: false,
fullscreenable: false,
maximizable: false,
parent: parentWindow,
skipTaskbar: options_.skipTaskbar,
alwaysOnTop: options_.alwaysOnTop,
useContentSize: options_.resizable,
modal: Boolean(parentWindow),
title: options_.title,
icon: options_.icon || undefined,
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
enableRemoteModule: options_.enableRemoteModule
}
});
promptWindow.setMenu(null);
promptWindow.setMenuBarVisibility(options_.menuBarVisible);
const getOptionsListener = event => {
event.returnValue = JSON.stringify(options_);
};
const cleanup = () => {
ipcMain.removeListener('prompt-get-options:' + id, getOptionsListener);
ipcMain.removeListener('prompt-post-data:' + id, postDataListener);
ipcMain.removeListener('prompt-error:' + id, errorListener);
if (promptWindow) {
promptWindow.close();
promptWindow = null;
}
};
const postDataListener = (event, value) => {
resolve(value);
event.returnValue = null;
cleanup();
};
const unresponsiveListener = () => {
reject(new Error('Window was unresponsive'));
cleanup();
};
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);
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
});
promptWindow.loadURL(promptUrl);
});
}
module.exports = electronPrompt;

View File

@ -0,0 +1,80 @@
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", Helvetica, Arial,
sans-serif;
line-height: 1.5em;
color: #333;
background-color: #fff;
overflow-y: hidden;
}
::-webkit-scrollbar {
width: 0 !important;
display: none;
}
#container {
align-items: center;
justify-content: center;
display: flex;
height: 100%;
overflow-y: hidden;
}
#form {
width: 100%;
padding-top: 0.5em;
}
#label {
max-width: 100%;
max-height: 100%;
margin-bottom: 0.8em;
padding: 0 0.5em;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
#data {
border-radius: 2px;
background: #fff;
width: 90%;
padding: 0.4em 0.5em;
border: 1px solid black;
min-height: 2em;
margin: 0 0 1.2em;
}
select#data {
height: 2em;
}
#data-container {
text-align: center;
}
#buttons {
text-align: right;
padding: 0 0.5em 0 0;
}
#buttons > button,
#buttons > input[type="submit"] {
border-radius: 2px;
border: 0;
margin: 0 0 0 0.5em;
font-size: 0.8em;
line-height: 1em;
padding: 0.6em 1em;
}
#ok {
background-color: #3879d9;
color: white;
}
#cancel {
background-color: #ddd;
color: black;
}

View File

@ -0,0 +1,18 @@
<html>
<head>
<link href="prompt.css" rel="stylesheet" />
</head>
<body>
<div id="container">
<form id="form">
<div id="label">...</div>
<div id="data-container"></div>
<div id="buttons">
<button id="cancel">Cancel</button>
<button type="submit" id="ok">OK</button>
</div>
</form>
</div>
<script src="prompt.js"></script>
</body>
</html>

View File

@ -0,0 +1,170 @@
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;
}
function promptRegister() {
promptId = document.location.hash.replace('#', '');
try {
promptOptions = JSON.parse(ipcRenderer.sendSync('prompt-get-options:' + promptId));
} catch (error) {
return promptError(error);
}
if (promptOptions.useHtmlLabel) {
document.querySelector('#label').innerHTML = promptOptions.label;
} else {
document.querySelector('#label').textContent = promptOptions.label;
}
if (promptOptions.buttonLabels && promptOptions.buttonLabels.ok) {
document.querySelector('#ok').textContent = promptOptions.buttonLabels.ok;
}
if (promptOptions.buttonLabels && promptOptions.buttonLabels.cancel) {
document.querySelector('#cancel').textContent = promptOptions.buttonLabels.cancel;
}
if (promptOptions.customStylesheet) {
try {
const customStyleContent = fs.readFileSync(promptOptions.customStylesheet);
if (customStyleContent) {
const customStyle = document.createElement('style');
customStyle.setAttribute('rel', 'stylesheet');
customStyle.append(document.createTextNode(customStyleContent));
document.head.append(customStyle);
}
} catch (error) {
return promptError(error);
}
}
document.querySelector('#form').addEventListener('submit', promptSubmit);
document.querySelector('#cancel').addEventListener('click', promptCancel);
const dataContainerElement = document.querySelector('#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);
dataElement.setAttribute('id', 'data');
dataElement.focus();
if (promptOptions.type === 'input') {
dataElement.select();
}
if (promptOptions.customScript) {
try {
const customScript = require(promptOptions.customScript);
customScript();
} catch (error) {
return promptError(error);
}
}
}
window.addEventListener('error', error => {
if (promptId) {
promptError('An error has occured on the prompt window: \n' + error);
}
});
docReady(promptRegister);