@@ -7,6 +7,52 @@ const resolveImageUrl = (url: string): string => {
77 return url . startsWith ( 'http' ) ? url : `${ getConfigValue ( 'APPFLOWY_BASE_URL' , '' ) } ${ url } ` ;
88} ;
99
10+ // Helper function to check image using Image() approach
11+ const checkImageWithImageElement = (
12+ imageUrl : string ,
13+ resolve : ( data : {
14+ ok : boolean ,
15+ status : number ,
16+ statusText : string ,
17+ error ?: string ,
18+ validatedUrl ?: string ,
19+ } ) => void
20+ ) => {
21+ const img = new Image ( ) ;
22+
23+ // Set a timeout to handle very slow loads
24+ const timeoutId = setTimeout ( ( ) => {
25+ resolve ( {
26+ ok : false ,
27+ status : 408 ,
28+ statusText : 'Request Timeout' ,
29+ error : 'Image loading timed out' ,
30+ } ) ;
31+ } , 10000 ) ; // 10 second timeout
32+
33+ img . onload = ( ) => {
34+ clearTimeout ( timeoutId ) ;
35+ resolve ( {
36+ ok : true ,
37+ status : 200 ,
38+ statusText : 'OK' ,
39+ validatedUrl : imageUrl ,
40+ } ) ;
41+ } ;
42+
43+ img . onerror = ( ) => {
44+ clearTimeout ( timeoutId ) ;
45+ resolve ( {
46+ ok : false ,
47+ status : 404 ,
48+ statusText : 'Image Not Found' ,
49+ error : 'Failed to load image' ,
50+ } ) ;
51+ } ;
52+
53+ img . src = imageUrl ;
54+ } ;
55+
1056export const checkImage = async ( url : string ) => {
1157 return new Promise ( ( resolve : ( data : {
1258 ok : boolean ,
@@ -15,47 +61,16 @@ export const checkImage = async (url: string) => {
1561 error ?: string ,
1662 validatedUrl ?: string ,
1763 } ) => void ) => {
18- // If it's an AppFlowy file storage URL, use authenticated fetch
64+ // If it's an AppFlowy file storage URL, try authenticated fetch first
1965 if ( isAppFlowyFileStorageUrl ( url ) ) {
2066 const token = getTokenParsed ( ) ;
2167
2268 if ( ! token ) {
2369 // Allow browser to load publicly-accessible URLs without authentication
2470 // Fall through to Image() approach with resolved URL
2571 const resolvedUrl = resolveImageUrl ( url ) ;
26- const img = new Image ( ) ;
27-
28- // Set a timeout to handle very slow loads
29- const timeoutId = setTimeout ( ( ) => {
30- resolve ( {
31- ok : false ,
32- status : 408 ,
33- statusText : 'Request Timeout' ,
34- error : 'Image loading timed out' ,
35- } ) ;
36- } , 10000 ) ; // 10 second timeout
37-
38- img . onload = ( ) => {
39- clearTimeout ( timeoutId ) ;
40- resolve ( {
41- ok : true ,
42- status : 200 ,
43- statusText : 'OK' ,
44- validatedUrl : resolvedUrl ,
45- } ) ;
46- } ;
47-
48- img . onerror = ( ) => {
49- clearTimeout ( timeoutId ) ;
50- resolve ( {
51- ok : false ,
52- status : 404 ,
53- statusText : 'Image Not Found' ,
54- error : 'Failed to load image' ,
55- } ) ;
56- } ;
57-
58- img . src = resolvedUrl ;
72+
73+ checkImageWithImageElement ( resolvedUrl , resolve ) ;
5974 return ;
6075 }
6176
@@ -67,6 +82,7 @@ export const checkImage = async (url: string) => {
6782 } ,
6883 } )
6984 . then ( ( response ) => {
85+ console . debug ( "fetchImageBlob response" , response ) ;
7086 if ( response . ok ) {
7187 // Convert to blob URL for use in img tag
7288 return response . blob ( ) . then ( ( blob ) => {
@@ -80,59 +96,20 @@ export const checkImage = async (url: string) => {
8096 } ) ;
8197 } ) ;
8298 } else {
83- resolve ( {
84- ok : false ,
85- status : response . status ,
86- statusText : response . statusText ,
87- error : `Failed to fetch image: ${ response . statusText } ` ,
88- } ) ;
99+ // If authenticated fetch fails, fall back to Image() approach
100+ // This allows publicly-accessible URLs to still work
101+ checkImageWithImageElement ( fullUrl , resolve ) ;
89102 }
90103 } )
91- . catch ( ( error ) => {
92- resolve ( {
93- ok : false ,
94- status : 500 ,
95- statusText : 'Internal Error' ,
96- error : error . message || 'Failed to fetch image' ,
97- } ) ;
104+ . catch ( ( ) => {
105+ // If fetch throws an error (CORS, network, etc.), fall back to Image() approach
106+ checkImageWithImageElement ( fullUrl , resolve ) ;
98107 } ) ;
99108 return ;
100109 }
101110
102111 // For non-AppFlowy URLs, use the original Image() approach
103- const img = new Image ( ) ;
104-
105- // Set a timeout to handle very slow loads
106- const timeoutId = setTimeout ( ( ) => {
107- resolve ( {
108- ok : false ,
109- status : 408 ,
110- statusText : 'Request Timeout' ,
111- error : 'Image loading timed out' ,
112- } ) ;
113- } , 10000 ) ; // 10 second timeout
114-
115- img . onload = ( ) => {
116- clearTimeout ( timeoutId ) ;
117- resolve ( {
118- ok : true ,
119- status : 200 ,
120- statusText : 'OK' ,
121- validatedUrl : url ,
122- } ) ;
123- } ;
124-
125- img . onerror = ( ) => {
126- clearTimeout ( timeoutId ) ;
127- resolve ( {
128- ok : false ,
129- status : 404 ,
130- statusText : 'Image Not Found' ,
131- error : 'Failed to load image' ,
132- } ) ;
133- } ;
134-
135- img . src = url ;
112+ checkImageWithImageElement ( url , resolve ) ;
136113 } ) ;
137114} ;
138115
0 commit comments