Skip to content

Persistent connection dialog #708

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 11 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,5 @@ stats.html
.vite
dev-dist
__screenshots__*
*.diff
npm/

*.diff
1 change: 1 addition & 0 deletions deno.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,5 @@
"out",
".vscode-test"
]

}
1 change: 1 addition & 0 deletions deno.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

40 changes: 40 additions & 0 deletions packages/web/public/i18n/locales/en/dialog.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,46 @@
"requiresFeatures": "This connection type requires <0></0>. Please use a supported browser, like Chrome or Edge.",
"requiresSecureContext": "This application requires a <0>secure context</0>. Please connect using HTTPS or localhost.",
"additionallyRequiresSecureContext": "Additionally, it requires a <0>secure context</0>. Please connect using HTTPS or localhost."
},
"tabs": {
"http": {
"title": "HTTP Servers",
"clearAll": "Clear All",
"noServers": "No HTTP servers added yet",
"addFirstServer": "Add your first Meshtastic server to get started",
"addNewDevice": "Add New Device",
"addServer": "Add HTTP Server",
"editServer": "Edit HTTP Server"
},
"serial": {
"title": "Serial Devices",
"adding": "Adding...",
"addDevice": "Add Serial Device",
"noDevices": "No serial devices connected",
"connectFirst": "Connect your first Meshtastic device via USB"
},
"bluetooth": {
"title": "Bluetooth Devices",
"pairing": "Pairing...",
"pairDevice": "Pair New Device",
"noDevices": "No Bluetooth devices paired",
"pairFirst": "Pair your first Meshtastic device"
},
"status": {
"online": "Online",
"offline": "Offline",
"checking": "Checking...",
"connecting": "Connecting...",
"connected": "Connected",
"available": "Available",
"paired": "Paired",
"unknown": "Unknown"
},
"actions": {
"connect": "Connect",
"cancel": "Cancel",
"saveChanges": "Save Changes"
}
}
},
"nodeDetails": {
Expand Down
22 changes: 12 additions & 10 deletions packages/web/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { DeviceWrapper } from "@app/DeviceWrapper.tsx";
import { DialogManager } from "@components/Dialog/DialogManager.tsx";
import { NewDeviceDialog } from "@components/Dialog/NewDeviceDialog.tsx";
import { KeyBackupReminder } from "@components/KeyBackupReminder.tsx";
import { Toaster } from "@components/Toaster.tsx";
import Footer from "@components/UI/Footer.tsx";
Expand All @@ -13,27 +12,30 @@ import { MapProvider } from "react-map-gl/maplibre";
import { CommandPalette } from "@components/CommandPalette/index.tsx";
import { SidebarProvider } from "@core/stores/sidebarStore.tsx";
import { useTheme } from "@core/hooks/useTheme.ts";
import { Outlet } from "@tanstack/react-router";
import { Outlet, useLocation, useNavigate } from "@tanstack/react-router";
import { TanStackRouterDevtools } from "@tanstack/react-router-devtools";
import { useEffect } from "react";

export function App() {
const { getDevice } = useDeviceStore();
const { selectedDevice, setConnectDialogOpen, connectDialogOpen } =
useAppStore();
const { selectedDevice } = useAppStore();
const navigate = useNavigate();
const location = useLocation();

const device = getDevice(selectedDevice);

// Sets up light/dark mode based on user preferences or system settings
useTheme();

// Redirect to messages when a device connects and we're on the dashboard
useEffect(() => {
if (device && location.pathname === "/") {
navigate({ to: "/messages/broadcast/0", replace: true });
}
}, [device, location.pathname, navigate]);

return (
<ErrorBoundary FallbackComponent={ErrorPage}>
<NewDeviceDialog
open={connectDialogOpen}
onOpenChange={(open) => {
setConnectDialogOpen(open);
}}
/>
<Toaster />
<TanStackRouterDevtools position="bottom-right" />
<DeviceWrapper device={device}>
Expand Down
61 changes: 61 additions & 0 deletions packages/web/src/components/ConnectionTabs/ConnectionTabs.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import {
Tabs,
TabsContent,
TabsList,
TabsTrigger,
} from "@components/UI/Tabs.tsx";
import { HTTPTab } from "@components/PageComponents/Connect/Tabs/HTTPTab.tsx";
import { BluetoothTab } from "@components/PageComponents/Connect/Tabs/BluetoothTab.tsx";
import { SerialTab } from "@components/PageComponents/Connect/Tabs/SerialTab.tsx";
import { Bluetooth, Server, Usb } from "lucide-react";

interface ConnectionTabsProps {
closeDialog?: () => void;
className?: string;
}

export const ConnectionTabs = (
{ closeDialog, className }: ConnectionTabsProps,
) => {
const handleClose = () => {
if (closeDialog) {
closeDialog();
}
};

return (
<Tabs
defaultValue="http"
className={`w-full max-w-2xl mx-auto ${className || ""}`}
>
<TabsList className="grid w-full grid-cols-3 mb-4">
<TabsTrigger value="http" className="flex items-center gap-2">
<Server className="h-5 w-5" />
HTTP
</TabsTrigger>
<TabsTrigger value="bluetooth" className="flex items-center gap-2">
<Bluetooth className="h-5 w-5" />
Bluetooth
</TabsTrigger>
<TabsTrigger value="serial" className="flex items-center gap-2">
<Usb className="h-5 w-5" />
Serial
</TabsTrigger>
</TabsList>

<div className="min-h-[400px] max-h-[500px] overflow-y-auto">
<TabsContent value="http" className="mt-0">
<HTTPTab closeDialog={handleClose} />
</TabsContent>

<TabsContent value="bluetooth" className="mt-0">
<BluetoothTab closeDialog={handleClose} />
</TabsContent>

<TabsContent value="serial" className="mt-0">
<SerialTab closeDialog={handleClose} />
</TabsContent>
</div>
</Tabs>
);
};
Loading