- #97 added option to fetch state event from local storage and fallback to server if necessary (allows for faster lookups and gives the full event object with information about when/who created it, etc)

- #97 remove num, bool, bin, and data from being options you can set to a state event (currently only objects and sometimes strings are allowed)
- Updated Leave Room node so it deletes the room from local storage
- Updated server config node so it deletes the matrix client from storage during shutdown (possibly solution to #94)
This commit is contained in:
Skylar Sadlier 2023-10-22 00:29:12 -06:00
parent fd605005d1
commit 1859696122
4 changed files with 60 additions and 22 deletions

View File

@ -44,6 +44,7 @@ module.exports = function(RED) {
try { try {
node.log("Leaving room " + msg.topic); node.log("Leaving room " + msg.topic);
node.server.matrixClient.leave(msg.topic); node.server.matrixClient.leave(msg.topic);
node.server.matrixClient.store.removeRoom(msg.topic);
node.send([msg, null]); node.send([msg, null]);
} catch(e) { } catch(e) {
node.error("Failed to leave room " + msg.topic + ": " + e, msg); node.error("Failed to leave room " + msg.topic + ": " + e, msg);

View File

@ -69,7 +69,7 @@
<dt class="optional">dynamic <dt class="optional">dynamic
<span class="property-type">string|object</span> <span class="property-type">string|object</span>
</dt> </dt>
<dd> You configure what room state events to output in the node configuration. <code style="white-space: normal;">m.room.name</code>, <code style="white-space: normal;">m.room.avatar</code>, and <code style="white-space: normal;">m.room.guest_access</code> will come back as strings otherwise you will get the full content object of the event (find this by referencing the <a href="https://spec.matrix.org/latest/client-server-api" target="_blank">Matrix Client-Server docs</a>)</dd> <dd> You configure what room state events to output in the node configuration. <code style="white-space: normal;">m.room.name</code>, <code style="white-space: normal;">m.room.avatar</code>, and <code style="white-space: normal;">m.room.guest_access</code> will come back as strings otherwise you will get the full content object of the event (find this by referencing the <a href="https://spec.matrix.org/latest/client-server-api" target="_blank">Matrix Client-Server docs</a>). Additionally there is a setting when configuring a getter called "Fetch from local storage" that if enabled will search the local storage for the room and try to fetch the state event that way and fallback to hitting the server if that isn't possible.</dd>
</li> </li>
</ol> </ol>
</script> </script>
@ -156,15 +156,17 @@
.appendTo(row2_1) .appendTo(row2_1)
.typedInput({ .typedInput({
default: defaultType || (type === 'set' ? 'str' : 'msg'), default: defaultType || (type === 'set' ? 'str' : 'msg'),
types: (type === 'set' ? ['msg','flow','global','str','num','bool','json','bin','date','jsonata'] : ['msg', 'flow', 'global']) types: (type === 'set' ? ['msg','flow','global','str','json','jsonata'] : ['msg', 'flow', 'global'])
}); });
var dcLabel = $('<label style="padding-left: 130px;"></label>').appendTo(row2_2); var lsLabel = $('<label style="padding-left: 130px;"></label>').appendTo(row2_2);
var localStorageEl = $('<input type="checkbox" class="node-input-rule-property-localStorage" style="width: auto; margin: 0 6px 0 0">').appendTo(lsLabel);
$('<span>').text("Fetch from local storage").appendTo(lsLabel);
propValInput.on("change", function(evt,type,val) { propValInput.on("change", function(evt,type,val) {
row2_2.toggle(type === "msg" || type === "flow" || type === "global" || type === "env"); row2_2.toggle(type === "msg" || type === "flow" || type === "global" || type === "env");
}) })
return [propValInput]; return [propValInput, localStorageEl];
} }
$('#node-input-rule-container').css('min-height','150px').css('min-width','450px').editableList({ $('#node-input-rule-container').css('min-height','150px').css('min-width','450px').editableList({
@ -259,6 +261,7 @@
.appendTo(row4); .appendTo(row4);
let propertyValue = null; let propertyValue = null;
let localStorageEl = null;
let fromValue = null; let fromValue = null;
let toValue = null; let toValue = null;
@ -277,12 +280,18 @@
if (!propertyValue) { if (!propertyValue) {
var parts = createPropertyValue(row2_1, row2_2, type); var parts = createPropertyValue(row2_1, row2_2, type);
propertyValue = parts[0]; propertyValue = parts[0];
localStorageEl = parts[1];
} else { } else {
propertyValue.typedInput('types', (type === 'set' ? ['msg','flow','global','str','num','bool','json','bin','date','jsonata','env'] : ['msg', 'flow', 'global'])); propertyValue.typedInput('types', (type === 'set' ? ['msg','flow','global','str','json','jsonata'] : ['msg', 'flow', 'global']));
} }
propertyValue.typedInput('show'); propertyValue.typedInput('show');
row2.show(); row2.show();
if(type === 'get') {
localStorageEl.parent().show();
} else {
localStorageEl.parent().hide();
}
row3.hide(); row3.hide();
row4.hide(); row4.hide();
}); });
@ -292,7 +301,14 @@
if (rule.t === "set" || rule.t === "get") { if (rule.t === "set" || rule.t === "get") {
var parts = createPropertyValue(row2_1, row2_2, rule.t, rule.tot); var parts = createPropertyValue(row2_1, row2_2, rule.t, rule.tot);
propertyValue = parts[0]; propertyValue = parts[0];
localStorageEl = parts[1];
propertyValue.typedInput('value',rule.to); propertyValue.typedInput('value',rule.to);
localStorageEl.prop("checked", !!rule.ls);
if(rule.t === 'get') {
localStorageEl.show();
} else {
localStorageEl.hide();
}
} }
selectField.change(); selectField.change();
container[0].appendChild(fragment); container[0].appendChild(fragment);
@ -319,6 +335,10 @@
to:rule.find(".node-input-rule-property-value").typedInput('value'), to:rule.find(".node-input-rule-property-value").typedInput('value'),
tot:rule.find(".node-input-rule-property-value").typedInput('type') tot:rule.find(".node-input-rule-property-value").typedInput('type')
}; };
if (r.t === "get" && rule.find(".node-input-rule-property-localStorage").prop("checked")) {
r.ls = true;
}
node.rules.push(r); node.rules.push(r);
}); });
}, },

View File

@ -226,10 +226,18 @@ module.exports = function(RED) {
value = cachedGetters[rule.p]; value = cachedGetters[rule.p];
} else { } else {
try { try {
// we may want to fetch from local storage in the future, this is how to do that if(rule.ls) {
// const room = this.getRoom(roomId); // we opted to lookup from local storage, will fallback to server if necessary
// const ev = room.currentState.getStateEvents(EventType.RoomEncryption, ""); let room = node.server.matrixClient.getRoom(msg.topic);
if(room) {
value = await room.getLiveTimeline().getState("f").getStateEvents(rule.p, "");
}
}
if(!value) {
// fetch the latest state event by type from server
value = await node.server.matrixClient.getStateEvent(msg.topic, rule.p, ""); value = await node.server.matrixClient.getStateEvent(msg.topic, rule.p, "");
if(value) {
// normalize some simpler events for easier access
switch(rule.p) { switch(rule.p) {
case "m.room.name": case "m.room.name":
value = value?.name value = value?.name
@ -244,6 +252,8 @@ module.exports = function(RED) {
value = value?.guest_access; value = value?.guest_access;
break; break;
} }
}
}
setToValue(value, rule); setToValue(value, rule);
} catch(e) { } catch(e) {
getterErrors[rule.p] = e; getterErrors[rule.p] = e;

View File

@ -174,6 +174,13 @@ module.exports = function(RED) {
node.on('close', function(done) { node.on('close', function(done) {
stopClient(); stopClient();
if(node.globalAccess) {
try {
node.context().global.delete('matrixClient["'+node.userId+'"]');
} catch(e){
node.error(e.message, {});
}
}
done(); done();
}); });