Files

388 lines
13 KiB
JavaScript

/*!
@file pi.js
@brief Contains PI for base action
@author Valentin Reinbold
@copyright (c) 2021, Corsair Memory, Inc. All Rights Reserved.
*/
function PI(inContext, inLanguage) {
// Init PI
var instance = this;
var appWarningMessage = document.getElementById('app-warning-message');
var authWarningMessage = document.getElementById('auth-warning-message');
var accessButton = document.getElementById('access-button');
// Add event listener
accessButton.addEventListener("click", () => {
instance.sendToPlugin({ 'grantAccess': true });
});
// Private function to return the action identifier
function getAction() {
// Find out type of action
if (instance instanceof MutePI)
return "com.elgato.discord.mute";
if (instance instanceof DeafenPI)
return "com.elgato.discord.deafen";
if (instance instanceof VoiceChannelPI)
return "com.elgato.discord.channel.voice";
if (instance instanceof TextChannelPI)
return "com.elgato.discord.channel.text";
if (instance instanceof PushToTalkPI)
return "com.elgato.discord.pushto.talk";
if (instance instanceof PushToMutePI)
return "com.elgato.discord.pushto.mute";
if (instance instanceof VolumePI)
return "com.elgato.discord.volumecontrol";
if (instance instanceof VolumeButtonPI)
return "com.elgato.discord.volumecontrolbutton";
if (instance instanceof UserVolumeButtonPI)
return "com.elgato.discord.uservolumecontrolbutton";
if (instance instanceof UserVolumeDialPI)
return "com.elgato.discord.uservolumecontroldial";
if (instance instanceof PushToTalkTogglePI)
return "com.elgato.discord.pushtotalktoggle";
if (instance instanceof NotificationsPI)
return "com.elgato.discord.notifications";
if (instance instanceof SetAudioDevicePI)
return "com.elgato.discord.setaudiodevice";
if (instance instanceof ServerStatsPI)
return "com.elgato.discord.serverstats";
if (instance instanceof SoundboardPI)
return "com.elgato.discord.soundboard";
}
// Public function called to initialize field
this.initField = function(key) {
// Init data
updateField(key, settings[key]);
// Add event listener
document.getElementById(key).addEventListener("input", fieldChanged);
}
// Private function called to update field
function updateField(key, value) {
value = value || "";
// Update field content
document.getElementById(key).value = value;
}
// Field changed
function fieldChanged(event) {
var key = event.srcElement.id;
var value = (event ? event.target.value : undefined);
// Update data
updateField(key, value);
// Update settings
settings[key] = value;
instance.saveSettings();
}
// Public function called to load the fields
this.load = function (data) {
if (data.disabled) {
// Show app warning message
appWarningMessage.style.display = "block";
authWarningMessage.style.display = "none";
}
else if (data.unauthorized) {
// Show auth warning message
appWarningMessage.style.display = "none";
authWarningMessage.style.display = "block";
}
else {
// Hide warning messages
appWarningMessage.style.display = "none";
authWarningMessage.style.display = "none";
}
}
// Public function to send data to the plugin
this.sendToPlugin = function (inData) {
sendToPlugin(getAction(), inContext, inData);
};
// Public function to save the settings
this.saveSettings = function () {
saveSettings(inContext, settings);
};
setTimeout(()=>this.saveSettings(), 1000);
/* --- Localization --- */
this.localization = {};
var finished = false;
loadLocalization(inLanguage);
loadLocalization("en");
function loadLocalization(language) {
getLocalization(language, function(inStatus, inLocalization) {
if (inStatus) {
instance.localization[language] = inLocalization['PI'];
if (!finished) {
finished = true;
}
else {
instance.localize(function (key) {
// Actual localization
var value = instance.localization[inLanguage][key];
if (value != undefined && value != "") {
return value;
}
// Default localization
value = instance.localization["en"][key];
if (value != undefined && value != "") {
return value;
}
return key;
});
}
}
else {
console.log(inLocalization);
}
});
}
// Localize the UI
this.localize = function (tr) {
// Check if localizations were loaded
if (instance.localization == null) {
return;
}
// Localize the warning message select
document.getElementById("app-warning").innerHTML = tr("AppWarning");
document.getElementById("auth-warning").innerHTML = tr("AuthWarning");
document.getElementById("access-label").innerHTML = tr("AccessLabel");
document.getElementById("access-button").innerHTML = tr("AccessButton");
const nodes = document.getElementsByClassName('translated');
for(const node of nodes){
const text = node.getAttribute("x-text");
//if(text){
// If the node has a dummy span child, we need to recreate it
let hasSpan = false;
const spans = node.getElementsByTagName("span");
if(spans.length > 0){
hasSpan = true;
}
const translated = tr(text);
node.innerHTML = translated ? translated : text;
if(hasSpan){
node.prepend(document.createElement("span"));
}
//}
}
};
// Load the localizations
function getLocalization(inLanguage, inCallback) {
var url = "../" + inLanguage + ".json";
var xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.onload = function () {
if (xhr.readyState == XMLHttpRequest.DONE) {
try {
data = JSON.parse(xhr.responseText);
var localization = data['Localization'];
inCallback(true, localization);
}
catch(e) {
inCallback(false, 'Localizations is not a valid json.');
}
}
else {
inCallback(false, 'Could not load the localizations.');
}
};
xhr.onerror = function () {
inCallback(false, 'An error occurred while loading the localizations.');
};
xhr.ontimeout = function () {
inCallback(false, 'Localization timed out.');
};
xhr.send();
}
this.setAndValidateField = function(input, key, value){
if(!input || !input.type){
return;
}
if (value === undefined){
value = settings[key];
}
switch(input.type){
//case "range": case "select-one":
case "radio": case "checkbox":
break;
case "range":
input.value = parseInt(value);
if( input.value != settings[key]){
settings[key] = parseInt(input.value);
}
break;
default:
input.value = value;
if( input.value != settings[key]){
settings[key] = input.value;
}
break;
}
}
this.addSliderTooltip = function (slider, textFn) {
if (typeof textFn != "function"){
textFn = (value)=>{
return value;
}
}
const adjustSlider = slider;
const tooltip = document.querySelector('.sdpi-info-label');
// Add clickable labels
const parent = slider.parentNode;
if (parent){
const clickables = parent.getElementsByClassName("clickable");
for( const clickable of clickables){
const value = clickable.getAttribute("x-value");
if (value){
clickable.addEventListener('click', (event)=>{
slider.value = value;
let ev = new Event("change", { "bubbles": true, "cancelable": true });
slider.dispatchEvent(ev);
})
}
}
}
tooltip.textContent = textFn(parseFloat(adjustSlider.value));
const fn = () => {
const tw = tooltip.getBoundingClientRect().width;
const rangeRect = adjustSlider.getBoundingClientRect();
const w = rangeRect.width - tw / 2;
const percnt = (adjustSlider.value - adjustSlider.min) / (adjustSlider.max - adjustSlider.min);
if (tooltip.classList.contains('hidden')) {
tooltip.style.top = '-1000px';
} else {
tooltip.style.left = `${rangeRect.left + Math.round(w * percnt) - tw / 4}px`;
tooltip.textContent = textFn(parseFloat(adjustSlider.value));
tooltip.style.top = `${rangeRect.top - 30}px`;
}
}
if (adjustSlider) {
adjustSlider.addEventListener(
'mouseenter',
function() {
tooltip.classList.remove('hidden');
tooltip.classList.add('shown');
fn();
},
false
);
adjustSlider.addEventListener(
'mouseout',
function() {
tooltip.classList.remove('shown');
tooltip.classList.add('hidden');
fn();
},
false
);
adjustSlider.addEventListener('input', fn, false);
}
}
// function called to empty the field options
this.emptyField = function (key) {
var options = document.getElementsByClassName(key);
while (options.length > 0) {
options[0].parentNode.removeChild(options[0]);
}
}
this.updateName = function(settingsField, nameField, node){
if (settings[settingsField] && node.selectedIndex >= 0){
// Ensure we actually have a nick for the user
let selectedOption = node.options[node.selectedIndex];
if (selectedOption){
settings[nameField] = selectedOption.innerText;
}
}
}
/** function called to load the field options
* @param {{key: any, value: any}} defaults
*/
this.loadField = function(key, list, defaults) {
// Remove previously shown options
this.emptyField(key);
if(Array.isArray(list)){
const newList = {};
for(const item of list){
if(item && item.id){
newList[item.id] = item;
}
}
list = newList;
}
if(defaults !== undefined){
if (typeof list !== "object"){
list = {};
}
if(defaults.value){
list[defaults.key] = {name: defaults.value};
}
}
// If there is no element
if (list == undefined || Object.keys(list).length == 0) {
// Show & Select the 'Nothing' option
document.getElementById('no-' + key).style.display = "block";
document.getElementById(key).value = 'no-' + key;
return;
}
// Hide the 'Nothing' option
document.getElementById('no-' + key).style.display = "none";
// Sort the elements alphabatically
var IDsSorted = Object.keys(list).sort((a, b) => {
return list[a].name.localeCompare(list[b].name);
});
// Add the options
IDsSorted.forEach(id => {
var option = "<option value='" + id + "' class='" + key + "'>" + list[id].name + "</option>";
document.getElementById('no-' + key).insertAdjacentHTML("beforebegin", option);
});
// If no existing element configured
if (settings[key] == undefined || !(settings[key] in list)) {
// If a default wasn't provided
if (!defaults || !defaults.key){
// Choose the first option in the list
settings[key] = IDsSorted[0];
}
else {
// Choose the default option
settings[key] = defaults.key;
}
this.saveSettings();
}
// Select the currently configured element
document.getElementById(key).value = settings[key];
}
}