jam-tracks / frontend /src /hooks /useSession.js
Mina Emadi
add demo preset system with sample track
08bdfee
import { useState, useCallback } from 'react'
export function useSession() {
const [sessionId, setSessionId] = useState(null)
const [stems, setStems] = useState([])
const [detection, setDetection] = useState(null)
const [loading, setLoading] = useState(false)
const [error, setError] = useState(null)
const clearError = useCallback(() => {
setError(null)
}, [])
// Upload files and automatically run detection
const upload = useCallback(async (formData) => {
setLoading(true)
setError(null)
try {
// Step 1: Upload files (formData already prepared by FileUpload component)
const uploadResponse = await fetch('/api/upload', {
method: 'POST',
body: formData
})
if (!uploadResponse.ok) {
const data = await uploadResponse.json().catch(() => ({}))
throw new Error(data.detail || `Upload failed: ${uploadResponse.status}`)
}
const uploadData = await uploadResponse.json()
console.log('Upload response:', uploadData)
setSessionId(uploadData.session_id)
setStems(uploadData.stems)
// Step 2: Automatically run detection with the session_id we just got
const detectResponse = await fetch(`/api/detect/${uploadData.session_id}`, {
method: 'POST'
})
if (!detectResponse.ok) {
const data = await detectResponse.json().catch(() => ({}))
throw new Error(data.detail || `Detection failed: ${detectResponse.status}`)
}
const detectData = await detectResponse.json()
console.log('Detection response:', detectData)
setDetection(detectData)
return { upload: uploadData, detection: detectData }
} catch (err) {
console.error('Error:', err)
setError(err.message)
return null
} finally {
setLoading(false)
}
}, [])
// Manual detect (if needed separately)
const detect = useCallback(async (sid = null) => {
const id = sid || sessionId
if (!id) {
setError('No session to detect')
return null
}
setLoading(true)
setError(null)
try {
const response = await fetch(`/api/detect/${id}`, {
method: 'POST'
})
if (!response.ok) {
const data = await response.json().catch(() => ({}))
throw new Error(data.detail || `Detection failed: ${response.status}`)
}
const data = await response.json()
setDetection(data)
return data
} catch (err) {
setError(err.message)
return null
} finally {
setLoading(false)
}
}, [sessionId])
const process = useCallback(async (semitones, targetBpm = null, regionStart = null, regionEnd = null) => {
if (!sessionId) {
setError('No session to process')
return null
}
setLoading(true)
setError(null)
try {
const body = { semitones, target_bpm: targetBpm }
if (regionStart !== null && regionEnd !== null) {
body.region_start = regionStart
body.region_end = regionEnd
}
const response = await fetch(`/api/process/${sessionId}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(body)
})
if (!response.ok) {
const data = await response.json().catch(() => ({}))
throw new Error(data.detail || `Processing failed: ${response.status}`)
}
const data = await response.json()
return data
} catch (err) {
setError(err.message)
return null
} finally {
setLoading(false)
}
}, [sessionId])
const getStems = useCallback(async () => {
if (!sessionId) return null
try {
const response = await fetch(`/api/stems/${sessionId}`)
if (!response.ok) {
throw new Error('Failed to get stems')
}
const data = await response.json()
return data
} catch (err) {
setError(err.message)
return null
}
}, [sessionId])
const loadPreset = useCallback(async (presetName) => {
setLoading(true)
setError(null)
try {
const uploadResponse = await fetch(`/api/preset/${presetName}`, { method: 'POST' })
if (!uploadResponse.ok) {
const data = await uploadResponse.json().catch(() => ({}))
throw new Error(data.detail || `Failed to load preset: ${uploadResponse.status}`)
}
const uploadData = await uploadResponse.json()
setSessionId(uploadData.session_id)
setStems(uploadData.stems)
const detectResponse = await fetch(`/api/detect/${uploadData.session_id}`, { method: 'POST' })
if (!detectResponse.ok) {
const data = await detectResponse.json().catch(() => ({}))
throw new Error(data.detail || `Detection failed: ${detectResponse.status}`)
}
const detectData = await detectResponse.json()
setDetection(detectData)
return { upload: uploadData, detection: detectData }
} catch (err) {
setError(err.message)
return null
} finally {
setLoading(false)
}
}, [])
const generate = useCallback(async (regionStart, regionEnd, duration = 15.0, prompt = null) => {
if (!sessionId) {
setError('No session to generate')
return null
}
setLoading(true)
setError(null)
try {
const body = { region_start: regionStart, region_end: regionEnd, duration }
if (prompt) {
body.prompt = prompt
}
const response = await fetch(`/api/generate/${sessionId}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(body)
})
if (!response.ok) {
const data = await response.json().catch(() => ({}))
throw new Error(data.detail || `Generation failed: ${response.status}`)
}
const data = await response.json()
return data
} catch (err) {
setError(err.message)
return null
} finally {
setLoading(false)
}
}, [sessionId])
return {
sessionId,
stems,
detection,
loading,
error,
upload,
detect,
process,
generate,
getStems,
loadPreset,
clearError
}
}