diff --git a/menu.js b/menu.js index bbe7204f..0312778f 100644 --- a/menu.js +++ b/menu.js @@ -6,7 +6,7 @@ const is = require("electron-is"); const { getAllPlugins } = require("./plugins/utils"); const config = require("./config"); -const prompt = require('electron-prompt'); +const prompt = require('./prompt'); const pluginEnabledMenu = (win, plugin, label = "", hasSubmenu = false) => ({ label: label || plugin, @@ -312,7 +312,7 @@ module.exports.setApplicationMenu = (win) => { const iconPath = path.join(__dirname, "assets", "youtube-music-tray.png"); const example = `Example: "socks5://127.0.0.1:9999"`; function setProxy(item) { - prompt({ + let options = { title: 'Set Proxy', label: 'Enter Proxy Address (leave empty to disable)', value: config.get("options.proxy") || example, @@ -322,8 +322,18 @@ function setProxy(item) { type: 'input', alwaysOnTop: true, icon: iconPath, - customStylesheet: path.join(__dirname, "darkPrompt.css"), - }) + customStylesheet: path.join(__dirname, "prompt","darkPrompt.css"), + }; + if (config.plugins.isEnabled("in-app-menu")) { + Object.assign(options, { + frame: false, + customScript: path.join(__dirname, "prompt","customTitlebar.js"), + enableRemoteModule: true, + height: 200, + width: 450, + }) + } + prompt(options) .then((input) => { if(input !== null && input !== example) { config.set("options.proxy", input); diff --git a/package.json b/package.json index 736374c5..36591897 100644 --- a/package.json +++ b/package.json @@ -70,11 +70,11 @@ "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", "electron-localshortcut": "^3.2.1", - "electron-prompt": "^1.6.2", "electron-store": "^7.0.2", "electron-unhandled": "^3.0.2", "electron-updater": "^4.3.6", diff --git a/prompt/customTitlebar.js b/prompt/customTitlebar.js new file mode 100644 index 00000000..203828d4 --- /dev/null +++ b/prompt/customTitlebar.js @@ -0,0 +1,12 @@ +const customTitlebar = require("custom-electron-titlebar"); + +module.exports = () => { + const bar = new customTitlebar.Titlebar({ + backgroundColor: customTitlebar.Color.fromHex("#050505"), + }); + try { + bar.updateMenu(null); + } catch (e) { + //will always throw type error - null isn't menu, but it works + } +} \ No newline at end of file diff --git a/darkPrompt.css b/prompt/darkPrompt.css similarity index 88% rename from darkPrompt.css rename to prompt/darkPrompt.css index 100a6ed5..3bdc5647 100644 --- a/darkPrompt.css +++ b/prompt/darkPrompt.css @@ -4,6 +4,16 @@ body { overflow: hidden; color:whitesmoke; } + +::-webkit-scrollbar { + width: 0 !important; + display: none; +} + +#label { + text-align: center; +} + #container { background: rgba( 0, 0, 0, 0.7 ); box-shadow: 0 8px 32px 0 rgba( 31, 38, 135, 0.37 ); @@ -11,7 +21,6 @@ body { -webkit-backdrop-filter: blur( 10.0px ); border-radius: 10px; border: 1px solid rgba(80, 0, 0, 0.4); - overflow: hidden; } diff --git a/prompt/index.js b/prompt/index.js new file mode 100644 index 00000000..d6664305 --- /dev/null +++ b/prompt/index.js @@ -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; diff --git a/prompt/page/prompt.css b/prompt/page/prompt.css new file mode 100644 index 00000000..b9d37777 --- /dev/null +++ b/prompt/page/prompt.css @@ -0,0 +1,72 @@ +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; +} + +#container { + align-items: center; + justify-content: center; + display: flex; + height: 100%; + overflow: auto; +} + +#form { + width: 100%; + padding-top: .5em; +} + +#label { + max-width: 100%; + max-height: 100%; + margin-bottom: .8em; + padding: 0 .5em; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +#data { + border-radius: 2px; + background: #fff; + width: 90%; + padding: .4em .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 .5em 0 0; +} + +#buttons > button, +#buttons > input[type=submit] { + border-radius: 2px; + border: 0; + margin: 0 0 0 .5em; + font-size: .8em; + line-height: 1em; + padding: .6em 1em +} + +#ok { + background-color: #3879D9; + color: white; +} + +#cancel { + background-color: #DDD; + color: black; +} diff --git a/prompt/page/prompt.html b/prompt/page/prompt.html new file mode 100644 index 00000000..cdbfa544 --- /dev/null +++ b/prompt/page/prompt.html @@ -0,0 +1,18 @@ + +
+ + + +