Skip to content

Commit

Permalink
feat(Vibration): added vibration node (#29)
Browse files Browse the repository at this point in the history
as a sub-type of a LED
  • Loading branch information
xiduzo authored Nov 25, 2024
1 parent 6146c88 commit dad188b
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 18 deletions.
32 changes: 29 additions & 3 deletions apps/electron-app/src/render/components/react-flow/nodes/Led.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export function Led(props: Props) {
type="target"
position={Position.Left}
id="brightness"
title={props.data.subType === 'vibration' ? 'intensity' : 'brightness'}
offset={0.5}
hint={`${isPmwPin ? '0-255' : 'requires PWM pin'}`}
isConnectable={isPmwPin}
Expand All @@ -37,21 +38,46 @@ export function Led(props: Props) {
}

function Value() {
const { id } = useNode();
const { id, data } = useNode();
const value = useNodeValue<LedValueType>(id, 0);

if (!value) return <Icons.LightbulbOff className="text-muted-foreground" size={48} />;
switch (data.subType) {
case 'vibration':
return <VibrationValue value={value} />;
default:
return <LedValue value={value} />;
}
}

function LedValue(props: { value: number }) {
if (!props.value) return <Icons.LightbulbOff className="text-muted-foreground" size={48} />;
return (
<Icons.Lightbulb
className="text-yellow-500"
size={48}
style={{
opacity: value > 1 ? value / 255 : 1, // Rhough dimmable LED
opacity: props.value > 1 ? props.value / 255 : 1, // Rhough dimmable LED
}}
/>
);
}

function VibrationValue(props: { value: number }) {
if (!props.value) return <Icons.VibrateOff className="text-muted-foreground" size={48} />;
return (
<section className="relative">
<Icons.Vibrate
className="text-orange-500 animate-wiggle"
size={48}
style={{
animationDuration: `${250 + (250 - (props.value > 1 ? props.value / 255 : 1) * 250)}ms`,
}}
/>
<div className="animate-ping w-8 h-8 bg-orange-500 rounded-full absolute left-[9px] right-0 bottom-0 top-2 -z-10"></div>
</section>
);
}

function Settings() {
const { pane, settings } = useNodeSettingsPane<LedData>();
const pins = usePins();
Expand Down
22 changes: 18 additions & 4 deletions apps/electron-app/src/render/components/react-flow/nodes/Node.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ function NodeSettingsPane<T extends Record<string, unknown>>(
const updateNodeInternals = useUpdateNodeInternals();
const deleteEdes = useDeleteEdges();

const { data, settingsOpened, id, type } = useNode<T>();
const { data, settingsOpened, setSettingsOpened, id, type } = useNode<T>();
const updateNode = useUpdateNode(id);

const ref = useRef<HTMLDivElement>();
Expand All @@ -188,15 +188,27 @@ function NodeSettingsPane<T extends Record<string, unknown>>(
index: 9998,
});

function saveSettings() {
deleteEdes(id, handlesToDelete.current);
updateNode(settings.current, type !== 'Note');
updateNodeInternals(id);
}

pane
.addButton({
title: 'Save',
index: 9998,
})
.on('click', saveSettings);

pane
.addButton({
title: 'Save & Close',
index: 9999,
})
.on('click', () => {
deleteEdes(id, handlesToDelete.current);
updateNode(settings.current, type !== 'Note');
updateNodeInternals(id);
saveSettings();
setSettingsOpened(false);
});

setPane(pane);
Expand Down Expand Up @@ -316,6 +328,8 @@ const node = cva(

export type BaseNode<Settings extends Record<string, unknown> = {}, Value = any> = Node<
Settings & {
type?: string;
subType?: string;
label: string;
animated?: string;
settingsOpen?: boolean;
Expand Down
15 changes: 13 additions & 2 deletions apps/electron-app/src/render/hooks/useCodeUploader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { useBoardPort, useBoardResult, useBoardStore } from '../stores/board';
import { UploadResult } from '../../common/types';
import { toast } from '@ui/index';
import { useClearNodeData } from '../stores/node-data';
import { useNewNode } from '../providers/NewNodeProvider';

export function useCodeUploader() {
const clearNodeData = useClearNodeData();
Expand Down Expand Up @@ -71,20 +72,30 @@ export function useCodeUploader() {

export function useAutoCodeUploader() {
const uploadCode = useCodeUploader();
const { nodeToAdd } = useNewNode();
const boardResult = useBoardResult();
const debounce = useRef<NodeJS.Timeout>();

const { nodesCount, edgesCount } = useNodeAndEdgeCount();

const lastNodesCount = useRef(-1);
const lastEdgesCount = useRef(-1);

useEffect(() => {
if (nodeToAdd?.length) return;
if (boardResult !== 'ready') return;

if (lastNodesCount.current === nodesCount && lastEdgesCount.current === edgesCount) return;

lastNodesCount.current = nodesCount;
lastEdgesCount.current = edgesCount;

debounce.current = setTimeout(() => {
uploadCode();
}, 5_000);
}, 1_000);

return () => {
clearTimeout(debounce.current);
};
}, [nodesCount, edgesCount, uploadCode, boardResult]);
}, [nodesCount, edgesCount, uploadCode, boardResult, nodeToAdd]);
}
28 changes: 19 additions & 9 deletions apps/electron-app/src/render/providers/NewNodeProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,16 @@ function NewNodeCommandDialog() {
const { open, setOpen, setNodeToAdd } = useNewNode();
const { addNode } = useTempNode();

function selectNode(type: NodeType, label?: string) {
function selectNode(type: NodeType, options?: { label?: string; subType?: string }) {
return function () {
const data = DEFAULT_NODE_DATA.get(type) ?? {};

if (label && 'label' in data) {
data.label = label;
}
const DEFAULT_DATA = DEFAULT_NODE_DATA.get(type) ?? {};

const id = Math.random().toString(36).substring(2, 8);
const newNode = {
data,
data: {
...DEFAULT_DATA,
...options,
},
id,
type,
position: { x: 0, y: 0 },
Expand Down Expand Up @@ -124,7 +123,7 @@ function NewNodeCommandDialog() {
<Badge variant="outline">Input</Badge>
</CommandShortcut>
</CommandItem>
<CommandItem onSelect={selectNode('Sensor', 'LDR')}>
<CommandItem onSelect={selectNode('Sensor', { label: 'LDR', subType: 'ldr' })}>
LDR (Light Dependent Resistor)
<CommandShortcut className="space-x-1">
<Badge variant="outline">Analog</Badge>
Expand All @@ -134,6 +133,7 @@ function NewNodeCommandDialog() {
<CommandItem onSelect={selectNode('Led')}>
LED
<CommandShortcut className="space-x-1">
<Badge variant="outline">Analog</Badge>
<Badge variant="outline">Digital</Badge>
<Badge variant="outline">Output</Badge>
</CommandShortcut>
Expand Down Expand Up @@ -161,7 +161,9 @@ function NewNodeCommandDialog() {
<Badge variant="outline">Output</Badge>
</CommandShortcut>
</CommandItem>
<CommandItem onSelect={selectNode('Sensor', 'Potentiometer')}>
<CommandItem
onSelect={selectNode('Sensor', { label: 'Potentiometer', subType: 'potentiometer' })}
>
Potentiometer
<CommandShortcut className="space-x-1">
<Badge variant="outline">Analog</Badge>
Expand All @@ -175,6 +177,14 @@ function NewNodeCommandDialog() {
<Badge variant="outline">Output</Badge>
</CommandShortcut>
</CommandItem>
<CommandItem onSelect={selectNode('Led', { label: 'Vibration', subType: 'vibration' })}>
Vibration
<CommandShortcut className="space-x-1">
<Badge variant="outline">Analog</Badge>
<Badge variant="outline">Digital</Badge>
<Badge variant="outline">Output</Badge>
</CommandShortcut>
</CommandItem>
</CommandGroup>
<CommandSeparator />
<CommandGroup heading="External">
Expand Down

0 comments on commit dad188b

Please sign in to comment.