// es-lint globals to stop red highlights
/*
global
SaveConfigToServer
sr_api, serverConfig, localConfig, refreshDarkMode ,$, livePortalVolatileData, updateMacroButtonsDisplay
*/
let processingTextAnimation_handle = [];
// data from extensions
let fulltriggerslist = {
triggers: [],
actions: [],
}
let extensionlist = []
// our data, ie saved trigger pairings etc
let usertriggerslist = {
pairings: [], // the trigger action pairs set
macrotriggers: [], // user defined macros
groups: [{ name: "Default" }] //user defined groups
}
// this will hold macros we create as for our dummy triggers
let triggersandactions =
{
triggers: [],
actions: []
}
//helper functions
//count number of times something appears in an array
const itemCounter = (value, field, index) =>
{
return value.filter((x) => x[field] == index).length;
};
// ============================================================================
// FUNCTION: initTriggersAndActions
// ============================================================================
/**
* Requests the triggers and actions 'SendTriggerAndActions' from each extension list in 'extension_list' and also the User triggers from the autopilot backend 'RequestUserTriggers'
* @param {strings[]} extension_list extensions to query
*/
function initTriggersAndActions (extension_list)
{
// get some defaults from local storage (if set)
if (!localStorage.getItem("selectedgroup"))
localStorage.setItem("selectedgroup", usertriggerslist.groups[0].name)
// request triggers and actions from all the current extensions we have
extension_list.forEach(ext =>
{
sr_api.sendMessage(
localConfig.DataCenterSocket,
sr_api.ServerPacket(
"ExtensionMessage",
serverConfig.extensionname,
sr_api.ExtensionPacket(
"SendTriggerAndActions",
serverConfig.extensionname,
"",
"",
ext
),
"",
ext
));
})
sr_api.sendMessage(
localConfig.DataCenterSocket,
sr_api.ServerPacket(
"ExtensionMessage",
serverConfig.extensionname,
sr_api.ExtensionPacket(
"RequestUserTriggers",
serverConfig.extensionname,
"",
"",
"autopilot"
),
"",
"autopilot"
));
}
// ============================================================================
// FUNCTION: receivedTrigger
// received triggers/actions from extension
// ============================================================================
/**
* Received trigger from an extension
* @param {Object[]} extensiontriggers triggers received from extension
*/
function receivedTrigger (extensiontriggers)
{
if (extensionlist[extensiontriggers.extensionname] == undefined)
{
extensionlist[extensiontriggers.extensionname] =
{
channel: extensiontriggers.channel,
description: extensiontriggers.description
}
}
if (extensiontriggers.triggers && extensiontriggers.triggers.length > 0)
fulltriggerslist.triggers[extensiontriggers.extensionname] = extensiontriggers.triggers
if (extensiontriggers.actions && extensiontriggers.actions.length > 0)
fulltriggerslist.actions[extensiontriggers.extensionname] = extensiontriggers.actions
fulltriggerslist.triggers = sortByKey(fulltriggerslist.triggers)
fulltriggerslist.actions = sortByKey(fulltriggerslist.actions)
// update the page with the new triggeroptions
populateGroupNamesDropdown();
addTriggerEntries();
addActionEntries();
populateTriggersTable();
populateMacroDisplay()
}
// ============================================================================
// FUNCTION: addTriggerEntries
// Loads first dropdown to chose extension for trigger
// ============================================================================
/**
* starts the process to build the webpage from the triggers and actions we have
*/
function addTriggerEntries ()
{
let TriggersExtensionChoser = document.getElementById("triggerExtensionChoser")
let triggerextensionnames = ""
let triggers = fulltriggerslist.triggers;
if (Object.keys(triggers).length > 0)
{
for (var trigger in triggers)
{
if (triggerextensionnames == "")
{
triggerextensionnames += "<option name='" + trigger + "' class='btn btn-secondary' value=" + trigger + " selected>" + trigger + "</option>";
TriggersExtensionChoser.title = trigger
}
else
triggerextensionnames += "<option name='" + trigger + "' class='btn btn-secondary' value=" + trigger + ">" + trigger + "</option>";
}
TriggersExtensionChoser.innerHTML = triggerextensionnames;
// check if we have stored a trigger extension name previously (adds memory to selected options for user)
let extensionname = localStorage.getItem("selectedtriggerextension")
if (extensionname)
{
triggersLoadTriggers(extensionname)// just load the first one to start with
TriggersExtensionChoser.value = extensionname
}
else
triggersLoadTriggers(fulltriggerslist.triggers[0])// just load the first one to start with
TriggersExtensionChoser.dispatchEvent(new Event('change'))
}
}
// ============================================================================
// Webpage callback to load correct extension triggers
// ============================================================================
// ============================================================================
// FUNCTION: triggersLoadTriggers
// loads trigger names into the dropdown.
// ============================================================================
function triggersLoadTriggers (name)
{
if (!Object.keys(extensionlist).includes(name))
{
if (extensionlist.length > 0)
name = Object.keys(extensionlist)[0]
else
return
}
// store the value so we remember it next time the usr loads the page
localStorage.setItem("selectedtriggerextension", name)
let TriggerExtensionTriggers = document.getElementById("triggerExtensionTriggers")
let selectedTrigger = fulltriggerslist.triggers[name]
let triggerextensiontriggers = ""
// set the title of the calling dropdown
document.getElementById("triggerExtensionChoserLabel").innerHTML = extensionlist[name].description;
document.getElementById("triggerExtensionChoser").title = name
for (var key in selectedTrigger)
{
if (triggerextensiontriggers == "")
{
triggerextensiontriggers += "<option data='" + selectedTrigger[key].messagetype + "' class='form-control' value='" + key + "' selected>" + selectedTrigger[key].displaytitle + "</option>";
TriggerExtensionTriggers.title = selectedTrigger[key].description
}
else
{
triggerextensiontriggers += "<option data='" + selectedTrigger[key].messagetype + "' class='form-control' value='" + key + "'>" + selectedTrigger[key].displaytitle + "</option>";
}
}
TriggerExtensionTriggers.innerHTML = triggerextensiontriggers;
triggersLoadParameters(0)
}
// ============================================================================
// FUNCTION: triggersLoadParameters
// ============================================================================
function triggersLoadParameters (id)
{
let extensionname = document.getElementById("triggerExtensionChoser").value;
let TriggerExtensionTriggerParameters = document.getElementById("triggerExtensionTriggerParameters")
// check we have triggers for this extension (macros might not have any by default)
if (fulltriggerslist.triggers[extensionname] != undefined)
{
let params = fulltriggerslist.triggers[extensionname][id].parameters
let triggername = fulltriggerslist.triggers[extensionname][id].name;
let triggerextensionparameters = ""
TriggerExtensionTriggerParameters.title = fulltriggerslist.triggers[extensionname][id].description
// set the title of the calling dropdown
document.getElementById("triggerExtensionTriggers").title = fulltriggerslist.triggers[extensionname][id].description
document.getElementById("triggerExtensionChoserChannel").value = extensionlist[extensionname].channel;
document.getElementById("triggerExtensionChoserTriggerName").value = fulltriggerslist.triggers[extensionname][id].name;
for (var key in params)
{
// Row
triggerextensionparameters += "<div class='row'>"
// Variable name text
triggerextensionparameters += "<div class='col-2'>"
triggerextensionparameters += "<div class='d-flex form-row align-items-center'>"
triggerextensionparameters += "<label class='form-label px-2 align-middle text-right' for=" + triggername + "_" + key + ">" + key + "</label>"
triggerextensionparameters += "</div>"
// variable data to match text box
triggerextensionparameters += "</div>"
triggerextensionparameters += "<div class='col-7'>"
triggerextensionparameters += "<input type='text' class='form-control' name='" + triggername + "_" + key + "' id='" + triggername + "_" + key + "' placeholder='" + key + "' value=''>"
triggerextensionparameters += "</div>"
triggerextensionparameters += "<div class='col-3'>"
// add the matcher dropdown to each variable name
triggerextensionparameters += "<select id='triggerExtensionTriggerParametersMatcher_" + key + "' class='selectpicker btn btn-secondary' data-style='btn-danger' title = '' value='1' name='triggerExtensionTriggerParametersMatcher_" + key + "' style='max-width: 100%'>"
triggerextensionparameters += "<option data='Exact Match' class='form-control' value='1'>Exact Match</option>";
triggerextensionparameters += "<option data='Anywhere' class='form-control' value='2'>Anywhere</option>";
triggerextensionparameters += "<option data='Start of line' class='form-control' value='3'>Start of line</option>";
triggerextensionparameters += "<option data='Doesn't Match' class='form-control' value='4'>Doesn't match</option>";
triggerextensionparameters += "<option data='Specific word' class='form-control' value='5'>Match a specific whole word</option>";
triggerextensionparameters += "</select>"
triggerextensionparameters += "</div>"
triggerextensionparameters += "</div>"
}
// cooldown timer
triggerextensionparameters += "<div class='row'>"
triggerextensionparameters += "<div class='col-2'>"
triggerextensionparameters += "<div class='d-flex form-row align-items-center'>"
triggerextensionparameters += "<label class='form-label px-2 align-middle text-right' for=" + triggername + "_cooldown>cooldown</label>"
triggerextensionparameters += "</div>"
triggerextensionparameters += "</div>"
triggerextensionparameters += "<div class='col-3'>"
triggerextensionparameters += "<div class='input-group'>"
triggerextensionparameters += "<input type='text' class='form-control' name='" + triggername + "_cooldown' id='" + triggername + "__cooldown' placeholder='cooldown' value='0'>seconds"
triggerextensionparameters += "</div>"
triggerextensionparameters += "</div>"
TriggerExtensionTriggerParameters.innerHTML = triggerextensionparameters;
}
}
// ============================================================================
// FUNCTION: addActionEntries
// Loads first dropdown to chose extension for action
// ============================================================================
function addActionEntries ()
{
let ActionExtensionChoser = document.getElementById("actionExtensionChoser")
let actionextensionnames = ""
let temparray = []
let tempobject = {}
let actions = fulltriggerslist.actions;
if (Object.keys(actions).length > 0)
{
for (var action in actions)
{
if (actionextensionnames == "")
{
actionextensionnames += "<option name='" + action + "' class=' btn btn-secondary ' value=" + action + " selected>" + action + "</option>";
ActionExtensionChoser.title = action
}
else
actionextensionnames += "<option name='" + action + "' class=' btn btn-secondary ' value=" + action + ">" + action + "</option>";
}
ActionExtensionChoser.innerHTML = actionextensionnames;
// check if we have stored a action extension name previously (adds memory to selected options for user)
let extensionname = localStorage.getItem("selectedactionextension")
if (extensionname)
{
actionLoadAction(extensionname)
ActionExtensionChoser.value = extensionname
}
else
actionLoadAction(fulltriggerslist.actions[0])// just load the first one to start with
ActionExtensionChoser.dispatchEvent(new Event('change'))
}
}
// ============================================================================
// Webpage callback to load correct extension action
// ============================================================================
// ============================================================================
// FUNCTION: actionLoadAction
// ============================================================================
function actionLoadAction (name)
{
if (!Object.keys(extensionlist).includes(name))
{
if (extensionlist.length > 0)
name = Object.keys(extensionlist)[0]
else
return
}
// store the value so we remember it next time the usr loads the page
localStorage.setItem("selectedactionextension", name)
let ActionExtensionAction = document.getElementById("actionExtensionAction")
let selectedAction = fulltriggerslist.actions[name]
let actionextensionaction = ""
document.getElementById("actionExtensionChoserLabel").innerHTML = name
document.getElementById("actionExtensionChoser").title = name
for (var key in selectedAction)
{
if (key != "paused")
{
if (actionextensionaction == "")
{
actionextensionaction += "<option data='" + selectedAction[key].messagetype + "' class='form-control' value='" + key + "' selected>" + selectedAction[key].displaytitle + "</option>";
ActionExtensionAction.title = selectedAction[key].description
}
else
{
actionextensionaction += "<option data='" + selectedAction[key].messagetype + "' class='form-control' value='" + key + "'>" + selectedAction[key].displaytitle + "</option>";
}
}
}
ActionExtensionAction.innerHTML = actionextensionaction;
actionLoadParameters(0)
return true;
}
// ============================================================================
// FUNCTION: actionLoadParameters
// ============================================================================
function actionLoadParameters (id)
{
let extensionname = document.getElementById("actionExtensionChoser").value;
let ActionExtensionActionParameters = document.getElementById("actionExtensionActionParameters")
let params = fulltriggerslist.actions[extensionname][id].parameters
let actionname = fulltriggerslist.actions[extensionname][id].name;
let actionextensionparameters = ""
// set the title of the calling dropdown
document.getElementById("actionExtensionAction").title = fulltriggerslist.actions[extensionname][id].description
document.getElementById("actionExtensionChoserChannel").value = extensionlist[extensionname].channel;
document.getElementById("actionExtensionChoserActionName").value = fulltriggerslist.actions[extensionname][id].name;
for (var key in params)
{
actionextensionparameters += "<div class='row'>"
actionextensionparameters += "<div class='col-2'>"
actionextensionparameters += "<div class='d-flex form-row align-items-center'>"
actionextensionparameters += "<label class='form-label px-2 align-middle' for=" + actionname + "_" + key + ">" + key + "</label>"
actionextensionparameters += "</div>"
actionextensionparameters += "</div>"
actionextensionparameters += "<div class='col-10'>"
actionextensionparameters += "<input type='text' class='form-control' name='" + actionname + "_" + key + "' id='" + actionname + "_" + key + "' placeholder='" + key + "' value='' title='" + key + "'>"
actionextensionparameters += "</div>"
actionextensionparameters += "</div>"
}
ActionExtensionActionParameters.innerHTML = actionextensionparameters;
}
// ============================================================================
// FUNCTION: populateGroupNamesDropdown
// populates the group dropdown
// ============================================================================
function populateGroupNamesDropdown ()
{
let GroupChoser = document.getElementById("triggerExtensionGroupName")
// that happen within StreamRoller. Ie you may want to post a chat message when someone donates, or change the hue lights or obs scene depending on chats mood etc.";
let groupnames = ""
let selected = ""
for (let i = 0; i < usertriggerslist.groups.length; i++)
{
if (usertriggerslist.groups[i].name == localStorage.getItem("selectedgroup") || groupnames == "")
{
selected = " selected"
GroupChoser.title = usertriggerslist.groups[i].name
}
else
selected = ""
groupnames += "<option name='" + usertriggerslist.groups[i].name + "' class='btn btn-secondary' value=" + usertriggerslist.groups[i].name + selected + ">" + usertriggerslist.groups[i].name + "</option>";
}
GroupChoser.innerHTML = groupnames;
}
// end create trigger form
// ============================================================================
// FUNCTION: createTriggerAction
// called when form submitted
// ============================================================================
function createTriggerAction (e)
{
let groupname = document.getElementById("triggerExtensionGroupName").value
let extname = document.getElementById("triggerExtensionChoser").value
let channel = document.getElementById("triggerExtensionChoserChannel").value
localStorage.setItem("selectedgroup", groupname)
let SingleEvent = {
group: groupname,
trigger:
{
name: document.getElementById("triggerExtensionChoserTriggerName").value,
extension: extname,
channel: channel,
messagetype: $("#triggerExtensionTriggers option:selected").attr('data'),
data: []
},
action:
{
name: document.getElementById("actionExtensionChoserActionName").value,
extension: document.getElementById("actionExtensionChoser").value,
channel: document.getElementById("actionExtensionChoserChannel").value,
messagetype: $("#actionExtensionAction option:selected").attr('data'),
data: []
}
}
let fieldsAsArray = $(e).serializeArray();
var fieldsAsObject = fieldsAsArray.reduce((obj, item) => (obj[item.name] = item.value, obj), {});
for (const entry in fieldsAsObject)
{
// entries will be the trigger/action name + "_" variable name
if (entry.indexOf(SingleEvent.trigger.name + "_") == 0)
{
let varname = entry.replace(SingleEvent.trigger.name + "_", "");
let tmpobj = {};
// store the matcher if we have one
if (document.getElementById("triggerExtensionTriggerParametersMatcher_" + varname) != null)
tmpobj["MATCHER_" + varname] = document.getElementById("triggerExtensionTriggerParametersMatcher_" + varname).value;
// we store the cd in the trigger area not the data area
if (varname == "cooldown")
SingleEvent.trigger.cooldown = fieldsAsObject[entry]
else
{
tmpobj[varname] = fieldsAsObject[entry];
SingleEvent.trigger.data.push(tmpobj);
}
}
if (entry.indexOf(SingleEvent.action.name + "_") == 0)
{
let varname = entry.replace(SingleEvent.action.name + "_", "");
let tmpobj = {};
tmpobj[varname] = fieldsAsObject[entry];
SingleEvent.action.data.push(tmpobj);
}
}
// add this action to the list
if (checkTriggerIsValid(SingleEvent) && groupname != "")
{
if (usertriggerslist.groups.find(x => x.name == groupname) == undefined)
alert("group doesn't exist", groupname)
else
usertriggerslist.pairings.push(SingleEvent)
}
updateServerPairingsList()
//populateTriggersTable();
return false;
}
// ============================================================================
// FUNCTION: createMacro
// called from create macro button
// ============================================================================
function createMacro (e)
{
let macroname = document.getElementById("macroName").value
let macrodescription = document.getElementById("macroDescription").value
let macrocolor = document.getElementById("macroColor").value
let macrobackgroundcolor = document.getElementById("macroBackgroundColor").value
let image = document.getElementById("macroimagename").value
if (macroname == "")
{
alert("Macro name empty")
return false;
}
for (let i = 0; i < triggersandactions.triggers.length; i++)
{
if (triggersandactions.triggers[i].name == macroname)
{
alert("Triggername already already exists")
return false
}
}
let SingleTrigger =
{
name: macroname,
description: macrodescription,
displaytitle: macroname,
extensionname: "autopilot",
messagetype: "trigger_" + macroname,
color: macrocolor,
backgroundcolor: macrobackgroundcolor,
image: image
}
// add these to the our triggers list so we can
// display them and send them to ourselves ;)
triggersandactions.triggers.push(SingleTrigger)
sortByKey(triggersandactions.triggers, "name")
// keep a copy of these in our user triggers so we
// can load them next time.
usertriggerslist.macrotriggers = triggersandactions
//mimic the triggers being sent to us
receivedTrigger(triggersandactions);
updateServerPairingsList();
//populateMacroDisplay()
return false;
}
// ============================================================================
// FUNCTION: deleteMacro
// called from delete macro button
// ============================================================================
function deleteMacro (e)
{
let macroname = document.getElementById("macroName").value
if (!window.confirm("Delete " + macroname + "?"))
return;
let deleted = false
// delete from the currently loaded extension triggers
for (let i = 0; i < fulltriggerslist.triggers.macros.length; i++)
{
if (fulltriggerslist.triggers.macros[i].name == macroname)
{
fulltriggerslist.triggers.macros.splice(i, 1)
deleted = true
sortByKey(fulltriggerslist.triggers, "name")
break;
}
}
// delete from our user defined triggers
for (let i = 0; i < usertriggerslist.macrotriggers.triggers.length; i++)
{
if (usertriggerslist.macrotriggers.triggers[i].name == macroname)
{
usertriggerslist.macrotriggers.triggers.splice(i, 1)
deleted = true
sortByKey(usertriggerslist.macrotriggers.triggers, "name")
break;
}
}
if (deleted)
{
updateServerPairingsList()
//addTriggerEntries()
//populateMacroDisplay()
}
return false;
}
// ============================================================================
// FUNCTION: populateMacroDisplay
// ============================================================================
function populateMacroDisplay ()
{
if (usertriggerslist.macrotriggers == undefined || usertriggerslist.macrotriggers.length == 0)
return;
let element = document.getElementById("existing_macro_list")
let tempstring = ""
for (let i = 0; i < usertriggerslist.macrotriggers.triggers.length; i++)
{
let color = "#999999"
let macroName = usertriggerslist.macrotriggers.triggers[i].name
let macroDescription = usertriggerslist.macrotriggers.triggers[i].description
let iconName = usertriggerslist.macrotriggers.triggers[i].image
let backgroundcolor = "#222255"
if (typeof (usertriggerslist.macrotriggers.triggers[i].color) != "undefined" && usertriggerslist.macrotriggers.triggers[i].color != "")
color = usertriggerslist.macrotriggers.triggers[i].color
if (typeof (usertriggerslist.macrotriggers.triggers[i].backgroundcolor) != "undefined" && usertriggerslist.macrotriggers.triggers[i].backgroundcolor != "")
backgroundcolor = usertriggerslist.macrotriggers.triggers[i].backgroundcolor
if (typeof (usertriggerslist.macrotriggers.triggers[i].image) != "undefined" && usertriggerslist.macrotriggers.triggers[i].image != "")
{
tempstring += "<div class='deckiconslot'>"
tempstring += "<img class='deckicon' src='/autopilot/images/deckicons/" + iconName + "' alt = '" + macroName + ": " + macroDescription + "' onclick='triggerMacroButton(\"macros\",\"" + macroName + "\");' title='" + macroName + ": " + macroDescription + "'>"
tempstring += "</div>"
}
else
{
tempstring += "<div class='deckiconslot'>"
tempstring += "<div class='nodeckicon' style='color:" + color + "; background-color:" + backgroundcolor + ";' alt='" + macroName + "' onclick='javascript:triggerMacroButton(\"macros\",\"" + macroName + "\");' title='" + macroName + ": " + macroDescription + "'>" + macroName + "</div> "
tempstring += "</div>"
}
}
element.innerHTML = tempstring
}
// ============================================================================
// FUNCTION: checkTriggerIsValid
// check we have the channels and extensions required
// ============================================================================
function checkTriggerIsValid (trigger)
{
//check we have the extensions and the channels to listen to
//probably need to update these but not sure what to put here yet :P
/*if (!Object.hasOwn(livePortalVolatileData.extensions, trigger.trigger.extension))
alert("Couldn't find extension", trigger.trigger.extension)
if (!livePortalVolatileData.channellist.includes(trigger.trigger.channel))
alert("Couldn't find channel", trigger.trigger.channel)
if (!Object.hasOwn(livePortalVolatileData.extensions, trigger.action.extension))
alert("Couldn't find extension", trigger.action.extension)
if (!livePortalVolatileData.channellist.includes(trigger.action.channel))
alert("Couldn't find channel", trigger.action.channel)*/
return true;
}
// ============================================================================
// FUNCTION: populateTriggersTable
// Shows the current tirgger pairings on screen
// ============================================================================
function populateTriggersTable ()
{
let table = document.getElementById("TriggersAndActionsTable")
table.innerHTML = "";
// create hide all groups button
let AllGroupsHidden = localStorage.getItem("AllGroupsHidden") == "true"
var group_actions = document.createElement("div")
group_actions.id = "AllGroupsHiddenButtons"
if (AllGroupsHidden)
{
btn = createAnchorButton('btn btn-secondary', "javascript:ToggleAllGroups();", 'Show/Hide All Groups', '/autopilot/images/show.png')
group_actions.innerHTML = "Show all groups"
}
else
{
btn = createAnchorButton('btn btn-secondary', "javascript:ToggleAllGroups();", 'Show/Hide All Groups', '/autopilot/images/hide.png')
group_actions.innerHTML = "Hide all groups"
}
btn.id = "AllGroupsHiddenButtonImage"
group_actions.appendChild(btn)
group_actions.appendChild(document.createElement("hr"))
table.appendChild(group_actions)
for (let g in usertriggerslist.groups)
{
let group = usertriggerslist.groups[g].name
var group_div = document.createElement("div")
let group_id = group + "_" + g
let span = document.createElement("span")
group_div.appendChild(span)
span.classList = 'fs-4'
span.innerHTML = "Group(" + itemCounter(usertriggerslist.pairings, "group", group) + "): " + group
// delete group button
var btn = createAnchorButton('btn btn-secondary', "javascript:DeleteTriggerGroup('" + group + "');", 'Delete ' + group_id + '_Group', '/autopilot/images/trash.png')
group_div.appendChild(btn)
// play button
btn = createAnchorButton('btn btn-secondary', "javascript:unPauseGroupButton('" + group + "');", 'Unpause ' + group_id + '_Group', '/autopilot/images/play.png')
group_div.appendChild(btn)
// pause button
btn = createAnchorButton('btn btn-secondary', "javascript:pauseGroupButton('" + group + "');", 'Pause ' + group_id + '_Group', '/autopilot/images/pause.png')
group_div.appendChild(btn)
// show hide button
if (AllGroupsHidden || localStorage.getItem(group + "visible") == "false")
btn = createAnchorButton('btn btn-secondary', "javascript:ShowHideTriggerGroup('" + group + "');", 'Show/Hide ' + group_id + '_Group', '/autopilot/images/show.png')
else
btn = createAnchorButton('btn btn-secondary', "javascript:ShowHideTriggerGroup('" + group + "');", 'Show/Hide ' + group_id + '_Group', '/autopilot/images/hide.png')
group_div.appendChild(btn)
table.appendChild(group_div)
// group body
let tbody = document.createElement("tbody")
tbody.id = group + "_TriggerGroupDisplay"
tbody.style.width = "100%"
table.appendChild(tbody)
if (AllGroupsHidden || localStorage.getItem(group + "visible") == "false")
tbody.style.display = "none"
else
tbody.style.display = "table"
// inset title for trigger column
let triggertitlerow = tbody.insertRow()
let titlecell = triggertitlerow.insertCell()
titlecell.classList = "text-center"
titlecell.innerHTML = "<h3>Triggers</h3>"
titlecell = triggertitlerow.insertCell()
titlecell.classList = "text-center"
titlecell.innerHTML = "<h3>Actions</h3>"
// table data
for (let i = 0; i < usertriggerslist.pairings.length; i++)
{
if (usertriggerslist.pairings[i].group == group)
{
//triggers/actions row
let tr = tbody.insertRow()
//split row into triggers and action cells
let triggerdatacell = tr.insertCell()
triggerdatacell.style.width = "50%"
let triggersdatacelltable = document.createElement("table")
triggerdatacell.appendChild(triggersdatacelltable)
let triggerdatacellrow = triggersdatacelltable.insertRow()
let actiondatacell = tr.insertCell()
actiondatacell.style.width = "50%"
let actiondatacelltable = document.createElement("table")
actiondatacell.appendChild(actiondatacelltable)
let actiondatacellrow = actiondatacelltable.insertRow()
actiondatacellrow.style.borderLeftWidth = "1px";
if (usertriggerslist.pairings[i].action.paused)
tr.style.color = "#ffffff6b"
// TRIGGERS
let td = triggerdatacellrow.insertCell()
td.innerHTML = i
//tablerows += "<td scope='row'>" + i + "</td>"
td = triggerdatacellrow.insertCell()
// td.scope = 'row'
td.role = 'button'
td.innerHTML = "<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' class='bi bi-trash' viewBox='0 0 16 16'><path d='M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5Zm2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5Zm3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0V6Z'/><path d='M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1v1ZM4.118 4 4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4H4.118ZM2.5 3h11V2h-11v1Z'/></svg >"
td.onclick = function () { delteTriggerAction(group, i); }
td = triggerdatacellrow.insertCell()
td.innerHTML = usertriggerslist.pairings[i].trigger.extension
td = triggerdatacellrow.insertCell()
td.innerHTML = usertriggerslist.pairings[i].trigger.messagetype.replace("trigger_", "").replace("_get", "")
td = triggerdatacellrow.insertCell()
let morethanoneentry = false
for (let j = 0; j < usertriggerslist.pairings[i].trigger.data.length; j++)
{
if (morethanoneentry)
//tablerows += ", ";
td.innerHTML += ", "
morethanoneentry = true;
for (let item in usertriggerslist.pairings[i].trigger.data[j])
{
let symbol = ""
if (item.indexOf("MATCHER_") != 0)
{
//don't show the matcher fields on screen
let searchtype = 1;
//get the matcher object if there is one
let temp = usertriggerslist.pairings[i].trigger.data.find((o) => typeof (o["MATCHER_" + item]) != "undefined")
// if we have a matcher object get the value so we can change the symbol on screen (=/^/* for exact, startswith, anywhere)
if (temp)
searchtype = temp["MATCHER_" + item]
switch (searchtype)
{
case "1":
symbol = "="
break;
case "2":
symbol = "*"
break;
case "3":
symbol = "^"
break;
case "4":
symbol = "!"
break;
case "5":
symbol = "#"
break;
default:
symbol = "="
}
td.innerHTML += item + " " + symbol + " " + usertriggerslist.pairings[i].trigger.data[j][item];
}
}
}
// ACTIONS
td = actiondatacellrow.insertCell()
td.innerHTML = usertriggerslist.pairings[i].action.extension
td = actiondatacellrow.insertCell()
td.innerHTML = usertriggerslist.pairings[i].action.messagetype.replace("action_", "")
td = actiondatacellrow.insertCell()
morethanoneentry = false
for (let j = 0; j < usertriggerslist.pairings[i].action.data.length; j++)
{
if (morethanoneentry)
td.innerHTML += ", ";
//tablerows += ", ";
morethanoneentry = true;
// we have amtched the action
for (let item in usertriggerslist.pairings[i].action.data[j])
td.innerHTML += item + " = " + usertriggerslist.pairings[i].action.data[j][item];
}
td = actiondatacellrow.insertCell()
if (usertriggerslist.pairings[i].action.paused)
td.appendChild(createAnchorButton('btn btn-secondary', "javascript:pauseActionButton('" + i + "');", 'Unpause' + i + ' action', '/autopilot/images/play.png', "20px"))
else
td.appendChild(createAnchorButton('btn btn-secondary', "javascript:pauseActionButton('" + i + "');", 'Pause' + i + ' action', '/autopilot/images/pause.png', "20px"))
// edit button
td = actiondatacellrow.insertCell()
td.appendChild(createAnchorButton('btn btn-secondary', "javascript:EditPairingButton(this,'" + group + "','" + i + "');", 'Edit ' + i, '/autopilot/images/edit.png', "20px"))
// run button
td = actiondatacellrow.insertCell()
td.appendChild(createAnchorButton('btn btn-secondary', "javascript:triggerActionButton('" + group + "','" + i + "');", 'Run ' + i + 'action', '/autopilot/images/run.png', "20px"))
}
}
}
populateGroupNamesDropdown();
}
// ============================================================================
// FUNCTION: ShowHideTriggerGroup
// callback for show/hide button
// ============================================================================
function ShowHideTriggerGroup (name)
{
let group = document.getElementById(name + "_TriggerGroupDisplay")
let visible = localStorage.getItem(name + "visible")
if (visible == "false")
{
localStorage.setItem(name + "visible", "true")
localStorage.setItem("AllGroupsHidden", "false");
group.style.display = "none"
}
else
{
localStorage.setItem(name + "visible", "false")
group.style.display = "block"
}
populateTriggersTable()
}
// ============================================================================
// FUNCTION: ToggleAllGroups
// callback for all groups button
// ============================================================================
function ToggleAllGroups ()
{
// invert the value (toggle button)
if (localStorage.getItem("AllGroupsHidden") == "true")
localStorage.setItem("AllGroupsHidden", "false")
else
localStorage.setItem("AllGroupsHidden", "true")
populateTriggersTable()
}
// ============================================================================
// FUNCTION: DeleteTriggerGroup
// callback for show/hide button
// ============================================================================
function DeleteTriggerGroup (name)
{
if (!window.confirm("Delete " + name + "?"))
return;
if (usertriggerslist.groups.find(x => x.name == name) != undefined)
{
if (typeof (usertriggerslist.pairings.find(item => item.group === "Default")) != "undefined")
alert("Group: not empty")
else if (name == "Default")
alert("Can't delete the default group")
else
{
for (let i = 0; i < usertriggerslist.groups.length; i++)
{
if (usertriggerslist.groups[i].name === name)
{
usertriggerslist.groups.splice(i, 1)
break;
}
}
}
}
else
alert("can't find group")
//populateTriggersTable()
//populateGroupNamesDropdown();
updateServerPairingsList()
}
// ============================================================================
// FUNCTION: createNewTriggerGroup
// Create new trigger group
// ============================================================================
function createNewTriggerGroup ()
{
addNewTriggerGroup(document.getElementById("triggergroupcreatename").value)
}
// ============================================================================
// FUNCTION: addNewTriggerGroup
// Create new trigger group
// ============================================================================
function addNewTriggerGroup (groupname)
{
if (usertriggerslist.groups.find(x => x.name == groupname) == undefined)
usertriggerslist.groups.push({ name: groupname, show: true })
updateServerPairingsList()
//populateTriggersTable()
//populateGroupNamesDropdown()
}
// ============================================================================
// FUNCTION: delteTriggerAction
// delete a trigger entry
// ============================================================================
function delteTriggerAction (group, id)
{
if (!window.confirm("Delete?"))
return;
if (usertriggerslist.pairings[id].group == group)
usertriggerslist.pairings.splice(id, 1)
updateServerPairingsList();
//populateTriggersTable();
}
// ============================================================================
// FUNCTION: pauseActionButton
// button to pause a trigger-action
// ============================================================================
function pauseActionButton (id)
{
usertriggerslist.pairings[id].action.paused = !(usertriggerslist.pairings[id].action.paused)
updateServerPairingsList()
//populateTriggersTable();
}
// ============================================================================
// FUNCTION: pauseGroupButton
// button to pause all trigger-actions in a group
// ============================================================================
function pauseGroupButton (group)
{
usertriggerslist.pairings.forEach(element =>
{
if (element.group == group)
element.action.paused = true;
});
updateServerPairingsList()
//populateTriggersTable();
}
// ============================================================================
// FUNCTION: pauseGroupButton
// button to pause all trigger-actions in a group
// ============================================================================
function unPauseGroupButton (group)
{
usertriggerslist.pairings.forEach(element =>
{
if (element.group == group)
element.action.paused = false;
});
updateServerPairingsList()
//populateTriggersTable();
}
// ============================================================================
// FUNCTION: triggerMacroButton
// button on the page for users to test the actions
// ============================================================================
function triggerMacroButton (group, name)
{
for (var i in usertriggerslist.pairings)
{
if (usertriggerslist.pairings[i].trigger.extension == group &&
usertriggerslist.pairings[i].trigger.name == name)
{
let params = {}
for (var j in usertriggerslist.pairings[i].action.data)
{
for (const property in usertriggerslist.pairings[i].action.data[j])
params[property] = usertriggerslist.pairings[i].action.data[j][property]
}
sr_api.sendMessage(localConfig.DataCenterSocket,
sr_api.ServerPacket("ExtensionMessage",
serverConfig.extensionname,
sr_api.ExtensionPacket(
usertriggerslist.pairings[i].action.messagetype,
serverConfig.extensionname,
params,
"",
usertriggerslist.pairings[i].action.extension),
"",
usertriggerslist.pairings[i].action.extension
),
);
}
}
}
// ============================================================================
// FUNCTION: triggerActionButton
// button on the page for users to test the actions
// ============================================================================
function triggerActionButton (group, id)
{
let action = usertriggerslist.pairings[id].action
//let params = { ...action.data }
let params = {}
for (var i in action.data)
{
for (const property in action.data[i])
params[property] = action.data[i][property]
}
sr_api.sendMessage(localConfig.DataCenterSocket,
sr_api.ServerPacket("ExtensionMessage",
serverConfig.extensionname,
sr_api.ExtensionPacket(
action.messagetype,
serverConfig.extensionname,
params,
"",
action.extension),
"",
action.extension
),
);
}
// ============================================================================
// FUNCTION: updateServerPairingsList
// update the server with the current pairings
// ============================================================================
function updateServerPairingsList ()
{
sr_api.sendMessage(localConfig.DataCenterSocket,
sr_api.ServerPacket("ExtensionMessage",
serverConfig.extensionname,
sr_api.ExtensionPacket(
"UpdateUserPairings",
serverConfig.extensionname,
usertriggerslist,
"",
"autopilot"),
"",
"autopilot"
),
);
}
// ============================================================================
// FUNCTION: receivedUserPairings
// ============================================================================
function receivedUserPairings (data)
{
if (data != null
&& typeof (data) != "undefined"
&& data != ""
&& Object.keys(data).length != 0)
{
usertriggerslist = structuredClone(data);
triggersandactions = structuredClone(data.macrotriggers)
receivedTrigger(data.macrotriggers)
// update the page with the new triggeroptions
populateGroupNamesDropdown();
addTriggerEntries();
addActionEntries();
populateTriggersTable();
}
}
// ============================================================================
// FUNCTION: EditPairingButton
// button on the page for users to edit the pairings
// ============================================================================
function EditPairingButton (event, g, i)
{
$("#editPairingModal").modal("show")
let editform = document.getElementById("updatePairingEditForm")
editform.innerHTML = ""
let pairing = usertriggerslist.pairings[i]
// Create title
editform.appendChild(createInputElement('triggerpairingidinputfield', 'triggerpairingid', 'hidden', i))
// start table
let table = document.createElement("table")
let tr = table.insertRow()
let td = tr.insertCell()
// group selection box
let selectgroup = createSelectGroup("triggerExtensionPairingModalGroupName", "selectpicker btn btn-secondary", "triggerExtensionPairingModalGroupName", "Select new group")
selectgroup.setAttribute("data-style", "btn-danger")
for (let i = 0; i < usertriggerslist.groups.length; i++)
{
var selectoption = createSelectOption(usertriggerslist.groups[i].name, usertriggerslist.groups[i].name, "btn btn-secondary", usertriggerslist.groups[i].name, usertriggerslist.groups[i].name)
selectgroup.appendChild(selectoption)
if (usertriggerslist.groups[i].name == g)
selectgroup.value = g
}
td.appendChild(selectgroup)
// start trigger table
tr = table.insertRow().insertCell().outerHTML = "<Th colspan='3'><H3>Trigger</h3></Th>"
tr = table.insertRow().insertCell().outerHTML = "<Th colspan='3'>" + pairing.trigger.extension + " -> " + pairing.trigger.messagetype.replace("trigger_", "") + "</Th>"
for (let j = 0; j < pairing.trigger.data.length; j++)
{
tr = table.insertRow()
for (let item in pairing.trigger.data[j])
{
if (item.indexOf("MATCHER_") != 0)
{
// add the field name
tr.insertCell().innerHTML = item
// add the field value
tr.insertCell().appendChild(createInputElement("triggerExtensionEditTriggerParameters" + item, "triggerExtensionEditTriggerParameters" + item, "text", pairing.trigger.data[j][item]))
td = tr.insertCell()
//start of matcher box div
var outer_div = document.createElement("div")
outer_div.classList = 'col-2'
td.appendChild(outer_div)
// select group matcher
var selectmatcher = createSelectGroup("triggerExtensionEditTriggerParametersMATCHER_" + item, "selectpicker btn btn-secondary", "triggerExtensionEditTriggerParametersMATCHER_" + item, "Select match type")
selectmatcher.setAttribute("data-style", "btn-danger")
outer_div.appendChild(selectmatcher)
var matchdiv = document.createElement("div")
matchdiv.classList = 'form-group'
outer_div.appendChild(matchdiv)
// add the options to the matcher group
var selectoption_1 = createSelectOption("Exact", "Exact", 'form-control', '1', "Exact Match")
var selectoption_2 = createSelectOption("Anywhere", "Anywhere", 'form-control', '2', "Anywhere")
var selectoption_3 = createSelectOption("Start of line", "Start of line", 'form-control', '3', "Start of line")
var selectoption_4 = createSelectOption("Doesn't match", "Doesn't match", 'form-control', '4', "Doesn't match")
var selectoption_5 = createSelectOption("Specific word", "Match a specific whole word", 'form-control', '5', "Match whole word")
selectmatcher.appendChild(selectoption_1)
selectmatcher.appendChild(selectoption_2)
selectmatcher.appendChild(selectoption_3)
selectmatcher.appendChild(selectoption_4)
selectmatcher.appendChild(selectoption_5)
// set the option to the current matcher type
let temp = pairing.trigger.data.find((o) => typeof (o["MATCHER_" + item]) != "undefined")
if (temp)
selectmatcher.value = temp["MATCHER_" + item]
}
}
}
tr = table.insertRow()
tr.insertCell().innerHTML = "cooldown"
tr.insertCell().appendChild(createInputElement("triggerExtensionEditTriggerParameterscooldown", "triggerExtensionEditTriggerParameterscooldown", "text", pairing.trigger.cooldown))
// start action table
tr = table.insertRow().insertCell().outerHTML = "<Th colspan='3'><H3>Action</h3></Th>"
tr = table.insertRow().insertCell().outerHTML = "<Th colspan='3'>" + pairing.action.extension + " -> " + pairing.action.messagetype.replace("action_", "") + "</Th>"
for (let j = 0; j < pairing.action.data.length; j++)
{
tr = table.insertRow()
for (let item in pairing.action.data[j])
{
if (item.indexOf("MATCHER_") != 0)
{
// add the field name
tr.insertCell().innerHTML = item
// add the field value
tr.insertCell().appendChild(createInputElement("actionExtensionEditActionParameters" + item, "actionExtensionEditActionParameters" + item, "text", pairing.action.data[j][item]))
td = tr.insertCell()
//start of matcher box div
outer_div = document.createElement("div")
outer_div.classList = 'col-2'
td.appendChild(outer_div)
// select group matcher
selectmatcher = createSelectGroup("actionExtensionEditActionParametersMATCHER_" + item, "selectpicker btn btn-secondary", "actionExtensionEditActionParametersMATCHER_" + item, "Select match type")
selectmatcher.setAttribute("data-style", "btn-danger")
outer_div.appendChild(selectmatcher)
matchdiv = document.createElement("div")
matchdiv.classList = 'form-group'
outer_div.appendChild(matchdiv)
// add the options to the matcher group
selectoption_1 = createSelectOption("Exact", "Exact", 'form-control', '1', "Exact Match")
selectoption_2 = createSelectOption("Anywhere", "Anywhere", 'form-control', '2', "Anywhere")
selectoption_3 = createSelectOption("Start of line", "Start of line", 'form-control', '3', "Start of line")
selectoption_4 = createSelectOption("Doesn't match", "Doesn't match", 'form-control', '4', "Doesn't match")
selectoption_5 = createSelectOption("Any word", "Match a specific whole word", 'form-control', '5', "Match whole word")
selectmatcher.appendChild(selectoption_1)
selectmatcher.appendChild(selectoption_2)
selectmatcher.appendChild(selectoption_3)
selectmatcher.appendChild(selectoption_4)
selectmatcher.appendChild(selectoption_5)
// set the option to the current matcher type
let temp = pairing.action.data.find((o) => typeof (o["MATCHER_" + item]) != "undefined")
if (temp)
selectmatcher.value = temp["MATCHER_" + item]
}
}
}
editform.appendChild(table)
}
// ============================================================================
// FUNCTION: createInputElement
// ============================================================================
function createInputElement (id, name, type, value)
{
var i = document.createElement("input");
i.id = id
i.type = type
i.name = name
i.value = value
return i
}
// ============================================================================
// FUNCTION: createTableElement
// ============================================================================
function createTableElement (id, type, name, value)
{
var i = document.createElement("table");
i.type = type
i.name = name
i.value = value
i.id = id
return i
}
// ============================================================================
// FUNCTION: createSelectGroup
// ============================================================================
function createSelectGroup (id, classlist, name, title)
{
var i = document.createElement("select")
i.id = id
i.classList = classlist
i.name = name
i.title = title
return i
}
// ============================================================================
// FUNCTION: createSelectOption
// ============================================================================
function createSelectOption (name, data, classList, value, innerHTML)
{
var i = document.createElement("option")
i.name = name
i.data = data
i.classList = classList
i.value = value
i.innerHTML = innerHTML
return i
}
// ============================================================================
// FUNCTION: createSelectOption
// ============================================================================
function createAnchorButton (classList, href, title, image, width = "40px")
{
//' style='padding:0px' title='Delete Group'>"
var i = document.createElement("a")
var j = document.createElement("img")
i.appendChild(j)
i.role = "button"
i.classList = classList
i.href = href
i.style.padding = "0px"
i.title = title
i.id = title + "_link";
j.id = title + "_image";
j.alt = title
j.src = image
j.style.width = width
return i
}
// ============================================================================
// FUNCTION: UpdatePairingButton
// Update the pairing buttons
// ============================================================================
function UpdatePairingButton (event)
{
let triggerpattern = "triggerExtensionEditTriggerParameters"
let actionpattern = "actionExtensionEditActionParameters"
// get the modal data as an array
let fieldsAsArray = $('#updatePairingEditForm').serializeArray();
// convert our array of objects into a more usable object
let fieldsAsObject = fieldsAsArray.reduce((obj, item) => (obj[item.name] = item.value, obj), {});
let pairingID = fieldsAsObject.triggerpairingid
if (pairingID == undefined)
alert("Trigger/Action pair not found")
for (const [key, value] of Object.entries(fieldsAsObject))
{
// we have a trigger variable
if (key.indexOf(triggerpattern) == 0)
{
let field = key.replace(triggerpattern, "")
for (let i = 0; i < usertriggerslist.pairings[pairingID].trigger.data.length; i++)
{
if (usertriggerslist.pairings[pairingID].trigger.data[i][field] != undefined)
usertriggerslist.pairings[pairingID].trigger.data[i][field] = value
}
if (key.indexOf("triggerExtensionEditTriggerParameterscooldown") == 0)
usertriggerslist.pairings[pairingID].trigger.cooldown = value
}
// we have an action variable
else if (key.indexOf(actionpattern) == 0)
{
let field = key.replace(actionpattern, "")
for (let i = 0; i < usertriggerslist.pairings[pairingID].action.data.length; i++)
{
if (usertriggerslist.pairings[pairingID].action.data[i][field] != undefined)
usertriggerslist.pairings[pairingID].action.data[i][field] = value
}
//usertriggerslist.pairings[pairingID].action.data[field] = value
}
else if (key.indexOf("triggerExtensionPairingModalGroupName") == 0)
{
usertriggerslist.pairings[pairingID].group = value;
}
else if (key.indexOf("triggerpairingid") == 0)
{
//ignore the id as we have already used it
}
else
console.log("Error: Skipping ", "'" + key.indexOf("actionExtensionEditActionParametersprofile") + "'", "'" + key + "'", "=", value)
}
$("#editPairingModal").modal("hide")
updateServerPairingsList();
}
// ============================================================================
// FUNCTION: setMacroImageTag
// click handler for imagepicker
// ============================================================================
function setMacroImageTag (name)
{
document.getElementById("macroimagename").value = name
document.getElementById("imageplaceholder").innerHTML = "<img src='/autopilot/images/deckicons/" + name + "'>"
$("#imagepicker").modal("hide")
}
// ============================================================================
// FUNCTION: sortByKey
// sorts an array of objects based on a key
// ============================================================================
function sortByKey (array)
{
const ordered = Object.keys(array).sort().reduce(
(obj, key) =>
{
obj[key] = array[key];
return obj;
},
{}
);
//console.log(array)
return ordered;
}
// ============================================================================
// FUNCTION: downloadServerDataClicked
// ============================================================================
function downloadServerDataClicked ()
{
// User has clicked on the download Server Data Button
try
{
RequestServerDataFile();
}
catch (err)
{
console.log("downloadServerDataClicked Error:", err, err.message)
}
}
// ============================================================================
// FUNCTION: RequestServerDataFile
// ============================================================================
function RequestServerDataFile ()
{
// request the saved data from the server (callback will go to downloadServerDataFileReceived below)
sr_api.sendMessage(
localConfig.DataCenterSocket,
sr_api.ServerPacket(
"ExtensionMessage",
serverConfig.extensionname,
sr_api.ExtensionPacket(
"RequestServerDataFile",
serverConfig.extensionname,
"",
"",
"autopilot"
),
"",
"autopilot"
));
}
// ============================================================================
// FUNCTION: downloadServerDataFileReceived
// ============================================================================
function downloadServerDataFileReceived (data)
{
try
{ // should only be called via a users request to download the server file after
// we have received the file from the server
let fileToDownload = JSON.stringify(data, null, 2);
var a = document.createElement("a");
var file = new Blob([fileToDownload], { type: "application/json" });
a.href = URL.createObjectURL(file);
a.download = "StreamRoller_autopilotBackup_" + getFileNameDateString() + ".json";
a.click();
}
catch (err)
{
console.log("downloadServerDataFileReceived Error:", err, err.message)
}
}
// ============================================================================
// FUNCTION: uploadServerDataClicked
// ============================================================================
function uploadServerDataClicked ()
{
try
{
// user has selected a file to upload to the server
var file = document.getElementById('AutoPilotDatFileUploadElement').files[0];
if (file)
{
var reader = new FileReader();
reader.readAsText(file, "application/json");
reader.onload = function (evt)
{
let userDataFile = JSON.parse(evt.target.result);
// some basic sanity checks.
if (userDataFile && userDataFile != ""
&& userDataFile.__version__)
{
console.log("userDataFile.__version__", userDataFile.__version__);
document.getElementById('AutoPilotDatFileUploadMessage').innerHTML = "Processing";
processingAnimation('AutoPilotDatFileUploadMessage');
saveUserDataFile(userDataFile)
}
else
{
document.getElementById('AutoPilotDatFileUploadMessage').innerHTML = "Error reading file, is it the correct format"
}
}
} else
document.getElementById('AutoPilotDatFileUploadMessage').innerHTML = "Error reading file, is it the correct format"
}
catch (err)
{
console.log("uploadServerDataClicked Error:", err, err.message)
}
}
// ============================================================================
// FUNCTION: saveUserDataFile
// ============================================================================
function saveUserDataFile (userDataFile)
{
// request the saved data from the server (callback will go to downloadServerDataFileReceived below)
sr_api.sendMessage(
localConfig.DataCenterSocket,
sr_api.ServerPacket(
"ExtensionMessage",
serverConfig.extensionname,
sr_api.ExtensionPacket(
"userRequestSaveDataFile",
serverConfig.extensionname,
userDataFile,
"",
"autopilot"
),
"",
"autopilot"
));
}
// ============================================================================
// FUNCTION: downloadServerDataFileReceivedResponse
// ============================================================================
function downloadServerDataFileReceivedResponse (data)
{
try
{
// clear the animation if we have it running
if (processingTextAnimation_handle['AutoPilotDatFileUploadMessage'])
{
clearInterval(processingTextAnimation_handle['AutoPilotDatFileUploadMessage'])
processingTextAnimation_handle['AutoPilotDatFileUploadMessage'] = null;
}
document.getElementById('AutoPilotDatFileUploadMessage').innerHTML = data.response;
}
catch (err)
{
console.log("downloadServerDataFileReceivedResponse Error:", err, err.message)
}
}
// ============================================================================
// FUNCTION: processingAnimation
// ============================================================================
function processingAnimation (element)
{
var count = 0;
// stop any previous timer we may have had for this element
if (processingTextAnimation_handle[element])
clearInterval(processingTextAnimation_handle[element])
processingTextAnimation_handle[element] = setInterval(function ()
{
// stop after 5 minutes if this keeps running
if (count > 300)
clearInterval(processingTextAnimation_handle[element]);
count++;
var dots = new Array(count % 10).join('.');
document.getElementById(element).innerHTML = "Processing" + dots;
}, 1000);
}
// ============================================================================
// FUNCTION: getFileNameDateString
// ============================================================================
function getFileNameDateString ()
{
// returns a suitable date string for appending to a filename
const date = new Date();
const year = date.getFullYear();
const month = `${date.getMonth() + 1}`.padStart(2, '0');
const day = `${date.getDate()}`.padStart(2, '0');
const hours = `${date.getHours()}`.padStart(2, '0');
const minutes = `${date.getMinutes()}`.padStart(2, '0');
const seconds = `${date.getSeconds()}`.padStart(2, '0');
return `${year}_${month}_${day}-${hours}_${minutes}_${seconds}`
}