Spaces:
Running
Running
File size: 4,006 Bytes
98847a8 b087e88 503a577 98847a8 ed37070 503a577 ed37070 503a577 ed37070 98847a8 ed37070 98847a8 ed37070 98847a8 ed37070 98847a8 503a577 98847a8 ed37070 98847a8 ed37070 98847a8 ed37070 98847a8 ed37070 98847a8 ed37070 98847a8 ed37070 98847a8 503a577 98847a8 |
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 |
import React, { useState, useEffect } from 'react'
import API from '../API'
import LoadingSpinner from './LoadingSpinner'
import ImageGallery from './ImageGallery'
import AudioGallery from './AudioGallery'
import VideoGallery from './VideoGallery'
interface ExamplesProps {
fileType: 'image' | 'audio' | 'video'
}
// Move ExamplesData type export to allow import in Galleries.tsx
export type ExamplesData = {
image_url: string
audio_url?: string
video_url?: string
name: string
metadata: {
[key: string]: string | boolean
}
}
const Examples = ({ fileType }: ExamplesProps) => {
const [examples, setExamples] = useState<{
[model: string]: { [attack: string]: ExamplesData[] }
}>({})
const [loading, setLoading] = useState(false)
const [error, setError] = useState<string | null>(null)
const [selectedModel, setSelectedModel] = useState<string | null>(null)
const [selectedAttack, setSelectedAttack] = useState<string | null>(null)
useEffect(() => {
setLoading(true)
setError(null)
API.fetchExamplesByType(fileType)
.then((data) => {
// data is a dictionary from {[model]: {[attack]: {image_url, audio_url, video_url, description}}}
setExamples(data)
// get the first model and attack if available
const models = Object.keys(data)
if (models.length > 0) {
setSelectedModel(models[0])
const attacks = Object.keys(data[models[0]])
if (attacks.length > 0) {
setSelectedAttack(attacks[0]) // Set the first attack of the first model
} else {
setSelectedAttack(null) // No attacks available
}
} else {
setSelectedModel(null)
setSelectedAttack(null) // No models available
}
// Reset loading state
setLoading(false)
})
.catch((err) => {
setError(err.message)
setLoading(false)
})
}, [fileType])
if (loading) {
return <LoadingSpinner />
}
return (
<div className="examples-container">
<div className="selectors-container flex flex-col md:flex-row gap-4 mb-4">
<fieldset className="fieldset">
<legend className="fieldset-legend">Model</legend>
<select
className="select select-bordered w-full"
value={selectedModel || ''}
onChange={(e) => setSelectedModel(e.target.value || null)}
>
{Object.keys(examples).map((model) => (
<option key={model} value={model}>
{model}
</option>
))}
</select>
</fieldset>
{selectedModel && (
<fieldset className="fieldset">
<legend className="fieldset-legend">Attack</legend>
<select
className="select select-bordered w-full"
value={selectedAttack || ''}
onChange={(e) => setSelectedAttack(e.target.value || null)}
>
{Object.keys(examples[selectedModel]).map((attack) => (
<option key={attack} value={attack}>
{attack}
</option>
))}
</select>
</fieldset>
)}
</div>
{error && <p className="error">Error: {error}</p>}
{selectedModel && selectedAttack && fileType === 'image' && (
<ImageGallery
selectedModel={selectedModel}
selectedAttack={selectedAttack}
examples={examples}
/>
)}
{selectedModel && selectedAttack && fileType === 'audio' && (
<AudioGallery
selectedModel={selectedModel}
selectedAttack={selectedAttack}
examples={examples}
/>
)}
{selectedModel && selectedAttack && fileType === 'video' && (
<VideoGallery
selectedModel={selectedModel}
selectedAttack={selectedAttack}
examples={examples}
/>
)}
</div>
)
}
export default Examples
|