2018-01-30 12:14:16 +01:00
|
|
|
/**
|
|
|
|
* BetterDiscord IPC Module
|
|
|
|
* Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
|
|
|
|
* All rights reserved.
|
|
|
|
* https://betterdiscord.net
|
|
|
|
*
|
|
|
|
* This source code is licensed under the MIT license found in the
|
|
|
|
* LICENSE file in the root directory of this source tree.
|
|
|
|
*/
|
|
|
|
|
2018-03-21 21:52:42 +01:00
|
|
|
import { ipcRenderer } from 'electron';
|
2018-01-30 12:14:16 +01:00
|
|
|
|
2018-03-21 21:52:42 +01:00
|
|
|
const callbacks = new WeakMap();
|
|
|
|
|
2018-03-22 03:37:30 +01:00
|
|
|
const ClientIPC = new class ClientIPC {
|
2018-03-21 21:52:42 +01:00
|
|
|
|
|
|
|
constructor() {
|
|
|
|
this.on('ping', () => 'pong', true);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Adds an IPC event listener.
|
|
|
|
* @param {String} channel The channel to listen on
|
|
|
|
* @param {Function} callback A function that will be called when a message is received
|
|
|
|
* @param {Boolean} reply Whether to automatically reply to the message with the callback's return value
|
|
|
|
* @return {Promise}
|
|
|
|
*/
|
|
|
|
on(channel, callback, reply) {
|
|
|
|
channel = channel.startsWith('bd-') ? channel : `bd-${channel}`;
|
|
|
|
|
|
|
|
const boundCallback = async (event, args) => {
|
|
|
|
const ipcevent = new BDIpcEvent(event, args);
|
|
|
|
try {
|
|
|
|
const r = callback(ipcevent, ipcevent.message);
|
|
|
|
if (reply) ipcevent.reply(await r);
|
|
|
|
} catch (err) {
|
|
|
|
console.error('Error in IPC callback:', err);
|
|
|
|
if (reply) ipcevent.reject(err);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
callbacks.set(callback, boundCallback);
|
|
|
|
ipcRenderer.on(channel, boundCallback);
|
|
|
|
}
|
|
|
|
|
|
|
|
off(channel, callback) {
|
|
|
|
ipcRenderer.removeListener(channel, callbacks.get(callback));
|
2018-01-30 12:14:16 +01:00
|
|
|
}
|
|
|
|
|
2018-03-21 21:52:42 +01:00
|
|
|
/**
|
|
|
|
* Sends a message to the main process and returns a promise that is resolved when the main process replies.
|
|
|
|
* @param {String} channel The channel to send a message to
|
|
|
|
* @param {Any} message Data to send to the main process
|
|
|
|
* @param {Boolean} error Whether to mark the message as an error
|
|
|
|
* @return {Promise}
|
|
|
|
*/
|
|
|
|
async send(channel, message, error) {
|
2018-01-30 12:14:16 +01:00
|
|
|
channel = channel.startsWith('bd-') ? channel : `bd-${channel}`;
|
2018-03-21 21:52:42 +01:00
|
|
|
|
2018-08-15 08:01:47 +02:00
|
|
|
const eid = `bd-${Date.now().toString()}`;
|
2018-03-21 21:52:42 +01:00
|
|
|
ipcRenderer.send(channel, { eid, message, error });
|
|
|
|
|
2018-01-30 12:14:16 +01:00
|
|
|
return new Promise((resolve, reject) => {
|
2018-03-21 21:52:42 +01:00
|
|
|
ipcRenderer.once(eid, (event, arg) => {
|
|
|
|
if (arg.error) reject(arg.message);
|
|
|
|
else resolve(arg.message);
|
2018-02-11 15:59:55 +01:00
|
|
|
});
|
2018-01-30 12:14:16 +01:00
|
|
|
});
|
|
|
|
}
|
2018-03-21 21:52:42 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Sends a message to the Discord window and returns a promise that is resolved when it replies.
|
|
|
|
* @param {String} channel The channel to send a message to
|
|
|
|
* @param {Any} message Data to send to the renderer process
|
|
|
|
* @return {Promise}
|
|
|
|
*/
|
|
|
|
sendToDiscord(channel, message) {
|
|
|
|
return this.send('bd-sendToDiscord', {
|
|
|
|
channel, message
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sends a message to the CSS editor window and returns a promise that is resolved when it replies.
|
|
|
|
* @param {String} channel The channel to send a message to
|
|
|
|
* @param {Any} message Data to send to the CSS editor window
|
|
|
|
* @return {Promise}
|
|
|
|
*/
|
|
|
|
sendToCssEditor(channel, message) {
|
|
|
|
return this.send('bd-sendToCssEditor', {
|
|
|
|
channel, message
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
ping() {
|
|
|
|
return this.send('ping');
|
|
|
|
}
|
|
|
|
|
|
|
|
getConfig() {
|
|
|
|
return this.send('getConfig');
|
|
|
|
}
|
|
|
|
|
|
|
|
showOpenDialog(options) {
|
|
|
|
return this.send('native-open', options);
|
|
|
|
}
|
|
|
|
|
|
|
|
compileSass(options) {
|
|
|
|
return this.send('compileSass', options);
|
|
|
|
}
|
|
|
|
|
|
|
|
dba(command) {
|
|
|
|
return this.send('dba', command);
|
|
|
|
}
|
|
|
|
|
2018-01-30 12:14:16 +01:00
|
|
|
}
|
|
|
|
|
2018-03-22 03:37:30 +01:00
|
|
|
export default ClientIPC;
|
|
|
|
|
2018-03-21 21:52:42 +01:00
|
|
|
/**
|
|
|
|
* An IPC event.
|
|
|
|
*/
|
2018-01-30 12:14:16 +01:00
|
|
|
class BDIpcEvent {
|
|
|
|
|
|
|
|
constructor(event, args) {
|
|
|
|
this.args = args;
|
|
|
|
this.ipcEvent = event;
|
2018-03-21 21:52:42 +01:00
|
|
|
this.replied = false;
|
2018-01-30 12:14:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
bindings() {
|
|
|
|
this.reply = this.reply.bind(this);
|
|
|
|
}
|
|
|
|
|
2018-03-21 21:52:42 +01:00
|
|
|
/**
|
|
|
|
* Sends a message back to the message's sender.
|
|
|
|
* @param {Any} message Data to send to this message's sender
|
|
|
|
*/
|
|
|
|
get send() { return this.reply }
|
|
|
|
reply(message, error) {
|
|
|
|
if (this.replied)
|
|
|
|
throw {message: 'This message has already been replied to.'};
|
|
|
|
|
|
|
|
this.replied = true;
|
|
|
|
return ClientIPC.send(this.eid, message, error);
|
2018-01-30 12:14:16 +01:00
|
|
|
}
|
|
|
|
|
2018-03-21 21:52:42 +01:00
|
|
|
reject(err) {
|
|
|
|
return this.reply(err, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
get message() {
|
|
|
|
return this.args.message;
|
|
|
|
}
|
|
|
|
|
|
|
|
get error() {
|
|
|
|
return this.args.error;
|
2018-01-30 12:14:16 +01:00
|
|
|
}
|
|
|
|
|
2018-03-21 21:52:42 +01:00
|
|
|
get eid() {
|
|
|
|
return this.args.eid;
|
2018-01-30 12:14:16 +01:00
|
|
|
}
|
|
|
|
}
|