Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
| import React, { useState, useEffect } from 'react' | |
| import API from '../API' | |
| import AudioPlayer from './AudioPlayer' | |
| import LoadingSpinner from './LoadingSpinner' | |
| interface ExamplesProps { | |
| fileType: 'image' | 'audio' | 'video' | |
| } | |
| type ExamplesData = { | |
| image_url: string | |
| audio_url?: string | |
| video_url?: string | |
| description: string | |
| } | |
| 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]) | |
| // Define the Gallery component within this file | |
| const Gallery = ({ | |
| selectedModel, | |
| selectedAttack, | |
| examples, | |
| fileType, | |
| }: { | |
| selectedModel: string | |
| selectedAttack: string | |
| examples: { | |
| [model: string]: { | |
| [attack: string]: ExamplesData[] | |
| } | |
| } | |
| fileType: 'image' | 'audio' | 'video' | |
| }) => { | |
| const exampleItems = examples[selectedModel][selectedAttack] | |
| return ( | |
| <div className="example-display"> | |
| {exampleItems.map((item, index) => ( | |
| <div key={index} className="example-item"> | |
| <p>{item.description}</p> | |
| {fileType === 'image' && ( | |
| <img src={item.image_url} alt={item.description} className="example-image" /> | |
| )} | |
| {fileType === 'audio' && item.audio_url && ( | |
| <> | |
| <AudioPlayer src={item.audio_url} /> | |
| <img src={item.image_url} alt={item.description} className="example-image" /> | |
| </> | |
| )} | |
| {fileType === 'video' && ( | |
| <video controls src={item.video_url} className="example-video" /> | |
| )} | |
| </div> | |
| ))} | |
| </div> | |
| ) | |
| } | |
| 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> | |
| {loading && <LoadingSpinner />} | |
| {error && <p className="error">Error: {error}</p>} | |
| {selectedModel && selectedAttack && ( | |
| <Gallery | |
| selectedModel={selectedModel} | |
| selectedAttack={selectedAttack} | |
| examples={examples} | |
| fileType={fileType} | |
| /> | |
| )} | |
| </div> | |
| ) | |
| } | |
| export default Examples | |