From 03ad8f96825b30fe61e56ac8199ca81d875935cf Mon Sep 17 00:00:00 2001 From: sparks-alec Date: Sun, 28 May 2023 07:06:57 -0400 Subject: [PATCH] refactor QLab --- plugins/qlab/cue.ejs | 261 +++++++++++-------- plugins/qlab/cuelist.ejs | 27 +- plugins/qlab/main.js | 529 +++++++++++++------------------------- plugins/qlab/template.ejs | 30 +-- 4 files changed, 362 insertions(+), 485 deletions(-) diff --git a/plugins/qlab/cue.ejs b/plugins/qlab/cue.ejs index e2b97ef..d6f78cf 100644 --- a/plugins/qlab/cue.ejs +++ b/plugins/qlab/cue.ejs @@ -1,145 +1,190 @@ +<% let cueKeys = allCues[cue.uniqueID]; %> <% let playbackPosition = workspace.playbackPosition==cue.uniqueID ? "playback-position" : "" %> - +<% let selected = workspace.selected.includes(cue.uniqueID) ? "selected": "" %> - +<% if(cueKeys && cueKeys.parent){ %> -
- <% if(cue.broken){ %> - + - <% }else if(cue.running){ %> - - - <% }else if(cue.paused){ %> - - - <% }else if(cue.loaded){ %> - - - <% }else if(cue.flagged){ %> - - - <% }else{ %> + + - <% } %> -
- <% if(cue.type == "Group" && cue.groupMode){ %> - - - <% }else{ %> - - - <% } %> + +
+ <% if(cueKeys.isBroken){ %> + + + <% }else if(cueKeys.isRunning){ %> + + + <% }else if(cueKeys.isPaused){ %> + + + <% }else if(cueKeys.isLoaded){ %> + + + <% }else if(cueKeys.isFlagged){ %> + + + <% }else{ %> + + <% } %> +
- - -
<%= cue.number || " " %>
- - - <% for(let i=0; i - - <% if(cue.cues && cue.cues.length==0 && i==cue.nestedGroupModes.length-1){ %> - - - <% }else if(cue.cues && i==cue.nestedGroupModes.length-1){ %> - - - <% }else if(cue.nestedGroupPosition[i]<=0){ %> - <% if(i - - - <% }else{ %> - - - <% } %> - - <% }else if(i - - - <% }else{ %> - - - <% } %> - - - <% } %> - - - - - - - <% if(cue.type=="Group"){ %> - <% if(cue.cues.length==0){ %> - <%= cue.listName %> + + <% if(cueKeys.type == "Group" && cueKeys.mode){ %> + <% }else{ %> - <%= cue.listName %> + <% } %> - <% }else if(cue.nestedGroupPosition[1]==0){ %> - <%= cue.listName %> - - <% }else{ %> - <%= cue.listName %> - - <% } %> - <%= cue.target %> + +
<%= cueKeys.number || " " %>
+ + + + + <% for(let i=0; i + + <% if(cue.type=="Group" && cue.cues.length==0 && i==cueKeys.nestedGroupModes.length-1){ %> + + + <% }else if(cue.type=="Group" && i==cueKeys.nestedGroupModes.length-1){ %> + + + <% }else if(cueKeys.nestedGroupPosition[i]<=0){ %> + <% if(cueKeys.nestedGroupPosition.slice(i+1).every(v => v === 0)){ %> + + + <% }else{ %> + + + <% } %> + + <% }else if(i + + + <% }else if(cueKeys.nestedGroupPosition[i]==undefined && cueKeys.nestedGroupPosition[i-1]==0){ %> + + + <% }else{ %> + + + <% } %> + + + <% } %> + + + + + + <% if(cue.type=="Group"){ %> + + <% if(cue.cues.length==0){ %> + <%= cueKeys.listName %> + + <% }else{ %> + <%= cueKeys.listName %> + + <% } %> + + <% }else if(cueKeys.nestedGroupPosition[cueKeys.nestedGroupModes.length-2]==0){ %> + <%= cueKeys.listName %> + + <% }else{ %> + <%= cueKeys.listName %> + + <% } %> + + + <% if(cueKeys.currentCueTarget){ %> + <%= allCues[cueKeys.currentCueTarget].number || allCues[cueKeys.currentCueTarget].listName %> - <% if(cue.preWait){ %> - <%= elapsedTime(cue.preWait, cue.preWaitElapsed, "preWait", cue) %> + <% }else{ %> + - <% }else{ %> - 00:00.00 - - <% } %> + <% } %> + - <% let cueTypesWithAction = ["Audio", "Mic", "Video", "Camera", "Text", "Light", "Fade", "Network", "MIDI File", "Timecode", "Wait"]; %> - <% if((cue.type=="Group" && cue.groupMode==3) || cueTypesWithAction.indexOf(cue.type)>=0){ %> - <%= elapsedTime(cue.duration, cue.actionElapsed, "action", cue) %> + + <% if(cueKeys.preWait){ %> + <%= elapsedTime(cueKeys.preWait, cueKeys.preWaitElapsed, "preWait", cueKeys) %> - <% }else{ %> - + <% }else{ %> + 00:00.00 - <% } %> + <% } %> - <% if(cue.postWait){ %> - <%= elapsedTime(cue.postWait, cue.postWaitElapsed, "postWait", cue) %> + + <% let cueTypesWithAction = ["Audio", "Mic", "Video", "Camera", "Text", "Light", "Fade", "Network", "MIDI File", "Timecode", "Wait"]; %> + <% if((cueKeys.type=="Group" && cueKeys.mode==3) || (cueKeys.type=="Group" && cueKeys.mode==6) || cueTypesWithAction.includes(cueKeys.type)){ %> + <%= elapsedTime(cueKeys.duration, cueKeys.actionElapsed, "action", cueKeys) %> - <% }else{ %> - 00:00.00 + <% }else{ %> + - <% } %> + <% } %> + + + + <% if(cueKeys.postWait){ %> + <%= elapsedTime(cueKeys.postWait, cueKeys.postWaitElapsed, "postWait", cueKeys) %> + + <% }else{ %> + 00:00.00 + + <% } %> - <% if(cue.continueMode==2){ %> -
+ + <% if(cueKeys.continueMode==2){ %> +
- <% }else if(cue.continueMode==1){ %> -
+ <% }else if(cueKeys.continueMode==1){ %> +
- <% }else{ %> - + <% }else{ %> + - <% } %> + <% } %> -<% - function prettyFormatTime(seconds){ + + <% }else{ %> + + + + + +
<%= cue.number || " " %>
+ <%= cue.listName %> + + 00:00.00 + + 00:00.00 + + + +<% } %> + +<% +function prettyFormatTime(seconds){ if(!seconds){ return "00:00.00"; } @@ -151,14 +196,14 @@ return string.substring(startIndex, string.length-2) } - function elapsedTime(def, value, type, cue){ +function elapsedTime(def, value, type, cue){ - if(type=="action" && cue.paused){ + if(type=="action" && cue.isPaused){ value-=cue.preWait; } let border, fill; - if(cue.paused){ + if(cue.isPaused){ border = "#f6e737"; fill = "rgba(255, 240, 60, 0.7)"; }else{ @@ -171,7 +216,7 @@ let percent = value/def*100; let bg = `style='background: black; background: linear-gradient(90deg, ${fill} ${percent}%, transparent ${percent}%);`; - if(cue.paused){ + if(cue.isPaused){ bg+= "outline-color: "+border+";"; bg+= "color: white;"; } @@ -179,7 +224,7 @@ return `
${prettyFormatTime(Math.min(def, value))}`; - }else if(type=="postWait" || type=="action"){ + }else if(type=="postWait" && cue.continueMode==0){ return `${prettyFormatTime(def)}`; }else{ diff --git a/plugins/qlab/cuelist.ejs b/plugins/qlab/cuelist.ejs index 93f1ecc..a3d64f8 100644 --- a/plugins/qlab/cuelist.ejs +++ b/plugins/qlab/cuelist.ejs @@ -1,13 +1,13 @@ -

<%= workspace.displayName %> — <%= cueList.displayName %>

+

<%= workspace.displayName %> — <%= cueList.listName %>

- + - + @@ -18,17 +18,17 @@ - - - + + + - <% for(const cue_id in cueList.cues){ %> - <%= displayCueRow(cueList.cues[cue_id]) %> + <% for(let i=0; i + <%= displayCueRow(cueList.cues[i]) %> <% } %> @@ -36,16 +36,13 @@ <% - - - function displayCueRow(q){ - let html = rowTemplate({cue: allCues[q.uniqueID], allCues: allCues, workspace: workspace}); + let html = rowTemplate({cue: q, allCues: allCues, workspace: workspace}); if(q.cues){ - q.cues.forEach(q =>{ - html += displayCueRow(q); - }) + for(let i=0; i { - device.data.workspaces[wksp.uniqueID] = { - uniqueID: wksp.uniqueID, - displayName: wksp.displayName, - cueLists: {}, - cues: {}, + for (let i = 0; i < json.length; i++) { + device.data.workspaces[json[i].uniqueID] = { + version: json[i].version, + displayName: json[i].displayName, + port: json[i].port, + udpReplyPort: json[i].udpReplyPort, + cueLists: [], + selected: [], }; - device.send(`/workspace/${wksp.uniqueID}/connect`, device.fields.passcode); - }); - - if (Object.keys(device.data.workspaces).length === 0) { - device.data.permission = 'no workspaces'; - device.draw(); + device.send(`/workspace/${json[i].uniqueID}/connect`, device.fields.passcode); } - } else if (match(oscAddressParts, ['reply', 'workspace', '*', 'connect'])) { - device.send(`/workspace/${oscAddressParts[2]}/updates`, [{ type: 'i', value: 1 }]); - device.send(`/workspace/${oscAddressParts[2]}/cueLists`); - } else if (match(oscAddressParts, ['reply', 'workspace', '*', 'cueLists'])) { this.deviceInfoUpdate(device, 'status', 'ok'); - const workspace = device.data.workspaces[oscAddressParts[2]]; - const json = JSON.parse(oscData.args[0]); - - workspace.cueLists = {}; - workspace.cues = {}; - - if (json.status === 'denied') { + } else if (/reply\/workspace\/.*\/connect/.test(oscData.address)) { + const json = JSON.parse(oscData.args[0]).data; + if (json === 'badpass') { device.data.permission = 'denied'; - device.draw(); - } else if (json.data) { - device.data.permission = 'ok'; - - json.data.forEach((cueList) => { - workspace.cueLists[cueList.uniqueID] = cueList; - addCueToWorkspace(workspace, cueList); - }); - - device.draw(); - - setTimeout(() => { - json.data.forEach((ql) => { - workspace.cueLists[ql.uniqueID] = ql; - getValuesForKeys(device, json.workspace_id, ql); - }); - }, 0); - } - } else if ( - match(oscAddressParts, ['reply', 'cue_id', '*', 'children']) || - match(oscAddressParts, ['reply', 'workspace', '*', 'cue_id', '*', 'children']) - ) { - const json = JSON.parse(oscData.args[0]); - const workspace = device.data.workspaces[json.workspace_id]; - const cueID = json.address.substring(55, 91); - const cue = workspace.cues[cueID]; - - if (!_.isEqual(cue.cues, json.data)) { - workspace.cueLists[cueID].cues = json.data; - addCueToWorkspace(workspace, workspace.cueLists[cueID]); - device.draw(); - getValuesForKeys(device, json.workspace_id, cue); - } - } else if ( - match(oscAddressParts, ['reply', 'cue_id', '*', 'valuesForKeys']) || - match(oscAddressParts, ['reply', 'workspace', '*', 'cue_id', '*', 'valuesForKeys']) - ) { - const json = JSON.parse(oscData.args[0]); - const cueValues = json.data; - const workspace = device.data.workspaces[json.workspace_id]; - let cue = workspace.cues[cueValues.uniqueID]; - - if (!cue) { - workspace.cues[cueValues.uniqueID] = {}; - cue = workspace.cues[cueValues.uniqueID]; - } - - cue.uniqueID = cueValues.uniqueID; - cue.number = cueValues.number; - cue.name = cueValues.name; - cue.listName = cueValues.listName; - cue.displayName = cueValues.displayName; - cue.broken = cueValues.isBroken; - cue.running = cueValues.isRunning; - cue.loaded = cueValues.isLoaded; - cue.flagged = cueValues.isFlagged; - cue.paused = cueValues.isPaused; - cue.type = cueValues.type; - // cue.cues = cueValues.children; - cue.preWait = cueValues.preWait; - cue.postWait = cueValues.postWait; - cue.duration = cueValues.currentDuration; - cue.colorName = cueValues.colorName; - cue.continueMode = cueValues.continueMode; - cue.groupMode = cueValues.mode; - cue.parent = cueValues.parent; - cue.cartRows = cueValues.cartRows; - cue.cartColumns = cueValues.cartColumns; - cue.cartPosition = cueValues.cartPosition; - cue.preWaitElapsed = cueValues.preWaitElapsed; - cue.actionElapsed = cueValues.actionElapsed; - cue.postWaitElapsed = cueValues.postWaitElapsed; - - // QLab 5 fix - if (cueValues.type === 'Group' || cueValues.type === 'Cue List') { - cue.cues = cueValues.children; } else { - cue.cues = undefined; - } - - const nestedGroupModes = []; - const nestedGroupPosition = []; - - let obj = cue; - let sum = 0; - - if (obj.cues) { - sum += obj.cues.length; - } - - while (obj.parent !== '[root group of cue lists]') { - let pos = _.findIndex(workspace.cues[obj.parent].cues, { - uniqueID: obj.uniqueID, - }); - pos = Math.abs(pos - workspace.cues[obj.parent].cues.length) - 1; - - if (obj.cues === undefined) { - sum += pos; - } - - nestedGroupPosition.unshift(sum); - - if (obj.cues) { - sum += pos; - nestedGroupModes.unshift(obj.groupMode); - } else { - nestedGroupModes.unshift(workspace.cues[obj.parent].groupMode); - } - - obj = workspace.cues[obj.parent]; - } - - cue.nestedGroupModes = nestedGroupModes; - cue.nestedGroupPosition = nestedGroupPosition; - - device.update('updateCueData', { - cue, - allCues: workspace.cues, - workspace, - }); - } else if (match(oscAddressParts, ['reply', 'cue_id', '*', 'preWaitElapsed'])) { - const oscArgs = JSON.parse(oscData.args[0]); - if (oscArgs.status !== 'error') { - const workspace = device.data.workspaces[oscArgs.workspace_id]; - if (workspace) { - const cue = workspace.cues[oscArgs.address.substring(55, 91)]; - - if (cue) { - cue.preWaitElapsed = oscArgs.data; - lastElapsedUpdate = Date.now(); - - device.update('updateCueData', { - cue, - allCues: workspace.cues, - workspace, - }); - } - } - } - } else if (match(oscAddressParts, ['reply', 'cue_id', '*', 'actionElapsed'])) { - const oscArgs = JSON.parse(oscData.args[0]); - if (oscArgs.status !== 'error') { - const workspace = device.data.workspaces[oscArgs.workspace_id]; - if (workspace) { - const cue = workspace.cues[oscArgs.address.substring(55, 91)]; - - if (cue) { - cue.actionElapsed = oscArgs.data; - lastElapsedUpdate = Date.now(); - - device.update('updateCueData', { - cue, - allCues: workspace.cues, - workspace, - }); - } - } - } - } else if (match(oscAddressParts, ['reply', 'cue_id', '*', 'postWaitElapsed'])) { - const oscArgs = JSON.parse(oscData.args[0]); - if (oscArgs.status !== 'error') { - const workspace = device.data.workspaces[oscArgs.workspace_id]; - if (workspace) { - const cue = workspace.cues[oscArgs.address.substring(55, 91)]; - - if (cue) { - cue.postWaitElapsed = oscArgs.data; - lastElapsedUpdate = Date.now(); - - device.update('updateCueData', { - cue, - allCues: workspace.cues, - workspace, - }); - } - } - } - } else if (match(oscAddressParts, ['update', 'workspace', '*', 'cue_id', '*'])) { - const workspace = device.data.workspaces[oscAddressParts[2]]; - - if (workspace) { - const cueLists = Object.keys(workspace.cueLists); - const cueID = oscAddressParts[4]; - - if (cueID !== '[root group of cue lists') { - if (cueLists.includes(cueID)) { - device.send(`/workspace/${workspace.uniqueID}/cue_id/${cueID}/children`); - } - - device.send(`/workspace/${oscAddressParts[2]}/cue_id/${cueID}/valuesForKeys`, [ - { type: 's', value: valuesForKeysString }, - ]); - } - } - } else if (match(oscAddressParts, ['update', 'workspace', '*'])) { - // occurs when cue lists are reordered or a list is deleted - device.send(`/workspace/${oscAddressParts[2]}/cueLists`); - } else if (match(oscAddressParts, ['update', 'workspace', '*', 'dashboard'])) { - // this workspace might be new, let's check - if (device.data.workspaces[oscAddressParts[2]] === undefined) { - device.send('/workspaces'); - } - } else if (match(oscAddressParts, ['update', 'workspace', '*', 'cueList', '*', 'playbackPosition'])) { - const workspace = device.data.workspaces[oscAddressParts[2]]; - - if (workspace) { - const cue = workspace.cues[oscData.args[0]]; - - if (cue) { - workspace.playbackPosition = oscData.args[0] ? cue.uniqueID : ''; - device.update('updatePlaybackPosition', { cue }); - } - } - } else if (match(oscAddressParts, ['update', 'workspace', '*', 'disconnect'])) { - delete device.data.workspaces[oscAddressParts[2]]; - if (Object.keys(device.data.workspaces).length === 0) { - device.data.permission = 'no workspaces'; + device.data.permission = 'ok'; + device.send(`/workspace/${msgAddr[2]}/cueLists`); + device.send(`/workspace/${msgAddr[2]}/updates`, [{ type: 'i', value: 1 }]); } + } else if (/reply\/workspace\/.*\/cueLists/.test(oscData.address)) { + const json = JSON.parse(oscData.args[0]).data; + device.data.workspaces[msgAddr[2]].cueLists = json; + device.data.somethingPlaying = false; + processCueList(device.data.workspaces[msgAddr[2]].cueLists, Object.keys(device.data.cueKeys), device, []); device.draw(); - } else if (match(oscAddressParts, ['reply', 'thump'])) { - // intermittent connection check even if nothing's happening - } else { - // console.log(address) + } else if (/reply\/cue_id\/.*\/valuesForKeys/.test(oscData.address)) { + const json = JSON.parse(oscData.args[0]); + const keyValues = json.data; + const cue = device.data.cueKeys[msgAddr[2]]; + + if (cue === undefined) { + // this cue is new! + console.log('HERE'); + // device.send(`/workspace/${json.workspace_id}/cueLists`); + // device.draw(); + } else { + // console.log(keyValues.number); + cue.uniqueID = keyValues.uniqueID; + cue.number = keyValues.number; + cue.listName = keyValues.listName; + cue.isBroken = keyValues.isBroken; + cue.isRunning = keyValues.isRunning; + cue.isLoaded = keyValues.isLoaded; + cue.isFlagged = keyValues.isFlagged; + cue.type = keyValues.type; + cue.cues = keyValues.children; + cue.preWait = keyValues.preWait; + cue.postWait = keyValues.postWait; + cue.duration = keyValues.duration; + cue.colorName = keyValues.colorName; + cue.continueMode = keyValues.continueMode; + cue.mode = keyValues.mode; + cue.parent = keyValues.parent; + cue.cartRows = keyValues.cartRows; + cue.cartColumns = keyValues.cartColumns; + cue.cartPosition = keyValues.cartPosition; + cue.displayName = keyValues.displayName; + cue.preWaitElapsed = keyValues.preWaitElapsed; + cue.actionElapsed = keyValues.actionElapsed; + cue.postWaitElapsed = keyValues.postWaitElapsed; + cue.isPaused = keyValues.isPaused; + cue.currentCueTarget = keyValues.currentCueTarget; + cue.armed = keyValues.armed; + + if (keyValues.isRunning) { + device.data.somethingPlaying = true; + } + + let testCue = device.data.cueKeys[msgAddr[2]]; + let nestedGroupModes; + + if (cue.type === 'Group') { + nestedGroupModes = [testCue.mode]; + } else if (cue.parent !== '[root group of cue lists]') { + nestedGroupModes = [device.data.cueKeys[cue.parent].mode]; + } + + while (testCue.parent !== '[root group of cue lists]') { + testCue = device.data.cueKeys[testCue.parent]; + if (testCue === undefined) { + break; + } + + nestedGroupModes.unshift(testCue.mode); + cue.nestedGroupModes = nestedGroupModes; + } + if (cue.type === 'Cue List' || cue.type === 'Group') { + device.data.cueKeys[msgAddr[2]].cueInWorkspace.cues = [...keyValues.children]; + } + if (cue.type !== 'Cue List') { + device.update('updateCueRow', { cue, workspace: device.data.workspaces[json.workspace_id] }); + } + } + // console.log(cue); + } else if (/reply\/cue_id\/active\/.*Elapsed/.test(oscData.address)) { + const json = JSON.parse(oscData.args[0]); + const addrParts = json.address.split('/'); + const cueID = addrParts[4]; + const keyName = addrParts[5]; + device.data.cueKeys[cueID][keyName] = json.data; + device.data.somethingPlaying = true; + device.draw(); + } else if (/reply\/workspace\/.*\/selectedCues/.test(oscData.address)) { + const json = JSON.parse(oscData.args[0]); + const workspace = device.data.workspaces[msgAddr[2]]; + workspace.selected = []; + for (let i = 0; i < json.data.length; i++) { + workspace.selected.push(json.data[i].uniqueID); + } + device.update('updatePlaybackAndSelected', { workspace: device.data.workspaces[json.workspace_id] }); + } else if (/update\/workspace\/.*\/cue_id\/.*/.test(oscData.address)) { + if (device.data.cueKeys[msgAddr[4]] && device.data.cueKeys[msgAddr[4]].type === 'Group') { + device.send(`/workspace/${msgAddr[2]}/cueLists`); + } else { + device.send(`/cue_id/${msgAddr[4]}/valuesForKeys`, [{ type: 's', value: valuesForKeysString }]); + } + } else if (/update\/workspace\/.*\/cueList\/.*\/playbackPosition/.test(oscData.address)) { + const workspace = device.data.workspaces[msgAddr[2]]; + // const cue = workspace.cues[oscData.args[0]]; + workspace.playbackPosition = oscData.args[0]; + // device.draw(); + device.update('updatePlaybackAndSelected', { workspace: device.data.workspaces[msgAddr[2]] }); + } else if (/update\/workspace\/.*\/dashboard/.test(oscData.address)) { + device.send(`/workspace/${msgAddr[2]}/selectedCues`); + device.send(`/cue_id/active/preWaitElapsed`); } }; +function processCueList(list, knownCueIDs, _device, _nestedIndex) { + const nestedIndex = _nestedIndex; + const device = _device; + + for (let i = 0; i < list.length; i++) { + const cue = list[i]; + nestedIndex[nestedIndex.length - 1] = list.length - i - 1; + + // if (!knownCueIDs.includes(cue.uniqueID)) { + device.send(`/cue_id/${cue.uniqueID}/valuesForKeys`, [{ type: 's', value: valuesForKeysString }]); + // } + + if (cue.cues.length > 0) { + const nest2 = [..._nestedIndex]; + nest2.push(cue.cues.length); + processCueList(cue.cues, knownCueIDs, device, nest2); + for (let j = 0; j < nestedIndex.length; j++) { + nestedIndex[j]++; + } + } + + if (!knownCueIDs.includes(cue.uniqueID)) { + device.data.cueKeys[cue.uniqueID] = { + nestedGroupPosition: [...nestedIndex], + }; + } else { + device.data.cueKeys[cue.uniqueID].nestedGroupPosition = [...nestedIndex]; + } + + device.data.cueKeys[cue.uniqueID].cueInWorkspace = list[i]; + } +} + exports.update = function update(device, doc, updateType, data) { - if (updateType === 'updateCueData') { + if (updateType === 'updateCueRow') { const $elem = doc.getElementById(data.cue.uniqueID); - - if ($elem) { - if (data.cue.type === 'Cue List') { - $elem.outerHTML = `

${data.workspace.displayName} — ${data.cue.name}

`; - } else if (data.cue.type === 'Cart') { - $elem.outerHTML = device.templates.cart({ - tileTemplate: device.templates.tile, - cueList: data.cue, - allCues: data.workspace.cues, - }); - } else if (data.cue.cartPosition && data.cue.cartPosition[0] !== 0) { - // checking that the parent cue is a cart cue - const parentCue = data.workspace.cues[data.cue.parent]; - if (parentCue && parentCue.type === 'Cart') { - $elem.outerHTML = device.templates.tile(data); - } else { - $elem.outerHTML = device.templates.cue(data); - } - } else { - $elem.outerHTML = device.templates.cue(data); - } - } - } else if (updateType === 'updatePlaybackPosition') { - Array.from(doc.getElementsByClassName('playback-position')).forEach(($elem, index, array) => { - $elem.classList.remove('playback-position'); + $elem.outerHTML = device.templates.cue({ allCues: device.data.cueKeys, cue: data.cue, workspace: data.workspace }); + } else if (updateType === 'updatePlaybackAndSelected') { + Array.from(doc.querySelectorAll('.selected')).forEach(($el) => { + $el.classList.remove('selected'); }); - - const $elem = doc.getElementById(data.cue.uniqueID); + Array.from(doc.querySelectorAll('.playback-position')).forEach(($el) => { + $el.classList.remove('playback-position'); + }); + for (let i = 0; i < data.workspace.selected.length; i++) { + const $elem = doc.getElementById(data.workspace.selected[i]); + $elem.classList.add('selected'); + } + const $elem = doc.getElementById(data.workspace.playbackPosition); $elem.classList.add('playback-position'); - $elem.scrollIntoView({ behavior: 'smooth', block: 'center' }); } }; -function addCueToWorkspace(_workspace, cue) { - const workspace = _workspace; - workspace.cues[cue.uniqueID] = cue; - workspace.cues[cue.uniqueID].nestedGroupModes = []; - workspace.cues[cue.uniqueID].nestedGroupPosition = []; - - if (cue.cues) { - // this cue has children so add them as well - cue.cues.forEach((childCue) => { - addCueToWorkspace(workspace, childCue); - }); - } -} - -function getValuesForKeys(device, workspaceID, cue) { - device.send(`/workspace/${workspaceID}/cue_id/${cue.uniqueID}/valuesForKeys`, [ - { type: 's', value: valuesForKeysString }, - ]); - if (cue.cues) { - cue.cues.forEach((childCue) => { - getValuesForKeys(device, workspaceID, childCue); - }); - } -} - -function match(testArray, patternArray) { - let out = true; - if (testArray.length !== patternArray.length) { - return false; - } - patternArray.forEach((patternPart, i) => { - if (testArray[i] !== patternPart && patternPart !== '*') { - out = false; - } - }); - return out; -} - +let ticks = 0; exports.heartbeat = function heartbeat(device) { - heartbeatCount++; - - if (Date.now() - lastElapsedUpdate > 300) { - interval = 24; - } else { - interval = 1; - } - - if (heartbeatCount % 20 === 0 && device.data.workspaces && Object.keys(device.data.workspaces).length === 0) { - device.send(`/version`); - device.send('/workspaces'); - } - - if (heartbeatCount % 16 === 0) { + ticks++; + if (ticks % 10 === 0) { device.send(`/thump`); } - - if (heartbeatCount % interval === 0 && device.data.workspaces && Object.keys(device.data.workspaces).length > 0) { + if (device.data.somethingPlaying) { device.send(`/cue_id/active/preWaitElapsed`); - device.send(`/cue_id/active/actionElapsed`); device.send(`/cue_id/active/postWaitElapsed`); + device.send(`/cue_id/active/actionElapsed`); } }; diff --git a/plugins/qlab/template.ejs b/plugins/qlab/template.ejs index e55bd0b..b50e6a2 100644 --- a/plugins/qlab/template.ejs +++ b/plugins/qlab/template.ejs @@ -3,26 +3,22 @@

QLab <%= data.version || "" %>

+<% const workspaceKeys = Object.keys(data.workspaces); %> - <% if(data.permission=="ok"){ - for(const workspace_id in data.workspaces){ - const workspace = data.workspaces[workspace_id]; - for(const cueList_id in workspace.cueLists){ - const ql = workspace.cueLists[cueList_id]; %> - - <% if(ql.type=="Cue List"){ %> - <%= templates.cuelist({cueList: ql, allCues: workspace.cues, rowTemplate: templates.cue, workspace: workspace}) %> - <% }else if(ql.type=="Cart"){ %> - <%= templates.cart({cueList: ql, allCues: workspace.cues, tileTemplate: templates.tile}) %> - <% } %> +<% for(let i=0; i + <% const workspace = data.workspaces[workspaceKeys[i]]; %> -<% }}}else if(data.permission=="no workspaces"){ %> +

<%= workspace.displayName %>

-

QLab is launched but there are no open Workspaces

+ <% for(let j=0; j + <% const cueList = workspace.cueLists[j]; %> -<% }else if(data.permission=="denied"){ %> + <% if(cueList.type=="Cue List"){ %> + <%= templates.cuelist({cueList: cueList, allCues: data.cueKeys, rowTemplate: templates.cue, workspace: workspace}) %> + <% }else if(cueList.type=="Cart"){ %> + <%= templates.cart({cueList: cueList, allCues: data.cueKeys, tileTemplate: templates.tile}) %> + <% } %> -

Incorrect Passcode or OSC Access Permissions

- + <% } %> -<% } %> +<% } %> \ No newline at end of file
Number QName TargetPre WaitActionPost WaitPre-WaitDurationPost-Wait