Skip to content
This repository was archived by the owner on Apr 10, 2026. It is now read-only.
Merged
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
2 changes: 1 addition & 1 deletion apps/electron-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"type": "git",
"url": "https://github.com/xiduzo/microflow"
},
"version": "0.8.4",
"version": "0.8.5",
"description": "An application which allows you to create flow-based logic for microcontrollers",
"author": {
"name": "Sander Boer",
Expand Down
50 changes: 19 additions & 31 deletions apps/electron-app/src/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
useFigmaStore,
useMqttStore,
} from '@microflow/mqtt-provider/client';
import { Toaster } from '@microflow/ui';
import { Toaster, TooltipProvider } from '@microflow/ui';
import { ReactFlowProvider } from '@xyflow/react';
import { createRoot } from 'react-dom/client';
import { useDarkMode, useLocalStorage } from 'usehooks-ts';

Copilot AI Nov 22, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused import useLocalStorage.

Suggested change
import { useDarkMode, useLocalStorage } from 'usehooks-ts';
import { useDarkMode } from 'usehooks-ts';

Copilot uses AI. Check for mistakes.
Expand All @@ -17,28 +17,28 @@ import { CelebrationParticles } from './render/components/CelebrationParticles';
import { NewNodeCommandDialog } from './render/providers/NewNodeProvider';
import { StrictMode, useEffect, useMemo } from 'react';
import { useAppStore } from './render/stores/app';
import { MqttSettingsForm } from './render/components/forms/MqttSettingsForm';
import { AdvancedSettingsForm } from './render/components/forms/AdvancedSettingsForm';
import { UserSettingsForm } from './render/components/forms/UserSettingsForm';
import { Settings } from './render/components/Settings';
import logger from 'electron-log/renderer';

export function App() {
return (
<section className='h-screen w-screen'>
<DarkMode />
<MQTT />
<FigmaSync />
<Settings />
<Toaster position='top-left' className='z-20' duration={5000} />
<CelebrationParticles />
<ReactFlowProvider>
<IpcDeepLinkListener />
<NewNodeCommandDialog />
<ReactFlowCanvas />
<IpcMenuListeners />
<BoardHooks />
</ReactFlowProvider>
</section>
<TooltipProvider>
<section className='h-screen w-screen'>
<DarkMode />
<MQTT />
<FigmaSync />
<Settings />
<Toaster position='top-left' className='z-20' duration={5000} />
<CelebrationParticles />
<ReactFlowProvider>
<IpcDeepLinkListener />
<NewNodeCommandDialog />
<ReactFlowCanvas />
<IpcMenuListeners />
<BoardHooks />
</ReactFlowProvider>
</section>
</TooltipProvider>
);
}

Expand Down Expand Up @@ -127,15 +127,3 @@ function DarkMode() {

return null;
}

function Settings() {
const { settingsOpen } = useAppStore();

return (
<>
<MqttSettingsForm open={settingsOpen === 'mqtt-settings'} />
<AdvancedSettingsForm open={settingsOpen === 'board-settings'} />
<UserSettingsForm open={settingsOpen === 'user-settings'} />
</>
);
}
10 changes: 7 additions & 3 deletions apps/electron-app/src/main/menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export function createMenu(mainWindow: BrowserWindow, createWindow: () => Promis
label: 'Flow',
submenu: [
{
label: 'Insert node',
label: 'Add node',
accelerator: isMac ? 'Cmd+K' : 'Ctrl+K',
click: () => sendMessage(mainWindow, 'add-node'),
},
Expand Down Expand Up @@ -143,13 +143,17 @@ export function createMenu(mainWindow: BrowserWindow, createWindow: () => Promis
label: 'Settings',
submenu: [
{
label: 'Microcontroller settings',
click: () => sendMessage(mainWindow, 'board-settings'),
label: 'User settings',
click: () => sendMessage(mainWindow, 'user-settings'),
},
{
label: 'MQTT settings',
click: () => sendMessage(mainWindow, 'mqtt-settings'),
},
{
label: 'Microcontroller settings',
click: () => sendMessage(mainWindow, 'board-settings'),
},
],
},
// Development-only menu
Expand Down
96 changes: 96 additions & 0 deletions apps/electron-app/src/render/components/Settings.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import {
Sheet,
SheetContent,
SheetHeader,
SheetTitle,
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger,
Icons,
} from '@microflow/ui';
import { useAppStore } from '../stores/app';
import { UserSettingsForm } from './forms/UserSettingsForm';
import { MqttSettingsForm } from './forms/MqttSettingsForm';
import { AdvancedSettingsForm } from './forms/AdvancedSettingsForm';
import { useEffect, useState } from 'react';

export function Settings() {
const { settingsOpen, setSettingsOpen } = useAppStore();
const [accordionValue, setAccordionValue] = useState<string>('');

// Map settingsOpen to accordion value
useEffect(() => {
if (settingsOpen === 'user-settings') {
setAccordionValue('user-settings');
} else if (settingsOpen === 'mqtt-settings') {
setAccordionValue('mqtt-settings');
} else if (settingsOpen === 'board-settings') {
setAccordionValue('board-settings');
}
}, [settingsOpen]);

const isOpen = !!settingsOpen;

function handleOpenChange(open: boolean) {
if (!open) {
setSettingsOpen(undefined);
setAccordionValue('');
}
}

return (
<Sheet open={isOpen} onOpenChange={handleOpenChange}>
<SheetContent className='overflow-y-hidden'>
<SheetHeader>
<SheetTitle className='flex gap-2 items-center'>
<Icons.Settings />
Settings
</SheetTitle>
</SheetHeader>
<div className='mt-6'>
<Accordion
type='single'
collapsible
value={accordionValue}
onValueChange={setAccordionValue}
>
<AccordionItem value='user-settings'>
<AccordionTrigger>
<div className='flex gap-2 items-center'>
<Icons.User size={16} />
User settings
</div>
</AccordionTrigger>
<AccordionContent className='px-1'>
<UserSettingsForm />
</AccordionContent>
</AccordionItem>
<AccordionItem value='mqtt-settings'>
<AccordionTrigger>
<div className='flex gap-2 items-center'>
<Icons.RadioTower size={16} />
MQTT settings
</div>
</AccordionTrigger>
<AccordionContent className='px-1'>
<MqttSettingsForm />
</AccordionContent>
</AccordionItem>
<AccordionItem value='board-settings'>
<AccordionTrigger>
<div className='flex gap-2 items-center'>
<Icons.Microchip size={16} />
Microcontroller settings
</div>
</AccordionTrigger>
<AccordionContent>

Copilot AI Nov 22, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The AccordionContent components have inconsistent className props. The first two have className='px-1' (lines 65, 76) while the third one (line 87) is missing this prop. For consistency, either add className='px-1' to the third AccordionContent or remove it from all if not needed.

Suggested change
<AccordionContent>
<AccordionContent className='px-1'>

Copilot uses AI. Check for mistakes.
<AdvancedSettingsForm />
</AccordionContent>
</AccordionItem>
</Accordion>
</div>
</SheetContent>
</Sheet>
);
}
Loading
Loading