@@ -230,132 +230,6 @@ function captureImageFromPTT() {
230230 showStatus ( 'IMAGE CAPTURED! GENERATE PALETTE' , 'success' ) ;
231231}
232232
233- // Function to upload image to multiple fallback services
234- async function uploadToImageHost ( imageData ) {
235- const services = [
236- {
237- name : 'catbox' ,
238- url : 'https://catbox.moe/user/api.php' ,
239- formData : ( blob ) => {
240- const formData = new FormData ( ) ;
241- formData . append ( 'reqtype' , 'fileupload' ) ;
242- formData . append ( 'fileToUpload' , blob , 'image.jpg' ) ;
243- return formData ;
244- }
245- } ,
246- {
247- name : 'imgur' ,
248- url : 'https://api.imgur.com/3/image' ,
249- headers : {
250- 'Authorization' : 'Client-ID 546c223def8fc9a' // Anonymous client ID
251- } ,
252- formData : ( blob ) => {
253- const formData = new FormData ( ) ;
254- formData . append ( 'image' , blob ) ;
255- return formData ;
256- }
257- } ,
258- {
259- name : 'freeimagehost' ,
260- url : 'https://freeimage.host/api/1/upload' ,
261- formData : ( blob ) => {
262- const formData = new FormData ( ) ;
263- formData . append ( 'key' , '6d207e02198a847aa98d0a2a901485a5' ) ; // Public key
264- formData . append ( 'source' , blob ) ;
265- formData . append ( 'format' , 'txt' ) ;
266- return formData ;
267- }
268- }
269- ] ;
270-
271- showStatus ( 'UPLOADING IMAGE...' , 'info' ) ;
272-
273- for ( let i = 0 ; i < services . length ; i ++ ) {
274- const service = services [ i ] ;
275- try {
276- showStatus ( `UPLOADING TO ${ service . name . toUpperCase ( ) } ...` , 'info' ) ;
277- console . log ( `Trying to upload to ${ service . name } ` ) ;
278-
279- // Convert data URL to Blob
280- const blob = dataURLToBlob ( imageData ) ;
281- console . log ( 'Blob created, size:' , blob . size , 'type:' , blob . type ) ;
282-
283- // Check if blob is valid
284- if ( blob . size === 0 ) {
285- throw new Error ( 'Image blob is empty' ) ;
286- }
287-
288- // Create FormData
289- const formData = service . formData ( blob ) ;
290-
291- // Try to upload with timeout
292- console . log ( 'Sending request to' , service . name ) ;
293- const controller = new AbortController ( ) ;
294- const timeoutId = setTimeout ( ( ) => controller . abort ( ) , 15000 ) ; // 15 second timeout
295-
296- const fetchOptions = {
297- method : 'POST' ,
298- body : formData ,
299- signal : controller . signal
300- } ;
301-
302- // Add headers if specified
303- if ( service . headers ) {
304- fetchOptions . headers = service . headers ;
305- }
306-
307- const response = await fetch ( service . url , fetchOptions ) ;
308-
309- clearTimeout ( timeoutId ) ;
310-
311- console . log ( `${ service . name } response status:` , response . status ) ;
312-
313- if ( response . ok ) {
314- let url ;
315- if ( service . name === 'imgur' ) {
316- const data = await response . json ( ) ;
317- url = data . data . link ;
318- } else if ( service . name === 'freeimagehost' ) {
319- url = await response . text ( ) ;
320- } else {
321- const responseText = await response . text ( ) ;
322- url = responseText . trim ( ) ;
323- }
324-
325- console . log ( 'Image uploaded successfully to:' , url ) ;
326-
327- // Validate that we got a URL
328- if ( url && url . length > 0 && ( url . startsWith ( 'http://' ) || url . startsWith ( 'https://' ) ) ) {
329- showStatus ( `UPLOADED TO ${ service . name . toUpperCase ( ) } SUCCESSFULLY` , 'success' ) ;
330- return { url, service : service . name } ;
331- } else {
332- throw new Error ( `Invalid URL received from ${ service . name } : ${ url } ` ) ;
333- }
334- } else {
335- const errorText = await response . text ( ) ;
336- throw new Error ( `Upload failed with status: ${ response . status } ${ response . statusText } - ${ errorText } ` ) ;
337- }
338- } catch ( error ) {
339- console . error ( `Error uploading to ${ service . name } :` , error ) ;
340- if ( i === services . length - 1 ) {
341- // Last service, throw the error
342- if ( error . name === 'AbortError' ) {
343- showStatus ( 'UPLOAD TIMED OUT - CHECK NETWORK' , 'error' ) ;
344- } else if ( error . message . includes ( 'fetch' ) ) {
345- showStatus ( 'NETWORK ERROR - UPLOAD SERVICE UNAVAILABLE' , 'error' ) ;
346- } else {
347- showStatus ( 'UPLOAD FAILED: ' + error . message , 'error' ) ;
348- }
349- throw error ;
350- } else {
351- // Try next service
352- showStatus ( `FAILED ${ service . name . toUpperCase ( ) } , TRYING NEXT...` , 'info' ) ;
353- continue ;
354- }
355- }
356- }
357- }
358-
359233// Helper function to convert data URL to Blob
360234function dataURLToBlob ( dataURL ) {
361235 try {
@@ -393,14 +267,14 @@ function analyzeColorsFromImage() {
393267 return ;
394268 }
395269
396- showStatus ( 'ANALYZING COLORS ...' , 'info' ) ;
270+ showStatus ( 'UPLOADING IMAGE TO IMGUR ...' , 'info' ) ;
397271 console . log ( 'Analyzing colors. PluginMessageHandler available:' , typeof PluginMessageHandler !== 'undefined' ) ;
398272
399273 // In a real R1 implementation, we would send this to the LLM
400274 if ( typeof PluginMessageHandler !== 'undefined' ) {
401- console . log ( 'Sending image directly to LLM ' ) ;
402- // Send image data directly to LLM for analysis
403- sendImageToLLM ( ) ;
275+ console . log ( 'Uploading image to imgur.com ' ) ;
276+ // Upload to imgur and then send URL to LLM
277+ uploadToImgurAndAnalyze ( ) ;
404278 } else {
405279 console . log ( 'Simulating analysis for browser testing' ) ;
406280 // Simulate analysis for browser testing with more realistic colors
@@ -594,16 +468,14 @@ window.onPluginMessage = function(data) {
594468 resetApp ( ) ;
595469 } , 2000 ) ;
596470 }
597- // Handle case where LLM requests image URL (fallback) - use new multi-service function
471+ // Handle case where LLM requests image URL - but we're already using imgur
598472 else if ( data . message . includes ( 'image' ) &&
599473 ( data . message . includes ( 'url' ) ||
600474 data . message . includes ( 'link' ) ||
601475 data . message . includes ( 'file' ) ||
602476 data . message . includes ( 'upload' ) ) ) {
603- showStatus ( 'LLM NEEDS IMAGE URL - UPLOADING...' , 'info' ) ;
604- console . log ( 'LLM requested image URL, using multi-service fallback' ) ;
605- // Use multi-service fallback only when LLM explicitly requests it
606- fallbackToImageHostAnalysis ( ) ;
477+ showStatus ( 'LLM REQUESTED IMAGE URL - ALREADY USING IMGUR' , 'info' ) ;
478+ console . log ( 'LLM requested image URL but we already sent imgur URL' ) ;
607479 } else if ( data . message . includes ( 'timeout' ) || data . message . includes ( 'failed' ) || data . message . includes ( 'error' ) ) {
608480 showStatus ( 'LLM ERROR: ' + data . message , 'error' ) ;
609481 } else {
@@ -710,34 +582,9 @@ function createColorShapes(colors) {
710582 return shapesContainer ;
711583}
712584
713- // Function to send image directly to LLM for analysis
714- function sendImageToLLM ( ) {
715- showStatus ( 'SENDING IMAGE TO LLM...' , 'info' ) ;
716-
717- try {
718- // Log the image data info for debugging
719- console . log ( 'Sending image to LLM. Image data length:' , capturedImageData ? capturedImageData . length : 'null' ) ;
720-
721- // Send image data directly to LLM for analysis with more specific instructions
722- const payload = {
723- message : `I'm sending you an image captured from the R1 device's camera. Please analyze this image and extract exactly 5 dominant colors in hex format. Return ONLY a JSON object in this exact format: {"colors": ["#hex1", "#hex2", "#hex3", "#hex4", "#hex5"]}. Do not request an image URL as I'm sending the image data directly.` ,
724- useLLM : true ,
725- wantsR1Response : false , // Set to false to get JSON response
726- imageData : capturedImageData // Send image data directly
727- } ;
728-
729- console . log ( 'Sending image to LLM with payload:' , JSON . stringify ( payload , null , 2 ) ) ;
730- PluginMessageHandler . postMessage ( JSON . stringify ( payload ) ) ;
731- showStatus ( 'IMAGE SENT TO LLM. WAITING FOR RESPONSE...' , 'info' ) ;
732- } catch ( error ) {
733- console . error ( 'Error sending image to LLM:' , error ) ;
734- showStatus ( 'LLM COMMUNICATION FAILED' , 'error' ) ;
735- }
736- }
737-
738- // Fallback function to use multiple image hosting services (only when LLM requests it)
739- async function fallbackToImageHostAnalysis ( ) {
740- showStatus ( 'UPLOADING IMAGE TO HOST...' , 'info' ) ;
585+ // Function to upload image to imgur and analyze
586+ async function uploadToImgurAndAnalyze ( ) {
587+ showStatus ( 'UPLOADING IMAGE TO IMGUR...' , 'info' ) ;
741588
742589 try {
743590 // Check if we have image data
@@ -752,33 +599,72 @@ async function fallbackToImageHostAnalysis() {
752599 throw new Error ( 'Captured image data is too small' ) ;
753600 }
754601
755- // Upload image to fallback services
756- const { url, service } = await uploadToImageHost ( capturedImageData ) ;
602+ // Convert data URL to Blob
603+ const blob = dataURLToBlob ( capturedImageData ) ;
604+ console . log ( 'Blob created, size:' , blob . size , 'type:' , blob . type ) ;
757605
758- if ( url && url . length > 0 ) {
759- showStatus ( `IMAGE UPLOADED TO ${ service . toUpperCase ( ) } ! REQUESTING ANALYSIS...` , 'info' ) ;
760- console . log ( 'Image uploaded to:' , url ) ;
761-
762- // Validate URL before sending to LLM
763- if ( ! url . startsWith ( 'http' ) ) {
764- throw new Error ( 'Invalid image URL received' ) ;
765- }
606+ // Check if blob is valid
607+ if ( blob . size === 0 ) {
608+ throw new Error ( 'Image blob is empty' ) ;
609+ }
610+
611+ // Create FormData for imgur
612+ const formData = new FormData ( ) ;
613+ formData . append ( 'image' , blob ) ;
614+
615+ // Try to upload to imgur with timeout
616+ console . log ( 'Sending request to imgur.com' ) ;
617+ const controller = new AbortController ( ) ;
618+ const timeoutId = setTimeout ( ( ) => controller . abort ( ) , 15000 ) ; // 15 second timeout
619+
620+ const response = await fetch ( 'https://api.imgur.com/3/image' , {
621+ method : 'POST' ,
622+ body : formData ,
623+ headers : {
624+ 'Authorization' : 'Client-ID 546c223def8fc9a' // Anonymous client ID
625+ } ,
626+ signal : controller . signal
627+ } ) ;
628+
629+ clearTimeout ( timeoutId ) ;
630+
631+ console . log ( 'Imgur response status:' , response . status ) ;
632+
633+ if ( response . ok ) {
634+ const data = await response . json ( ) ;
635+ const imageUrl = data . data . link ;
766636
767- // Send image URL to LLM for analysis with clearer instructions
768- const payload = {
769- message : `I've uploaded the image to ${ url } using ${ service } . Please analyze this image and extract exactly 5 dominant colors in hex format. Return ONLY a JSON object in this exact format: {"colors": ["#hex1", "#hex2", "#hex3", "#hex4", "#hex5"]}.` ,
770- useLLM : true ,
771- wantsR1Response : false // Set to false to get JSON response
772- } ;
637+ console . log ( 'Image uploaded successfully to:' , imageUrl ) ;
773638
774- console . log ( 'Sending to LLM:' , payload . message ) ;
775- showStatus ( 'REQUESTING COLOR ANALYSIS...' , 'info' ) ;
776- PluginMessageHandler . postMessage ( JSON . stringify ( payload ) ) ;
639+ // Validate that we got a URL
640+ if ( imageUrl && imageUrl . length > 0 && ( imageUrl . startsWith ( 'http://' ) || imageUrl . startsWith ( 'https://' ) ) ) {
641+ showStatus ( 'IMAGE UPLOADED TO IMGUR! REQUESTING ANALYSIS...' , 'success' ) ;
642+
643+ // Send image URL to LLM for analysis
644+ const payload = {
645+ message : `Please analyze the colors in this image and provide exactly 5 dominant colors in hex format. Response format: {"colors": ["#hex1", "#hex2", "#hex3", "#hex4", "#hex5"]}. Image URL: ${ imageUrl } ` ,
646+ useLLM : true ,
647+ wantsR1Response : false // Set to false to get JSON response
648+ } ;
649+
650+ console . log ( 'Sending to LLM:' , payload . message ) ;
651+ showStatus ( 'REQUESTING COLOR ANALYSIS...' , 'info' ) ;
652+ PluginMessageHandler . postMessage ( JSON . stringify ( payload ) ) ;
653+ } else {
654+ throw new Error ( 'Invalid URL received from imgur' ) ;
655+ }
777656 } else {
778- throw new Error ( 'Failed to get image URL from hosting service' ) ;
657+ const errorData = await response . json ( ) ;
658+ throw new Error ( 'Upload failed with status: ' + response . status + ' - ' + ( errorData . data ? errorData . data . error : 'Unknown error' ) ) ;
779659 }
780660 } catch ( error ) {
781- console . error ( 'Image hosting analysis error:' , error ) ;
782- showStatus ( 'ANALYSIS FAILED: ' + error . message , 'error' ) ;
661+ console . error ( 'Imgur upload error:' , error ) ;
662+ if ( error . name === 'AbortError' ) {
663+ showStatus ( 'UPLOAD TIMED OUT - CHECK NETWORK' , 'error' ) ;
664+ } else if ( error . message . includes ( 'fetch' ) ) {
665+ showStatus ( 'NETWORK ERROR - IMGUR UNAVAILABLE' , 'error' ) ;
666+ } else {
667+ showStatus ( 'UPLOAD FAILED: ' + error . message , 'error' ) ;
668+ }
783669 }
784670}
0 commit comments