mirror of
				https://gitlab.nic.cz/turris/reforis/foris-js.git
				synced 2025-10-30 22:20:31 +01:00 
			
		
		
		
	Merge branch 'ws-unsubscription' into 'dev'
Add WS unsubscribtion. See merge request turris/reforis/foris-js!53
This commit is contained in:
		| @@ -20,14 +20,16 @@ import { useForisModule, useForm } from "../hooks"; | ||||
| import { STATES as SUBMIT_BUTTON_STATES, SubmitButton } from "./SubmitButton"; | ||||
|  | ||||
| ForisForm.propTypes = { | ||||
|     /** WebSocket object see `scr/common/WebSockets.js`. */ | ||||
|     /** Optional WebSocket object. See `scr/common/WebSockets.js`. | ||||
|      * `forisConfig.wsModule` should be specified when it's passed. | ||||
|      *  */ | ||||
|     ws: PropTypes.object, | ||||
|     /** Foris configuration object. See usage in main components. */ | ||||
|     forisConfig: PropTypes.shape({ | ||||
|         /** reForis Flask aplication API endpoint from `src/common/API.js`. */ | ||||
|         endpoint: PropTypes.string.isRequired, | ||||
|         /** `foris-controller` module name to be used via WebSockets. | ||||
|          *  If it's not passed then WebSockets aren't used | ||||
|          *  It can be use only with `ws` prop. | ||||
|          * */ | ||||
|         wsModule: PropTypes.string, | ||||
|         /** `foris-controller` action name to be used via WebSockets. | ||||
| @@ -49,6 +51,17 @@ ForisForm.propTypes = { | ||||
|     children: PropTypes.node.isRequired, | ||||
|     /** Optional override of form submit callback */ | ||||
|     onSubmitOverridden: PropTypes.func, | ||||
|  | ||||
|     // eslint-disable-next-line react/no-unused-prop-types | ||||
|     customWSProp(props) { | ||||
|         const wsModuleIsSpecified = !!(props.forisConfig && props.forisConfig.wsModule); | ||||
|         if (props.ws && !wsModuleIsSpecified) { | ||||
|             return new Error("forisConfig.wsModule should be specified when ws object is passed."); | ||||
|         } | ||||
|         if (!props.ws && wsModuleIsSpecified) { | ||||
|             return new Error("forisConfig.wsModule is specified without passing ws object."); | ||||
|         } | ||||
|     }, | ||||
| }; | ||||
|  | ||||
| ForisForm.defaultProps = { | ||||
|   | ||||
| @@ -61,9 +61,36 @@ export class WebSockets { | ||||
|         return this; | ||||
|     } | ||||
|  | ||||
|     subscribe(params) { | ||||
|     subscribe(module) { | ||||
|         this.waitForConnection(() => { | ||||
|             this.send("subscribe", params); | ||||
|             this.send("subscribe", module); | ||||
|         }); | ||||
|         return this; | ||||
|     } | ||||
|  | ||||
|     unbind(module, action, callback) { | ||||
|         const callbacks = this.callbacks[module][action]; | ||||
|  | ||||
|         const index = callbacks.indexOf(callback); | ||||
|         if (index !== -1) { | ||||
|             callbacks.splice(index, 1); | ||||
|         } | ||||
|  | ||||
|         if (callbacks.length === 0) { | ||||
|             delete this.callbacks[module][action]; | ||||
|         } | ||||
|  | ||||
|         if (Object.keys(this.callbacks[module]).length === 0) { | ||||
|             this.unsubscribe(module); | ||||
|         } | ||||
|  | ||||
|         return this; | ||||
|     } | ||||
|  | ||||
|     unsubscribe(module) { | ||||
|         this.waitForConnection(() => { | ||||
|             this.send("unsubscribe", module); | ||||
|             delete this.callbacks[module]; | ||||
|         }); | ||||
|         return this; | ||||
|     } | ||||
| @@ -82,15 +109,15 @@ export class WebSockets { | ||||
|         let chain; | ||||
|         try { | ||||
|             chain = this.callbacks[json.module][json.action]; | ||||
|         } catch (e) { | ||||
|             if (e instanceof TypeError) { | ||||
|                 console.log(`Callback for this message wasn't found:${e.data}`); | ||||
|             } else throw e; | ||||
|         } catch (error) { | ||||
|             if (error instanceof TypeError) { | ||||
|                 console.log(`Callback for this message wasn't found:${error.data}`); | ||||
|             } else throw error; | ||||
|         } | ||||
|  | ||||
|         if (typeof chain === "undefined") return; | ||||
|  | ||||
|         for (let i = 0; i < chain.length; i++) chain[i](json); | ||||
|         chain.forEach((callback) => callback(json)); | ||||
|     } | ||||
|  | ||||
|     close() { | ||||
|   | ||||
| @@ -11,12 +11,21 @@ export function useWSForisModule(ws, module, action = "update_settings") { | ||||
|     const [data, setData] = useState(null); | ||||
|  | ||||
|     useEffect(() => { | ||||
|         if (ws && module) { | ||||
|             ws.subscribe(module) | ||||
|                 .bind(module, action, (msg) => { | ||||
|         // Sometimes we want to disable this hook if WS is not passed. We can't make conditional | ||||
|         // hooks, but we can disable it here. It's used especially in ForisForm when a module | ||||
|         // doesn't present any WS endpoint. | ||||
|         if (!ws) return; | ||||
|  | ||||
|         function callback(msg) { | ||||
|             setData(msg.data); | ||||
|                 }); | ||||
|         } | ||||
|  | ||||
|         ws.subscribe(module) | ||||
|             .bind(module, action, callback); | ||||
|  | ||||
|         return () => { | ||||
|             ws.unbind(module, action, callback); | ||||
|         }; | ||||
|     }, [action, module, ws]); | ||||
|  | ||||
|     return [data]; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user