@vention/machine-logic-ui-sdk 0.14.0 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.esm.js +118 -15
- package/package.json +2 -2
- package/src/index.d.ts +3 -0
- package/src/lib/components/virtual-keyboard/keyboard-layouts.d.ts +1 -0
- package/src/lib/mqtt/mqtt-context.d.ts +12 -0
- package/src/lib/mqtt/mqtt-types.d.ts +56 -0
- package/src/lib/mqtt/use-mqtt-subscription.d.ts +6 -0
package/index.esm.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx } from 'react/jsx-runtime';
|
|
2
2
|
import 'react-simple-keyboard/build/css/index.css';
|
|
3
|
-
import { useState, useRef, useEffect } from 'react';
|
|
3
|
+
import { useState, useRef, useEffect, createContext, useMemo, useContext } from 'react';
|
|
4
4
|
import Keyboard from 'react-simple-keyboard';
|
|
5
5
|
import mqtt from 'mqtt';
|
|
6
6
|
|
|
@@ -1815,6 +1815,20 @@ const VirtualKeyboard = () => {
|
|
|
1815
1815
|
const [keyboardLayoutName, setKeyboardLayoutName] = useState(KeyboardLayoutName.DEFAULT);
|
|
1816
1816
|
const [focusedTextInput, setFocusedTextInput] = useState();
|
|
1817
1817
|
const virtualKeyboardRef = useRef(null);
|
|
1818
|
+
const keyboardContainerRef = useRef(null);
|
|
1819
|
+
useEffect(function handleClickOutsideListeners() {
|
|
1820
|
+
function handleClickOutside(event) {
|
|
1821
|
+
if (keyboardContainerRef.current && !keyboardContainerRef.current.contains(event.target)) {
|
|
1822
|
+
setIsKeyboardVisible(false);
|
|
1823
|
+
}
|
|
1824
|
+
}
|
|
1825
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
1826
|
+
document.addEventListener("touchstart", handleClickOutside);
|
|
1827
|
+
return () => {
|
|
1828
|
+
document.removeEventListener("mousedown", handleClickOutside);
|
|
1829
|
+
document.removeEventListener("touchstart", handleClickOutside);
|
|
1830
|
+
};
|
|
1831
|
+
}, []);
|
|
1818
1832
|
useEffect(function showOrHideKeyboard() {
|
|
1819
1833
|
// The keyboard will appear/disappear on mouse down
|
|
1820
1834
|
// However, if the user is clicking something, like a submit button or the input itself, the mouse up will happen a few milliseconds after the keyboard is shown/hidden
|
|
@@ -1830,14 +1844,6 @@ const VirtualKeyboard = () => {
|
|
|
1830
1844
|
clearTimeout(showTimeout);
|
|
1831
1845
|
};
|
|
1832
1846
|
}
|
|
1833
|
-
const hideTimeout = setTimeout(() => {
|
|
1834
|
-
var _a;
|
|
1835
|
-
(_a = virtualKeyboardRef.current) === null || _a === void 0 ? void 0 : _a.destroy();
|
|
1836
|
-
setIsKeyboardVisible(false);
|
|
1837
|
-
}, effectDelayMs);
|
|
1838
|
-
return () => {
|
|
1839
|
-
clearTimeout(hideTimeout);
|
|
1840
|
-
};
|
|
1841
1847
|
}, [focusedTextInput]);
|
|
1842
1848
|
useEffect(function scrollInputIntoViewAfterKeyboardAppears() {
|
|
1843
1849
|
if (isKeyboardVisible && focusedTextInput !== undefined) {
|
|
@@ -1886,11 +1892,13 @@ const VirtualKeyboard = () => {
|
|
|
1886
1892
|
capture: true
|
|
1887
1893
|
});
|
|
1888
1894
|
return () => {
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1895
|
+
if (!isKeyboardVisible) {
|
|
1896
|
+
focusedTextInput.removeEventListener("blur", unsetFocusedTextInput, {
|
|
1897
|
+
capture: true
|
|
1898
|
+
});
|
|
1899
|
+
}
|
|
1892
1900
|
};
|
|
1893
|
-
}, [focusedTextInput, initialInputValue]);
|
|
1901
|
+
}, [focusedTextInput, initialInputValue, isKeyboardVisible]);
|
|
1894
1902
|
// Stay in sync with external changes originating from code or physical keyboard
|
|
1895
1903
|
useEffect(function syncExternalChangesFromCodeOrKeyboard() {
|
|
1896
1904
|
if (focusedTextInput === undefined) {
|
|
@@ -1909,6 +1917,9 @@ const VirtualKeyboard = () => {
|
|
|
1909
1917
|
focusedTextInput.addEventListener("click", updateKeyboardInput, {
|
|
1910
1918
|
capture: true
|
|
1911
1919
|
});
|
|
1920
|
+
focusedTextInput.addEventListener("touchstart", updateKeyboardInput, {
|
|
1921
|
+
capture: true
|
|
1922
|
+
});
|
|
1912
1923
|
focusedTextInput.addEventListener("touchend", updateKeyboardInput, {
|
|
1913
1924
|
capture: true
|
|
1914
1925
|
});
|
|
@@ -1919,6 +1930,9 @@ const VirtualKeyboard = () => {
|
|
|
1919
1930
|
focusedTextInput.removeEventListener("click", updateKeyboardInput, {
|
|
1920
1931
|
capture: true
|
|
1921
1932
|
});
|
|
1933
|
+
focusedTextInput.removeEventListener("touchstart", updateKeyboardInput, {
|
|
1934
|
+
capture: true
|
|
1935
|
+
});
|
|
1922
1936
|
focusedTextInput.removeEventListener("touchend", updateKeyboardInput, {
|
|
1923
1937
|
capture: true
|
|
1924
1938
|
});
|
|
@@ -1956,11 +1970,23 @@ const VirtualKeyboard = () => {
|
|
|
1956
1970
|
break;
|
|
1957
1971
|
}
|
|
1958
1972
|
};
|
|
1973
|
+
const handleKeyboardContainerEvents = event => {
|
|
1974
|
+
event.stopPropagation();
|
|
1975
|
+
if (event.cancelable && event.type === "mousedown") {
|
|
1976
|
+
event.preventDefault();
|
|
1977
|
+
}
|
|
1978
|
+
if (focusedTextInput) {
|
|
1979
|
+
focusedTextInput.focus();
|
|
1980
|
+
}
|
|
1981
|
+
};
|
|
1959
1982
|
if (!isKeyboardVisible) {
|
|
1960
1983
|
return null;
|
|
1961
1984
|
}
|
|
1962
1985
|
return jsx("div", {
|
|
1963
1986
|
id: "virtual_keyboard",
|
|
1987
|
+
ref: keyboardContainerRef,
|
|
1988
|
+
onMouseDown: handleKeyboardContainerEvents,
|
|
1989
|
+
onTouchStart: handleKeyboardContainerEvents,
|
|
1964
1990
|
children: jsx(Keyboard, {
|
|
1965
1991
|
keyboardRef: ref => {
|
|
1966
1992
|
virtualKeyboardRef.current = ref;
|
|
@@ -1989,7 +2015,6 @@ const VirtualKeyboard = () => {
|
|
|
1989
2015
|
layoutName: keyboardLayoutName,
|
|
1990
2016
|
preventMouseDownDefault: true,
|
|
1991
2017
|
stopMouseDownPropagation: true,
|
|
1992
|
-
autoUseTouchEvents: true,
|
|
1993
2018
|
display: KeyboardDisplay,
|
|
1994
2019
|
newLineOnEnter: true
|
|
1995
2020
|
})
|
|
@@ -2499,4 +2524,82 @@ const getMachineCodeProcessHttpUrl = processName => {
|
|
|
2499
2524
|
return `${executionEngineHttpUrl}/v1/machineCode/services/${processName}`;
|
|
2500
2525
|
};
|
|
2501
2526
|
|
|
2502
|
-
|
|
2527
|
+
const defaultContext = {
|
|
2528
|
+
client: null,
|
|
2529
|
+
connectionStatus: "disconnected"
|
|
2530
|
+
};
|
|
2531
|
+
const mqttContext = /*#__PURE__*/createContext(defaultContext);
|
|
2532
|
+
const MqttProvider = props => {
|
|
2533
|
+
const [connectionStatus, setConnectionStatus] = useState("disconnected");
|
|
2534
|
+
const [mqttClient, setMqttClient] = useState(null);
|
|
2535
|
+
const contextValue = useMemo(() => ({
|
|
2536
|
+
client: mqttClient,
|
|
2537
|
+
connectionStatus
|
|
2538
|
+
}), [mqttClient, connectionStatus]);
|
|
2539
|
+
useEffect(function mqttConnection() {
|
|
2540
|
+
function connectToMqtt() {
|
|
2541
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2542
|
+
const client = mqtt.connect(yield getMqttWsUrl());
|
|
2543
|
+
client.on("connect", () => {
|
|
2544
|
+
setConnectionStatus("connected");
|
|
2545
|
+
setMqttClient(client);
|
|
2546
|
+
});
|
|
2547
|
+
client.on("error", error => {
|
|
2548
|
+
setConnectionStatus("error");
|
|
2549
|
+
console.error("MQTT error:", error);
|
|
2550
|
+
});
|
|
2551
|
+
client.on("offline", () => {
|
|
2552
|
+
setConnectionStatus("disconnected");
|
|
2553
|
+
});
|
|
2554
|
+
client.on("end", () => {
|
|
2555
|
+
setConnectionStatus("disconnected");
|
|
2556
|
+
});
|
|
2557
|
+
return function cleanup() {
|
|
2558
|
+
setMqttClient(null);
|
|
2559
|
+
setConnectionStatus("disconnected");
|
|
2560
|
+
client.end();
|
|
2561
|
+
};
|
|
2562
|
+
});
|
|
2563
|
+
}
|
|
2564
|
+
connectToMqtt();
|
|
2565
|
+
}, []);
|
|
2566
|
+
return jsx(mqttContext.Provider, {
|
|
2567
|
+
value: contextValue,
|
|
2568
|
+
children: props.children
|
|
2569
|
+
});
|
|
2570
|
+
};
|
|
2571
|
+
|
|
2572
|
+
var MqttSandingTopics;
|
|
2573
|
+
(function (MqttSandingTopics) {
|
|
2574
|
+
MqttSandingTopics["SET_APP_STATE"] = "sandingMachineApp/setAppState";
|
|
2575
|
+
MqttSandingTopics["CALIBRATE"] = "sandingMachineApp/calibrate";
|
|
2576
|
+
MqttSandingTopics["STATE_APP"] = "sandingMachineApp/state/app";
|
|
2577
|
+
MqttSandingTopics["STATE_ROBOT"] = "sandingMachineApp/state/robot";
|
|
2578
|
+
MqttSandingTopics["STATE_STATION"] = "sandingMachineApp/state/station";
|
|
2579
|
+
MqttSandingTopics["CHANGE_SANDING_PAPER"] = "sandingMachineApp/state/changeSandingPaper";
|
|
2580
|
+
MqttSandingTopics["SANDING_PAPER_CHANGED"] = "sandingMachineApp/sandingPaperChanged";
|
|
2581
|
+
MqttSandingTopics["GET_INITIAL_STATE"] = "sandingMachineApp/getInitialState";
|
|
2582
|
+
MqttSandingTopics["NOTIFICATION_MESSAGES"] = "sandingMachineApp/notification/messages";
|
|
2583
|
+
})(MqttSandingTopics || (MqttSandingTopics = {}));
|
|
2584
|
+
|
|
2585
|
+
const useMqttSubscription = props => {
|
|
2586
|
+
const mqtt = useContext(mqttContext);
|
|
2587
|
+
const [message, setMessage] = useState();
|
|
2588
|
+
useEffect(function test() {
|
|
2589
|
+
var _a, _b;
|
|
2590
|
+
if (mqtt.connectionStatus !== "connected" || !mqtt.client) return;
|
|
2591
|
+
(_a = mqtt.client) === null || _a === void 0 ? void 0 : _a.subscribe(props.topic);
|
|
2592
|
+
// Using the on message is not optimal as for every subscription we will add a new listener
|
|
2593
|
+
// For the sake of simplicity we will keep it like this
|
|
2594
|
+
(_b = mqtt.client) === null || _b === void 0 ? void 0 : _b.on("message", (topic, message) => {
|
|
2595
|
+
if (topic === props.topic) setMessage(JSON.parse(message.toString()));
|
|
2596
|
+
});
|
|
2597
|
+
return function cleanup() {
|
|
2598
|
+
var _a;
|
|
2599
|
+
(_a = mqtt.client) === null || _a === void 0 ? void 0 : _a.unsubscribe(props.topic);
|
|
2600
|
+
};
|
|
2601
|
+
}, [mqtt, props.topic]);
|
|
2602
|
+
return message;
|
|
2603
|
+
};
|
|
2604
|
+
|
|
2605
|
+
export { MqttClient, MqttProvider, MqttSandingTopics, VirtualKeyboard, connectToMqttAndGetClient, getExecutionEngineHttpUrl, getMachineCodeProcessHttpUrl, getMqttWsUrl, isOnEdge, isTouchScreenDevice, mqttContext, useMqttSubscription };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vention/machine-logic-ui-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/VentionCo/machine-cloud.git"
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
},
|
|
12
12
|
"license": "MIT",
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"react-simple-keyboard": "3.
|
|
14
|
+
"react-simple-keyboard": "3.8.15",
|
|
15
15
|
"mqtt": "5.10.1"
|
|
16
16
|
},
|
|
17
17
|
"peerDependencies": {
|
package/src/index.d.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
1
|
export * from "./lib/components/virtual-keyboard/virtual-keyboard";
|
|
2
2
|
export * from "./lib/utils/machine-logic-ui-sdk-utils";
|
|
3
3
|
export * from "./lib/mqtt-browser/mqtt-client";
|
|
4
|
+
export * from "./lib/mqtt/mqtt-context";
|
|
5
|
+
export * from "./lib/mqtt/mqtt-types";
|
|
6
|
+
export * from "./lib/mqtt/use-mqtt-subscription";
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ReactNode } from "react";
|
|
2
|
+
import { MqttClient } from "mqtt";
|
|
3
|
+
interface MqttContext {
|
|
4
|
+
client: MqttClient | null;
|
|
5
|
+
connectionStatus: "connected" | "disconnected" | "error";
|
|
6
|
+
}
|
|
7
|
+
export declare const mqttContext: import("react").Context<MqttContext>;
|
|
8
|
+
interface Props {
|
|
9
|
+
children: ReactNode;
|
|
10
|
+
}
|
|
11
|
+
export declare const MqttProvider: (props: Props) => import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
export declare enum MqttSandingTopics {
|
|
2
|
+
SET_APP_STATE = "sandingMachineApp/setAppState",
|
|
3
|
+
CALIBRATE = "sandingMachineApp/calibrate",
|
|
4
|
+
STATE_APP = "sandingMachineApp/state/app",
|
|
5
|
+
STATE_ROBOT = "sandingMachineApp/state/robot",
|
|
6
|
+
STATE_STATION = "sandingMachineApp/state/station",
|
|
7
|
+
CHANGE_SANDING_PAPER = "sandingMachineApp/state/changeSandingPaper",
|
|
8
|
+
SANDING_PAPER_CHANGED = "sandingMachineApp/sandingPaperChanged",
|
|
9
|
+
GET_INITIAL_STATE = "sandingMachineApp/getInitialState",
|
|
10
|
+
NOTIFICATION_MESSAGES = "sandingMachineApp/notification/messages"
|
|
11
|
+
}
|
|
12
|
+
export type SandingApplicationState = "stop" | "start" | "home" | "freedrive";
|
|
13
|
+
export type SandingRobotState = "fault" | "ready";
|
|
14
|
+
type MqttSetAppStatePayload = {
|
|
15
|
+
state: SandingApplicationState;
|
|
16
|
+
};
|
|
17
|
+
type MqttCalibratePayload = object;
|
|
18
|
+
type MqttRobotStatePayload = {
|
|
19
|
+
state: SandingRobotState;
|
|
20
|
+
};
|
|
21
|
+
export type StationState = {
|
|
22
|
+
completedSteps: number;
|
|
23
|
+
totalSteps: number;
|
|
24
|
+
isActive: boolean;
|
|
25
|
+
isVacuumActivated: boolean;
|
|
26
|
+
isPanelInPlace: boolean;
|
|
27
|
+
};
|
|
28
|
+
export type MqttStationStatePayload = {
|
|
29
|
+
station1: StationState;
|
|
30
|
+
station2: StationState;
|
|
31
|
+
station3: StationState;
|
|
32
|
+
station4: StationState;
|
|
33
|
+
};
|
|
34
|
+
type MqttChangeSandingPaperPayload = object;
|
|
35
|
+
type MqttSandingPaperChangedPayload = object;
|
|
36
|
+
type MqttGetInitialStatePayload = object;
|
|
37
|
+
export type MqttNotificationPayload = {
|
|
38
|
+
id: string;
|
|
39
|
+
message: string;
|
|
40
|
+
type: "info" | "warn" | "error";
|
|
41
|
+
timestamp: number;
|
|
42
|
+
isRead?: boolean;
|
|
43
|
+
};
|
|
44
|
+
type MqttPayloadMapping = {
|
|
45
|
+
[MqttSandingTopics.SET_APP_STATE]: MqttSetAppStatePayload;
|
|
46
|
+
[MqttSandingTopics.CALIBRATE]: MqttCalibratePayload;
|
|
47
|
+
[MqttSandingTopics.STATE_APP]: MqttSetAppStatePayload;
|
|
48
|
+
[MqttSandingTopics.STATE_ROBOT]: MqttRobotStatePayload;
|
|
49
|
+
[MqttSandingTopics.STATE_STATION]: MqttStationStatePayload;
|
|
50
|
+
[MqttSandingTopics.CHANGE_SANDING_PAPER]: MqttChangeSandingPaperPayload;
|
|
51
|
+
[MqttSandingTopics.SANDING_PAPER_CHANGED]: MqttSandingPaperChangedPayload;
|
|
52
|
+
[MqttSandingTopics.GET_INITIAL_STATE]: MqttGetInitialStatePayload;
|
|
53
|
+
[MqttSandingTopics.NOTIFICATION_MESSAGES]: MqttNotificationPayload;
|
|
54
|
+
};
|
|
55
|
+
export type MqttPayloadByTopic<T extends MqttSandingTopics> = MqttPayloadMapping[T];
|
|
56
|
+
export {};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { MqttSandingTopics, MqttPayloadByTopic } from "./mqtt-types";
|
|
2
|
+
interface Props<TMqttTopic> {
|
|
3
|
+
topic: TMqttTopic;
|
|
4
|
+
}
|
|
5
|
+
export declare const useMqttSubscription: <TMqttTopic extends MqttSandingTopics>(props: Props<TMqttTopic>) => MqttPayloadByTopic<TMqttTopic>;
|
|
6
|
+
export {};
|