Initial sandbox commit (not fully working)

This commit is contained in:
Adam McQuilkin
2025-11-02 09:14:19 -08:00
parent 4386854e9d
commit 40c8b3c3ed
10 changed files with 785 additions and 390 deletions

View File

@@ -46,6 +46,7 @@
"@serialport/bindings-cpp",
"@tailwindcss/oxide",
"core-js",
"electron",
"esbuild",
"simple-git-hooks"
]

74
packages/desktop/main.ts Normal file
View File

@@ -0,0 +1,74 @@
import { app, BrowserWindow } from "electron";
import path from "path";
import { fileURLToPath } from "url";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const __webroot = path.join(__dirname, "./built-web-app");
console.log("Hello, world!");
console.log(__filename);
console.log(__dirname);
console.log(__webroot);
function createWindow() {
const win = new BrowserWindow({
width: 1200,
height: 800,
webPreferences: {
contextIsolation: true,
nodeIntegration: false,
},
});
// if (process.env.NODE_ENV === "development") {
// // Optionally run Vite dev server and load URL
// win.loadURL("http://localhost:3000");
// win.webContents.openDevTools();
// } else {
// win.loadFile(path.join(__dirname, "../dist/index.html"));
// }
win.webContents.openDevTools();
win.loadFile(path.join(__webroot, "index.html"));
// Serial permission handler
win.webContents.session.on(
"select-serial-port",
(event, portList, webContents, callback) => {
console.log("portList", portList);
event.preventDefault();
const selectedPort = portList[portList.length - 1];
console.log("selectedPort", selectedPort);
if (!selectedPort) {
callback("");
} else {
callback(selectedPort.portId);
}
},
);
// // Bluetooth selection event
// win.webContents.on(
// "select-bluetooth-device",
// (event, deviceList, callback) => {
// event.preventDefault();
// // Example: pick first device, or show your own UI
// if (deviceList.length > 0) {
// callback(deviceList[0].deviceId);
// } else {
// callback(""); // cancel
// }
// },
// );
}
app.whenReady().then(() => {
app.commandLine.appendSwitch("enable-web-bluetooth");
app.commandLine.appendSwitch("enable-experimental-web-platform-features");
createWindow();
});
app.on("window-all-closed", () => {
if (process.platform !== "darwin") app.quit();
});

View File

@@ -0,0 +1,22 @@
{
"name": "desktop",
"version": "1.0.0",
"description": "",
"main": "index.js",
"type": "module",
"scripts": {
"start": "cd ../web && pnpm run build && cd ../desktop/ && rm -rf dist && mkdir -p dist/ && cp -r ../web/dist ./dist/built-web-app && tsc && electron ./dist/main.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"packageManager": "pnpm@10.11.1",
"dependencies": {
"electron": "^39.0.0"
},
"devDependencies": {
"@types/node": "^24.9.2",
"tsx": "^4.20.6",
"typescript": "^5.9.3"
}
}

View File

@@ -0,0 +1,44 @@
{
// Visit https://aka.ms/tsconfig to read more about this file
"compilerOptions": {
// File Layout
// "rootDir": "./src",
"outDir": "./dist",
// Environment Settings
// See also https://aka.ms/tsconfig/module
"module": "nodenext",
"target": "esnext",
"types": [],
// For nodejs:
// "lib": ["esnext"],
// "types": ["node"],
// and npm install -D @types/node
// Other Outputs
"sourceMap": true,
"declaration": true,
"declarationMap": true,
// Stricter Typechecking Options
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true,
// Style Options
// "noImplicitReturns": true,
// "noImplicitOverride": true,
// "noUnusedLocals": true,
// "noUnusedParameters": true,
// "noFallthroughCasesInSwitch": true,
// "noPropertyAccessFromIndexSignature": true,
// Recommended Options
"strict": true,
"jsx": "react-jsx",
// "verbatimModuleSyntax": true,
"isolatedModules": true,
"noUncheckedSideEffectImports": true,
"moduleDetection": "force",
"skipLibCheck": true
}
}

View File

@@ -87,21 +87,21 @@ export const CommandPalette = () => {
label: t("goto.command.messages"),
icon: MessageSquareIcon,
action() {
navigate({ to: "/messages" });
navigate({ to: "./messages" });
},
},
{
label: t("goto.command.map"),
icon: MapIcon,
action() {
navigate({ to: "/map" });
navigate({ to: "./map" });
},
},
{
label: t("goto.command.config"),
icon: SettingsIcon,
action() {
navigate({ to: "/config" });
navigate({ to: "./config" });
},
tags: ["settings"],
},
@@ -109,7 +109,7 @@ export const CommandPalette = () => {
label: t("goto.command.nodes"),
icon: UsersIcon,
action() {
navigate({ to: "/nodes" });
navigate({ to: "./nodes" });
},
},
],

View File

@@ -14,8 +14,10 @@ export function useBrowserFeatureDetection(): BrowserSupport {
["Web Serial", !!navigator.serial],
[
"Secure Context",
globalThis.location.protocol === "https:" ||
globalThis.location.hostname === "localhost",
true,
// globalThis.location.protocol === "https:" ||
// globalThis.location.hostname === "localhost" ||
// globalThis.location.hostname === "file:",
],
];

View File

@@ -29,7 +29,7 @@ i18next
.init({
backend: {
// With this setup, {{lng}} will correctly resolve to 'en-US', 'fi-FI', etc.
loadPath: "/i18n/locales/{{lng}}/{{ns}}.json",
loadPath: "./i18n/locales/{{lng}}/{{ns}}.json",
},
react: {
useSuspense: true,

View File

@@ -33,7 +33,7 @@ const indexRoute = createRoute({
component: Dashboard,
loader: () => {
// Redirect to the broadcast messages page on initial load
return redirect({ to: "/messages/broadcast/0", replace: true });
return redirect({ to: "./messages/broadcast/0", replace: true });
},
});

View File

@@ -34,6 +34,7 @@ export default defineConfig(({ mode }) => {
const isTest = env.VITE_IS_TEST;
return {
base: "./",
plugins: [
react(),
tailwindcss(),

1015
pnpm-lock.yaml generated
View File

File diff suppressed because it is too large Load Diff