@@ -53,6 +53,12 @@ export type WalletMeta = {
5353
5454const maxAllowedImagesPerMessage = 4 ;
5555
56+ function showSigninToUploadImagesToast ( ) {
57+ toast . error ( "Sign in to upload images to Nebula" , {
58+ position : "top-right" ,
59+ } ) ;
60+ }
61+
5662export function ChatBar ( props : {
5763 sendMessage : ( message : NebulaUserMessage ) => void ;
5864 isChatStreaming : boolean ;
@@ -105,6 +111,8 @@ export function ChatBar(props: {
105111 } ,
106112 } ) ;
107113
114+ const supportedFileTypes = [ "image/jpeg" , "image/png" , "image/webp" ] ;
115+
108116 async function handleImageUpload ( files : File [ ] ) {
109117 const totalFiles = files . length + images . length ;
110118
@@ -113,14 +121,22 @@ export function ChatBar(props: {
113121 `You can only upload up to ${ maxAllowedImagesPerMessage } images at a time` ,
114122 {
115123 position : "top-right" ,
116- }
124+ } ,
117125 ) ;
118126 return ;
119127 }
120128
121129 const validFiles : File [ ] = [ ] ;
122130
123131 for ( const file of files ) {
132+ if ( ! supportedFileTypes . includes ( file . type ) ) {
133+ toast . error ( "Unsupported file type" , {
134+ description : `File: ${ file . name } ` ,
135+ position : "top-right" ,
136+ } ) ;
137+ continue ;
138+ }
139+
124140 if ( file . size <= 5 * 1024 * 1024 ) {
125141 validFiles . push ( file ) ;
126142 } else {
@@ -136,7 +152,7 @@ export function ChatBar(props: {
136152 validFiles . map ( async ( image ) => {
137153 const b64 = await uploadImageMutation . mutateAsync ( image ) ;
138154 return { file : image , b64 : b64 } ;
139- } )
155+ } ) ,
140156 ) ;
141157
142158 setImages ( ( prev ) => [ ...prev , ...urls ] ) ;
@@ -153,38 +169,43 @@ export function ChatBar(props: {
153169 < div
154170 className = { cn (
155171 "overflow-hidden rounded-2xl border border-border bg-card transition-colors" ,
156- isDragOver &&
157- props . allowImageUpload &&
158- "border-nebula-pink-foreground bg-nebula-pink/5" ,
159- props . className
172+ isDragOver && "border-nebula-pink-foreground bg-nebula-pink/5" ,
173+ props . className ,
160174 ) }
161175 onDrop = { ( e ) => {
162- e . preventDefault ( ) ;
163176 setIsDragOver ( false ) ;
164- if ( ! props . allowImageUpload ) return ;
177+ e . preventDefault ( ) ;
178+ if ( ! props . allowImageUpload ) {
179+ showSigninToUploadImagesToast ( ) ;
180+ return ;
181+ }
165182 const files = Array . from ( e . dataTransfer . files ) ;
166183 if ( files . length > 0 ) handleImageUpload ( files ) ;
167184 } }
168185 onDragOver = { ( e ) => {
169186 e . preventDefault ( ) ;
170- if ( props . allowImageUpload ) {
171- setIsDragOver ( true ) ;
187+ setIsDragOver ( true ) ;
188+ if ( ! props . allowImageUpload ) {
189+ return ;
172190 }
173191 } }
174192 onDragEnter = { ( e ) => {
175193 e . preventDefault ( ) ;
176- if ( props . allowImageUpload ) {
177- setIsDragOver ( true ) ;
194+ setIsDragOver ( true ) ;
195+ if ( ! props . allowImageUpload ) {
196+ return ;
178197 }
179198 } }
180199 onDragLeave = { ( e ) => {
181200 e . preventDefault ( ) ;
201+ if ( ! props . allowImageUpload ) {
202+ return ;
203+ }
182204 // Only set drag over to false if we're leaving the container entirely
183205 if ( ! e . currentTarget . contains ( e . relatedTarget as Node ) ) {
184206 setIsDragOver ( false ) ;
185207 }
186208 } }
187- aria-dropeffect = { props . allowImageUpload ? "copy" : "none" }
188209 >
189210 { images . length > 0 && (
190211 < ImagePreview
@@ -203,10 +224,13 @@ export function ChatBar(props: {
203224 value = { message }
204225 onChange = { ( e ) => setMessage ( e . target . value ) }
205226 onPaste = { ( e ) => {
206- if ( ! props . allowImageUpload ) return ;
207227 const files = Array . from ( e . clipboardData . files ) ;
208228 if ( files . length > 0 ) {
209229 e . preventDefault ( ) ;
230+ if ( ! props . allowImageUpload ) {
231+ showSigninToUploadImagesToast ( ) ;
232+ return ;
233+ }
210234 handleImageUpload ( files ) ;
211235 }
212236 } }
@@ -321,7 +345,7 @@ export function ChatBar(props: {
321345 < ImageUploadButton
322346 multiple
323347 value = { undefined }
324- accept = "image/jpeg,image/png,image/webp"
348+ accept = { supportedFileTypes . join ( "," ) }
325349 onChange = { ( files ) => {
326350 handleImageUpload ( files ) ;
327351 } }
@@ -582,7 +606,7 @@ function WalletSelector(props: {
582606 key = { wallet . address }
583607 className = { cn (
584608 "flex cursor-pointer items-center justify-between px-3 py-4 hover:bg-accent/50" ,
585- props . selectedAddress === wallet . address && "bg-accent/50"
609+ props . selectedAddress === wallet . address && "bg-accent/50" ,
586610 ) }
587611 onKeyDown = { ( e ) => {
588612 if ( e . key === "Enter" || e . key === " " ) {
0 commit comments