diff --git a/gcs/src/components/dashboard/tabsSectionTabs/actionTabsSection.jsx b/gcs/src/components/dashboard/tabsSectionTabs/actionTabsSection.jsx index fa779bc0c..2411ad462 100644 --- a/gcs/src/components/dashboard/tabsSectionTabs/actionTabsSection.jsx +++ b/gcs/src/components/dashboard/tabsSectionTabs/actionTabsSection.jsx @@ -10,6 +10,11 @@ import { useEffect, useMemo, useState } from "react" import { Button, NumberInput, Popover, Select, Tabs } from "@mantine/core" import { useLocalStorage } from "@mantine/hooks" +// Styling imports +import resolveConfig from "tailwindcss/resolveConfig" +import tailwindConfig from "../../../../tailwind.config" +const tailwindColors = resolveConfig(tailwindConfig).theme.colors + // Mavlink import { getFlightModeMap } from "../../../helpers/mavlinkConstants" @@ -27,6 +32,7 @@ import { } from "../../../redux/slices/droneInfoSlice" import { NoConnectionMsg } from "../tabsSection" +import { useRebootCallback } from "../../../helpers/useRebootCallback" export default function ActionTabsSection({ connected, @@ -113,6 +119,7 @@ const ArmTakeoffLandAction = () => { defaultValue: 10, }) const isArmed = useSelector(selectArmed) + const rebootCallback = useRebootCallback() function armDisarm(arm, force = false) { // TODO: Add force arm ability @@ -165,6 +172,15 @@ const ArmTakeoffLandAction = () => { > Land + + {/** Reboot Button */} + ) diff --git a/gcs/src/components/mainContent.jsx b/gcs/src/components/mainContent.jsx index 62e069ee1..61059dc8e 100644 --- a/gcs/src/components/mainContent.jsx +++ b/gcs/src/components/mainContent.jsx @@ -8,6 +8,7 @@ import { Route, Routes } from "react-router-dom" import SettingsModal from "./settingsModal" import { Commands } from "./spotlight/commandHandler" import Toolbar from "./toolbar/toolbar" +import AutopilotRebootModal from "./params/autopilotRebootModal.jsx" // Wrappers import { SettingsProvider } from "../helpers/settingsProvider" @@ -59,6 +60,7 @@ export default function AppContent() { } /> + diff --git a/gcs/src/components/spotlight/actions.js b/gcs/src/components/spotlight/actions.js index cddf74f44..fc2f26478 100644 --- a/gcs/src/components/spotlight/actions.js +++ b/gcs/src/components/spotlight/actions.js @@ -135,3 +135,6 @@ AddSpotlightAction( RunCommand("new_preflight_checklist") }, ) +AddSpotlightAction("reboot_autopilot", "Reboot Autopilot", "command", () => { + RunCommand("reboot_autopilot") +}) diff --git a/gcs/src/components/spotlight/commandHandler.js b/gcs/src/components/spotlight/commandHandler.js index 952e095f3..d553620ad 100644 --- a/gcs/src/components/spotlight/commandHandler.js +++ b/gcs/src/components/spotlight/commandHandler.js @@ -8,12 +8,14 @@ import { useHotkeys } from "@mantine/hooks" import { useEffect, useState } from "react" import { useNavigate } from "react-router" import { useSettings } from "../../helpers/settings" +import { useRebootCallback } from "../../helpers/useRebootCallback" let commands = [] export function Commands() { let navigate = useNavigate() const [isMac, setIsMac] = useState(false) + const rebootCallback = useRebootCallback() useEffect(() => { window.ipcRenderer.invoke("app:is-mac").then((result) => { @@ -49,6 +51,7 @@ export function Commands() { AddCommand("open_settings", () => { open() }) + AddCommand("reboot_autopilot", rebootCallback) // Register hotkeys useHotkeys([ diff --git a/gcs/src/helpers/useRebootCallback.js b/gcs/src/helpers/useRebootCallback.js new file mode 100644 index 000000000..b407929a2 --- /dev/null +++ b/gcs/src/helpers/useRebootCallback.js @@ -0,0 +1,22 @@ +import { useCallback } from "react" +import { useDispatch } from "react-redux" + +import { + emitRebootAutopilot, + setAutoPilotRebootModalOpen, + resetParamState, +} from "../redux/slices/paramsSlice.js" + +/** + * Hook that returns a callback to reboot the autopilot. + * Initiates autopilot reboot, displays status modal, and resets params. + * @returns Callback to reboot autopilot + */ +export function useRebootCallback() { + const dispatch = useDispatch() + return useCallback(() => { + dispatch(emitRebootAutopilot()) + dispatch(setAutoPilotRebootModalOpen(true)) + dispatch(resetParamState()) + }, [dispatch]) +} diff --git a/gcs/src/params.jsx b/gcs/src/params.jsx index dc90c4b88..cc5e38cfd 100644 --- a/gcs/src/params.jsx +++ b/gcs/src/params.jsx @@ -22,9 +22,9 @@ const tailwindColors = resolveConfig(tailwindConfig).theme.colors // Custom components, helpers, and data import Layout from "./components/layout.jsx" import NoDroneConnected from "./components/noDroneConnected.jsx" -import AutopilotRebootModal from "./components/params/autopilotRebootModal.jsx" import ParamsToolbar from "./components/params/paramsToolbar.jsx" import { Row } from "./components/params/row.jsx" +import { useRebootCallback } from "./helpers/useRebootCallback.js" // Redux import { useDispatch, useSelector } from "react-redux" @@ -34,7 +34,6 @@ import { showErrorNotification } from "./helpers/notification.js" import { selectConnectedToDrone } from "./redux/slices/droneConnectionSlice.js" import { emitExportParamsToFile, - emitRebootAutopilot, emitRefreshParams, emitSetMultipleParams, resetParamState, @@ -46,7 +45,6 @@ import { selectParamSearchValue, selectShowModifiedParams, selectShownParams, - setAutoPilotRebootModalOpen, setFetchingVars, setHasFetchedOnce, setLoadedFileName, @@ -70,6 +68,7 @@ function cleanFloat(value, decimals = 5) { export default function Params() { const dispatch = useDispatch() const connected = useSelector(selectConnectedToDrone) + const rebootCallback = useRebootCallback() // Parameter states const hasFetchedOnce = useSelector(selectHasFetchedOnce) @@ -125,12 +124,6 @@ export default function Params() { dispatch(setFetchingVars(true)) } - function rebootCallback() { - dispatch(emitRebootAutopilot()) - dispatch(setAutoPilotRebootModalOpen(true)) - dispatch(resetParamState()) - } - async function saveParamsToFile() { const options = { title: "Save parameters to a file", @@ -208,7 +201,6 @@ export default function Params() { return ( - {connected ? (