Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom Prompt for changing options #243

Merged
merged 32 commits into from
Oct 24, 2021
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
e4eed2e
add custom-electron-prompt
Araxeus Apr 27, 2021
a229ba9
disable reload of plugins on window created
Araxeus Apr 27, 2021
964974c
add keybind changer v1
Araxeus Apr 30, 2021
e456035
fix typo
Araxeus Apr 30, 2021
49e51de
update shortcuts config
Araxeus Apr 30, 2021
54cbe3f
lint
Araxeus Apr 30, 2021
d0d4ada
restore original menu lint
Araxeus Apr 30, 2021
ec981ac
refactor registerAllShortcuts
Araxeus Apr 30, 2021
ebaa018
Merge remote-tracking branch 'upstream/master' into custom-electron-p…
Araxeus May 4, 2021
79acf6c
Volume Steps Prompt
Araxeus May 4, 2021
22c5ea5
lint
Araxeus May 4, 2021
34a4e6b
proxy url check
Araxeus May 4, 2021
b97a86f
Update yarn.lock
Araxeus May 4, 2021
db8d946
fix electron dependency
Araxeus May 4, 2021
98c00f7
format proxy example
Araxeus May 4, 2021
5cee331
update prompt version and lint
Araxeus May 4, 2021
834f867
massive prompt speed boost with v1.1.0
Araxeus May 5, 2021
6b147b0
fix prompt width
Araxeus May 5, 2021
5418ef7
Merge branch 'master' into custom-electron-prompt
Araxeus May 7, 2021
f910593
use spread operator + async await
Araxeus May 9, 2021
36317c9
globalize promptOptions
Araxeus May 9, 2021
0eca303
lint
Araxeus May 9, 2021
580caef
destructure keybind output
Araxeus May 10, 2021
e43c01d
lint
Araxeus May 10, 2021
002081b
use store migration
Araxeus May 11, 2021
355f611
use placeholder proxy example
Araxeus May 13, 2021
b2c2098
fix empty string input validation in setProxy
Araxeus May 14, 2021
664be51
Merge branch 'master' into custom-electron-prompt
Araxeus Jun 25, 2021
52a4608
create options.global if needed
Araxeus Jul 20, 2021
a49817f
Merge branch 'master' into custom-electron-prompt
Araxeus Jul 20, 2021
65eaaec
Merge branch 'master' into custom-electron-prompt
Araxeus Aug 19, 2021
1cd4f53
Merge branch 'master' into custom-electron-prompt
Araxeus Oct 19, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions config/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ const defaultConfig = {
// Disabled plugins
shortcuts: {
enabled: false,
overrideMediaKeys: false,
Araxeus marked this conversation as resolved.
Show resolved Hide resolved
},
downloader: {
enabled: false,
Expand Down Expand Up @@ -58,9 +59,8 @@ const defaultConfig = {
steps: 1, //percentage of volume to change
arrowsShortcut: true, //enable ArrowUp + ArrowDown local shortcuts
globalShortcuts: {
enabled: false, // enable global shortcuts
volumeUp: "Shift+PageUp", // Keybind default can be changed
volumeDown: "Shift+PageDown"
volumeUp: "",
volumeDown: ""
},
savedVolume: undefined //plugin save volume between session here
}
Expand Down
6 changes: 4 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ if (config.get("options.proxy")) {
}

// Adds debug features like hotkeys for triggering dev tools and reload
require("electron-debug")();
require("electron-debug")({
showDevTools: false //disable automatic devTools on new window
});

// Prevent window being garbage collected
let mainWindow;
Expand All @@ -58,7 +60,7 @@ function onClosed() {

function loadPlugins(win) {
injectCSS(win.webContents, path.join(__dirname, "youtube-music.css"));
win.webContents.on("did-finish-load", () => {
win.webContents.once("did-finish-load", () => {
if (is.dev()) {
console.log("did finish load");
win.webContents.openDevTools();
Expand Down
44 changes: 44 additions & 0 deletions menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const is = require("electron-is");

const { getAllPlugins } = require("./plugins/utils");
const config = require("./config");
const prompt = require("custom-electron-prompt");

const pluginEnabledMenu = (win, plugin, label = "", hasSubmenu = false) => ({
label: label || plugin,
Expand Down Expand Up @@ -143,6 +144,14 @@ const mainMenuTemplate = (win) => [
{
label: "Advanced options",
submenu: [
{
label: "Proxy",
type: "checkbox",
checked: !!config.get("options.proxy"),
click: (item) => {
setProxy(item, win);
}
},
{
label: "Disable hardware acceleration",
type: "checkbox",
Expand Down Expand Up @@ -300,3 +309,38 @@ module.exports.setApplicationMenu = (win) => {
const menu = Menu.buildFromTemplate(menuTemplate);
Menu.setApplicationMenu(menu);
};

const iconPath = path.join(__dirname, "assets", "youtube-music-tray.png");
const example = "Example: 'socks5://127.0.0.1:9999'";
function setProxy(item, win) {
let options = {
title: 'Set Proxy',
label: 'Enter Proxy Address: (leave empty to disable)',
value: config.get("options.proxy") || example,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Idea of feature for the prompt plugin: the ability to have a placeholder (would be better suited for example instead of putting it as value and checking later that value !== example)

Copy link
Collaborator Author

@Araxeus Araxeus May 9, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is already a placeholder which is the value field

instead of putting it as value and checking later that value !== example

Are you talking about implementing this exact logic in custom-electron-prompt ?

I could make an boolean option placeholder which will mean "return null if output=options.value"
but it seems kinda unnecessary..

I think it might be best to let whoever implements the prompt decide what to do with the output, since there could be many different intentions when using the prompt,

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, idea was to add a implement the placeholder logic/field in custom-electron-prompt! (main pro of a placeholder is to avoid having a fake value to remove when filling the field, contrary to a default value - here, it feels we have a placeholder used a default value 🙃)
Not a big deal though, does not block merging - just an improvement idea for the custom-prompt package :)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

355f611 changed the input field "placeholder" attribute to the previous example as you suggested
(didn't need to change custom-electron-prompt itself)

I'm not sure its better though, since you can't copy paste or edit that text, and it disappears when typing. which can makes it harder for people that don't know the format

type: 'input',
inputAttrs: {
type: 'url'
},
icon: iconPath,
customStylesheet: "dark",
width: 450,
};
//TODO: custom bar on prompt need testing on macOS
if (!is.macOS()) {
Araxeus marked this conversation as resolved.
Show resolved Hide resolved
Object.assign(options, {
Araxeus marked this conversation as resolved.
Show resolved Hide resolved
frame: false,
customScript: path.join(__dirname, "plugins", "in-app-menu", "prompt-custom-titlebar.js"),
Araxeus marked this conversation as resolved.
Show resolved Hide resolved
enableRemoteModule: true,
});
}
prompt(options, win)
.then(output => {
Araxeus marked this conversation as resolved.
Show resolved Hide resolved
if (output !== null && output !== example) {
config.set("options.proxy", output);
item.checked = output !== "";
} else { //user pressed cancel
item.checked = !item.checked; //reset checkbox
}
})
.catch(console.error);
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
"YoutubeNonStop": "git://github.com/lawfx/YoutubeNonStop.git#v0.9.0",
"async-mutex": "^0.3.1",
"browser-id3-writer": "^4.4.0",
"custom-electron-prompt": "^1.1.0",
"chokidar": "^3.5.1",
"custom-electron-titlebar": "^3.2.6",
"discord-rpc": "^3.2.0",
Expand Down
14 changes: 14 additions & 0 deletions plugins/in-app-menu/prompt-custom-titlebar.js
Original file line number Diff line number Diff line change
@@ -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";
};
4 changes: 1 addition & 3 deletions plugins/precise-volume/front.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ module.exports = (options) => {

setupLocalArrowShortcuts(options);

if (options.globalShortcuts?.enabled) {
setupGlobalShortcuts(options);
}
setupGlobalShortcuts(options);

firstRun(options);

Expand Down
96 changes: 93 additions & 3 deletions plugins/precise-volume/menu.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,109 @@
const { enabled } = require("./back");
const { app } = require("electron");
const { setOptions } = require("../../config/plugins");
const prompt = require("custom-electron-prompt");
const path = require("path");
const is = require("electron-is");

module.exports = (win, options) => [
{
label: "Arrowkeys controls",
label: "Local Arrowkeys Controls",
type: "checkbox",
checked: !!options.arrowsShortcut,
click: (item) => {
// Dynamically change setting if plugin enabled
click: item => {
// Dynamically change setting if plugin is enabled
if (enabled()) {
win.webContents.send("setArrowsShortcut", item.checked);
} else { // Fallback to usual method if disabled
options.arrowsShortcut = item.checked;
setOptions("precise-volume", options);
}
}
},
{
label: "Global Hotkeys",
type: "checkbox",
checked: !!options.globalShortcuts.volumeUp || !!options.globalShortcuts.volumeDown,
click: item => promptGlobalShortcuts(win, options, item)
},
{
label: "Set Custom Volume Steps",
click: () => promptVolumeSteps(win, options)
}
];

const iconPath = path.join(app.getAppPath(), "assets", "youtube-music-tray.png");
const customTitlebarPath = path.join(app.getAppPath(), "plugins", "in-app-menu", "prompt-custom-titlebar.js");
// Helper function for globalShortcuts prompt
const kb = (label_, value_, default_) => { return { value: value_, label: label_, default: default_ || undefined }; };

function promptVolumeSteps(win, options) {
const promptOptions = {
title: "Volume Steps",
label: "Choose Volume Increase/Decrease Steps",
value: options.steps || 1,
type: "counter",
counterOptions: { minimum: 0, maximum: 100, multiFire: true },
width: 380
};

setupPromptOptions(promptOptions);

prompt(promptOptions, win)
.then(output => {
if (output || output === 0) { // 0 is somehow valid
options.steps = output;
setOptions("precise-volume", options);
}
}).catch(console.error);
}

function promptGlobalShortcuts(win, options, item) {
const promptOptions = {
title: "Global Volume Keybinds",
label: "Choose Global Volume Keybinds:",
type: "keybind",
keybindOptions: [
kb("Increase Volume", "volumeUp", options.globalShortcuts?.volumeUp),
kb("Decrease Volume", "volumeDown", options.globalShortcuts?.volumeDown)
]
};

setupPromptOptions(promptOptions);

prompt(promptOptions, win)
.then(output => {
if (output) {
for (const keybindObject of output) {
options.globalShortcuts[keybindObject.value] = keybindObject.accelerator;
Araxeus marked this conversation as resolved.
Show resolved Hide resolved
}

setOptions("precise-volume", options);

item.checked = !!options.globalShortcuts.volumeUp || !!options.globalShortcuts.volumeDown;
} else {
// Reset checkbox if prompt was canceled
item.checked = !item.checked;
}
})
.catch(console.error);
}

function setupPromptOptions(options) {
// TODO Custom titlebar needs testing on macOS
if (is.macOS()) {
Object.assign(options, {
customStylesheet: "dark",
icon: iconPath
});
} else {
Object.assign(options, {
customStylesheet: "dark",
icon: iconPath,
// The following are used for custom titlebar
frame: false,
customScript: customTitlebarPath,
enableRemoteModule: true
});
}
}
69 changes: 52 additions & 17 deletions plugins/shortcuts/back.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const { globalShortcut } = require("electron");
const electronLocalshortcut = require("electron-localshortcut");
const { setOptions } = require("../../config/plugins");

const getSongControls = require("../../providers/song-controls");

Expand All @@ -19,31 +20,65 @@ function registerShortcuts(win, options) {
const songControls = getSongControls(win);
const { playPause, next, previous, search } = songControls;

_registerGlobalShortcut(win.webContents, "MediaPlayPause", playPause);
_registerGlobalShortcut(win.webContents, "MediaNextTrack", next);
_registerGlobalShortcut(win.webContents, "MediaPreviousTrack", previous);
updateOptions(options);

if (options.overrideMediaKeys) {
_registerGlobalShortcut(win.webContents, "MediaPlayPause", playPause);
_registerGlobalShortcut(win.webContents, "MediaNextTrack", next);
_registerGlobalShortcut(win.webContents, "MediaPreviousTrack", previous);
}

_registerLocalShortcut(win, "CommandOrControl+F", search);
_registerLocalShortcut(win, "CommandOrControl+L", search);

const { global, local } = options;
(global || []).forEach(({ shortcut, action }) => {
console.debug("Registering global shortcut", shortcut, ":", action);
if (!action || !songControls[action]) {
console.warn("Invalid action", action);
return;
const shortcutOptions = { global, local };

for (const optionType in shortcutOptions) {
registerAllShortcuts(shortcutOptions[optionType], optionType);
}

function registerAllShortcuts(container, type) {
for (const action in container) {
if (!container[action]) {
continue; // Action accelerator is empty
}

console.debug(`Registering ${type} shortcut`, container[action], ":", action);
if (!songControls[action]) {
console.warn("Invalid action", action);
continue;
}

if (type === "global") {
_registerGlobalShortcut(win.webContents, container[action], songControls[action]);
} else { // type === "local"
_registerLocalShortcut(win, local[action], songControls[action]);
}
}
}
}

_registerGlobalShortcut(win.webContents, shortcut, songControls[action]);
});
(local || []).forEach(({ shortcut, action }) => {
console.debug("Registering local shortcut", shortcut, ":", action);
if (!action || !songControls[action]) {
console.warn("Invalid action", action);
return;
/** Update options to new format if they are still an array (old format) */
function updateOptions(options) {
Copy link
Owner

@th-ch th-ch May 11, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a one-shot operation that can be done with a store migration (there are examples in in config/store.js)

Copy link
Collaborator Author

@Araxeus Araxeus May 11, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved the code to store migration in 002081b
Is it alright this way? should the version be higher?

(prompt-custom-titlebar.js was already moved to providers folder before 😝)

let updated = false;
for (const optionType of ["global", "local"]) {
if (Array.isArray(options[optionType])) {
const updatedOptions = {};
for (const optionObject of options[optionType]) {
if (optionObject.action && optionObject.shortcut) {
updatedOptions[optionObject.action] = optionObject.shortcut;
}
}

options[optionType] = updatedOptions;
updated = true;
}
}

_registerLocalShortcut(win, shortcut, songControls[action]);
});
if (updated) {
setOptions("shortcuts", options);
}
}

module.exports = registerShortcuts;
Loading