Use a signal to trigger the mute event

This commit is contained in:
Michael Peters 2022-02-24 00:32:38 -06:00
parent 4401b6ad73
commit 4a440c9dd6
11 changed files with 38 additions and 661 deletions

View File

@ -13,29 +13,15 @@ Note that since this client is running the Discord web client, the following fea
- Discord's "High Quality Audio" or whatever
## Configuration
> ~/.config/discord-sandbox/settings.json
> delay: Push to Talk Release Delay (ms)
> pttDevice: Push to Talk Device ("mouse" or "keyboard")
> key: Push to Talk Key
## Toggle Mute
Push-to-Talk is configured using the SIGUSR2. Send a SIGUSR2 to the electron process to trigger a click on the mute button.
You can send this signal in the terminal with pkill
`pkill -SIGUSR2 --oldest electron`
### Example Configuration
> {
> "delay": "1000"
> "pttDevice": "mouse"
> "key": "4"
> }
> Note: Make sure to use --oldest. Otherwise, the electron GPU processes will get angry and quit passive-agressively:
> [130264:0223/232600.871793:FATAL:gpu\_data\_manager\_impl\_private.cc(448)] GPU process isn't usable. Goodbye.
> /home/michael/builds/discord-sandboxed/node\_modules/electron/dist/electron exited with signal SIGTRAP
## Push to Talk
1. To enable push-to-talk, open Discord-Sandbox, set your push-to-talk key to `Backspace`, and lower the `Push to Talk Release Delay` slider all the way to 0 as shown.
<p align="center">
<img src="./docs/img/PTTSettings.PNG" />
</p>
2. Click on the gear icon in the top left corner. Check the box to enable system-wide push to talk. Set your push to talk key by clicking in the black box and pressing the desired key (Default PTT key is mouse button 4). Configuration settings are stored in `/Documents/DiscordSandbox/config.json`.
<p align="center">
<img src="./docs/img/PTT.PNG" />
</p>
## Telemetry Mitigations
@ -45,7 +31,7 @@ As detailed from [Luna Mendes' discord-unofficial-docs]("https://luna.gitlab.io/
Discord likely does other sneaky things to spy on us. If you have any ideas on improving this project's security/privacy please let me know by opening an issue!
Clicking on the Logs icon to the right of the settings button in the client will open the Log window, which will detail when a communication by the client is blocked.
Clicking on the Logs icon in the client will open the Log window, which will detail when a communication by the client is blocked.
<p align="center">
<img src="./docs/img/logs.PNG" />
</p>

245
main.js
View File

@ -4,38 +4,18 @@ const {clipboard} = require('electron')
const path = require('path')
const URL = require('url').URL
const { initConfig, saveConfig } = require('./src/config')
let ioHook = null
try {
ioHook = require('iohook')
} catch(e) {
console.log(e)
ioHook = false
}
'use strict';
let mainWindow
let logWindow
let settingsWindow
let devMode = false
let selfMute = false
let isConnected = false
let webViewSession = null
let isTalking = false
let muteTimeout = null
let configObj
let micPermissionGranted = false
let isChangingPTTKey = false
let pttEnable = 'mousedown' // init to mousedown/up
let pttDisable = 'mouseup'
let pttWatch = 'button'
// Set Dev mode
if (process.argv.length === 3) {
if (process.argv[2] === 'dev'){
@ -43,21 +23,6 @@ if (process.argv.length === 3) {
}
}
function unmuteMic() {
if ( selfMute === false){
isTalking = true
console.log("Talking")
mainWindow.webContents.send('micOpen', 'mic-open')
mainWindow.setTitle("MIC OPEN")
}
}
function muteMic() {
console.log("Not Talking")
mainWindow.webContents.send('micClose', 'mic-closed')
mainWindow.setTitle("MIC CLOSED")
}
function createMainWindow () {
// Create the browser window.
mainWindow = new BrowserWindow({
@ -115,28 +80,6 @@ function createLogWindow() {
})
}
function createSettingsWindow() {
settingsWindow = new BrowserWindow({
width: 700,
height: 400,
show: true,
resizable: false,
alwaysOnTop:true,
webPreferences: {
preload: path.join(__dirname, 'src/settingsLoad.js'),
nodeIntegration: false,
enableRemoteModule: false,
},
frame: false
})
settingsWindow.loadFile('./views/settings.html')
settingsWindow.setTitle("Settings")
settingsWindow.on('closed', function () {
isChangingPTTKey = false
settingsWindow = null
})
}
function maximizeMinimizeState(windowName){
if (windowName.isMaximized()) {
@ -146,66 +89,13 @@ function maximizeMinimizeState(windowName){
}
}
function restartioHook() {
if (ioHook) {
console.log("restarting io Hook")
return new Promise((resolve, reject) => {
return new Promise((resolve, reject) => {
ioHook.removeAllListeners('mousedown', () => {})
ioHook.removeAllListeners('mouseup', () => {})
ioHook.removeAllListeners('keydown', () => {})
ioHook.removeAllListeners('keyup', () => {})
ioHook.unload()
console.log("ioHook stopped")
return resolve(true)
}).then (v => {
return new Promise((resolve, reject) => {
ioHook.load()
console.log("ioHook started")
return resolve(true)
}).then(v => {
ioHook.start()
return resolve(true)
})
})
})
}
}
function setPTTKey() {
if (ioHook && configObj.pttDevice && configObj.pttDevice) {
console.log("Set PTT Key")
if (configObj.pttDevice === 'mouse'){
pttEnable = 'mousedown'
pttDisable = 'mouseup'
pttWatch = 'button'
}else if (configObj.pttDevice === 'keyboard'){
pttEnable = 'keydown'
pttDisable = 'keyup'
pttWatch = 'keycode'
}else {
console.log("ERROR: configObj did not set PTT device to mouse or keyboard.")
}
ioHook.on(pttEnable, event => {
if (event[pttWatch] == configObj.key && (micPermissionGranted === true) && (isConnected === true) && (isChangingPTTKey === false)) {
clearTimeout(muteTimeout)
unmuteMic()
}
})
ioHook.on(pttDisable, event => {
if (event[pttWatch] == configObj.key) {
if (isTalking === true) {
isTalking = false
muteTimeout = setTimeout(() => muteMic(), configObj.delay)
}
}
})
}else {
console.log("Not listening for keypresses. ioHook library error or PTT keys not set.")
}
function listenForKeySignal() {
console.log('listening for key signals...');
// Listen for process signal
// SIGUSR2 - Toggle muted
process.on('SIGUSR2', () => {
mainWindow.webContents.send('micToggle', 'mic-toggled');
});
}
app.on('ready', createMainWindow)
@ -332,13 +222,6 @@ ipcMain.on('asynchronous-message', (event, _data) => {
mainWindow.webContents.send('devMode', devMode)
}
if (msg === 'confirmMicClose') {
if (isTalking === true) {
console.log("Mic state desync. Opening Mic.")
unmuteMic()
}
}
if (msg === 'blockUpdate') {
if (logWindow){
logWindow.webContents.send('blockUpdate', _data.data)
@ -352,9 +235,6 @@ ipcMain.on('asynchronous-message', (event, _data) => {
if (_data.data.wName === 1) {
logWindow.minimize()
}
if (_data.data.wName === 2) {
settingsWindow.minimize()
}
}
if (msg === 'maximizeApplication') {
@ -364,9 +244,6 @@ ipcMain.on('asynchronous-message', (event, _data) => {
if (_data.data.wName === 1) {
maximizeMinimizeState(logWindow)
}
if (_data.data.wName === 2) {
maximizeMinimizeState(settingsWindow)
}
}
if (msg === 'closeApplication') {
@ -376,9 +253,6 @@ ipcMain.on('asynchronous-message', (event, _data) => {
if (_data.data.wName === 1) {
logWindow.close()
}
if (_data.data.wName === 2) {
settingsWindow.close()
}
}
if (msg === 'openLog') {
@ -390,114 +264,11 @@ ipcMain.on('asynchronous-message', (event, _data) => {
logWindow.center()
}
}
if (msg === 'openSettings') {
if (settingsWindow) {
if (settingsWindow.isMinimized()) settingsWindow.restore()
settingsWindow.focus()
}else {
createSettingsWindow()
settingsWindow.center()
}
}
if (msg === 'SettingsDOMReady') {
if (settingsWindow) {
console.log("SettingsDOMReady. Sending Settings DOM obj")
settingsWindow.webContents.send('settingsObj', configObj)
}
}
if (msg === 'setPTTKey') {
if (settingsWindow) {
if (ioHook) {
isChangingPTTKey = true
console.log("waiting for user to rebind")
if (settingsWindow && isChangingPTTKey) {
restartioHook().then(v => {
mainWindow.blur()
ioHook.once('keydown', event => {
if (settingsWindow && isChangingPTTKey) {
console.log("rebind success")
configObj.pttDevice = 'keyboard'
configObj.key = event.keycode
isChangingPTTKey = false
saveConfig(configObj)
settingsWindow.webContents.send('settingsObj', configObj)
setPTTKey()
}
})
// Ignore using left click (mouse1)
ioHook.once('mousedown', event => {
if (settingsWindow && isChangingPTTKey && event.button !== 1) {
console.log("rebind success")
configObj.pttDevice = 'mouse'
configObj.key = event.button
isChangingPTTKey = false
saveConfig(configObj)
settingsWindow.webContents.send('settingsObj', configObj)
setPTTKey()
}
})
})
}
}
}
}
if (msg === 'cancelSetPTTKey') {
console.log("cancel set new PTT")
isChangingPTTKey = false
saveConfig(configObj)
settingsWindow.webContents.send('settingsObj', configObj)
}
if (msg === 'setPTTDelay') {
console.log(`New PTT Delay: ${_data.data} ms`)
configObj.delay = _data.data
saveConfig(configObj)
settingsWindow.webContents.send('settingsObj', configObj)
}
if (msg === 'disablePTT') {
if (_data.data === false) {
console.log(`PTT Disabled`)
configObj.delay = null
configObj.key = null
configObj.pttDevice = null
saveConfig(configObj)
settingsWindow.webContents.send('settingsObj', configObj)
}
if (_data.data === true) {
console.log(`PTT Enabled`)
configObj.delay = 1000
configObj.key = "none"
configObj.pttDevice = "none"
saveConfig(configObj)
settingsWindow.webContents.send('settingsObj', configObj)
}
}
})
app.on('ready', event => {
console.log(`Dev Mode: ${devMode}`)
initConfig()
.then(value => {
configObj = value
return configObj
})
.then(configObj => {
console.log(configObj)
restartioHook().then(() => {
setPTTKey()
})
})
listenForKeySignal();
})

View File

@ -1,51 +0,0 @@
const {app} = require('electron')
const fs = require('graceful-fs')
const path = require('path')
function _saveToConfig (configObj) {
return new Promise(function (resolve, reject) {
const configFile = path.join(app.getPath('home'), '.config', 'discord-sandboxed', 'config.json');
console.log('\tUpdating config.json', configObj)
fs.writeFile(configFile, JSON.stringify(configObj, null, 2), (err) => {
if (err) throw err;
return resolve(configObj)
})
})
}
module.exports = {
initConfig: function () {
return new Promise((resolve, reject) => {
const configDir = path.join(app.getPath('home'), '.config', 'discord-sandboxed');
const configFile = path.join(app.getPath('home'), '.config', 'discord-sandboxed', 'config.json');
console.log('init config at ', configFile);
let configObj // Init configObj
// If config dir does not exist create it
if (!fs.existsSync(configDir)){
fs.mkdirSync(configDir)
}
// If config.json does not exist, create it with blank values
if (!fs.existsSync(configFile)) {
console.log(`\tCreated Default Config at [${configFile}]`)
configObj = {
'pttDevice': 'mouse',
'key': '4',
'delay': '1000',
}
return resolve(_saveToConfig(configObj))
}
try {
configObj = JSON.parse(fs.readFileSync(configFile, 'utf8'))
return resolve(configObj)
} catch (err) {
return reject(err)
}
})
},
saveConfig: function(configObj) {
return _saveToConfig(configObj)
}
}

View File

@ -1,20 +1,16 @@
const { ipcRenderer } = require('electron')
// Pass commands sent from main.js to mainRender.js
ipcRenderer.on('devMode', (event, msg) => {
console.log(`PRELOAD: Dev Mode: ${msg}`)
window.postMessage({ type: "devMode", text: `${msg}` }, "*")
})
ipcRenderer.on('micOpen', (event, msg) => {
window.postMessage({ type: "micOpen"}, "*")
ipcRenderer.on('micToggle', (event, msg) => {
console.log('got toggle mic');
window.postMessage({ type: "micToggle"}, "*")
})
ipcRenderer.on('micClose', (event, msg) => {
window.postMessage({ type: "micClose"}, "*")
})
ipcRenderer.on('URLCopied', (event, msg) => {
window.postMessage({ type: "URLCopied"}, "*")
})
@ -80,12 +76,7 @@ window.addEventListener(
if (event.data.type === 'openLog'){
ipcRenderer.send('asynchronous-message', {msg: 'openLog'})
}
if (event.data.type === 'openSettings'){
ipcRenderer.send('asynchronous-message', {msg: 'openSettings'})
}
}
},
false
)
)

View File

@ -1,50 +0,0 @@
const { ipcRenderer } = require('electron')
// Pass commands sent from main.js to settingsRender
ipcRenderer.on('settingsObj', (event, msg) => {
window.postMessage({ type: "settingsObj", payload: msg }, "*")
})
ipcRenderer.on('unfocused', (event, msg) => {
window.postMessage({ type: "unfocused"}, "*")
})
ipcRenderer.on('focused', (event, msg) => {
window.postMessage({ type: "focused"}, "*")
})
// Pass commands sent from settings window (processed by settingsRender.js) to main.js
window.addEventListener(
"message",
event => {
if (event.origin === "file://" && event.source === window) {
if (event.data.type === 'SettingsDOMReady'){
ipcRenderer.send('asynchronous-message', {msg: 'SettingsDOMReady'})
}
if (event.data.type === 'setPTTKey'){
ipcRenderer.send('asynchronous-message', {msg: 'setPTTKey'})
}
if (event.data.type === 'cancelSetPTTKey'){
ipcRenderer.send('asynchronous-message', {msg: 'cancelSetPTTKey'})
}
if (event.data.type === 'setPTTDelay'){
ipcRenderer.send('asynchronous-message', {msg: 'setPTTDelay', data: event.data.delay})
}
if (event.data.type === 'disablePTT'){
ipcRenderer.send('asynchronous-message', {msg: 'disablePTT', data: event.data.pttEnable})
}
if (event.data.type === 'minimizeApplication'){
ipcRenderer.send('asynchronous-message', {msg: 'minimizeApplication', data: event.data.payload})
}
if (event.data.type === 'maximizeApplication'){
ipcRenderer.send('asynchronous-message', {msg: 'maximizeApplication', data: event.data.payload})
}
if (event.data.type === 'closeApplication'){
ipcRenderer.send('asynchronous-message', {msg: 'closeApplication', data: event.data.payload})
}
}
},
false
)

View File

@ -1,37 +0,0 @@
html, body{
color: #ffffff;
font-family: "Hack Nerd Font", Courier, monospace;
background-color: #2f3136;
margin: 0px;
padding: 0px;
}
td:last-child {
padding-left: 16px;
}
.settingsContainer {
color: #ffffff;
margin: 16px;
}
.niceButton {
color: #ffffff;
background-color: #000000;
padding: 8px;
border-radius: 8px;
cursor: pointer;
}
input {
font-family: "Hack Nerd Font", Courier, monospace;
display: inline-block;
color: #dcddde;
background-color: #36393f;
border: 1px solid #1d1e22;
border-radius: 4px;
padding: 8px;
outline: none;
}

View File

@ -15,54 +15,6 @@
<div class="title-bar" id="titleBar">
<div class="menu-button-container">
<div id="openSettingsButton" class="menu-button">
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12">
<path
fill="currentColor"
fillRule="evenodd"
clipRule="evenodd"
d="
M 12.00,5.00
C 12.00,5.00 12.00,7.00 12.00,7.00
12.00,7.00 10.59,7.00 10.57,7.01
10.42,7.59 10.17,8.13 9.84,8.61
9.84,8.61 10.74,9.51 10.74,9.51
10.74,9.51 9.49,10.75 9.49,10.75
9.49,10.75 8.59,9.85 8.59,9.85
8.11,10.19 7.57,10.44 6.99,10.59
6.99,10.59 6.99,12.00 6.99,12.00
6.99,12.00 4.99,12.00 4.99,12.00
4.99,12.00 4.99,10.58 4.99,10.58
4.41,10.43 3.87,10.18 3.39,9.85
3.39,9.85 2.49,10.75 2.49,10.75
2.49,10.75 1.25,9.50 1.25,9.50
1.25,9.50 2.15,8.60 2.15,8.60
1.81,8.13 1.56,7.58 1.41,7.00
1.41,7.00 0.00,7.00 0.00,7.00
0.00,7.00 0.00,5.00 0.00,5.00
0.00,5.00 1.41,5.00 1.41,5.00
1.56,4.42 1.81,3.88 2.15,3.40
2.15,3.40 1.25,2.50 1.25,2.50
1.25,2.50 2.50,1.25 2.50,1.25
2.50,1.25 3.40,2.15 3.40,2.15
3.87,1.81 4.42,1.56 5.00,1.41
5.00,1.41 5.00,0.00 5.00,0.00
5.00,0.00 7.00,0.00 7.00,0.00
7.00,0.00 7.00,1.41 7.00,1.41
7.58,1.57 8.12,1.81 8.60,2.15
8.60,2.15 9.51,1.25 9.51,1.25
9.51,1.25 10.75,2.50 10.75,2.50
10.75,2.50 9.85,3.40 9.85,3.40
10.19,3.87 10.44,4.42 10.59,5.00
10.59,5.00 12.00,5.00 12.00,5.00 Z
M 6.00,8.00
C 7.10,8.00 8.00,7.10 8.00,6.00
8.00,4.90 7.10,4.00 6.00,4.00
4.90,4.00 4.00,4.90 4.00,6.00
4.00,7.10 4.90,8.00 6.00,8.00 Z"
/>
</svg>
</div>
<div id="openLogButton" class="menu-button">
<svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-card-text" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M14.5 3h-13a.5.5 0 0 0-.5.5v9a.5.5 0 0 0 .5.5h13a.5.5 0 0 0 .5-.5v-9a.5.5 0 0 0-.5-.5zm-13-1A1.5 1.5 0 0 0 0 3.5v9A1.5 1.5 0 0 0 1.5 14h13a1.5 1.5 0 0 0 1.5-1.5v-9A1.5 1.5 0 0 0 14.5 2h-13z"/>
@ -94,7 +46,13 @@
<div id="mainDisplay">
<!-- https://electronjs.org/docs/tutorial/security#15-disable-the-remote-module -->
<webview id="discord" enableremotemodule="false" webpreferences="useragent='Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; AS; rv:11.0) like Gecko'" partition="persist:discord" src="https://discord.com/login"></webview>
<webview
id="discord"
enableremotemodule="false"
webpreferences="useragent='Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; AS; rv:11.0) like Gecko'"
partition="persist:discord"
src="https://discord.com/login"
></webview>
</div>
</div>

View File

@ -19,18 +19,10 @@ function convertObjToString(arr) {
return arrStr
}
function openMic(webview){
console.log("talking")
document.getElementById("overlay").style.display = "block";
webview.sendInputEvent({keyCode: 'Backspace', type: 'keyDown'});
//webview.sendInputEvent({keyCode: 'Backspace', type: 'char'});
}
function muteMic(webview){
console.log("not talking")
document.getElementById("overlay").style.display = "none";
webview.sendInputEvent({keyCode: 'Backspace', type: 'keyUp'});
//webview.sendInputEvent({keyCode: 'Backspace', type: 'char'});
function toggleMic(webview) {
webview.executeJavaScript(`
document.querySelector('button[aria-label="Mute"]').click();
`);
}
function removeBloat(webview) {
@ -85,8 +77,8 @@ onload = () => {
// Insert JS to detect when discord finishes loading
webview.addEventListener('did-finish-load', function() {
webview.executeJavaScript(`
(function(open, send) {
let whiteList = ${_whiteList}
@ -156,32 +148,6 @@ onload = () => {
}
})(XMLHttpRequest.prototype.open, XMLHttpRequest.prototype.send)
`)
webview.executeJavaScript(`
let dlButton = document.querySelectorAll('[aria-label="Download Apps"]')
t = setInterval(function(){
let dlButton = document.querySelectorAll('[aria-label="Servers sidebar"]')
if(dlButton.length != 0) {
console.log("--discord-load-complete")
clearInterval(t)
isMicMuted()
}else {
console.log("waiting for load")
console.log(dlButton)
}
}, 500);
`)
// Insert a function that will be called later
webview.executeJavaScript(`
function isMicMuted() {
if (document.querySelectorAll('[aria-label="Mute"]')[0].getAttribute("aria-checked") === "false"){
console.log("unmuted")
}else {
console.log("muted")
}
}
`)
})
// Send commands to preload.js
@ -269,14 +235,9 @@ onload = () => {
document.getElementById('titleBar').style.color = "#ffffff"
}
if (event.data.type === 'micOpen'){
openMic(webview)
window.postMessage({ type: "confirmMicOpen"}, "*")
}
if (event.data.type === 'micClose'){
muteMic(webview)
window.postMessage({ type: "confirmMicClose"}, "*")
if (event.data.type === 'micToggle') {
console.log('toggling mic');
toggleMic(webview);
}
if (event.data.type === 'URLCopied') {
@ -286,4 +247,4 @@ onload = () => {
},
false
)
}
}

View File

@ -1,86 +0,0 @@
let windowName = 2
let configObj = null
let isSettingPTTKey = false
onload = () => {
window.postMessage({ type: "SettingsDOMReady"}, "*")
console.log("sent dom ready")
}
const setPTTEnable = document.getElementById('pttEnable')
if (setPTTEnable) {
setPTTEnable.onclick = function () {
console.log(`Set PTT Enabled: ${setPTTEnable.checked}`)
window.postMessage({ type: "disablePTT" , pttEnable: setPTTEnable.checked}, "*")
if (setPTTEnable.checked) {
setPTTKey.style.display = "block"
setPTTDelay.type = "number"
}else {
setPTTKey.style.display = "none"
setPTTDelay.type = "hidden"
}
}
}
const setPTTKey = document.getElementById('setPTTKeyButton')
if (setPTTKey) {
setPTTKey.onclick = function () {
if (isSettingPTTKey === false) {
isSettingPTTKey = true
console.log("Rebind PTT key clicked")
window.postMessage({ type: "setPTTKey"}, "*")
document.getElementById("setPTTKeyButton").innerText = "Press any key... Click here to cancel"
}else {
window.postMessage({ type: "cancelSetPTTKey"}, "*")
}
}
}
const setPTTDelay = document.getElementById('pttDelay')
if (setPTTDelay) {
setPTTDelay.onchange = function () {
console.log(setPTTDelay.value)
window.postMessage({ type: "setPTTDelay" , delay: setPTTDelay.value}, "*")
}
}
function displayCurrentSettings() {
if (configObj.pttDevice && configObj.key) {
setPTTEnable.checked = true
setPTTKey.innerText = `${configObj.pttDevice} button ${configObj.key}`
setPTTDelay.value = configObj.delay
setPTTKey.style.display = "block"
setPTTDelay.type = "number"
}else {
setPTTEnable.checked = false
setPTTKey.style.display = "none"
setPTTDelay.type = "hidden"
}
}
// Accept commands from settingsLoad.js
window.addEventListener(
"message",
event => {
if (event.origin === "file://" && event.source === window) {
if (event.data.type === 'settingsObj') {
isSettingPTTKey = false
configObj = event.data.payload
console.log(configObj)
displayCurrentSettings()
}
if (event.data.type === 'unfocused'){
console.log("window unfocused")
document.getElementById('titleBar').style.color = "#7f7f7f"
}
if (event.data.type === 'focused'){
console.log("window focused")
document.getElementById('titleBar').style.color = "#ffffff"
}
}
},
false
)

View File

@ -1,5 +1,5 @@
// Send window minimize/maximize/close commands to main
// See windowName variable in mainRender.js, logRender.js, and settingsRender.js
// See windowName variable in mainRender.js and logRender.js
const minButton = document.getElementById('minimize-button')
if (minButton) {
minButton.onclick = function () {
@ -28,9 +28,3 @@ if (logButton) {
}
}
const settingsButton = document.getElementById('openSettingsButton')
if (settingsButton) {
settingsButton.onclick = function () {
window.postMessage({ type: "openSettings" }, "*")
}
}

View File

@ -1,60 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!--style-src 'self' 'unsafe-inline' needs evaluation, some conflict with node_modules\electron\dist\resources\electron.asar\renderer\web-view\web-view-impl.js-->
<meta http-equiv="Content-Security-Policy" content="default-src none; script-src 'self'; style-src 'self' 'unsafe-inline'">
<link type="text/css" rel="stylesheet" href="./css/settingsStyle.css">
<link type="text/css" rel="stylesheet" href="./css/titlebar.css">
</head>
<body>
<div class="title-bar" id="titleBar">
<div class="app-name-container">
<div>Settings</div>
</div>
<div class="window-controls-container">
<div id="minimize-button" class="minimize-button menu-button">
<svg width="12" height="12" viewBox="0 0 12 12">
<rect fill="currentColor" width="10" height="1" x="1" y="6" />
</svg>
</div>
<div id="close-button" class="close-button menu-button">
<svg width="12" height="12" viewBox="0 0 12 12">
<polygon fill="currentColor" fillRule="evenodd" points="11 1.576 6.583 6 11 10.424 10.424 11 6 6.583 1.576 11 1 10.424 5.417 6 1 1.576 1.576 1 6 5.417 10.424 1" />
</svg>
</div>
</div>
</div>
<div id="settingsContainer" class="settingsContainer">
<table>
<tr>
<td align="right">Enable System-wide Push to Talk</td>
<td>
<input type="checkbox" id="pttEnable" name="ptt">
</td>
</tr>
<tr>
<td align="right">Push to Talk Key</td>
<td>
<span id='setPTTKeyButton' class="niceButton">loading...</span>
</td>
</tr>
<tr>
<td align="right">Push to Talk Release Delay (ms)</td>
<td>
<input id='pttDelay' type="number">
</td>
</tr>
</table>
</div>
<script src="./js/settingsRender.js"></script>
<script src="./js/titlebar.js"></script>
</body>
</html>