MCPcopy Create free account
hub / github.com/TanStack/ai / handleImageUpload

Function handleImageUpload

examples/ts-react-chat/src/routes/realtime.tsx:100–165  ·  view source on GitHub ↗
(e: React.ChangeEvent<HTMLInputElement>)

Source from the content-addressed store, hash-verified

98
99 // Handle image file selection
100 const handleImageUpload = (e: React.ChangeEvent<HTMLInputElement>) => {
101 const file = e.target.files?.[0]
102 // Always reset the input up front so the same file can be selected
103 // again even if we bail below.
104 const resetInput = () => {
105 e.target.value = ''
106 }
107 if (!file) {
108 resetInput()
109 return
110 }
111
112 // Bail if the file has no MIME type — in practice an empty `type` is
113 // a sign of a corrupt file or a browser that couldn't sniff it, and
114 // the OpenAI-compatible realtime API requires an explicit mime.
115 if (!file.type) {
116 // eslint-disable-next-line no-console
117 console.error('[realtime] Cannot send image: file has no MIME type', file)
118 window.alert(
119 'Could not determine the image type. Please try a different file.',
120 )
121 resetInput()
122 return
123 }
124
125 const reader = new FileReader()
126 reader.onerror = () => {
127 // eslint-disable-next-line no-console
128 console.error('[realtime] FileReader failed', reader.error)
129 window.alert(
130 `Failed to read image file: ${reader.error?.message ?? 'Unknown error'}`,
131 )
132 resetInput()
133 }
134 reader.onload = () => {
135 const result = reader.result
136 // `result` is null on abort/error, and is an ArrayBuffer (not a
137 // string) if someone changes the readAs* method later. Guard both.
138 if (result == null || typeof result !== 'string') {
139 // eslint-disable-next-line no-console
140 console.error('[realtime] FileReader result was not a string', result)
141 window.alert('Failed to read image file: unexpected reader output.')
142 resetInput()
143 return
144 }
145 // Extract base64 data (remove data:image/xxx;base64, prefix). A
146 // malformed data URL (no comma, or empty payload after the comma)
147 // means there's nothing sendable — surface it instead of silently
148 // no-op'ing.
149 const parts = result.split(',')
150 const base64 = parts[1]
151 if (!base64) {
152 // eslint-disable-next-line no-console
153 console.error(
154 '[realtime] FileReader produced a malformed data URL',
155 result.slice(0, 64),
156 )
157 window.alert('Failed to read image file: malformed image data.')

Callers

nothing calls this directly

Calls 3

resetInputFunction · 0.85
errorMethod · 0.65
sendImageFunction · 0.50

Tested by

no test coverage detected