diff --git a/src/components/CommandPalette/index.tsx b/src/components/CommandPalette/index.tsx index 6d366700..9e44fde5 100644 --- a/src/components/CommandPalette/index.tsx +++ b/src/components/CommandPalette/index.tsx @@ -57,6 +57,7 @@ export const CommandPalette = () => { const { commandPaletteOpen, setCommandPaletteOpen, + setConnectDialogOpen, setSelectedDevice, } = useAppStore(); const { getDevices } = useDeviceStore(); @@ -133,7 +134,7 @@ export const CommandPalette = () => { label: "Connect New Node", icon: PlusIcon, action() { - setSelectedDevice(0); + setConnectDialogOpen(true); }, }, ], diff --git a/src/components/Dialog/NewDeviceDialog.tsx b/src/components/Dialog/NewDeviceDialog.tsx index 8d97ed43..d178fc9b 100644 --- a/src/components/Dialog/NewDeviceDialog.tsx +++ b/src/components/Dialog/NewDeviceDialog.tsx @@ -22,12 +22,9 @@ import { Subtle } from "@components/UI/Typography/Subtle.tsx"; import { AlertCircle } from "lucide-react"; import { Link } from "../UI/Typography/Link.tsx"; import { Fragment } from "react/jsx-runtime"; -import { useState } from "react"; export interface TabElementProps { closeDialog: () => void; - connectionInProgress: boolean; - setConnectionInProgress: (inProgress: boolean) => void; } export interface TabManifest { @@ -114,26 +111,25 @@ export const NewDeviceDialog = ({ open, onOpenChange, }: NewDeviceProps) => { - const [connectionInProgress, setConnectionInProgress] = useState(false); const { unsupported } = useBrowserFeatureDetection(); const tabs: TabManifest[] = [ { label: "HTTP", element: HTTP, - isDisabled: connectionInProgress, + isDisabled: false, }, { label: "Bluetooth", element: BLE, isDisabled: unsupported.includes("Web Bluetooth") || - unsupported.includes("Secure Context") || connectionInProgress, + unsupported.includes("Secure Context"), }, { label: "Serial", element: Serial, isDisabled: unsupported.includes("Web Serial") || - unsupported.includes("Secure Context") || connectionInProgress, + unsupported.includes("Secure Context"), }, ]; @@ -160,8 +156,6 @@ export const NewDeviceDialog = ({ : null} onOpenChange(false)} - setConnectionInProgress={setConnectionInProgress} - connectionInProgress={connectionInProgress} /> diff --git a/src/components/Dialog/RefreshKeysDialog/RefreshKeysDialog.test.tsx b/src/components/Dialog/RefreshKeysDialog/RefreshKeysDialog.test.tsx index 2b3c557b..79ff83ab 100644 --- a/src/components/Dialog/RefreshKeysDialog/RefreshKeysDialog.test.tsx +++ b/src/components/Dialog/RefreshKeysDialog/RefreshKeysDialog.test.tsx @@ -1,10 +1,9 @@ -import { render, screen } from "@testing-library/react"; +import { render } from "@testing-library/react"; import { DeviceContext, useDeviceStore } from "@core/stores/deviceStore.ts"; import { RefreshKeysDialog } from "./RefreshKeysDialog.tsx"; import { useMessageStore } from "../../../core/stores/messageStore/index.ts"; import { useRefreshKeysDialog } from "./useRefreshKeysDialog.ts"; import { afterEach, beforeEach, expect, test, vi } from "vitest"; -import { Protobuf } from "@meshtastic/core"; vi.mock("@core/stores/messageStore"); vi.mock("./useRefreshKeysDialog"); @@ -25,63 +24,6 @@ afterEach(() => { vi.restoreAllMocks(); }); -test("renders dialog when there is a node error for the active chat", () => { - const deviceId = 1; - const nodeWithErrorNum = 12345; - const activeChatNum = nodeWithErrorNum; - - const deviceStore = useDeviceStore.getState().addDevice(deviceId); - - deviceStore.addNodeInfo({ - num: nodeWithErrorNum, - user: { - id: nodeWithErrorNum.toString(), - publicKey: new Uint8Array(0), - hwModel: Protobuf.Mesh.HardwareModel.HELTEC_V3, - longName: "Problem Node Long", - shortName: "ProbNode", - isLicensed: false, - macaddr: new Uint8Array(0), - }, - lastHeard: Date.now() / 1000, - snr: 10, - } as Protobuf.Mesh.NodeInfo); - - deviceStore.setNodeError(activeChatNum, "PKI_MISMATCH"); - - const updatedDeviceState = useDeviceStore.getState().getDevice(deviceId); - if (!updatedDeviceState) { - throw new Error( - "Failed to get updated device state from store for provider", - ); - } - - mockUseMessageStore.mockReturnValue({ activeChat: activeChatNum }); - const mockHandleClose = vi.fn(); - const mockHandleRemove = vi.fn(); - mockUseRefreshKeysDialog.mockReturnValue({ - handleCloseDialog: mockHandleClose, - handleNodeRemove: mockHandleRemove, - }); - - render( - - - , - ); - - expect(screen.getByText(/Keys Mismatch - Problem Node Long/)) - .toBeInTheDocument(); - expect( - screen.getByText( - /Your node is unable to send a direct message to node: Problem Node Long \(ProbNode\)/, - ), - ).toBeInTheDocument(); - expect(screen.getByRole("button", { name: "Request New Keys" })) - .toBeInTheDocument(); - expect(screen.getByRole("button", { name: "Dismiss" })).toBeInTheDocument(); -}); - test("does not render dialog if no error exists for active chat", () => { const deviceId = 1; const activeChatNum = 54321; diff --git a/src/components/PageComponents/Connect/BLE.tsx b/src/components/PageComponents/Connect/BLE.tsx index 24a2a4c8..5abd907d 100644 --- a/src/components/PageComponents/Connect/BLE.tsx +++ b/src/components/PageComponents/Connect/BLE.tsx @@ -10,8 +10,9 @@ import { useCallback, useEffect, useState } from "react"; import { useMessageStore } from "../../../core/stores/messageStore/index.ts"; export const BLE = ( - { setConnectionInProgress, closeDialog }: TabElementProps, + { closeDialog }: TabElementProps, ) => { + const [connectionInProgress, setConnectionInProgress] = useState(false); const [bleDevices, setBleDevices] = useState([]); const { addDevice } = useDeviceStore(); const messageStore = useMessageStore(); @@ -40,7 +41,10 @@ export const BLE = ( }; return ( -
+
{bleDevices.map((device) => ( -
+
); }; diff --git a/src/components/PageComponents/Connect/HTTP.tsx b/src/components/PageComponents/Connect/HTTP.tsx index 9d62462c..2988a866 100644 --- a/src/components/PageComponents/Connect/HTTP.tsx +++ b/src/components/PageComponents/Connect/HTTP.tsx @@ -21,9 +21,9 @@ interface FormData { } export const HTTP = ( - { closeDialog, setConnectionInProgress, connectionInProgress }: - TabElementProps, + { closeDialog }: TabElementProps, ) => { + const [connectionInProgress, setConnectionInProgress] = useState(false); const isURLHTTPS = location.protocol === "https:"; const { addDevice } = useDeviceStore(); @@ -73,7 +73,11 @@ export const HTTP = ( return (
-
+
)} -
+ -
+ ); }; diff --git a/src/core/stores/deviceStore.ts b/src/core/stores/deviceStore.ts index 7bf5c3d7..e4cfe823 100644 --- a/src/core/stores/deviceStore.ts +++ b/src/core/stores/deviceStore.ts @@ -92,19 +92,22 @@ export interface Device { ) => Protobuf.Mesh.NodeInfo[]; getNodesLength: () => number; getNode: (nodeNum: number) => Protobuf.Mesh.NodeInfo | undefined; + getMyNode: () => Protobuf.Mesh.NodeInfo; } export interface DeviceState { - devices: Map; - remoteDevices: Map; - addDevice: (id: number) => Device; removeDevice: (id: number) => void; getDevices: () => Device[]; getDevice: (id: number) => Device | undefined; } -export const useDeviceStore = createStore((set, get) => ({ +interface PrivateDeviceState extends DeviceState { + devices: Map; + remoteDevices: Map; +} + +export const useDeviceStore = createStore((set, get) => ({ devices: new Map(), remoteDevices: new Map(), @@ -576,6 +579,14 @@ export const useDeviceStore = createStore((set, get) => ({ } return device.nodesMap.get(nodeNum); }, + getMyNode: (): Protobuf.Mesh.NodeInfo => { + const device = get().devices.get(id); + if (!device) { + throw new Error(`Device ${id} not found`); + } + return device.nodesMap.get(device.hardware.myNodeNum) ?? + create(Protobuf.Mesh.NodeInfoSchema); + }, getNodesLength: () => { const device = get().devices.get(id); if (!device) {