mirror of
https://github.com/jhbruhn/respira.git
synced 2026-01-27 02:13:41 +00:00
refactor: Derive patternUploaded from patternInfo instead of syncing state
Removed redundant patternUploaded state from PatternStore and replaced it with a derived selector usePatternUploaded() in MachineStore that computes it from patternInfo !== null. This eliminates duplicate state, removes the need for synchronization logic, and ensures a single source of truth for pattern upload status. Updated all components (App, LeftSidebar, FileUpload, PatternCanvas, WorkflowStepper) to use the derived selector. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
c81930d1b7
commit
467eb9df95
5 changed files with 18 additions and 12 deletions
|
|
@ -1,6 +1,6 @@
|
|||
import { useState, useCallback } from 'react';
|
||||
import { useShallow } from 'zustand/react/shallow';
|
||||
import { useMachineStore } from '../stores/useMachineStore';
|
||||
import { useMachineStore, usePatternUploaded } from '../stores/useMachineStore';
|
||||
import { usePatternStore } from '../stores/usePatternStore';
|
||||
import { useUIStore } from '../stores/useUIStore';
|
||||
import { convertPesToPen, type PesPatternData } from '../formats/import/pesImporter';
|
||||
|
|
@ -40,18 +40,19 @@ export function FileUpload() {
|
|||
pesData: pesDataProp,
|
||||
currentFileName,
|
||||
patternOffset,
|
||||
patternUploaded,
|
||||
setPattern,
|
||||
} = usePatternStore(
|
||||
useShallow((state) => ({
|
||||
pesData: state.pesData,
|
||||
currentFileName: state.currentFileName,
|
||||
patternOffset: state.patternOffset,
|
||||
patternUploaded: state.patternUploaded,
|
||||
setPattern: state.setPattern,
|
||||
}))
|
||||
);
|
||||
|
||||
// Derived state: pattern is uploaded if machine has pattern info
|
||||
const patternUploaded = usePatternUploaded();
|
||||
|
||||
// UI store
|
||||
const {
|
||||
pyodideReady,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { useShallow } from 'zustand/react/shallow';
|
||||
import { useMachineStore } from '../stores/useMachineStore';
|
||||
import { useMachineStore, usePatternUploaded } from '../stores/useMachineStore';
|
||||
import { usePatternStore } from '../stores/usePatternStore';
|
||||
import { ConnectionPrompt } from './ConnectionPrompt';
|
||||
import { FileUpload } from './FileUpload';
|
||||
|
|
@ -13,13 +13,15 @@ export function LeftSidebar() {
|
|||
}))
|
||||
);
|
||||
|
||||
const { pesData, patternUploaded } = usePatternStore(
|
||||
const { pesData } = usePatternStore(
|
||||
useShallow((state) => ({
|
||||
pesData: state.pesData,
|
||||
patternUploaded: state.patternUploaded,
|
||||
}))
|
||||
);
|
||||
|
||||
// Derived state: pattern is uploaded if machine has pattern info
|
||||
const patternUploaded = usePatternUploaded();
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-4 md:gap-5 lg:gap-6 lg:overflow-hidden">
|
||||
{/* Connect Button or Browser Hint - Show when disconnected */}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { useEffect, useRef, useState, useCallback } from 'react';
|
||||
import { useShallow } from 'zustand/react/shallow';
|
||||
import { useMachineStore } from '../stores/useMachineStore';
|
||||
import { useMachineStore, usePatternUploaded } from '../stores/useMachineStore';
|
||||
import { usePatternStore } from '../stores/usePatternStore';
|
||||
import { Stage, Layer, Group } from 'react-konva';
|
||||
import Konva from 'konva';
|
||||
|
|
@ -27,16 +27,17 @@ export function PatternCanvas() {
|
|||
const {
|
||||
pesData,
|
||||
patternOffset: initialPatternOffset,
|
||||
patternUploaded,
|
||||
setPatternOffset,
|
||||
} = usePatternStore(
|
||||
useShallow((state) => ({
|
||||
pesData: state.pesData,
|
||||
patternOffset: state.patternOffset,
|
||||
patternUploaded: state.patternUploaded,
|
||||
setPatternOffset: state.setPatternOffset,
|
||||
}))
|
||||
);
|
||||
|
||||
// Derived state: pattern is uploaded if machine has pattern info
|
||||
const patternUploaded = usePatternUploaded();
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const stageRef = useRef<Konva.Stage | null>(null);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { useState, useRef, useEffect } from 'react';
|
||||
import { useShallow } from 'zustand/react/shallow';
|
||||
import { useMachineStore } from '../stores/useMachineStore';
|
||||
import { useMachineStore, usePatternUploaded } from '../stores/useMachineStore';
|
||||
import { usePatternStore } from '../stores/usePatternStore';
|
||||
import { CheckCircleIcon, InformationCircleIcon, ExclamationTriangleIcon } from '@heroicons/react/24/solid';
|
||||
import { MachineStatus } from '../types/machine';
|
||||
|
|
@ -268,14 +268,14 @@ export function WorkflowStepper() {
|
|||
// Pattern store
|
||||
const {
|
||||
pesData,
|
||||
patternUploaded,
|
||||
} = usePatternStore(
|
||||
useShallow((state) => ({
|
||||
pesData: state.pesData,
|
||||
patternUploaded: state.patternUploaded,
|
||||
}))
|
||||
);
|
||||
|
||||
// Derived state: pattern is uploaded if machine has pattern info
|
||||
const patternUploaded = usePatternUploaded();
|
||||
const hasPattern = pesData !== null;
|
||||
const hasErrorFlag = hasError(machineError);
|
||||
const currentStep = getCurrentStep(machineStatus, isConnected, hasPattern, patternUploaded);
|
||||
|
|
|
|||
|
|
@ -552,3 +552,5 @@ export const useMachineStatus = () => useMachineStore((state) => state.machineSt
|
|||
export const useMachineError = () => useMachineStore((state) => state.machineError);
|
||||
export const usePatternInfo = () => useMachineStore((state) => state.patternInfo);
|
||||
export const useSewingProgress = () => useMachineStore((state) => state.sewingProgress);
|
||||
// Derived state: pattern is uploaded if machine has pattern info
|
||||
export const usePatternUploaded = () => useMachineStore((state) => state.patternInfo !== null);
|
||||
|
|
|
|||
Loading…
Reference in a new issue