File size: 4,123 Bytes
5de5922
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
affdc98
 
5de5922
 
affdc98
 
 
 
 
 
 
 
5de5922
affdc98
 
 
 
 
 
5de5922
affdc98
5de5922
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import React, { useState } from 'react';
import './App.css';
import FileUpload from './components/FileUpload';
import AudioPlayer from './components/AudioPlayer';
import ProcessingStatus from './components/ProcessingStatus';
import Header from './components/Header';

function App() {
  const [uploadedFile, setUploadedFile] = useState(null);
  const [separatedTracks, setSeparatedTracks] = useState(null);
  const [isProcessing, setIsProcessing] = useState(false);
  const [processingProgress, setProcessingProgress] = useState(0);
  const [error, setError] = useState(null);

  const handleFileUpload = async (file) => {
    setUploadedFile(file);
    setIsProcessing(true);
    setError(null);
    setProcessingProgress(0);

    const formData = new FormData();
    formData.append('audio', file);

    try {
      // Simulate smooth progress updates with exponential decay
      const startTime = Date.now();
      const progressInterval = setInterval(() => {
        setProcessingProgress(prev => {
          const elapsed = Date.now() - startTime;
          // Use exponential approach to 95% over time, then slow crawl to 98%
          let targetProgress;
          if (elapsed < 30000) { // First 30 seconds: quick progress to 95%
            targetProgress = 95 * (1 - Math.exp(-elapsed / 10000));
          } else { // After 30 seconds: slow crawl from 95% to 98%
            const extraTime = elapsed - 30000;
            targetProgress = 95 + 3 * (1 - Math.exp(-extraTime / 20000));
          }
          
          // Smooth transition towards target
          const diff = targetProgress - prev;
          const increment = Math.max(0.1, diff * 0.1); // At least 0.1% progress each update
          
          return Math.min(98, prev + increment);
        });
      }, 500); // Update every 500ms for smoother animation

      const response = await fetch('/api/separate', {
        method: 'POST',
        body: formData,
      });

      clearInterval(progressInterval);

      if (!response.ok) {
        const errorData = await response.json().catch(() => ({ error: 'Unknown server error' }));
        throw new Error(errorData.error || `Server error: ${response.status} ${response.statusText}`);
      }

      const result = await response.json();
      setSeparatedTracks(result.tracks);
      setProcessingProgress(100);
      
      // Store session ID for cleanup
      window.currentSessionId = result.session_id;
    } catch (err) {
      setError(err.message);
    } finally {
      setIsProcessing(false);
    }
  };

  const handleReset = async () => {
    // Clean up the current session if it exists
    if (separatedTracks && window.currentSessionId) {
      try {
        await fetch(`/api/cleanup/${window.currentSessionId}`, {
          method: 'POST'
        });
      } catch (error) {
        console.warn('Failed to cleanup session:', error);
      }
    }
    
    setUploadedFile(null);
    setSeparatedTracks(null);
    setIsProcessing(false);
    setProcessingProgress(0);
    setError(null);
    window.currentSessionId = null;
  };

  return (
    <div className="App">
      <Header />
      
      <main className="main-content">
        {!uploadedFile && !separatedTracks && (
          <FileUpload onFileUpload={handleFileUpload} />
        )}

        {isProcessing && (
          <ProcessingStatus 
            progress={processingProgress}
            fileName={uploadedFile?.name}
          />
        )}

        {error && (
          <div className="error-container">
            <div className="error-message">
              <h3>Processing Error</h3>
              <p>{error}</p>
              <button onClick={handleReset} className="retry-button">
                Try Again
              </button>
            </div>
          </div>
        )}

        {separatedTracks && !isProcessing && (
          <AudioPlayer 
            key={uploadedFile?.name || 'default'}
            tracks={separatedTracks}
            originalFileName={uploadedFile?.name}
            onReset={handleReset}
          />
        )}
      </main>
    </div>
  );
}

export default App;