Spaces:
Sleeping
Sleeping
| import type { ProcessingStep } from '@/types/processing'; | |
| import { useCallback, useEffect, useState } from 'react'; | |
| const DEFAULT_STEPS: ProcessingStep[] = [ | |
| { | |
| id: 'preprocessing', | |
| title: '็ปๅๅๅฆ็', | |
| description: '็ปๅใฎๅๅฆ็ใๅฎ่กใใฆใใพใ', | |
| status: 'pending', | |
| estimatedTime: 10, | |
| }, | |
| { | |
| id: 'segmentation', | |
| title: '่ฆ็ด ่ญๅฅ', | |
| description: 'AIๅๆใซใใ็ปๅใฎๅ่ฆ็ด ใ่ญๅฅใใฆใใพใ', | |
| status: 'pending', | |
| estimatedTime: 30, | |
| }, | |
| { | |
| id: 'mask-generation', | |
| title: 'ใในใฏ็ๆ', | |
| description: '็ทจ้็จใฎใในใฏใ็ๆใใฆใใพใ', | |
| status: 'pending', | |
| estimatedTime: 20, | |
| }, | |
| { | |
| id: 'background', | |
| title: '่ๆฏ่ฃๅฎ', | |
| description: 'ไธ่ฆใช่ฆ็ด ใ้คๅปใใ่ๆฏใ่ช็ถใซ่ฃๅฎใใฆใใพใ', | |
| status: 'pending', | |
| estimatedTime: 45, | |
| }, | |
| { | |
| id: 'object', | |
| title: 'ใชใใธใงใฏใๅ็ๆ', | |
| description: 'ไบบ็ฉใๅๅใ่ไฝๆจฉใใชใผใฎ็ปๅใซ็ฝฎใๆใใฆใใพใ', | |
| status: 'pending', | |
| estimatedTime: 60, | |
| }, | |
| { | |
| id: 'maincopy', | |
| title: 'ใกใคใณใณใใผๅคๆด', | |
| description: 'ๆฐใใใกใคใณใณใใผใใญในใใๆ็ปใใฆใใพใ', | |
| status: 'pending', | |
| estimatedTime: 40, | |
| }, | |
| { | |
| id: 'header', | |
| title: 'ใใใใผๅๆ', | |
| description: 'ๅ ใฎใใใใผใไฟ่ญทใใชใใๆ็ต็ปๅใๅๆใใฆใใพใ', | |
| status: 'pending', | |
| estimatedTime: 20, | |
| }, | |
| ]; | |
| interface UseProgressManagerOptions { | |
| initialSteps?: ProcessingStep[]; | |
| autoProgress?: boolean; | |
| progressInterval?: number; | |
| } | |
| export function useProgressManager({ initialSteps = DEFAULT_STEPS, autoProgress = false, progressInterval = 1000 }: UseProgressManagerOptions = {}) { | |
| const [steps, setSteps] = useState<ProcessingStep[]>(initialSteps); | |
| const [currentStepId, setCurrentStepId] = useState<string | undefined>(); | |
| const [totalProgress, setTotalProgress] = useState(0); | |
| const [estimatedTimeRemaining, setEstimatedTimeRemaining] = useState<number | undefined>(); | |
| const [isProcessing, setIsProcessing] = useState(false); | |
| const [startTime, setStartTime] = useState<number | undefined>(); | |
| // ในใใใใ้ๅงใใ | |
| const startStep = useCallback( | |
| (stepId: string) => { | |
| setSteps((prev) => prev.map((step) => (step.id === stepId ? { ...step, status: 'in_progress' as const } : step))); | |
| setCurrentStepId(stepId); | |
| if (!startTime) { | |
| setStartTime(Date.now()); | |
| } | |
| }, | |
| [startTime], | |
| ); | |
| // ในใใใใๅฎไบใใ | |
| const completeStep = useCallback( | |
| (stepId: string, actualTime?: number) => { | |
| setSteps((prev) => | |
| prev.map((step) => | |
| step.id === stepId | |
| ? { | |
| ...step, | |
| status: 'completed' as const, | |
| actualTime: actualTime || step.estimatedTime, | |
| } | |
| : step, | |
| ), | |
| ); | |
| // ๆฌกใฎในใใใใ่ชๅ็ใซ้ๅง | |
| const currentIndex = steps.findIndex((step) => step.id === stepId); | |
| if (currentIndex >= 0 && currentIndex < steps.length - 1) { | |
| const nextStep = steps[currentIndex + 1]; | |
| if (autoProgress) { | |
| setTimeout(() => startStep(nextStep.id), 500); | |
| } | |
| } else { | |
| // ๆๅพใฎในใใใใๅฎไบ | |
| setCurrentStepId(undefined); | |
| setIsProcessing(false); | |
| } | |
| }, | |
| [steps, autoProgress, startStep], | |
| ); | |
| // ในใใใใใจใฉใผใซใใ | |
| const errorStep = useCallback((stepId: string, errorMessage?: string) => { | |
| setSteps((prev) => | |
| prev.map((step) => | |
| step.id === stepId | |
| ? { | |
| ...step, | |
| status: 'error' as const, | |
| description: errorMessage || step.description, | |
| } | |
| : step, | |
| ), | |
| ); | |
| }, []); | |
| // ๅ จไฝใฎ้ฒ่ก็ถๆณใ่จ็ฎ | |
| useEffect(() => { | |
| const completedSteps = steps.filter((step) => step.status === 'completed').length; | |
| const currentStepIndex = currentStepId ? steps.findIndex((step) => step.id === currentStepId) : -1; | |
| let progress = (completedSteps / steps.length) * 100; | |
| // ็พๅจๅฎ่กไธญใฎในใใใใฎ้ฒ่ก็ถๆณใๆจๅฎ | |
| if (currentStepIndex >= 0) { | |
| const partialProgress = (1 / steps.length) * 0.5; // ็พๅจใฎในใใใใฎ50%ใจใใฆไปฎๅฎ | |
| progress += partialProgress * 100; | |
| } | |
| setTotalProgress(Math.min(progress, 100)); | |
| }, [steps, currentStepId]); | |
| // ๆฎใๆ้ใ่จ็ฎ | |
| useEffect(() => { | |
| if (!isProcessing || !currentStepId) { | |
| setEstimatedTimeRemaining(undefined); | |
| return; | |
| } | |
| const completedSteps = steps.filter((step) => step.status === 'completed'); | |
| const remainingSteps = steps.filter((step) => step.status === 'pending' || (step.status === 'in_progress' && step.id !== currentStepId)); | |
| const currentStep = steps.find((step) => step.id === currentStepId); | |
| let remainingTime = 0; | |
| // ๆฎใใฎในใใใใฎๆจๅฎๆ้ใๅ่จ | |
| remainingSteps.forEach((step) => { | |
| remainingTime += step.estimatedTime || 30; | |
| }); | |
| // ็พๅจใฎในใใใใฎๆฎใๆ้๏ผไปฎใซ50%ๅฎไบใจไปฎๅฎ๏ผ | |
| if (currentStep) { | |
| remainingTime += (currentStep.estimatedTime || 30) * 0.5; | |
| } | |
| setEstimatedTimeRemaining(Math.ceil(remainingTime)); | |
| }, [steps, currentStepId, isProcessing]); | |
| // ๅฆ็ใ้ๅงใใ | |
| const startProcessing = useCallback(() => { | |
| setIsProcessing(true); | |
| setStartTime(Date.now()); | |
| if (steps.length > 0) { | |
| startStep(steps[0].id); | |
| } | |
| }, [steps, startStep]); | |
| // ๅฆ็ใใชใปใใใใ | |
| const resetProgress = useCallback(() => { | |
| setSteps(initialSteps); | |
| setCurrentStepId(undefined); | |
| setTotalProgress(0); | |
| setEstimatedTimeRemaining(undefined); | |
| setIsProcessing(false); | |
| setStartTime(undefined); | |
| }, [initialSteps]); | |
| // ใซในใฟใ ในใใใใ่จญๅฎใใ | |
| const setCustomSteps = useCallback((newSteps: ProcessingStep[]) => { | |
| setSteps(newSteps); | |
| setCurrentStepId(undefined); | |
| setTotalProgress(0); | |
| }, []); | |
| return { | |
| steps, | |
| currentStepId, | |
| totalProgress, | |
| estimatedTimeRemaining, | |
| isProcessing, | |
| startStep, | |
| completeStep, | |
| errorStep, | |
| startProcessing, | |
| resetProgress, | |
| setCustomSteps, | |
| }; | |
| } | |