Skip to content

Commit 69faee5

Browse files
authored
Merge pull request #1572 from bartbutenaers/ui-switch-sync-issue
ui-switch: sync issue
2 parents 6e66c17 + 1d95f57 commit 69faee5

File tree

3 files changed

+17
-6
lines changed

3 files changed

+17
-6
lines changed

docs/contributing/guides/registration.md

+9-2
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@ Similar to `onAction`, when used as a boolean, this flag will trigger the defaul
100100
2. Appends any `msg.topic` defined on the node config
101101
3. Runs `evts.beforeSend()` _(if provided)_
102102
4. Store the most recent message on the widget under the `._msg` property which will contain the latest state/value of the widget
103-
5. Sends the `msg` onwards to any connected nodes
103+
5. Pushes a `widget-sync` event to synchronize the widgets in all clients.
104+
6. Sends the `msg` onwards to any connected nodes
104105

105106
#### Custom `onChange` Handler
106107

@@ -111,8 +112,10 @@ Alternatively, you can override this default behaviour by providing a custom `on
111112
* Handle the input from the widget
112113
* @param {object} msg - the last known msg received (prior to this new value)
113114
* @param {boolean} value - the updated value sent by the widget
115+
* @param {Socket} conn - socket.io socket connecting to the server
116+
* @param {String} id - widget id sending the action
114117
*/
115-
onChange: async function (msg, value) {
118+
onChange: async function (msg, value, conn, id) {
116119
// ensure we have latest instance of the widget's node
117120
const wNode = RED.nodes.getNode(node.id)
118121

@@ -127,6 +130,10 @@ onChange: async function (msg, value) {
127130
const off = RED.util.evaluateNodeProperty(config.offvalue, config.offvalueType, wNode)
128131
msg.payload = value ? on : off
129132

133+
// sync this change to all clients with the same widget
134+
const exclude = [conn.id]
135+
base.emit('widget-sync:' + id, msg, node, exclude)
136+
130137
// simulate Node-RED node receiving an input
131138
wNode.send(msg)
132139
}

nodes/config/ui_base.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -650,7 +650,7 @@ module.exports = function (RED) {
650650

651651
msg = addConnectionCredentials(RED, msg, conn, n)
652652

653-
async function defaultHandler (msg, value) {
653+
async function defaultHandler (msg, value, conn, id) {
654654
if (typeof (value) === 'object' && value !== null && hasProperty(value, 'payload')) {
655655
msg.payload = value.payload
656656
} else {
@@ -673,7 +673,7 @@ module.exports = function (RED) {
673673
// Most of the time, we can just use this default handler,
674674
// but sometimes a node needs to do something specific (e.g. ui-switch)
675675
const handler = typeof (widgetEvents.onChange) === 'function' ? widgetEvents.onChange : defaultHandler
676-
await handler(msg, value)
676+
await handler(msg, value, conn, id)
677677
} catch (error) {
678678
console.log(error)
679679
let errorHandler = typeof (widgetEvents.onError) === 'function' ? widgetEvents.onError : null

nodes/widgets/ui_switch.js

+6-2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ module.exports = function (RED) {
1414

1515
// which group are we rendering this widget
1616
const group = RED.nodes.getNode(config.group)
17+
const base = group.getBase()
1718

1819
// retrieve the assigned on/off values
1920
const on = RED.util.evaluateNodeProperty(config.onvalue, config.onvalueType, node)
@@ -27,7 +28,7 @@ module.exports = function (RED) {
2728
const evts = {
2829
// runs on UI interaction
2930
// value = true | false from the ui-switch
30-
onChange: async function (msg, value) {
31+
onChange: async function (msg, value, conn, id) {
3132
msg.payload = value ? on : off
3233

3334
if (config.topic || config.topicType) {
@@ -42,7 +43,10 @@ module.exports = function (RED) {
4243
shape: 'ring',
4344
text: value ? states[1] : states[0]
4445
})
45-
datastore.save(group.getBase(), node, msg)
46+
datastore.save(base, node, msg)
47+
48+
const exclude = [conn.id] // sync this change to all clients with the same widget
49+
base.emit('widget-sync:' + id, msg, node, exclude) // let all other connect clients now about the value change
4650

4751
// simulate Node-RED node receiving an input
4852
node.send(msg)

0 commit comments

Comments
 (0)