Merge pull request #268 from stagehacks/qlab-faster-redraw-fix

better handling of DOM updates for device drawing
This commit is contained in:
Joel Wetzell
2025-11-23 15:25:47 -06:00
committed by GitHub
4 changed files with 274 additions and 5334 deletions
+239 -5312
View File
File diff suppressed because it is too large Load Diff
+3 -1
View File
@@ -33,11 +33,13 @@
"atem-connection": "3.5.0",
"bonjour": "3.5.0",
"electron-updater": "6.6.2",
"html-to-vdom": "0.7.0",
"lodash": "4.17.21",
"md5": "2.3.0",
"netmask": "2.0.2",
"osc": "2.4.5",
"uuid": "13.0.0"
"uuid": "13.0.0",
"virtual-dom": "2.1.1"
},
"build": {
"appId": "com.stagehacks.cueview",
+13 -1
View File
@@ -162,7 +162,19 @@ exports.data = function data(_device, oscData) {
device.data.cueKeys[msgAddr[2]].cueInWorkspace
);
}
device.draw();
if (cue.type === 'Cue List') {
// draw cue list right away
device.draw();
} else {
// set up a timeout in case more messages come along to avoid fast re-drawing
if (device.drawTimeout !== undefined) {
clearTimeout(device.drawTimeout);
}
device.drawTimeout = setTimeout(() => {
device.draw();
}, 250);
}
}
if (cue.type !== 'Cue List' && cue.type !== 'Cart') {
+19 -20
View File
@@ -2,6 +2,13 @@ const { ipcRenderer } = require('electron');
const DEVICE = require('./device.js');
const PLUGINS = require('./plugins.js');
const { saveAll } = require('./saveSlots.js');
const { h, diff, patch, create } = require('virtual-dom');
const VNode = require('virtual-dom/vnode/vnode');
const VText = require('virtual-dom/vnode/vtext');
const convertHtml = require('html-to-vdom')({
VNode,
VText,
});
const pinnedDevices = [];
module.exports.pinnedDevices = pinnedDevices;
@@ -40,17 +47,17 @@ function drawDeviceFrame(id) {
</style>
<link href='src/assets/css/plugin_default.css' rel='stylesheet' type='text/css'>
</head>
<body>
${generateBodyHTML(d)}
</body>
</html>
`;
d.contentBodyElement = create(h('body', convertHtml(generateBodyHTML(d))));
$deviceDrawArea.setAttribute('class', `${d.type} draw-area`);
$deviceDrawArea.contentWindow.document.open();
$deviceDrawArea.contentWindow.document.write(str);
$deviceDrawArea.contentWindow.document.body = d.contentBodyElement;
$deviceDrawArea.contentWindow.document.close();
$deviceDrawArea.contentWindow.document.onclick = function (e) {
$deviceDrawArea.contentWindow.document.onclick = (e) => {
switchDevice(d.id);
};
@@ -74,7 +81,7 @@ function generateBodyHTML(d) {
listName: d.displayName || d.defaultName,
});
} catch (err) {
console.log(err);
console.error(err);
return '<h3>Plugin Template Error</h3>';
}
} else {
@@ -98,23 +105,15 @@ function generateBodyHTML(d) {
module.exports.draw = function draw(device) {
const d = device;
const $deviceDrawArea = document.getElementById(`device-${d.id}-draw-area`);
if (device.drawTimeout !== undefined) {
clearTimeout(device.drawTimeout);
if (d.contentBodyElement) {
const newVNode = h('body', convertHtml(generateBodyHTML(d)));
const domPatches = diff(d.contentBodyElement, newVNode);
d.contentBodyElement = patch(d.contentBodyElement, domPatches);
} else {
drawDeviceFrame(d.id);
}
d.drawTimeout = setTimeout(() => {
if ($deviceDrawArea) {
const scriptEl = $deviceDrawArea.contentWindow.document
.createRange()
.createContextualFragment(generateBodyHTML(d));
$deviceDrawArea.contentWindow.document.body.replaceChildren(scriptEl);
} else {
drawDeviceFrame(d.id);
}
d.drawn = true;
}, 200);
d.drawn = true;
};
module.exports.update = function update(device, type, data) {