/*! @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 = ""; 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]; } }