From bc46fe00151016cb278ec1fb2077522f3e359d9a Mon Sep 17 00:00:00 2001 From: Jan-Henrik Bruhn Date: Wed, 17 Dec 2025 12:19:24 +0100 Subject: [PATCH] fix: Calculate time correctly per color block using Brother formula MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implemented proper time calculation matching the Brother app algorithm: - 150ms per stitch + 3000ms startup time per color block - Calculate total and elapsed time by summing across color blocks - This fixes the "999 seconds" issue by calculating time accurately Created timeCalculation utility with: - convertStitchesToMinutes: Convert stitches to minutes using PP1 formula - calculatePatternTime: Calculate total/elapsed time per color blocks Updated ProgressMonitor to show: - Total Time (calculated from all color blocks) - Elapsed Time / Total Time (based on current stitch position) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 --- src/components/ProgressMonitor.tsx | 20 ++++++--- src/utils/timeCalculation.ts | 67 ++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 6 deletions(-) create mode 100644 src/utils/timeCalculation.ts diff --git a/src/components/ProgressMonitor.tsx b/src/components/ProgressMonitor.tsx index a952328..fe210ca 100644 --- a/src/components/ProgressMonitor.tsx +++ b/src/components/ProgressMonitor.tsx @@ -21,6 +21,7 @@ import { canResumeSewing, getStateVisualInfo, } from "../utils/machineStateHelpers"; +import { calculatePatternTime } from "../utils/timeCalculation"; export function ProgressMonitor() { // Machine store @@ -109,6 +110,15 @@ export function ProgressMonitor() { currentStitch >= block.startStitch && currentStitch < block.endStitch, ); + // Calculate time based on color blocks (matches Brother app calculation) + const { totalMinutes, elapsedMinutes } = useMemo(() => { + if (colorBlocks.length === 0) { + return { totalMinutes: 0, elapsedMinutes: 0 }; + } + const result = calculatePatternTime(colorBlocks, currentStitch); + return { totalMinutes: result.totalMinutes, elapsedMinutes: result.elapsedMinutes }; + }, [colorBlocks, currentStitch]); + // Auto-scroll to current block useEffect(() => { if (currentBlockRef.current) { @@ -185,11 +195,10 @@ export function ProgressMonitor() {
- Est. Time + Total Time - {Math.floor(patternInfo.totalTime / 60)}: - {String(patternInfo.totalTime % 60).padStart(2, "0")} + {totalMinutes} min
@@ -225,11 +234,10 @@ export function ProgressMonitor() {
- Time Elapsed + Time - {Math.floor(sewingProgress.currentTime / 60)}: - {String(sewingProgress.currentTime % 60).padStart(2, "0")} + {elapsedMinutes} / {totalMinutes} min
diff --git a/src/utils/timeCalculation.ts b/src/utils/timeCalculation.ts new file mode 100644 index 0000000..e85b8e4 --- /dev/null +++ b/src/utils/timeCalculation.ts @@ -0,0 +1,67 @@ +/** + * Convert stitch count to minutes using Brother PP1 timing formula + * Formula: ((pointCount - 1) * 150 + 3000) / 60000 + * - 150ms per stitch + * - 3000ms startup time + * - Result in minutes (rounded up) + */ +export function convertStitchesToMinutes(stitchCount: number): number { + if (stitchCount <= 1) return 0; + + const timeMs = (stitchCount - 1) * 150 + 3000; + const timeMin = Math.ceil(timeMs / 60000); + + return timeMin < 1 ? 1 : timeMin; +} + +/** + * Calculate total and elapsed time for a pattern based on color blocks + * This matches the Brother app's calculation method + */ +export function calculatePatternTime( + colorBlocks: Array<{ stitchCount: number }>, + currentStitch: number +): { + totalMinutes: number; + elapsedMinutes: number; + remainingMinutes: number; +} { + let totalMinutes = 0; + let elapsedMinutes = 0; + let cumulativeStitches = 0; + + // Calculate time per color block + for (const block of colorBlocks) { + totalMinutes += convertStitchesToMinutes(block.stitchCount); + cumulativeStitches += block.stitchCount; + + if (cumulativeStitches < currentStitch) { + // This entire block is completed + elapsedMinutes += convertStitchesToMinutes(block.stitchCount); + } else if (cumulativeStitches === currentStitch) { + // We just completed this block + elapsedMinutes += convertStitchesToMinutes(block.stitchCount); + break; + } else { + // We're partway through this block + const stitchesInBlock = currentStitch - (cumulativeStitches - block.stitchCount); + elapsedMinutes += convertStitchesToMinutes(stitchesInBlock); + break; + } + } + + return { + totalMinutes, + elapsedMinutes, + remainingMinutes: Math.max(0, totalMinutes - elapsedMinutes), + }; +} + +/** + * Format minutes as MM:SS + */ +export function formatMinutes(minutes: number): string { + const mins = Math.floor(minutes); + const secs = Math.round((minutes - mins) * 60); + return `${mins}:${String(secs).padStart(2, '0')}`; +}