init
This commit is contained in:
commit
1211fc9edd
|
@ -0,0 +1,21 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2024 iceyrazor
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
|
@ -0,0 +1,49 @@
|
||||||
|
{
|
||||||
|
"airtime_data": {
|
||||||
|
"stream_url": "https://radiosidewinder.out.airtime.pro:8000/radiosidewinder_b?_ga=1.133037898.513622194.1447957646/;stream.mp3",
|
||||||
|
"api_url": "https://radiosidewinder.airtime.pro/api/live-info?type=interval&limit=5&_=1646343267200"
|
||||||
|
},
|
||||||
|
"volumes": [
|
||||||
|
{
|
||||||
|
"default": 0.15
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lookfor": [
|
||||||
|
[
|
||||||
|
"currentShow",
|
||||||
|
0,
|
||||||
|
"name"
|
||||||
|
],
|
||||||
|
"Galnet News"
|
||||||
|
],
|
||||||
|
"volume": 0.3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lookfor": [
|
||||||
|
[
|
||||||
|
"currentShow",
|
||||||
|
0,
|
||||||
|
"name"
|
||||||
|
],
|
||||||
|
"Clan Ads"
|
||||||
|
],
|
||||||
|
"volume": 0.3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lookfor": [
|
||||||
|
[
|
||||||
|
"currentShow",
|
||||||
|
0,
|
||||||
|
"name"
|
||||||
|
],
|
||||||
|
"Commercial Break"
|
||||||
|
],
|
||||||
|
"volume": 0.05
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"read_cmd_file": "false",
|
||||||
|
"default_size": [
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
const electron = require('electron'),
|
||||||
|
{app,BrowserWindow,Menu,Tray,ipcMain} = require('electron'),
|
||||||
|
fs=require('fs'),
|
||||||
|
path=require('path');
|
||||||
|
|
||||||
|
myWindow=null;
|
||||||
|
global.tray=null;
|
||||||
|
app.whenReady().then(()=>{
|
||||||
|
|
||||||
|
//get display. if default config isnt too small. use configs size.
|
||||||
|
let primaryscreen=electron.screen.getPrimaryDisplay()
|
||||||
|
let config=JSON.parse(fs.readFileSync(path.join(__dirname,"config.json")));
|
||||||
|
let setsize=[]
|
||||||
|
if(config["default_size"][0]<150&config["default_size"][1]<150){
|
||||||
|
setsize=[Math.round(primaryscreen.bounds.width/2.8),Math.round(primaryscreen.bounds.height/1.2)]
|
||||||
|
} else {
|
||||||
|
setsize=config["default_size"]
|
||||||
|
}
|
||||||
|
|
||||||
|
myWindow=new BrowserWindow({
|
||||||
|
width: setsize[0],
|
||||||
|
height: setsize[1],
|
||||||
|
frame: false,
|
||||||
|
transparent:true,
|
||||||
|
resizable:true,
|
||||||
|
useContentSize: true,
|
||||||
|
webPreferences:{
|
||||||
|
nodeIntegration: true,
|
||||||
|
contextIsolation: false,
|
||||||
|
enableRemoteModule: false,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
myWindow.loadFile('src/index.html');
|
||||||
|
|
||||||
|
//change default size on delay so config isnt spammed
|
||||||
|
let window_size_forc=myWindow.getSize()
|
||||||
|
myWindow.on('resize', function () {
|
||||||
|
window_size_forc = myWindow.getSize();
|
||||||
|
|
||||||
|
if(typeof window_size_forc[0]=="object"|typeof window_size_forc[0]=="array"){
|
||||||
|
window_size_forc=window_size_forc[0]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function set_conf_size_loop(){
|
||||||
|
let config=JSON.parse(fs.readFileSync(path.join(__dirname,"config.json")));
|
||||||
|
|
||||||
|
if(config["default_size"][0]!=window_size_forc[0]|config["default_size"][1]!=window_size_forc[1]){
|
||||||
|
config["default_size"]=window_size_forc
|
||||||
|
fs.writeFileSync(path.join(__dirname,"config.json"),JSON.stringify(config,null,2))
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout(set_conf_size_loop,3000)
|
||||||
|
}
|
||||||
|
set_conf_size_loop()
|
||||||
|
});
|
||||||
|
|
||||||
|
stop_cursor=false
|
||||||
|
let win_size=[]
|
||||||
|
ipcMain.on("setpos",(req,data)=>{
|
||||||
|
stop_cursor=false
|
||||||
|
win_size=myWindow.getSize();
|
||||||
|
function move_loop(){
|
||||||
|
if(stop_cursor==true){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let cursor_pos=electron.screen.getCursorScreenPoint()
|
||||||
|
|
||||||
|
myWindow.setPosition(cursor_pos.x-data.x,cursor_pos.y-data.y)
|
||||||
|
myWindow.setSize(win_size[0],win_size[1])
|
||||||
|
setTimeout(move_loop,20)
|
||||||
|
}
|
||||||
|
move_loop()
|
||||||
|
})
|
||||||
|
|
||||||
|
ipcMain.on("stoppos",(req,data)=>{
|
||||||
|
stop_cursor=true
|
||||||
|
myWindow.setSize(win_size[0],win_size[1])
|
||||||
|
})
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"name": "stream-volumizer",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"description": "a little peice of software that allows you to have differnt volume levels during different parts of a Airtime stream",
|
||||||
|
"main": "main.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
|
"start": "electron ."
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"volume",
|
||||||
|
"auto",
|
||||||
|
"control"
|
||||||
|
],
|
||||||
|
"author": "iceyrazor",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"electron": "^17.1.0"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,128 @@
|
||||||
|
#raw_json{
|
||||||
|
display: none;
|
||||||
|
overflow-y: scroll;
|
||||||
|
height: 400px;
|
||||||
|
width: 90%;
|
||||||
|
border: 2px solid black;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#volumes_control{
|
||||||
|
position: relative;
|
||||||
|
overflow-y: scroll;
|
||||||
|
max-width: 600px;
|
||||||
|
height: 500px;
|
||||||
|
border: 2px solid black;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
#volumes_control > div{
|
||||||
|
display: flex;
|
||||||
|
background-color: rgb(230,230,230);
|
||||||
|
margin-bottom: 3px;
|
||||||
|
align-content: flex-start;
|
||||||
|
justify-content: center;
|
||||||
|
grid-gap: 3px;
|
||||||
|
padding: 3px;
|
||||||
|
}
|
||||||
|
#volumes_control textarea{
|
||||||
|
border: 2px inset rgb(120,120,120);
|
||||||
|
font-size: 15px;
|
||||||
|
width: 180px;
|
||||||
|
height: 15px;
|
||||||
|
resize: none;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
#volumes_control button{
|
||||||
|
height: 20px;
|
||||||
|
min-width: 20px;
|
||||||
|
align-items: center;
|
||||||
|
justify-items: center;
|
||||||
|
}
|
||||||
|
#volume_wrap{
|
||||||
|
position: relative;
|
||||||
|
max-width: 600px;
|
||||||
|
}
|
||||||
|
#vol_update_button{
|
||||||
|
background-color: rgb(200,200,200);
|
||||||
|
border: 2px solid black;
|
||||||
|
position: absolute;
|
||||||
|
display: block;
|
||||||
|
width: 100px;
|
||||||
|
height: 15px;
|
||||||
|
padding: 3px;
|
||||||
|
bottom: 3px;
|
||||||
|
left: calc(50% - 50px);
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
#vol_update_button:hover{
|
||||||
|
background-color: rgb(190,190,190);
|
||||||
|
}
|
||||||
|
|
||||||
|
.vol_update_button_tooltip{
|
||||||
|
visibility: hidden;
|
||||||
|
position: absolute;
|
||||||
|
width: 120px;
|
||||||
|
left: calc(50% - (120px/2));
|
||||||
|
bottom: 50px;
|
||||||
|
border: 2px solid black;
|
||||||
|
padding: 3px;
|
||||||
|
background-color: rgb(260,260,260);
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
.vol_update_button_wrap:hover .vol_update_button_tooltip{
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
#vol_add_button{
|
||||||
|
background-color: rgb(200,200,200);
|
||||||
|
border: 2px solid black;
|
||||||
|
position: absolute;
|
||||||
|
display: block;
|
||||||
|
width: 50px;
|
||||||
|
height: 15px;
|
||||||
|
padding: 3px;
|
||||||
|
bottom: 3px;
|
||||||
|
left: 65%;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.play_grid,.show_grid{
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
border: 2px solid black;
|
||||||
|
padding: 4px;
|
||||||
|
}
|
||||||
|
#airtime_next,#airtime_next_show{
|
||||||
|
border-left: 2px dashed rgb(120,120,120);
|
||||||
|
padding-left: 10px;
|
||||||
|
}
|
||||||
|
#airtime_np,#airtime_np_show{
|
||||||
|
padding-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#move_button{
|
||||||
|
position: absolute;
|
||||||
|
padding: 3px;
|
||||||
|
top: 5px;
|
||||||
|
right: 5px;
|
||||||
|
user-select: none;
|
||||||
|
border: 2px solid black;
|
||||||
|
}
|
||||||
|
|
||||||
|
#background_plate{
|
||||||
|
position: fixed;
|
||||||
|
left: 0px;
|
||||||
|
top: 0px;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
background-color: rgba(255,255,255,1);
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#error_box{
|
||||||
|
display: none;
|
||||||
|
padding: 4px;
|
||||||
|
background-color: rgba(255,50,50);
|
||||||
|
}
|
|
@ -0,0 +1,260 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<title></title>
|
||||||
|
<link rel="stylesheet" href="index.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="background_plate"></div>
|
||||||
|
<div id="error_box"></div>
|
||||||
|
|
||||||
|
<audio controls="controls" id="airtime_radio"></audio>
|
||||||
|
<div id="move_button">click to drag</div>
|
||||||
|
|
||||||
|
<div class="play_grid">
|
||||||
|
<div id="airtime_np"></div>
|
||||||
|
<div id="airtime_next"></div>
|
||||||
|
</div>
|
||||||
|
<div class="show_grid">
|
||||||
|
<div id="airtime_np_show"></div>
|
||||||
|
<div id="airtime_next_show"></div>
|
||||||
|
</div>
|
||||||
|
<div id="curr_date"></div>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
<p>volumes for different things</p>
|
||||||
|
<div id="volume_wrap">
|
||||||
|
<div id="volumes_control"></div>
|
||||||
|
<div class="vol_update_button_wrap">
|
||||||
|
<div align="center" id="vol_update_button" onClick="update_conf()">
|
||||||
|
update
|
||||||
|
</div>
|
||||||
|
<span class="vol_update_button_tooltip">please dont spam this button</span>
|
||||||
|
<div align="center" id="vol_add_button" onClick="add_conf()">add</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br><br>
|
||||||
|
<button onclick="toggle_raw_json()">toggle raw json data</button><br><br>
|
||||||
|
<div id="raw_json"></div>
|
||||||
|
|
||||||
|
<script language="javascript">
|
||||||
|
const fs=require('fs'),
|
||||||
|
path=require("path"),
|
||||||
|
{ipcRenderer}=require('electron');
|
||||||
|
|
||||||
|
//error box func
|
||||||
|
function set_error_box(err){
|
||||||
|
error_box.style.display="block";
|
||||||
|
error_box.innerHTML=err
|
||||||
|
}
|
||||||
|
|
||||||
|
//fetch config
|
||||||
|
let config_data={}
|
||||||
|
function fetch_config(){
|
||||||
|
try{
|
||||||
|
config_data=JSON.parse(fs.readFileSync(path.join(__dirname,"..","config.json")));
|
||||||
|
config_data["error"]=false
|
||||||
|
} catch(err){
|
||||||
|
config_data={err:err.toString(),"error":true}
|
||||||
|
set_error_box("config error:: "+err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
airtime_radio.innerHTML='<source src="'+config_data["airtime_data"]["stream_url"]
|
||||||
|
+'" type="audio/mp3">Your browser does not support the audio element.'
|
||||||
|
|
||||||
|
volumes_str=""
|
||||||
|
for(let i in config_data.volumes){
|
||||||
|
if(!config_data.volumes[i].default){
|
||||||
|
volumes_str+='<div id="volumes_control_'+i+'">'+
|
||||||
|
'<textarea style="resize: vertical;"></textarea> name:<textarea></textarea>volume: <input type="number" min="0" max="1"></input>'+
|
||||||
|
'<button onclick="move_conf_vol('+i+',\'+\')">+</button>'+
|
||||||
|
'<button onclick="move_conf_vol('+i+',\'-\')">-</button>'+
|
||||||
|
'<button onclick="del_conf('+i+')">del</button>'+
|
||||||
|
'</div>'
|
||||||
|
setTimeout(()=>{
|
||||||
|
document.getElementById("volumes_control_"+i).children[0].value=config_data.volumes[i].lookfor[0]
|
||||||
|
document.getElementById("volumes_control_"+i).children[1].value=config_data.volumes[i].lookfor[1]
|
||||||
|
document.getElementById("volumes_control_"+i).children[2].value=config_data.volumes[i].volume
|
||||||
|
},250)
|
||||||
|
} else {
|
||||||
|
volumes_str+='<div id="volumes_control_'+i+'">'+'default: <textarea></textarea></div>'
|
||||||
|
setTimeout(()=>{
|
||||||
|
document.getElementById("volumes_control_"+i).children[0].value=config_data.volumes[i].default
|
||||||
|
},250)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
volumes_str+='<div id="spacer" style="background-color: rgba(0,0,0,0); margin-bottom: 20px"></div>'
|
||||||
|
volumes_control.innerHTML=volumes_str
|
||||||
|
}
|
||||||
|
console.log(fetch_config());
|
||||||
|
|
||||||
|
//move volume config
|
||||||
|
function move_conf_vol(id,dir){
|
||||||
|
if(dir=="+"){
|
||||||
|
arraymove(config_data.volumes,id,id-1)
|
||||||
|
}
|
||||||
|
if(dir=="-"){
|
||||||
|
arraymove(config_data.volumes,id,id+1)
|
||||||
|
}
|
||||||
|
if(config_data.volumes[1].default){
|
||||||
|
arraymove(config_data.volumes,1,0)
|
||||||
|
}
|
||||||
|
fs.writeFileSync(path.join(__dirname,"..","config.json"),JSON.stringify(config_data,null,2))
|
||||||
|
fetch_config()
|
||||||
|
}
|
||||||
|
|
||||||
|
//misc function to move arrays via index to index
|
||||||
|
function arraymove(arr, fromIndex, toIndex) {
|
||||||
|
let element = arr[fromIndex];
|
||||||
|
arr.splice(fromIndex, 1);
|
||||||
|
arr.splice(toIndex, 0, element);
|
||||||
|
return arr
|
||||||
|
}
|
||||||
|
|
||||||
|
//edit config
|
||||||
|
function update_conf(){
|
||||||
|
for(i in config_data.volumes){
|
||||||
|
if(config_data.volumes[i].default){
|
||||||
|
config_data.volumes[i].default=volumes_control.children[i].children[0].value
|
||||||
|
} else {
|
||||||
|
config_data.volumes[i].lookfor[0]=volumes_control.children[i].children[0].value.split(",")
|
||||||
|
config_data.volumes[i].lookfor[1]=volumes_control.children[i].children[1].value
|
||||||
|
config_data.volumes[i].volume=parseFloat(volumes_control.children[i].children[2].value)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
fs.writeFileSync(path.join(__dirname,"..","config.json"),JSON.stringify(config_data,null,2))
|
||||||
|
fetch_config()
|
||||||
|
fetch_api_data()
|
||||||
|
}
|
||||||
|
|
||||||
|
//del config
|
||||||
|
function del_conf(id){
|
||||||
|
config_data.volumes.splice(id,1)
|
||||||
|
fs.writeFileSync(path.join(__dirname,"..","config.json"),JSON.stringify(config_data,null,2))
|
||||||
|
fetch_config()
|
||||||
|
fetch_api_data()
|
||||||
|
}
|
||||||
|
|
||||||
|
//addconf
|
||||||
|
function add_conf(){
|
||||||
|
config_data.volumes.push({"lookfor":[["currentShow",0,"name"],"n/a"],"volume":0.5})
|
||||||
|
fs.writeFileSync(path.join(__dirname,"..","config.json"),JSON.stringify(config_data,null,2))
|
||||||
|
fetch_config()
|
||||||
|
fetch_api_data()
|
||||||
|
}
|
||||||
|
|
||||||
|
//fetch api data and use it??
|
||||||
|
async function fetch_api_data(){
|
||||||
|
if(config_data["airtime_data"]["api_url"]&&config_data["airtime_data"]["api_url"]!=""){
|
||||||
|
await fetch(config_data["airtime_data"]["api_url"],{cache:"no-cache"})
|
||||||
|
.then(res=>res.json())
|
||||||
|
.then(res=>{
|
||||||
|
api_data=res;
|
||||||
|
raw_json.innerHTML=JSON.stringify(res, null, 4); //put in the raw json data in json box
|
||||||
|
np_next(res)
|
||||||
|
//set volume based on "volumes" config
|
||||||
|
set_volume(res)
|
||||||
|
set_date();
|
||||||
|
});
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return "api not set"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//this loop is set seperately so the fetch api could be called seperately on song changes
|
||||||
|
//please do not change the timeout, the api it fetches is not mine, no need to spam it
|
||||||
|
function loop_fetch_api_data(){
|
||||||
|
if(config_data["error"]==false){
|
||||||
|
fetch_api_data()
|
||||||
|
.then(res=>{
|
||||||
|
if(res=="api not set"){
|
||||||
|
set_error_box("api not set")
|
||||||
|
} else {
|
||||||
|
setTimeout(loop_fetch_api_data,13000)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
loop_fetch_api_data()
|
||||||
|
|
||||||
|
|
||||||
|
function set_date(){
|
||||||
|
let date=new Date();
|
||||||
|
let dateconstruct=date.getUTCFullYear()+"-"+(date.getUTCMonth()+1)+"-"+(date.getUTCDay()-1)+" "+date.getUTCHours()+
|
||||||
|
":"+date.getUTCMinutes()+":"+date.getUTCSeconds()+" UTC";
|
||||||
|
curr_date.innerHTML=dateconstruct
|
||||||
|
}
|
||||||
|
|
||||||
|
function np_next(data){
|
||||||
|
airtime_np.innerHTML="<h1>now playing</h1>"+
|
||||||
|
"<p>track</p>"+data["current"]["name"]
|
||||||
|
|
||||||
|
airtime_next.innerHTML="<h1>next</h1>"+
|
||||||
|
"<p>track</p>"+data["next"]["name"]
|
||||||
|
|
||||||
|
airtime_np_show.innerHTML="<h1>current show</h1>"+
|
||||||
|
data["currentShow"][0]["name"]
|
||||||
|
|
||||||
|
airtime_next_show.innerHTML="<h1>next show</h1>"+
|
||||||
|
data["nextShow"][0]["name"]+'<p>starts at</p>'+data["nextShow"][0]["start_timestamp"]+
|
||||||
|
'<span style="padding:4px"></span>'+data["timezone"]
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggle_raw_json(){
|
||||||
|
if(getComputedStyle(raw_json).display=="none"){
|
||||||
|
raw_json.style.display="block"
|
||||||
|
} else {
|
||||||
|
raw_json.style.display="none"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function set_volume(data){
|
||||||
|
for(elem of document.getElementById("volumes_control").children){
|
||||||
|
if(elem.id!="update_button"&elem.id!="spacer"){
|
||||||
|
elem.style.backgroundColor="rgb(230,230,230)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(vol in config_data.volumes){
|
||||||
|
if(!config_data.volumes[vol].default){
|
||||||
|
|
||||||
|
if(config_data.volumes[vol].lookfor[0]){
|
||||||
|
if(getNested(data,config_data.volumes[vol].lookfor[0]).includes(config_data.volumes[vol].lookfor[1])){
|
||||||
|
airtime_radio.volume=config_data.volumes[vol].volume
|
||||||
|
document.getElementById('volumes_control_'+(vol)).style.backgroundColor="rgb(0,255,0)"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
airtime_radio.volume=config_data.volumes[0].default
|
||||||
|
document.getElementById('volumes_control_0').style.backgroundColor="rgb(0,255,0)"
|
||||||
|
}
|
||||||
|
|
||||||
|
function getNested(obj, arr) {
|
||||||
|
const keys=[...arr];
|
||||||
|
if (keys.length === 0) return obj;
|
||||||
|
|
||||||
|
if(obj[keys[0]]){
|
||||||
|
return getNested(obj[keys.shift()], keys)
|
||||||
|
} else {
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//move window with cursor bs because electron doesnt have this >:(
|
||||||
|
move_button.addEventListener("mousedown",(eve)=>{
|
||||||
|
ipcRenderer.send("setpos",{x:eve.clientX,y:eve.clientY})
|
||||||
|
})
|
||||||
|
move_button.addEventListener("mouseup",(eve)=>{
|
||||||
|
ipcRenderer.send("stoppos",{})
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
Reference in New Issue