diff --git a/apps/mcdu/src/App.jsx b/apps/mcdu/src/App.jsx
index 7f6eae5e..72047b61 100644
--- a/apps/mcdu/src/App.jsx
+++ b/apps/mcdu/src/App.jsx
@@ -1,9 +1,10 @@
import './assets/css/App.css';
-import React, { useEffect, useState } from 'react';
+import React, { useEffect, useRef, useState } from 'react';
import useWebSocket, { ReadyState } from 'react-use-websocket';
import { McduScreen } from './components/McduScreen';
import { McduButtons } from './components/McduButtons';
import { WebsocketContext } from './WebsocketContext';
+import { McduKeyboardEvents } from './McduKeyboardEvents';
import darkBg from './assets/images/mcdu-a32nx-dark.png';
import bg from './assets/images/mcdu-a32nx.png';
@@ -43,7 +44,7 @@ const App = () => {
// automaticaly upgrate to wss if the page is served over https
if (window.location.protocol === 'https:') {
socketUrl = socketUrl.replace('ws', 'wss');
- };
+ }
const [content, setContent] = useState(
{
@@ -79,6 +80,13 @@ const App = () => {
reconnectInterval: 500,
});
+ const { onKeyboardInput } = new McduKeyboardEvents(sendMessage);
+ const rootPanelRef = useRef(null);
+
+ useEffect(() => {
+ rootPanelRef.current.focus();
+ }, []);
+
useEffect(() => {
if (readyState === ReadyState.OPEN) {
sendMessage('requestUpdate');
@@ -100,7 +108,7 @@ const App = () => {
}
return (
- <>
+
{!fullscreen && (
<>
@@ -151,7 +159,7 @@ const App = () => {
>
)}
- >
+
);
};
diff --git a/apps/mcdu/src/McduKeyboardEvents.js b/apps/mcdu/src/McduKeyboardEvents.js
new file mode 100644
index 00000000..9df866ef
--- /dev/null
+++ b/apps/mcdu/src/McduKeyboardEvents.js
@@ -0,0 +1,71 @@
+const McduFunctionalKeys = {
+ Tab: 'DIR',
+ Insert: 'PROG',
+ Home: 'PERF',
+ PageUp: 'INIT',
+ Enter: 'DATA',
+ NumpadEnter: 'DATA',
+ Delete: 'FPLN',
+ End: 'RAD',
+ PageDown: 'FUEL',
+ Escape: 'MENU',
+ ShiftLeft: 'AIRPORT',
+ ArrowLeft: 'PREVPAGE',
+ ArrowRight: 'NEXTPAGE',
+ ArrowUp: 'UP',
+ ArrowDown: 'DOWN',
+ Backspace: 'CLR',
+ Space: 'SP',
+ Minus: 'PLUSMINUS',
+ NumpadSubtract: 'PLUSMINUS',
+ NumpadAdd: 'PLUSMINUS',
+ Period: 'DOT',
+ NumpadDecimal: 'DOT',
+ NumpadDivide: 'DIV',
+ Slash: 'DIV',
+ NumpadMultiply: 'OVFY',
+};
+
+export class McduKeyboardEvents {
+ constructor(socketSender) {
+ this.socketSender = socketSender;
+ this.mcduFunctionalKeys = McduFunctionalKeys;
+ }
+
+ getMcduKey = (keyEvent) => {
+ // match mcdu L/R row input for F keys
+ if (keyEvent.code.match(/F\d+/)) {
+ const fn = parseInt(keyEvent.code.replace('F', ''));
+ return fn <= 6 ? `L${fn}` : `R${fn - 6}`;
+ }
+
+ // match a-z
+ if (keyEvent.code.match(/Key[A-Z]/)) {
+ return keyEvent.code.replace('Key', '').toLocaleUpperCase();
+ }
+
+ // match 0-9
+ if (keyEvent.code.match(/(Digit|Numpad)\d/i)) {
+ return keyEvent.code.replace(/Digit|Numpad/i, '');
+ }
+
+ // match mcdu function keys
+ return this.mcduFunctionalKeys[keyEvent.code];
+ }
+
+ onKeyboardInput = (keyEvent) => {
+ //console.log('event', { key: keyEvent.key, code: keyEvent.code });
+ const key = this.getMcduKey(keyEvent);
+
+ if (key) {
+ keyEvent.preventDefault();
+ keyEvent.stopPropagation();
+ } else {
+ return;
+ }
+
+ //console.log(`mcdu key: ${key}`);
+
+ this.socketSender(`event:left:${key}`);
+ }
+}
diff --git a/apps/mcdu/src/index.html b/apps/mcdu/src/index.html
index 21c5a17f..bc852a26 100644
--- a/apps/mcdu/src/index.html
+++ b/apps/mcdu/src/index.html
@@ -14,6 +14,9 @@