diff --git a/src/matrix-leave-room.js b/src/matrix-leave-room.js index daebb33..b46f8d7 100644 --- a/src/matrix-leave-room.js +++ b/src/matrix-leave-room.js @@ -44,6 +44,7 @@ module.exports = function(RED) { try { node.log("Leaving room " + msg.topic); node.server.matrixClient.leave(msg.topic); + node.server.matrixClient.store.removeRoom(msg.topic); node.send([msg, null]); } catch(e) { node.error("Failed to leave room " + msg.topic + ": " + e, msg); diff --git a/src/matrix-room-state-events.html b/src/matrix-room-state-events.html index 26c7be1..08395dc 100644 --- a/src/matrix-room-state-events.html +++ b/src/matrix-room-state-events.html @@ -69,7 +69,7 @@
dynamic string|object
-
You configure what room state events to output in the node configuration. m.room.name, m.room.avatar, and m.room.guest_access will come back as strings otherwise you will get the full content object of the event (find this by referencing the Matrix Client-Server docs)
+
You configure what room state events to output in the node configuration. m.room.name, m.room.avatar, and m.room.guest_access will come back as strings otherwise you will get the full content object of the event (find this by referencing the Matrix Client-Server docs). 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.
@@ -156,15 +156,17 @@ .appendTo(row2_1) .typedInput({ 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 = $('').appendTo(row2_2); + var lsLabel = $('').appendTo(row2_2); + var localStorageEl = $('').appendTo(lsLabel); + $('').text("Fetch from local storage").appendTo(lsLabel); propValInput.on("change", function(evt,type,val) { 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({ @@ -259,6 +261,7 @@ .appendTo(row4); let propertyValue = null; + let localStorageEl = null; let fromValue = null; let toValue = null; @@ -277,12 +280,18 @@ if (!propertyValue) { var parts = createPropertyValue(row2_1, row2_2, type); propertyValue = parts[0]; + localStorageEl = parts[1]; } 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'); row2.show(); + if(type === 'get') { + localStorageEl.parent().show(); + } else { + localStorageEl.parent().hide(); + } row3.hide(); row4.hide(); }); @@ -292,7 +301,14 @@ if (rule.t === "set" || rule.t === "get") { var parts = createPropertyValue(row2_1, row2_2, rule.t, rule.tot); propertyValue = parts[0]; + localStorageEl = parts[1]; propertyValue.typedInput('value',rule.to); + localStorageEl.prop("checked", !!rule.ls); + if(rule.t === 'get') { + localStorageEl.show(); + } else { + localStorageEl.hide(); + } } selectField.change(); container[0].appendChild(fragment); @@ -319,6 +335,10 @@ to:rule.find(".node-input-rule-property-value").typedInput('value'), 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); }); }, diff --git a/src/matrix-room-state-events.js b/src/matrix-room-state-events.js index e8f2a1f..bd6025c 100644 --- a/src/matrix-room-state-events.js +++ b/src/matrix-room-state-events.js @@ -226,23 +226,33 @@ module.exports = function(RED) { value = cachedGetters[rule.p]; } else { try { - // we may want to fetch from local storage in the future, this is how to do that - // const room = this.getRoom(roomId); - // const ev = room.currentState.getStateEvents(EventType.RoomEncryption, ""); - value = await node.server.matrixClient.getStateEvent(msg.topic, rule.p, ""); - switch(rule.p) { - case "m.room.name": - value = value?.name - break; - case "m.room.topic": - value = value?.topic - break; - case "m.room.avatar": - value = value?.url - break; - case "m.room.guest_access": - value = value?.guest_access; - break; + if(rule.ls) { + // we opted to lookup from local storage, will fallback to server if necessary + 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, ""); + if(value) { + // normalize some simpler events for easier access + switch(rule.p) { + case "m.room.name": + value = value?.name + break; + case "m.room.topic": + value = value?.topic + break; + case "m.room.avatar": + value = value?.url + break; + case "m.room.guest_access": + value = value?.guest_access; + break; + } + } } setToValue(value, rule); } catch(e) { diff --git a/src/matrix-server-config.js b/src/matrix-server-config.js index 920f3af..59c9e2a 100644 --- a/src/matrix-server-config.js +++ b/src/matrix-server-config.js @@ -174,6 +174,13 @@ module.exports = function(RED) { node.on('close', function(done) { stopClient(); + if(node.globalAccess) { + try { + node.context().global.delete('matrixClient["'+node.userId+'"]'); + } catch(e){ + node.error(e.message, {}); + } + } done(); });