const { ipcRenderer } = require('electron');
const DEVICE = require('./device.js');
const PLUGINS = require('./plugins.js');
const { saveAll } = require('./saveSlots.js');
const pinnedDevices = [];
module.exports.pinnedDevices = pinnedDevices;
let activeDevice = false;
module.exports.init = function init() {
populatePluginLists();
};
function drawDeviceFrame(id) {
const $deviceDrawArea = document.getElementById(`device-${id}-draw-area`);
const $devicePinned = document.getElementById(`device-${id}-pinned`);
if ($deviceDrawArea == null) {
return true;
}
const d = DEVICE.all[id];
if (d.frameDrawn) {
return true;
}
const str = `
${generateBodyHTML(d)}
`;
$deviceDrawArea.setAttribute('class', `${d.type} draw-area`);
$deviceDrawArea.contentWindow.document.open();
$deviceDrawArea.contentWindow.document.write(str);
$deviceDrawArea.contentWindow.document.close();
$deviceDrawArea.contentWindow.document.onclick = function (e) {
switchDevice(d.id);
};
if (d.pinIndex) {
$devicePinned.style.display = 'block';
} else {
$devicePinned.style.display = 'none';
}
d.frameDrawn = true;
return true;
}
function generateBodyHTML(d) {
if (d.status === 'ok') {
try {
return PLUGINS.all[d.type].template({
templates: d.templates,
data: d.data,
listName: d.displayName || d.defaultName,
});
} catch (err) {
console.log(err);
return 'Plugin Template Error
';
}
} else {
return `
${d.displayName || d.defaultName}
${d.type} is not responding to requests for data.
IP ${d.addresses[0]}
Port ${d.port}
${PLUGINS.all[d.type].info()}
`;
}
}
module.exports.draw = function draw(device) {
const d = device;
const $deviceDrawArea = document.getElementById(`device-${d.id}-draw-area`);
if ($deviceDrawArea) {
const scriptEl = $deviceDrawArea.contentWindow.document.createRange().createContextualFragment(generateBodyHTML(d));
$deviceDrawArea.contentWindow.document.body.replaceChildren(scriptEl);
} else {
drawDeviceFrame(d.id);
}
d.drawn = true;
};
module.exports.update = function update(device, type, data) {
const doc = document.getElementById(`device-${device.id}-draw-area`);
if (doc) {
PLUGINS.all[device.type].update(device, doc.contentWindow.document, type, data);
}
};
module.exports.addDeviceToList = function addDeviceToList(device) {
const d = device;
let html = '';
if (d.status === 'ok') {
html += "done
";
} else if (d.status === 'refresh') {
html += "refresh
";
} else {
html += "clear
";
}
html += `
${d.displayName || d.defaultName}
`;
const elem = document.getElementById(d.id);
if (elem == null) {
document
.getElementById('device-list')
.insertAdjacentHTML('beforeend', `${html}`);
} else {
elem.innerHTML = html;
}
};
module.exports.removeDeviceFromList = function removeDeviceFromList(device) {
const d = device;
document.getElementById(d.id).remove();
};
function switchDevice(id) {
if (activeDevice && activeDevice.pinIndex === false && activeDevice.id !== id) {
document.getElementById(`device-${activeDevice.id}`).remove();
activeDevice.frameDrawn = false;
activeDevice = false;
}
activeDevice = DEVICE.all[id];
let cols = 1;
if (pinnedDevices.length > 0) {
cols += pinnedDevices.length;
}
if (pinnedDevices.includes(activeDevice) || id === undefined) {
cols--;
}
document.getElementById('all-devices').style.gridTemplateColumns = `repeat(${cols}, 1fr)`;
if (id === undefined) {
document.getElementById('refresh-device-button').disabled = true;
document.getElementById('device-settings-table').style.display = 'none';
const $activeDevice = document.querySelector('.active-device');
if ($activeDevice) {
$activeDevice.classList.remove('active-device');
}
return;
}
document.getElementById('refresh-device-button').disabled = false;
const i = DEVICE.all[id].id;
const $deviceWrapper = document.getElementById(`device-${i}`);
if (!$deviceWrapper) {
let html = ``;
html += `

`;
html += `

`;
html += `
`;
document.getElementById('all-devices').insertAdjacentHTML('afterbegin', html);
}
window.switchClass(document.getElementById(id), 'active-device');
drawDeviceFrame(id);
window.switchClass(document.getElementById(`device-${id}`), 'active-device-outline');
document.getElementById('device-settings-table').style.display = 'block';
document.getElementById('device-settings-plugin-dropdown').value = activeDevice.type;
document.getElementById('device-settings-name').value = activeDevice.displayName || activeDevice.defaultName || '';
document.getElementById('device-settings-ip').value = activeDevice.addresses[0] || '';
document.getElementById('device-settings-port').value = activeDevice.remotePort || '';
document.getElementById('device-settings-pin').checked = activeDevice.pinIndex;
if (activeDevice.plugin.config.mayChangePorts) {
document.getElementById('device-settings-port').disabled = false;
document.getElementById('device-settings-rx-port').disabled = false;
} else {
document.getElementById('device-settings-port').disabled = true;
document.getElementById('device-settings-rx-port').disabled = true;
}
if (activeDevice.plugin.config.mayChangeLocalPort === false) {
document.getElementById('device-settings-rx-port').disabled = true;
} else {
document.getElementById('device-settings-rx-port').disabled = false;
}
if (activeDevice.plugin.config.localPort) {
// document.getElementById('device-settings-port-label').textContent = 'Remote\nPort:';
document.getElementById('device-settings-rx-port-row').style.display = 'table-row';
document.getElementById('device-settings-rx-port').value = activeDevice.localPort || '';
} else {
document.getElementById('device-settings-port-label').textContent = 'Port:';
document.getElementById('device-settings-rx-port-row').style.display = 'none';
}
updateFields();
ipcRenderer.send('enableDeviceDropdown', '');
ipcRenderer.send('setDevicePin', !DEVICE.all[id].pinIndex === false);
}
module.exports.switchDevice = switchDevice;
function updateFields() {
document.getElementById('device-settings-fields').innerHTML = '';
if (activeDevice && activeDevice.plugin.config.fields) {
const fields = activeDevice.plugin.config.fields;
fields.forEach((field) => {
// generic input setup
const $elem = document.createElement('input');
$elem.value = activeDevice.fields[field.key];
$elem.name = field.key;
$elem.onchange = function onchange(e) {
activeDevice.fields[field.key] = $elem.value;
field.action(activeDevice);
saveAll();
};
// type specific setup
if (field.type === 'textinput') {
$elem.type = 'text';
const rowHTML = `| ${field.label}: | |
`;
document.getElementById('device-settings-fields').insertAdjacentHTML('beforeend', rowHTML);
document.getElementById(field.key).appendChild($elem);
}
});
}
}
module.exports.updateFields = updateFields;
module.exports.getActiveDevice = function getActiveDevice() {
return activeDevice;
};
module.exports.pinActiveDevice = function pinActiveDevice() {
if (activeDevice === undefined) {
return;
}
if (!pinnedDevices.includes(DEVICE.all[activeDevice.id])) {
pinnedDevices.push(DEVICE.all[activeDevice.id]);
}
DEVICE.changeActivePinIndex(true);
};
module.exports.unpinActiveDevice = function unpinActiveDevice() {
if (activeDevice === undefined) {
return;
}
pinnedDevices.splice(pinnedDevices.indexOf(DEVICE.all[activeDevice.id]), 1);
DEVICE.changeActivePinIndex(false);
};
module.exports.pinDevice = function pinDevice(device) {
pinnedDevices.push(device);
DEVICE.changePinIndex(device, true);
};
module.exports.unpinDevice = function unpinDevice(device) {
pinnedDevices.push(device);
DEVICE.changePinIndex(device, false);
};
module.exports.resetPinned = function resetPinned() {
pinnedDevices.length = 0;
activeDevice = false;
try {
document.querySelector('#device-list .active-device').classList.remove('active-device');
} catch (err) {
//
}
document.getElementById('all-devices').innerHTML = '';
};
module.exports.getPinnedDevices = function getPinnedDevices() {
return pinnedDevices;
};
module.exports.toggleSlotButtons = function toggleSlotButtons(slotIndex) {
// remove all currently active classes
const currentActiveSlots = document.getElementsByClassName('active');
for (let i = 0; i < currentActiveSlots.length; i++) {
const slotButton = currentActiveSlots[i];
slotButton.classList.remove('active');
}
// add the active class to the newly selected slot
document.getElementById(`save-slot-${slotIndex}`).classList.add('active');
};
module.exports.selectPreviousDevice = function selectPreviousDevice() {
if (activeDevice === undefined) {
return;
}
const keys = Object.keys(DEVICE.all);
const prevIndex = Math.max(0, keys.indexOf(activeDevice.id) - 1);
switchDevice(keys[prevIndex]);
};
module.exports.selectNextDevice = function selectNextDevice() {
if (activeDevice === undefined) {
return;
}
const keys = Object.keys(DEVICE.all);
const prevIndex = Math.min(keys.length - 1, keys.indexOf(activeDevice.id) + 1);
switchDevice(keys[prevIndex]);
};
module.exports.trafficSignal = function trafficSignal(device) {
const $signal = document.querySelector(`#device-${device.id} .device-traffic-signal`);
if ($signal) {
$signal.style.opacity = 1;
setTimeout(() => {
$signal.style.opacity = 0.3;
}, 50);
}
};
function populatePluginLists() {
let typeSelect = '';
let addSelect = '';
Object.keys(PLUGINS.all).forEach((pluginType) => {
const plugin = PLUGINS.all[pluginType];
addSelect += ``;
typeSelect += ``;
});
document.getElementById('device-settings-plugin-dropdown').innerHTML = typeSelect;
document.getElementById('add-device-button').innerHTML = addSelect;
}