File size: 4,532 Bytes
98847a8
 
ed37070
b087e88
98847a8
ed37070
 
 
 
 
 
 
 
 
 
 
 
98847a8
ed37070
98847a8
 
 
 
 
 
 
 
 
 
 
ed37070
98847a8
ed37070
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
98847a8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ed37070
 
 
98847a8
 
 
 
 
 
 
 
 
 
 
ed37070
 
 
 
 
 
 
 
 
 
98847a8
 
 
 
 
 
 
 
 
ed37070
 
 
98847a8
ed37070
98847a8
 
 
 
 
 
 
 
 
ed37070
98847a8
ed37070
 
 
98847a8
ed37070
98847a8
 
 
 
 
 
 
 
 
ed37070
 
 
98847a8
b087e88
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
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