From 12bd63a9d9e01c0d65a7f6c3fb60b22f1616f956 Mon Sep 17 00:00:00 2001 From: ewc340 Date: Wed, 16 Jun 2021 21:22:39 -0700 Subject: [PATCH 01/32] Add mobx dependency --- package.json | 2 ++ yarn.lock | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/package.json b/package.json index 30313c20..cf51693b 100644 --- a/package.json +++ b/package.json @@ -117,6 +117,8 @@ "json-loader": "0.5.7", "keymirror": "0.1.1", "lodash": ">=4.17.21", + "mobx": "^6.3.2", + "mobx-react-lite": "^3.2.0", "mousetrap": "1.6.1", "numeral": "2.0.6", "object-assign": "4.1.1", diff --git a/yarn.lock b/yarn.lock index 423d98b9..ac2b9c66 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6302,6 +6302,16 @@ mkdirp@^1.0.4: resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== +mobx-react-lite@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/mobx-react-lite/-/mobx-react-lite-3.2.0.tgz#331d7365a6b053378dfe9c087315b4e41c5df69f" + integrity sha512-q5+UHIqYCOpBoFm/PElDuOhbcatvTllgRp3M1s+Hp5j0Z6XNgDbgqxawJ0ZAUEyKM8X1zs70PCuhAIzX1f4Q/g== + +mobx@^6.3.2: + version "6.3.2" + resolved "https://registry.yarnpkg.com/mobx/-/mobx-6.3.2.tgz#125590961f702a572c139ab69392bea416d2e51b" + integrity sha512-xGPM9dIE1qkK9Nrhevp0gzpsmELKU4MFUJRORW/jqxVFIHHWIoQrjDjL8vkwoJYY3C2CeVJqgvl38hgKTalTWg== + mocha@5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/mocha/-/mocha-5.0.0.tgz#cccac988b0bc5477119cba0e43de7af6d6ad8f4e" From 0d82ab9dea600b00d03f23e7c4625e5144946b22 Mon Sep 17 00:00:00 2001 From: ewc340 Date: Wed, 16 Jun 2021 21:36:42 -0700 Subject: [PATCH 02/32] Add mobx store skeleton --- renderer/contexts/index.ts | 1 + renderer/contexts/stores.ts | 4 ++++ renderer/hooks.ts/index.ts | 1 + renderer/hooks.ts/useStores.ts | 4 ++++ renderer/stores/console.ts | 30 ++++++++++++++++++++++++++++++ renderer/stores/index.ts | 1 + renderer/stores/root.ts | 10 ++++++++++ 7 files changed, 51 insertions(+) create mode 100644 renderer/contexts/index.ts create mode 100644 renderer/contexts/stores.ts create mode 100644 renderer/hooks.ts/index.ts create mode 100644 renderer/hooks.ts/useStores.ts create mode 100644 renderer/stores/console.ts create mode 100644 renderer/stores/index.ts create mode 100644 renderer/stores/root.ts diff --git a/renderer/contexts/index.ts b/renderer/contexts/index.ts new file mode 100644 index 00000000..a8c69102 --- /dev/null +++ b/renderer/contexts/index.ts @@ -0,0 +1 @@ +export { storesContext } from './stores'; diff --git a/renderer/contexts/stores.ts b/renderer/contexts/stores.ts new file mode 100644 index 00000000..8869d286 --- /dev/null +++ b/renderer/contexts/stores.ts @@ -0,0 +1,4 @@ +import React from 'react'; +import { RootStore } from '../stores'; + +export const storesContext = React.createContext(RootStore); diff --git a/renderer/hooks.ts/index.ts b/renderer/hooks.ts/index.ts new file mode 100644 index 00000000..f7113c82 --- /dev/null +++ b/renderer/hooks.ts/index.ts @@ -0,0 +1 @@ +export { useStores } from './useStores'; diff --git a/renderer/hooks.ts/useStores.ts b/renderer/hooks.ts/useStores.ts new file mode 100644 index 00000000..456a3f1c --- /dev/null +++ b/renderer/hooks.ts/useStores.ts @@ -0,0 +1,4 @@ +import React from 'react'; +import { storesContext } from '../contexts'; + +export const useStores = () => React.useContext(storesContext); diff --git a/renderer/stores/console.ts b/renderer/stores/console.ts new file mode 100644 index 00000000..7529db06 --- /dev/null +++ b/renderer/stores/console.ts @@ -0,0 +1,30 @@ +import { makeAutoObservable } from 'mobx'; +import { RootStore } from './root'; + +export class ConsoleStore { + rootStore: RootStore; + + showConsole = false; + consoleData: string[] = []; + disableScroll = false; + consoleUnread = false; + + constructor(rootStore: RootStore) { + makeAutoObservable(this); + this.rootStore = rootStore; + } + + updateConsole = (value: string[]) => { + this.consoleData = [...this.consoleData, ...value]; + this.consoleUnread = !this.consoleUnread; + }; + + clearConsole = () => { + this.consoleData = []; + }; + + toggleConsole = () => { + this.showConsole = !this.showConsole; + this.consoleUnread = false; + }; +} diff --git a/renderer/stores/index.ts b/renderer/stores/index.ts new file mode 100644 index 00000000..2788108a --- /dev/null +++ b/renderer/stores/index.ts @@ -0,0 +1 @@ +export { RootStore } from './root'; diff --git a/renderer/stores/root.ts b/renderer/stores/root.ts new file mode 100644 index 00000000..457dc809 --- /dev/null +++ b/renderer/stores/root.ts @@ -0,0 +1,10 @@ +import { ConsoleStore } from './console'; + +export class RootStore { + console: ConsoleStore; + + constructor() { + this.console = new ConsoleStore(this); + /** Initialize more stores here (try to keep it in alphabetical order) */ + } +} From b78ece78ae254b207a342757c874c682444be230 Mon Sep 17 00:00:00 2001 From: ewc340 Date: Wed, 16 Jun 2021 21:52:07 -0700 Subject: [PATCH 03/32] Remove mobx-react-lite and add mobx-react --- package.json | 2 +- yarn.lock | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index cf51693b..91cece78 100644 --- a/package.json +++ b/package.json @@ -118,7 +118,7 @@ "keymirror": "0.1.1", "lodash": ">=4.17.21", "mobx": "^6.3.2", - "mobx-react-lite": "^3.2.0", + "mobx-react": "^7.2.0", "mousetrap": "1.6.1", "numeral": "2.0.6", "object-assign": "4.1.1", diff --git a/yarn.lock b/yarn.lock index ac2b9c66..df4400c5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6307,6 +6307,13 @@ mobx-react-lite@^3.2.0: resolved "https://registry.yarnpkg.com/mobx-react-lite/-/mobx-react-lite-3.2.0.tgz#331d7365a6b053378dfe9c087315b4e41c5df69f" integrity sha512-q5+UHIqYCOpBoFm/PElDuOhbcatvTllgRp3M1s+Hp5j0Z6XNgDbgqxawJ0ZAUEyKM8X1zs70PCuhAIzX1f4Q/g== +mobx-react@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/mobx-react/-/mobx-react-7.2.0.tgz#241e925e963bb83a31d269f65f9f379e37ecbaeb" + integrity sha512-KHUjZ3HBmZlNnPd1M82jcdVsQRDlfym38zJhZEs33VxyVQTvL77hODCArq6+C1P1k/6erEeo2R7rpE7ZeOL7dg== + dependencies: + mobx-react-lite "^3.2.0" + mobx@^6.3.2: version "6.3.2" resolved "https://registry.yarnpkg.com/mobx/-/mobx-6.3.2.tgz#125590961f702a572c139ab69392bea416d2e51b" From bb59063f595529aeebadeb9bad7abd8b27edad4e Mon Sep 17 00:00:00 2001 From: ewc340 Date: Wed, 16 Jun 2021 21:52:55 -0700 Subject: [PATCH 04/32] Add RootStore context and hook --- renderer/{hooks.ts => hooks}/index.ts | 0 renderer/{hooks.ts => hooks}/useStores.ts | 0 renderer/stores/console.ts | 4 ++-- renderer/stores/root.ts | 5 ++++- 4 files changed, 6 insertions(+), 3 deletions(-) rename renderer/{hooks.ts => hooks}/index.ts (100%) rename renderer/{hooks.ts => hooks}/useStores.ts (100%) diff --git a/renderer/hooks.ts/index.ts b/renderer/hooks/index.ts similarity index 100% rename from renderer/hooks.ts/index.ts rename to renderer/hooks/index.ts diff --git a/renderer/hooks.ts/useStores.ts b/renderer/hooks/useStores.ts similarity index 100% rename from renderer/hooks.ts/useStores.ts rename to renderer/hooks/useStores.ts diff --git a/renderer/stores/console.ts b/renderer/stores/console.ts index 7529db06..f312cec7 100644 --- a/renderer/stores/console.ts +++ b/renderer/stores/console.ts @@ -2,14 +2,14 @@ import { makeAutoObservable } from 'mobx'; import { RootStore } from './root'; export class ConsoleStore { - rootStore: RootStore; + rootStore: typeof RootStore; showConsole = false; consoleData: string[] = []; disableScroll = false; consoleUnread = false; - constructor(rootStore: RootStore) { + constructor(rootStore: typeof RootStore) { makeAutoObservable(this); this.rootStore = rootStore; } diff --git a/renderer/stores/root.ts b/renderer/stores/root.ts index 457dc809..dea88a60 100644 --- a/renderer/stores/root.ts +++ b/renderer/stores/root.ts @@ -1,6 +1,7 @@ import { ConsoleStore } from './console'; +// Make sure store imports are in alphabetical order -export class RootStore { +class RootStore_ { console: ConsoleStore; constructor() { @@ -8,3 +9,5 @@ export class RootStore { /** Initialize more stores here (try to keep it in alphabetical order) */ } } + +export const RootStore = new RootStore_(); From 01f880e9cd997d68b1dba8dbc103df6585d94377 Mon Sep 17 00:00:00 2001 From: ewc340 Date: Wed, 16 Jun 2021 21:53:03 -0700 Subject: [PATCH 05/32] Add Dummy component --- renderer/components/Dummy.tsx | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 renderer/components/Dummy.tsx diff --git a/renderer/components/Dummy.tsx b/renderer/components/Dummy.tsx new file mode 100644 index 00000000..7e35c31e --- /dev/null +++ b/renderer/components/Dummy.tsx @@ -0,0 +1,10 @@ +import { Observer } from 'mobx-react'; +import React from 'react'; +import { useStores } from '../hooks'; + +// Use as an example of how to use the useStores hook - will delete later +export const Dummy = () => { + const { console } = useStores(); + + return {() =>
{console.consoleUnread}
}
+} \ No newline at end of file From fbe728269fd8d8c31a6933d11ae4dfbbbba10a95 Mon Sep 17 00:00:00 2001 From: lancejackson Date: Wed, 23 Jun 2021 19:55:06 -0700 Subject: [PATCH 06/32] Include bootstrap updates with mobx migration (#119) * Bootstrap version updated to 1.5.2 * what am i doing * Changed Graph to Container and smPush/smPull to xs * replaced Label with Badge, Navbar.header with Navbar, and Navbar.Form pullRight with Navbar * ConsoleOutput done. Fixing typescript errors on ConfigBox * straight up removed smPush and smPull * Fixed bsStyle for button and changed to variant in UpdateBox * upgrade bootstrap in Editor, upgrade glyphs to FA * ConsoleOutput done. ConfigBox has one more error * ConsoleOutput done. ConfigBox almost done (validation error left) * updated Gamepad.tsx and GamepadList.tsx * Working on Formik, added isValid props to Form.Control * add PeripheralGroup component w collapse hook * rid leftover old bootstrap * last second bootstrap fixes * fix bootstrap mostly * Fixed editor bsSize, fixed swapped editor/peripherals, added margin to peripherals * add default font value * Added margin to gamepadlist, ordered peripherals/gamepad/editor correctly * Dnav background * Added margin to top of App * look, a dark theme! Co-authored-by: meshankhosla Co-authored-by: Thomas Lee Co-authored-by: Andrew Dacayanan Co-authored-by: Saketh Panchumarthy --- main/MenuTemplate/DawnMenu.ts | 8 + package-lock.json | 339 +++++++++++++++++++ package.json | 12 +- renderer/actions/SettingsActions.ts | 5 + renderer/components/App.tsx | 10 +- renderer/components/ConfigBox.tsx | 124 +++---- renderer/components/ConsoleOutput.tsx | 10 +- renderer/components/DNav.tsx | 39 ++- renderer/components/Dashboard.tsx | 13 +- renderer/components/Editor.tsx | 124 +++---- renderer/components/EditorContainer.ts | 3 +- renderer/components/Gamepad.tsx | 9 +- renderer/components/GamepadList.tsx | 19 +- renderer/components/PeripheralGroup.tsx | 59 ++++ renderer/components/PeripheralList.tsx | 68 ++-- renderer/components/StatusLabel.tsx | 8 +- renderer/components/TooltipButton.tsx | 20 +- renderer/components/UpdateBox.tsx | 2 +- renderer/consts/actions.ts | 1 + renderer/reducers/settings.ts | 11 +- renderer/types/actions/index.ts | 2 +- renderer/types/actions/settings-actions.ts | 7 +- renderer/utils/utils.ts | 7 + static/bootstrap/css/bootstrap.min.css | 9 +- static/bootstrap/css/bootstrap.min.css.map | 2 +- yarn.lock | 358 +++++++++++++++------ 26 files changed, 941 insertions(+), 328 deletions(-) create mode 100644 package-lock.json create mode 100644 renderer/components/PeripheralGroup.tsx diff --git a/main/MenuTemplate/DawnMenu.ts b/main/MenuTemplate/DawnMenu.ts index 594a7731..090fc986 100644 --- a/main/MenuTemplate/DawnMenu.ts +++ b/main/MenuTemplate/DawnMenu.ts @@ -15,6 +15,14 @@ const DawnMenu: MenuItemConstructorOptions = { app.quit(); }, }, + { // this should be a button in the UI instead of a context menu + label: 'Dark/Light Theme', + click() { + RendererBridge.reduxDispatch({ + type: 'TOGGLE_THEME_GLOBAL', + }); + } + }, { label: 'Field Control Mode', click() { diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..1d928ac2 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,339 @@ +{ + "name": "dawn", + "version": "2.1.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/runtime": { + "version": "7.13.10", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.13.10.tgz", + "integrity": "sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "@types/hoist-non-react-statics": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", + "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==", + "requires": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, + "@types/prop-types": { + "version": "15.7.3", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz", + "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==" + }, + "@types/react": { + "version": "16.14.5", + "resolved": "https://registry.npmjs.org/@types/react/-/react-16.14.5.tgz", + "integrity": "sha512-YRRv9DNZhaVTVRh9Wmmit7Y0UFhEVqXqCSw3uazRWMxa2x85hWQZ5BN24i7GXZbaclaLXEcodEeIHsjBA8eAMw==", + "requires": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "@types/react-bootstrap": { + "version": "0.32.25", + "resolved": "https://registry.npmjs.org/@types/react-bootstrap/-/react-bootstrap-0.32.25.tgz", + "integrity": "sha512-VTa6viz5L+uPblEiF2pZz/n425cC49hrjLTsiLySxf7fw+UkchkjpskrsOHRvC6cCgCAG9futRWvOOjD1IBQqQ==", + "dev": true, + "requires": { + "@types/react": "*" + } + }, + "@types/react-redux": { + "version": "7.1.16", + "resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.16.tgz", + "integrity": "sha512-f/FKzIrZwZk7YEO9E1yoxIuDNRiDducxkFlkw/GNMGEnK9n4K8wJzlJBghpSuOVDgEUHoDkDF7Gi9lHNQR4siw==", + "requires": { + "@types/hoist-non-react-statics": "^3.3.0", + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0", + "redux": "^4.0.0" + } + }, + "@types/scheduler": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.1.tgz", + "integrity": "sha512-EaCxbanVeyxDRTQBkdLb3Bvl/HK7PBK6UJjsSixB0iHKoWxE5uu2Q/DgtpOhPIojN0Zl1whvOd7PoHs2P0s5eA==" + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "requires": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" + } + } + }, + "classnames": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz", + "integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==" + }, + "core-js": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", + "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==" + }, + "csstype": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.7.tgz", + "integrity": "sha512-KxnUB0ZMlnUWCsx2Z8MUsr6qV6ja1w9ArPErJaJaF8a5SOWoHLIszeCTKGRGRgtLgYrs1E8CHkNSP1VZTTPc9g==" + }, + "dom-helpers": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.4.0.tgz", + "integrity": "sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==", + "requires": { + "@babel/runtime": "^7.1.2" + } + }, + "hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "requires": { + "react-is": "^16.7.0" + } + }, + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "requires": { + "loose-envify": "^1.0.0" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "keycode": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/keycode/-/keycode-2.2.0.tgz", + "integrity": "sha1-PQr1bce4uOXLqNCpfxByBO7CKwQ=" + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "prop-types-extra": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/prop-types-extra/-/prop-types-extra-1.1.1.tgz", + "integrity": "sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew==", + "requires": { + "react-is": "^16.3.2", + "warning": "^4.0.0" + }, + "dependencies": { + "warning": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", + "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", + "requires": { + "loose-envify": "^1.0.0" + } + } + } + }, + "pwa-helpers": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/pwa-helpers/-/pwa-helpers-0.9.1.tgz", + "integrity": "sha512-4sP/C9sSxQ3w80AATmvCEI3R+MHzCwr2RSZEbLyMkeJgV3cRk7ySZRUrQnBDSA7A0/z6dkYtjuXlkhN1ZFw3iA==" + }, + "react-bootstrap": { + "version": "0.32.0", + "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-0.32.0.tgz", + "integrity": "sha512-AbWq1qjDpuYZzXSF0N6oXwwlWa1MWNEhqH/d5I51Q4AN/zn8oTBqx7HgIICR0Jk6xGy76LzJQGr+31VP3ehfVw==", + "requires": { + "babel-runtime": "^6.11.6", + "classnames": "^2.2.5", + "dom-helpers": "^3.2.0", + "invariant": "^2.2.1", + "keycode": "^2.1.2", + "prop-types": "^15.5.10", + "prop-types-extra": "^1.0.1", + "react-overlays": "^0.8.0", + "react-prop-types": "^0.4.0", + "react-transition-group": "^2.0.0", + "uncontrollable": "^4.1.0", + "warning": "^3.0.0" + }, + "dependencies": { + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + } + } + } + }, + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "react-lifecycles-compat": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", + "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" + }, + "react-overlays": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/react-overlays/-/react-overlays-0.8.3.tgz", + "integrity": "sha512-h6GT3jgy90PgctleP39Yu3eK1v9vaJAW73GOA/UbN9dJ7aAN4BTZD6793eI1D5U+ukMk17qiqN/wl3diK1Z5LA==", + "requires": { + "classnames": "^2.2.5", + "dom-helpers": "^3.2.1", + "prop-types": "^15.5.10", + "prop-types-extra": "^1.0.1", + "react-transition-group": "^2.2.0", + "warning": "^3.0.0" + }, + "dependencies": { + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + } + } + } + }, + "react-prop-types": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/react-prop-types/-/react-prop-types-0.4.0.tgz", + "integrity": "sha1-+ZsL+0AGkpya8gUefBQUpcdbk9A=", + "requires": { + "warning": "^3.0.0" + } + }, + "react-redux": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.3.tgz", + "integrity": "sha512-ZhAmQ1lrK+Pyi0ZXNMUZuYxYAZd59wFuVDGUt536kSGdD0ya9Q7BfsE95E3TsFLE3kOSFp5m6G5qbatE+Ic1+w==", + "requires": { + "@babel/runtime": "^7.12.1", + "@types/react-redux": "^7.1.16", + "hoist-non-react-statics": "^3.3.2", + "loose-envify": "^1.4.0", + "prop-types": "^15.7.2", + "react-is": "^16.13.1" + }, + "dependencies": { + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + } + } + } + }, + "react-transition-group": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.9.0.tgz", + "integrity": "sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg==", + "requires": { + "dom-helpers": "^3.4.0", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2", + "react-lifecycles-compat": "^3.0.4" + }, + "dependencies": { + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + } + } + } + }, + "redux": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.0.5.tgz", + "integrity": "sha512-VSz1uMAH24DM6MF72vcojpYPtrTUu3ByVWfPL1nPfVRb5mZVTve5GnNCUV53QM/BZ66xfWrm0CTWoM+Xlz8V1w==", + "requires": { + "loose-envify": "^1.4.0", + "symbol-observable": "^1.2.0" + } + }, + "regenerator-runtime": { + "version": "0.13.7", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", + "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==" + }, + "symbol-observable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", + "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==" + }, + "uncontrollable": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-4.1.0.tgz", + "integrity": "sha1-4DWCkSUuGGUiLZCTmxny9J+Bwak=", + "requires": { + "invariant": "^2.1.0" + } + }, + "warning": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz", + "integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=", + "requires": { + "loose-envify": "^1.0.0" + } + } + } +} diff --git a/package.json b/package.json index 91cece78..250a1f39 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,7 @@ "@types/node": "^14.0.14", "@types/numeral": "^0.0.28", "@types/react": "^16.9.43", - "@types/react-bootstrap": "^0.32.22", + "@types/react-bootstrap": "0.32.25", "@types/react-dom": "^16.9.8", "@types/react-joyride": "^2.0.5", "@types/react-redux": "^7.1.9", @@ -109,10 +109,15 @@ "zip-webpack-plugin": "3.0.0" }, "dependencies": { + "@fortawesome/fontawesome-svg-core": "^1.2.35", + "@fortawesome/free-solid-svg-icons": "^5.15.3", + "@fortawesome/react-fontawesome": "^0.1.14", "ace-builds": "^1.4.12", + "bootstrap": "4.6.0", "bufferutil": "4.0.1", "create-react-class": "15.6.2", "electron-json-storage": "4.0.2", + "formik": "^2.2.6", "immutable": "3.8.2", "json-loader": "0.5.7", "keymirror": "0.1.1", @@ -126,13 +131,14 @@ "postinstall-postinstall": "^2.1.0", "prop-types": "15.6.0", "protobufjs": "^6.10.2", + "pwa-helpers": "^0.9.1", "react": "^16.13.1", "react-ace": "^9.1.3", - "react-bootstrap": "0.32.0", + "react-bootstrap": "^1.6.0", "react-dom": "^16.13.1", "react-immutable-proptypes": "2.1.0", "react-joyride": "^2.2.1", - "react-redux": "^7.2.1", + "react-redux": "^7.2.3", "redux": "^4.0.5", "redux-saga": "^1.1.3", "seedrandom": "2.4.3", diff --git a/renderer/actions/SettingsActions.ts b/renderer/actions/SettingsActions.ts index 887289ea..e15ade45 100644 --- a/renderer/actions/SettingsActions.ts +++ b/renderer/actions/SettingsActions.ts @@ -10,3 +10,8 @@ export const changeTheme: SettingsActions['changeTheme'] = (theme: string) => ({ type: consts.SettingsActionsTypes.CHANGE_THEME, theme, }); + +export const toggleThemeGlobal: SettingsActions['toggleThemeGlobal'] = (globalTheme: 'light' | 'dark') => ({ + type: consts.SettingsActionsTypes.TOGGLE_THEME_GLOBAL, + globalTheme, +}); \ No newline at end of file diff --git a/renderer/components/App.tsx b/renderer/components/App.tsx index c8aed043..275333a7 100644 --- a/renderer/components/App.tsx +++ b/renderer/components/App.tsx @@ -12,9 +12,13 @@ import { removeAsyncAlert } from '../actions/AlertActions'; import { updateFieldControl } from '../actions/FieldActions'; import { logging, startLog } from '../utils/utils'; import { FieldControlConfig } from '../types'; +import { library } from '@fortawesome/fontawesome-svg-core'; +import { fas } from '@fortawesome/free-solid-svg-icons'; type ElectronJSONStorage = typeof electronJSONStorage; +library.add(fas); + const storage = remote.require('electron-json-storage') as ElectronJSONStorage; interface AlertType { @@ -29,6 +33,7 @@ interface StateProps { masterStatus: boolean; isRunningCode: boolean; asyncAlerts: Array; + globalTheme: string; } interface DispatchProps { @@ -140,8 +145,10 @@ class AppComponent extends React.Component { const { runtimeStatus, masterStatus, connectionStatus, isRunningCode } = this.props; const { tourRunning } = this.state; + const bsPrefix = (this.props.globalTheme === 'dark' ? 'text-light bg-dark ' : ''); // mind the space at the end + return ( -
+
({ asyncAlerts: state.asyncAlerts, stationNumber: state.fieldStore.stationNumber, isRunningCode: state.info.isRunningCode, + globalTheme: state.settings.globalTheme, }); const mapDispatchToProps = (dispatch: Dispatch) => ({ diff --git a/renderer/components/ConfigBox.tsx b/renderer/components/ConfigBox.tsx index 5dc1b189..0235dca5 100644 --- a/renderer/components/ConfigBox.tsx +++ b/renderer/components/ConfigBox.tsx @@ -1,13 +1,14 @@ import React, { useState, useEffect } from 'react'; -import { Modal, Button, FormGroup, Form, FormControl, ControlLabel } from 'react-bootstrap'; +import { Modal, Button, Form } from 'react-bootstrap'; import { ipcRenderer } from 'electron'; import { connect } from 'react-redux'; import { Dispatch } from 'redux'; import _ from 'lodash'; -import { defaults, getValidationState, logging } from '../utils/utils'; +import { defaults, getValidationState, logging, isValidationState } from '../utils/utils'; import { updateFieldControl } from '../actions/FieldActions'; import { ipChange, udpTunnelIpChange, sshIpChange } from '../actions/InfoActions'; import storage from 'electron-json-storage'; +import { Formik } from 'formik'; interface Config { stationNumber: number; @@ -35,6 +36,8 @@ interface OwnProps { } type Props = StateProps & DispatchProps & OwnProps; +type FormControlElement = HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement; + export const ConfigBoxComponent = (props: Props) => { const [ipAddress, setIPAddress] = useState(props.ipAddress); @@ -48,7 +51,7 @@ export const ConfigBoxComponent = (props: Props) => { const [originalStationNumber, setOriginalStationNumber] = useState(props.stationNumber); const [originalFCAddress, setOriginalFCAddress] = useState(props.fcAddress); - const saveChanges = (e: React.FormEvent
) => { + const saveChanges = (e: React.FormEvent) => { e.preventDefault(); props.onUDPTunnelingIpAddressChange(udpTunnelIpAddress); @@ -87,23 +90,23 @@ export const ConfigBoxComponent = (props: Props) => { props.hide(); }; - const handleIpChange = (e: React.FormEvent) => { + const handleIpChange = (e: React.FormEvent) => { setIPAddress(e.currentTarget.value); }; - const handleUDPTunnelIpChange = (e: React.FormEvent) => { + const handleUDPTunnelIpChange = (e: React.FormEvent) => { setUDPTunnelIpAddress(e.currentTarget.value); }; - const handleSSHIpChange = (e: React.FormEvent) => { + const handleSSHIpChange = (e: React.FormEvent) => { setSSHAddress(e.currentTarget.value); } - const handleFcChange = (e: React.FormEvent) => { + const handleFcChange = (e: React.FormEvent) => { setFCAddress(e.currentTarget.value); }; - const handleStationChange = (e: React.FormEvent) => { + const handleStationChange = (e: React.FormEvent) => { setStationNumber(parseInt(e.currentTarget.value)); }; @@ -176,54 +179,63 @@ export const ConfigBoxComponent = (props: Props) => { const { shouldShow } = props; return ( - - - - Dawn Configuration - - -

- Make sure only one computer (running instance of Dawn) is attempting to connect to the robot at a time! (i.e. not trying to - connect to the same IP Address) -

- - IP Address - - - - - - UDP Tunneling - - - - - - SSH Address - - - - -

Field Control Settings

- - Field Control IP Address - - - - - = 0 && stationNumber <= 4 ? 'success' : 'error'}> - Field Control Station Number - - - -
- - - - -
+ // TODO: Figure out formik stuff + + +
+ + Dawn Configuration + + +

+ Make sure only one computer (running instance of Dawn) is attempting to connect to the robot at a time! (i.e. not trying to + connect to the same IP Address) +

+ + IP Address + + + + + + UDP Tunneling + + + + + + SSH Address + + + + +

Field Control Settings

+ + Field Control IP Address + + + + + + Field Control Station Number + = 0 && stationNumber <= 4}/> + + +
+ + + +
+
+
); }; diff --git a/renderer/components/ConsoleOutput.tsx b/renderer/components/ConsoleOutput.tsx index 92c86a25..0f2d3499 100644 --- a/renderer/components/ConsoleOutput.tsx +++ b/renderer/components/ConsoleOutput.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { Panel } from 'react-bootstrap'; +import { Card } from 'react-bootstrap'; interface StateProps { toggleConsole: () => void; @@ -49,14 +49,14 @@ export class ConsoleOutput extends React.Component { const height = `${String(this.props.height)}px`; // TODO: Use Panel.Collapse return (
- - +
 {
                 ))}
               
- - + +
); } diff --git a/renderer/components/DNav.tsx b/renderer/components/DNav.tsx index 2e23ed29..980a2c76 100644 --- a/renderer/components/DNav.tsx +++ b/renderer/components/DNav.tsx @@ -1,6 +1,6 @@ import React, { useState } from 'react'; import { connect } from 'react-redux'; -import { Navbar, ButtonToolbar, ButtonGroup, Label } from 'react-bootstrap'; +import { Navbar, ButtonToolbar, ButtonGroup, Badge } from 'react-bootstrap'; import { ConfigBox } from './ConfigBox'; import { UpdateBox } from './UpdateBox'; import { StatusLabel } from './StatusLabel'; @@ -18,7 +18,8 @@ interface StateProps { udpTunnelAddress: string; sshAddress: string; fieldControlStatus: boolean; - latencyValue: number + latencyValue: number; + globalTheme: string; } interface OwnProps { @@ -86,8 +87,19 @@ const DNavComponent = (props: Props) => { startTour, } = props; + /** + * 4.21.2021 + * DELETE THIS COMMENT BLOCK IF THIS WORKS + * (lines: 98, 101) Navbar.Header replaced with: Navbar + * (lines: 124, 156) Navbar.Form pullRight replaced with: Navbar + */ + return ( - + { hide={() => toggleUpdateModal(!showUpdateModal)} /> toggleConfigModal(!showConfigModal)} /> - + {createHeader()} - + {runtimeStatus ? ( - + {`Runtime v${runtimeVersion}: ${String(robotState[codeStatus])}`} ) : ( '' @@ -122,9 +134,9 @@ const DNavComponent = (props: Props) => { /> - + {`Latency: ${props.latencyValue}`} - + { bsStyle="info" onClick={startTour} id="tour-button" - glyph="info-sign" + icon="info-circle" disabled={false} /> { bsStyle="info" onClick={() => toggleConfigModal(!showConfigModal)} id="update-address-button" - glyph="transfer" + icon="exchange-alt" disabled={false} /> { onClick={() => toggleUpdateModal(!showUpdateModal)} disabled={!runtimeStatus} id="update-software-button" - glyph="cloud-upload" + icon="cloud-upload-alt" /> - + ); @@ -172,7 +184,8 @@ const mapStateToProps = (state: ApplicationState) => ({ sshAddress: state.info.sshAddress, fieldControlStatus: state.fieldStore.fieldControl, runtimeVersion: state.peripherals.runtimeVersion, - latencyValue: state.editor.latencyValue + latencyValue: state.editor.latencyValue, + globalTheme: state.settings.globalTheme, }); export const DNav = connect(mapStateToProps)(DNavComponent); diff --git a/renderer/components/Dashboard.tsx b/renderer/components/Dashboard.tsx index fd0788a1..885db71e 100644 --- a/renderer/components/Dashboard.tsx +++ b/renderer/components/Dashboard.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { Grid, Row, Col } from 'react-bootstrap'; +import { Container, Row, Col } from 'react-bootstrap'; import { Step } from 'react-joyride'; import PeripheralList from './PeripheralList'; import { GamepadList } from './GamepadList'; @@ -12,16 +12,19 @@ interface StateProps { isRunningCode: boolean; // Currently not provided by runtime, and not used in Editor } +//smPush={8} and smPull={4} straight up removed + export const Dashboard = (props: StateProps) => ( - + - + - + - + ); + diff --git a/renderer/components/Editor.tsx b/renderer/components/Editor.tsx index a31e9545..749202c7 100644 --- a/renderer/components/Editor.tsx +++ b/renderer/components/Editor.tsx @@ -1,15 +1,15 @@ import React from 'react'; import { - Panel, + Card, ButtonGroup, DropdownButton, - MenuItem, FormGroup, FormControl, Form, InputGroup, OverlayTrigger, Tooltip, + Dropdown, } from 'react-bootstrap'; import AceEditor from 'react-ace'; import { Ace } from 'ace-builds' @@ -54,6 +54,7 @@ interface StateProps { disableScroll: boolean; consoleUnread: boolean; latencyValue: number; + globalTheme: string; } interface OwnProps { @@ -520,43 +521,46 @@ export class Editor extends React.Component { } return ( - - - Editing: {pathToName(this.props.filepath) ? pathToName(this.props.filepath) : '[ New File ]' } {changeMarker} - - + + + Editing: {pathToName(this.props.filepath) ? pathToName(this.props.filepath) : '[ New File ]' } {changeMarker} + +
- New File - New File + Open - Open + Save - Save + Save As + >Save As @@ -566,7 +570,7 @@ export class Editor extends React.Component { id="run" text="Run" onClick={this.startRobot} - glyph="play" + icon="play" disabled={this.state.isRunning || !this.props.runtimeStatus || this.props.fieldControlActivity} @@ -575,37 +579,38 @@ export class Editor extends React.Component { id="stop" text="Stop" onClick={this.stopRobot} - glyph="stop" + icon="stop" disabled={!(this.state.isRunning || this.state.simulate)} /> - { this.setState({ mode: robotState.AUTONOMOUS, modeDisplay: robotState.AUTOSTR }); }} - >Autonomous - Autonomous + { this.setState({ mode: robotState.TELEOP, modeDisplay: robotState.TELEOPSTR }); }} - >Tele-Operated - Tele-Operated + Simulate Competition + >Simulate Competition {' '} @@ -614,7 +619,7 @@ export class Editor extends React.Component { id="toggle-console" text="Toggle Console" onClick={this.toggleConsole} - glyph="console" + icon="terminal" disabled={false} bsStyle={this.props.consoleUnread ? 'danger' : ''} /> @@ -622,28 +627,28 @@ export class Editor extends React.Component { id="clear-console" text="Clear Console" onClick={this.props.onClearConsole} - glyph="remove" + icon="times" disabled={false} /> windowInfo.CONSOLEMAX} /> @@ -652,46 +657,46 @@ export class Editor extends React.Component { Text Size}> - this.changeFontsizeToFont(8)} - >8 - 8 + this.changeFontsizeToFont(12)} - >12 - 12 + this.changeFontsizeToFont(14)} - >14 - 14 + this.changeFontsizeToFont(16)} - >16 - 16 + this.changeFontsizeToFont(20)} - >20 - 20 + this.changeFontsizeToFont(24)} - >24 - 24 + this.changeFontsizeToFont(28)} - >28 + >28 @@ -699,7 +704,7 @@ export class Editor extends React.Component { id="toggleKeyboardControl" text="Toggle Keyboard Control Mode" onClick={this.toggleKeyboardControl} - glyph="text-background" + icon="keyboard" disabled={false} bsStyle={this.state.isKeyboardModeToggled ? 'info' : 'default'} /> @@ -709,29 +714,30 @@ export class Editor extends React.Component { id="increase-font-size" text="Increase font size" onClick={this.increaseFontsize} - glyph="zoom-in" + icon="search-plus" disabled={this.props.fontSize >= 28} /> {this.themes.map((theme: string) => ( - {theme} - + ))} @@ -740,7 +746,7 @@ export class Editor extends React.Component { id="checkLatency" text="Initiate Latency Check" onClick={this.checkLatency} - glyph="send" + icon="paper-plane" disabled={false} /> @@ -787,8 +793,8 @@ export class Editor extends React.Component { output={this.props.consoleData} disableScroll={this.props.disableScroll} /> - - + + ); } } diff --git a/renderer/components/EditorContainer.ts b/renderer/components/EditorContainer.ts index d38d6844..d2619237 100644 --- a/renderer/components/EditorContainer.ts +++ b/renderer/components/EditorContainer.ts @@ -33,7 +33,8 @@ const mapStateToProps = (state: ApplicationState) => ({ disableScroll: state.console.disableScroll, consoleUnread: state.console.consoleUnread, keyboardBitmap: state.editor.keyboardBitmap, - latencyValue: state.editor.latencyValue + latencyValue: state.editor.latencyValue, + globalTheme: state.settings.globalTheme, }); const mapDispatchToProps = (dispatch: Dispatch) => ({ diff --git a/renderer/components/Gamepad.tsx b/renderer/components/Gamepad.tsx index 300e80e2..1c0b27e6 100644 --- a/renderer/components/Gamepad.tsx +++ b/renderer/components/Gamepad.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { Modal, Button, - ListGroupItem, + ListGroup, Table, } from 'react-bootstrap'; import _ from 'lodash'; @@ -20,6 +20,7 @@ interface State { showModal: boolean; } + const NUM_GAMEPAD_BUTTONS = 17; const NUM_GAMEPAD_AXES = 4; @@ -67,10 +68,10 @@ export class Gamepad extends React.Component { } const values = this.roundedValues(); return ( - +
{this.renderHeader()} -
@@ -107,7 +108,7 @@ export class Gamepad extends React.Component { -
+ ); } }; diff --git a/renderer/components/GamepadList.tsx b/renderer/components/GamepadList.tsx index fddaa09a..b3806208 100644 --- a/renderer/components/GamepadList.tsx +++ b/renderer/components/GamepadList.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { Panel, ListGroup } from 'react-bootstrap'; +import { Card, ListGroup } from 'react-bootstrap'; import { connect } from 'react-redux'; import _ from 'lodash'; import { Gamepad } from './Gamepad'; @@ -7,6 +7,7 @@ import { Input } from '../../protos/protos'; interface StateProps { gamepads: Input[] | undefined; + globalTheme: string; } type Props = StateProps; @@ -27,22 +28,26 @@ const GamepadListComponent = (props: Props) => { ); } return ( - - Gamepads - + Gamepads + {interior} - - + + ); }; const mapStateToProps = (state: ApplicationState) => ({ gamepads: state.gamepads.gamepads, + globalTheme: state.settings.globalTheme, }); export const GamepadList = connect(mapStateToProps)(GamepadListComponent); diff --git a/renderer/components/PeripheralGroup.tsx b/renderer/components/PeripheralGroup.tsx new file mode 100644 index 00000000..979949a3 --- /dev/null +++ b/renderer/components/PeripheralGroup.tsx @@ -0,0 +1,59 @@ +import React, { useState } from 'react'; +import { Card, Collapse } from 'react-bootstrap'; +import { Peripheral as PeripheralComponent } from './Peripheral'; +import { PeripheralTypes } from '../consts'; +import { Peripheral } from '../types'; +import _ from 'lodash'; + +const cleanerNames = {}; +cleanerNames[PeripheralTypes.MOTOR_SCALAR] = 'Motors'; +cleanerNames[PeripheralTypes.SENSOR_BOOLEAN] = 'Boolean Sensors'; +cleanerNames[PeripheralTypes.SENSOR_SCALAR] = 'Numerical Sensors'; +cleanerNames[PeripheralTypes.LimitSwitch] = 'Limit Switches'; +cleanerNames[PeripheralTypes.LineFollower] = 'Line Followers'; +cleanerNames[PeripheralTypes.Potentiometer] = 'Potentiometers'; +cleanerNames[PeripheralTypes.Encoder] = 'Encoders'; +cleanerNames[PeripheralTypes.MetalDetector] = 'Metal Detectors'; +cleanerNames[PeripheralTypes.ServoControl] = 'Servo Controllers'; +cleanerNames[PeripheralTypes.RFID] = 'RFID'; +cleanerNames[PeripheralTypes.YogiBear] = 'Yogi Bear'; +cleanerNames[PeripheralTypes.GameValues] = 'Game Values'; +cleanerNames[PeripheralTypes.PolarBear] = 'Polar Bear'; +cleanerNames[PeripheralTypes.KoalaBear] = 'Koala Bear'; + +interface PGProps { + peripherals: Peripheral[], + groupName: string, +} + +const PeripheralGroup = (props: PGProps) => { + const [out, setOut] = useState(true); // controls toggle + + const { peripherals, groupName } = props; + const groupNameCleaned = groupName; //cleanerNames[groupName] as string; + + return ( + + + setOut(!out)} style={{ fontWeight: 'bold' }}> + {groupName || 'Generic'} + + + + + {_.map(peripherals, (peripheral: Peripheral) => ( + + ))} + + + + ) +} + +export default PeripheralGroup; \ No newline at end of file diff --git a/renderer/components/PeripheralList.tsx b/renderer/components/PeripheralList.tsx index 15d2b800..75aaeb9f 100644 --- a/renderer/components/PeripheralList.tsx +++ b/renderer/components/PeripheralList.tsx @@ -1,26 +1,10 @@ import React from 'react'; import _ from 'lodash'; -import { Panel, PanelGroup, ListGroup } from 'react-bootstrap'; -import { PeripheralTypes } from '../consts'; -import { Peripheral as PeripheralComponent } from './Peripheral'; +import { Card, CardGroup, ListGroup } from 'react-bootstrap'; +// import { Peripheral as PeripheralComponent } from './Peripheral'; import { Peripheral, PeripheralList } from '../types'; import { connect } from 'react-redux'; - -const cleanerNames = {}; -cleanerNames[PeripheralTypes.MOTOR_SCALAR] = 'Motors'; -cleanerNames[PeripheralTypes.SENSOR_BOOLEAN] = 'Boolean Sensors'; -cleanerNames[PeripheralTypes.SENSOR_SCALAR] = 'Numerical Sensors'; -cleanerNames[PeripheralTypes.LimitSwitch] = 'Limit Switches'; -cleanerNames[PeripheralTypes.LineFollower] = 'Line Followers'; -cleanerNames[PeripheralTypes.Potentiometer] = 'Potentiometers'; -cleanerNames[PeripheralTypes.Encoder] = 'Encoders'; -cleanerNames[PeripheralTypes.MetalDetector] = 'Metal Detectors'; -cleanerNames[PeripheralTypes.ServoControl] = 'Servo Controllers'; -cleanerNames[PeripheralTypes.RFID] = 'RFID'; -cleanerNames[PeripheralTypes.YogiBear] = 'Yogi Bear'; -cleanerNames[PeripheralTypes.GameValues] = 'Game Values'; -cleanerNames[PeripheralTypes.PolarBear] = 'Polar Bear'; -cleanerNames[PeripheralTypes.KoalaBear] = 'Koala Bear'; +import PeripheralGroup from './PeripheralGroup'; // const filter = new Set(); @@ -31,6 +15,7 @@ interface OwnProps { interface StateProps { peripheralList: PeripheralList; + globalTheme: string; } const handleAccordion = (devices: Peripheral[]) => { @@ -49,33 +34,14 @@ const handleAccordion = (devices: Peripheral[]) => { const groupNameCleaned = groupName; //cleanerNames[groupName] as string; return ( - - - - - {groupName || 'Generic'} - - - - - {_.map(peripheralGroups[groupName], (peripheral) => ( - - ))} - - - - + + ); }); }; @@ -97,17 +63,23 @@ const PeripheralListComponent = (props: StateProps & OwnProps) => { } return ( - - Peripherals - + + Peripherals + {panelBody} - - + + ); }; const mapStateToProps = (state: ApplicationState) => ({ - peripheralList: Object.assign({}, state.peripherals.peripheralList) + peripheralList: Object.assign({}, state.peripherals.peripheralList), + globalTheme: state.settings.globalTheme, }); const PeripheralListContainer = connect(mapStateToProps)(PeripheralListComponent); diff --git a/renderer/components/StatusLabel.tsx b/renderer/components/StatusLabel.tsx index 59cf4f97..25e89c3e 100644 --- a/renderer/components/StatusLabel.tsx +++ b/renderer/components/StatusLabel.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { Label } from 'react-bootstrap'; +import { Badge } from 'react-bootstrap'; import { connect } from 'react-redux'; import numeral from 'numeral'; @@ -52,11 +52,11 @@ const StatusLabelComponent = (props: Props) => { } return (
- + {labelText} {' '} - +
); }; diff --git a/renderer/components/TooltipButton.tsx b/renderer/components/TooltipButton.tsx index ca108ffe..8957d032 100644 --- a/renderer/components/TooltipButton.tsx +++ b/renderer/components/TooltipButton.tsx @@ -1,22 +1,30 @@ import React from 'react'; import { Button, - Glyphicon, OverlayTrigger, Tooltip, } from 'react-bootstrap'; +import { + findIconDefinition, + IconLookup +} from '@fortawesome/fontawesome-svg-core'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; + interface StateProp{ id: string; text: string; onClick: () => void; - glyph: string; + icon: IconLookup["iconName"]; disabled: boolean; bsStyle?: string; - placement?: string; + placement?: 'auto' | 'top' | 'bottom' | 'left' | 'right'; } export const TooltipButton = (props: StateProp) => { + // Look up definition of FA icon passed to props + const iconDef = findIconDefinition({ prefix: 'fas', iconName: props.icon}); + const tooltip = ( {props.text} ); @@ -24,13 +32,13 @@ export const TooltipButton = (props: StateProp) => { ); diff --git a/renderer/components/UpdateBox.tsx b/renderer/components/UpdateBox.tsx index 79b2442b..8197760f 100644 --- a/renderer/components/UpdateBox.tsx +++ b/renderer/components/UpdateBox.tsx @@ -139,7 +139,7 @@ class UpdateBoxContainer extends React.Component {