@@ -90,7 +90,7 @@ const ImageLoader = {
90
90
) {
91
91
let complete = false ;
92
92
const interval = setInterval ( callback , 16 ) ;
93
- const requestId = ImageLoader . load ( uri , callback , errorCallback ) ;
93
+ const { requestId } = ImageLoader . load ( { uri } , callback , errorCallback ) ;
94
94
95
95
function callback ( ) {
96
96
const image = requests [ `${ requestId } ` ] ;
@@ -118,7 +118,11 @@ const ImageLoader = {
118
118
has ( uri : string ) : boolean {
119
119
return ImageUriCache . has ( uri ) ;
120
120
} ,
121
- load ( uri : string , onLoad : Function , onError : Function ) : number {
121
+ load (
122
+ source : { uri : string } ,
123
+ onLoad : Function ,
124
+ onError : Function
125
+ ) : LoadRequest {
122
126
id += 1 ;
123
127
const image = new window . Image ( ) ;
124
128
image . onerror = onError ;
@@ -142,14 +146,56 @@ const ImageLoader = {
142
146
setTimeout ( onDecode , 0 ) ;
143
147
}
144
148
} ;
145
- image . src = uri ;
149
+ image . src = source . uri ;
146
150
requests [ `${ id } ` ] = image ;
147
- return id ;
151
+
152
+ return {
153
+ cancel : ( ) => ImageLoader . abort ( id ) ,
154
+ requestId : id
155
+ } ;
156
+ } ,
157
+ loadWithHeaders (
158
+ source : ImageSource ,
159
+ onLoad : Function ,
160
+ onError : Function
161
+ ) : LoadRequest {
162
+ let loadRequest : LoadRequest ;
163
+ let uri : string ;
164
+ const abortCtrl = new AbortController ( ) ;
165
+ const request = new Request ( source . uri , {
166
+ headers : source . headers ,
167
+ signal : abortCtrl . signal
168
+ } ) ;
169
+ request . headers . append ( 'accept' , 'image/*' ) ;
170
+
171
+ fetch ( request )
172
+ . then ( ( response ) => response . blob ( ) )
173
+ . then ( ( blob ) => {
174
+ uri = URL . createObjectURL ( blob ) ;
175
+ loadRequest = ImageLoader . load ( { uri } , onLoad , onError ) ;
176
+ } )
177
+ . catch ( ( error ) => {
178
+ if ( error . name !== 'AbortError' && onError ) {
179
+ onError ( { nativeEvent : error . message } ) ;
180
+ }
181
+ } ) ;
182
+
183
+ return {
184
+ get requestId ( ) {
185
+ if ( loadRequest ) return loadRequest . requestId ;
186
+ return - 1 ;
187
+ } ,
188
+ cancel : ( ) => {
189
+ abortCtrl . abort ( ) ;
190
+ if ( loadRequest ) loadRequest . cancel ( ) ;
191
+ URL . revokeObjectURL ( uri ) ;
192
+ }
193
+ } ;
148
194
} ,
149
195
prefetch ( uri : string ) : Promise < void > {
150
196
return new Promise ( ( resolve , reject ) => {
151
197
ImageLoader . load (
152
- uri ,
198
+ { uri } ,
153
199
( ) => {
154
200
// Add the uri to the cache so it can be immediately displayed when used
155
201
// but also immediately remove it to correctly reflect that it has no active references
@@ -172,4 +218,14 @@ const ImageLoader = {
172
218
}
173
219
} ;
174
220
221
+ export type LoadRequest = {
222
+ cancel : Function ,
223
+ requestId : number
224
+ } ;
225
+
226
+ type ImageSource = {
227
+ uri : string ,
228
+ headers : { [ key : string ] : string }
229
+ } ;
230
+
175
231
export default ImageLoader ;
0 commit comments