Skip to content

Commit

Permalink
chore: check nodes (#56)
Browse files Browse the repository at this point in the history
* init checking nodes

* 2nd round of fixes

* re-upload when flow changes while uploading already

* small textual updates
  • Loading branch information
xiduzo authored Dec 29, 2024
1 parent ca6128f commit 7a67a6f
Show file tree
Hide file tree
Showing 25 changed files with 301 additions and 275 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export function IconWithValue(props: Props) {
<section className="flex flex-col text-center gap-1 text-muted-foreground">
<Icon icon={props.icon} size={48} className={props.iconClassName} />
<div className="text-xs tabular-nums">
{formatter.format(props.value)}
{typeof props.value === 'number' ? formatter.format(props.value) : props.value}
{props.suffix}
</div>
</section>
Expand All @@ -16,7 +16,7 @@ export function IconWithValue(props: Props) {

type Props = {
icon: IconName;
value: number;
value: string | number;
suffix?: string;
iconClassName?: string;
};
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import { useEffect, useMemo } from 'react';
import { Icons } from '@ui/index';

export function Calculate(props: Props) {
const hasSingleInput = ['ceil', 'floor', 'round'].includes(props.data.function as string);

const [first, second] = useMemo(() => {
switch (props.data.function) {
case 'add':
Expand All @@ -23,17 +25,26 @@ export function Calculate(props: Props) {
case 'min':
return ['first operand', 'second operand'];
default:
return ['first', 'second'];
return ['input', 'input'];
}
}, [props.data.function]);

return (
<NodeContainer {...props}>
<Value />
<Settings />

<Handle type="target" position={Position.Left} id="1" title={first} offset={-0.5} />
<Handle type="target" position={Position.Left} id="2" title={second} offset={0.5} />
<Handle type="source" position={Position.Right} id="change" />
<Handle
type="target"
position={Position.Left}
id="1"
title={first}
offset={!hasSingleInput ? -0.5 : 0}
/>
{!hasSingleInput && (
<Handle type="target" position={Position.Left} id="2" title={second} offset={0.5} />
)}
<Handle type="source" position={Position.Right} id="change" title="result" />
</NodeContainer>
);
}
Expand All @@ -56,13 +67,19 @@ function Value() {
return <Icons.ArrowUpToLine size={48} className="text-muted-foreground" />;
case 'min':
return <Icons.ArrowDownToLine size={48} className="text-muted-foreground" />;
case 'ceil':
return <Icons.ChevronUp size={48} className="text-muted-foreground" />;
case 'floor':
return <Icons.ChevronDown size={48} className="text-muted-foreground" />;
case 'round':
return <Icons.ChevronsUpDown size={48} className="text-muted-foreground" />;
default:
return <div>{data.function}</div>;
return <Icons.CircleHelp size={48} className="text-muted-foreground" />;
}
}

function Settings() {
const { pane, settings } = useNodeSettings<CalculateData>();
const { pane, settings, setHandlesToDelete } = useNodeSettings<CalculateData>();

useEffect(() => {
if (!pane) return;
Expand All @@ -71,16 +88,25 @@ function Settings() {
index: 0,
type: 'list',
options: [
{ text: 'add', value: 'add' },
{ text: 'subtract', value: 'subtract' },
{ text: 'multiply', value: 'multiply' },
{ text: 'divide', value: 'divide' },
{ text: 'addition', value: 'add' },
{ text: 'subtraction', value: 'subtract' },
{ text: 'multiplication', value: 'multiply' },
{ text: 'division', value: 'divide' },
{ text: 'modulo', value: 'modulo' },
{ text: 'max', value: 'max' },
{ text: 'min', value: 'min' },
{ text: 'maximum', value: 'max' },
{ text: 'minimum', value: 'min' },
{ text: 'round up', value: 'ceil' },
{ text: 'round down', value: 'floor' },
{ text: 'round closest', value: 'round' },
],
});

gateType.on('change', event => {
const hasSingleInput = ['ceil', 'floor', 'round'].includes(event.value as string);

setHandlesToDelete(hasSingleInput ? ['2'] : []);
});

return () => {
gateType.dispose();
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,21 @@ function Settings() {
useEffect(() => {
if (!pane) return;

pane.addBinding(settings, 'delay', {
const delayBinding = pane.addBinding(settings, 'delay', {
index: 0,
min: 100,
step: 100,
});

const forgetPriviousBinding = pane.addBinding(settings, 'forgetPrevious', {
index: 1,
label: 'debounce',
});

return () => {
delayBinding.dispose();
forgetPriviousBinding.dispose();
};
}, [pane, settings]);

return null;
Expand All @@ -45,5 +55,6 @@ Delay.defaultProps = {
tags: ['event', 'control'],
label: 'Delay',
delay: 1000,
forgetPrevious: false,
} satisfies Props['data'],
};
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ function LedValue(props: { value: number }) {
className="text-yellow-500"
size={48}
style={{
opacity: props.value > 1 ? props.value / 255 : 1, // Rhough dimmable LED
opacity: props.value !== 1 ? props.value / 255 + 0.1 : 1, // Rhough dimmable LED
}}
/>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ function Settings() {
pin.supportedModes.includes(MODES.INPUT) && !pin.supportedModes.includes(MODES.I2C);

if (settings.controller === 'HCSR501') {
return isCorrectMode && pin.supportedModes.includes(MODES.ANALOG);
} else {
return isCorrectMode && !pin.supportedModes.includes(MODES.ANALOG);
} else {
return isCorrectMode && pin.supportedModes.includes(MODES.ANALOG);
}
})
.map(mapPinToPaneOption),
Expand Down
23 changes: 12 additions & 11 deletions apps/electron-app/src/render/components/react-flow/nodes/Node.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ type SettingsContextProps<T extends Record<string, unknown>> = {
pane: Pane | null;
settings: T;
setHandlesToDelete: (handles: string[]) => void;
saveSettings: () => void;
};

const NodeSettingsPaneContext = createContext<SettingsContextProps<{}>>(
Expand Down Expand Up @@ -176,6 +177,15 @@ function NodeSettingsPane<T extends Record<string, unknown>>(
handlesToDelete.current = handles;
}, []);

const saveSettings = useCallback(() => {
if (handlesToDelete.current.length > 0) {
deleteEdes(id, handlesToDelete.current);
updateNodeInternals(id); // for xyflow to apply the changes of the removed edges
}

updateNode(settings, type !== 'Note');
}, [updateNode, deleteEdes, updateNodeInternals, id, settings]);

// TODO: update this after undo / redo
useEffect(() => {
if (settingsOpened) return;
Expand All @@ -191,15 +201,6 @@ function NodeSettingsPane<T extends Record<string, unknown>>(
container: ref.current ?? undefined,
});

function saveSettings() {
if (handlesToDelete.current.length > 0) {
deleteEdes(id, handlesToDelete.current);
updateNodeInternals(id); // for xyflow to apply the changes of the removed edges
}

updateNode(settings, type !== 'Note');
}

pane.registerPlugin(TweakpaneEssentialPlugin);
pane.registerPlugin(TweakpaneTextareaPlugin);
pane.registerPlugin(TweakpaneCameraPlugin);
Expand Down Expand Up @@ -237,10 +238,10 @@ function NodeSettingsPane<T extends Record<string, unknown>>(
setPane(null);
pane.dispose();
};
}, [settingsOpened, deleteEdes, type, id, updateNode, updateNodeInternals]);
}, [settingsOpened, type, id, saveSettings]);

return (
<NodeSettingsPaneContext.Provider value={{ pane, settings, setHandlesToDelete }}>
<NodeSettingsPaneContext.Provider value={{ pane, settings, saveSettings, setHandlesToDelete }}>
{props.children}
{settingsOpened &&
(createPortal(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ function Settings() {

pane.addBinding(settings, 'autoStart', {
index: 5,
label: 'auto start',
});
}, [pane, settings]);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@ import { type MatrixData, type MatrixValueType } from '@microflow/components';
import { Position } from '@xyflow/react';
import { useEffect, useState } from 'react';
import { Handle } from '../Handle';
import { BaseNode, NodeContainer, useNodeSettings } from '../Node';
import { BaseNode, NodeContainer, useNodeData, useNodeSettings } from '../Node';
import { MatrixDisplay } from './MatrixDisplay';
import { useNodeValue } from '../../../../stores/node-data';
import { MODES } from '../../../../../common/types';
import { mapPinToPaneOption } from '../../../../../utils/pin';
import { DEFAULT_MATRIX_SHAPE, DEFAULT_MATRIX_START_SHAPE } from '@microflow/components/contants';
import {
DEFAULT_MATRIX_SHAPE,
DEFAULT_MATRIX_START_SHAPE,
MatrixShape,
} from '@microflow/components/contants';
import {
Button,
Dialog,
Expand Down Expand Up @@ -49,25 +53,32 @@ function Value() {
}

function Settings() {
const { pane, settings } = useNodeSettings<MatrixData>();
const data = useNodeData<MatrixData>();
const { pane, settings, saveSettings } = useNodeSettings<MatrixData>();
const pins = usePins();
const [editorOpened, setEditorOpened] = useState(false);

const [shapes, setShapes] = useState(
settings.shapes?.map(shape => ({
(settings.shapes ?? data.shapes ?? [DEFAULT_MATRIX_SHAPE]).map(shape => ({
id: uuid(),
shape,
})) ?? [DEFAULT_MATRIX_SHAPE],
})),
);

function updateShapes(newShapes: { id: string; shape: MatrixShape }[]) {
setShapes(newShapes);
settings.shapes = newShapes.map(({ shape }) => shape);
saveSettings();
}

function swapShapes(id: string, hoveredId: string) {
const nextShapes = [...shapes];
const leftIndex = shapes.findIndex(shape => shape.id === id);
const rightIndex = shapes.findIndex(shape => shape.id === hoveredId);

nextShapes[leftIndex] = shapes[rightIndex];
nextShapes[rightIndex] = shapes[leftIndex];
setShapes(nextShapes);
updateShapes(nextShapes);
}

useEffect(() => {
Expand Down Expand Up @@ -171,13 +182,13 @@ function Settings() {
...nextShapes[index],
shape: newShape,
};
setShapes(nextShapes);
updateShapes(nextShapes);
}}
dimensions={settings.dims}
onDelete={() => {
const nextShapes = [...shapes];
nextShapes.splice(index, 1);
setShapes(nextShapes);
updateShapes(nextShapes);
}}
shape={shape}
/>
Expand All @@ -189,10 +200,10 @@ function Settings() {
<MatrixEditor
key={shapes.length}
onSave={newShape => {
setShapes([...shapes, { id: uuid(), shape: newShape }]);
updateShapes([...shapes, { id: uuid(), shape: newShape }]);
}}
dimensions={settings.dims}
shape={DEFAULT_MATRIX_SHAPE}
shape={[]}
>
<Button variant="outline">Add new shape</Button>
</MatrixEditor>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ function Value() {

function Settings() {
// @ts-expect-error PiezoData is not of type `Record<string, unknown>`
const { pane, settings, setHandlesToDelete } = useNodeSettings<PiezoData>();
const { pane, settings, setHandlesToDelete, saveSettings } = useNodeSettings<PiezoData>();
const pins = usePins();
const [editorOpened, setEditorOpened] = useState(false);

Expand Down Expand Up @@ -142,7 +142,8 @@ function Settings() {
setEditorOpened(false);
}}
onSave={data => {
data.song = data.song;
settings.song = data.song;
saveSettings();
setEditorOpened(false);
}}
/>
Expand Down
6 changes: 1 addition & 5 deletions apps/electron-app/src/render/hooks/useBoard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ export function useCelebrateFirstUpload() {

export function useCheckBoard() {
const { setBoardResult, setUploadResult } = useBoardStore();
const uploadCode = useCodeUploader();
const [{ ip }] = useLocalStorage<AdvancedConfig>('advanced-config', {
ip: undefined,
});
Expand Down Expand Up @@ -58,10 +57,7 @@ export function useCheckBoard() {
console.debug(`[CHECK] >>>`, { ip });
window.electron.ipcRenderer.send('ipc-check-board', { ip });
break;
case 'ready':
uploadCode();
break;
}
});
}, [ip, setUploadResult, uploadCode]);
}, [ip, setUploadResult]);
}
Loading

0 comments on commit 7a67a6f

Please sign in to comment.