react-native-fast-image 10.3.0 → 10.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -4
- package/android/src/main/java/com/fastimage/FastImageViewConverter.java +1 -1
- package/android/src/main/java/com/fastimage/FastImageViewManager.java +14 -1
- package/android/src/main/java/com/fastimage/FastImageViewWithUrl.java +145 -5
- package/dist/index.cjs.js +10 -4
- package/dist/index.cjs.js.flow +9 -1
- package/dist/index.cjs.web.js +29 -7
- package/dist/index.cjs.web.js.flow +9 -1
- package/dist/index.d.ts +30 -3
- package/dist/index.js +10 -4
- package/dist/index.js.flow +9 -1
- package/dist/index.web.js +29 -7
- package/dist/index.web.js.flow +9 -1
- package/dist/placeholders.d.ts +2 -1
- package/dist/specs/FastImageViewNativeComponent.d.ts +1 -0
- package/ios/FastImage/FFFDownsampledImage.h +10 -7
- package/ios/FastImage/FFFDownsampledImage.m +25 -3
- package/ios/FastImage/FFFastImageModule.mm +1 -1
- package/ios/FastImage/FFFastImageView.h +8 -0
- package/ios/FastImage/FFFastImageView.m +239 -16
- package/ios/FastImage/FFFastImageViewComponentView.mm +22 -1
- package/package.json +1 -1
- package/src/index.js.flow +9 -1
- package/src/index.tsx +60 -13
- package/src/index.web.tsx +48 -4
- package/src/placeholders.ts +26 -9
- package/src/specs/FastImageViewNativeComponent.ts +7 -2
package/dist/index.js
CHANGED
|
@@ -234,8 +234,14 @@ var FastImageViewNativeComponent_default = codegenNativeComponent("FastImageView
|
|
|
234
234
|
var NativeFastImageModule_default = TurboModuleRegistry.get("FastImageModule");
|
|
235
235
|
//#endregion
|
|
236
236
|
//#region src/placeholders.ts
|
|
237
|
+
const SCHEME = /^[a-z][a-z\d+.-]*:/i;
|
|
237
238
|
function isImageName(value) {
|
|
238
|
-
return
|
|
239
|
+
return !SCHEME.test(value) && !value.startsWith("/");
|
|
240
|
+
}
|
|
241
|
+
function placeholderSource(value) {
|
|
242
|
+
const uri = typeof value === "string" ? value : value && typeof value === "object" ? value.uri : void 0;
|
|
243
|
+
if (typeof uri !== "string" || !/^https?:/i.test(uri)) return void 0;
|
|
244
|
+
return typeof value === "string" ? { uri } : value;
|
|
239
245
|
}
|
|
240
246
|
function hasSourcePlaceholder(value) {
|
|
241
247
|
return !!value && typeof value === "object" && ("thumbhash" in value || "blurDataUri" in value);
|
|
@@ -243,7 +249,7 @@ function hasSourcePlaceholder(value) {
|
|
|
243
249
|
function dataUri(value) {
|
|
244
250
|
if (typeof value !== "string" || value === "") return void 0;
|
|
245
251
|
if (/^data:/i.test(value)) return value;
|
|
246
|
-
if (typeof __DEV__ !== "undefined" && __DEV__) warnOnce("placeholder-url", `react-native-fast-image: \`
|
|
252
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) warnOnce("placeholder-url", `react-native-fast-image: \`blurDataUri\` takes a data uri (data:image/…): "${value.slice(0, 60)}" is ignored. For a placeholder loaded from a url, use \`placeholder\`.`, "warn");
|
|
247
253
|
}
|
|
248
254
|
//#endregion
|
|
249
255
|
//#region src/index.tsx
|
|
@@ -321,7 +327,7 @@ function builtInTransition() {
|
|
|
321
327
|
}
|
|
322
328
|
let defaultTransition;
|
|
323
329
|
function FastImageBase({ source, placeholder, defaultSource, tintColor, onLoadStart, onProgress, onLoad, onError, onLoadEnd, style, children, objectFit, objectPosition, loop, transition, loading: _loading, sizes: _sizes, forwardedRef, ...viewProps }) {
|
|
324
|
-
var _props$recyclingKey, _defaultTransition;
|
|
330
|
+
var _placeholderSource, _props$recyclingKey, _defaultTransition;
|
|
325
331
|
const { fallback, resizeMode: _resizeMode, ...props } = viewProps;
|
|
326
332
|
if (__DEV__ && fallback !== void 0) warnOnce("fallback", "react-native-fast-image: `fallback` was removed in 10.0, and does nothing: images always load natively. Remove it, or use React Native's Image for those images.", "warn");
|
|
327
333
|
if (__DEV__) warnIfChildren(children);
|
|
@@ -339,7 +345,7 @@ function FastImageBase({ source, placeholder, defaultSource, tintColor, onLoadSt
|
|
|
339
345
|
sourcePlaceholders: placeholders.some(Boolean) ? placeholders : void 0
|
|
340
346
|
};
|
|
341
347
|
}, [source, shared]);
|
|
342
|
-
const resolvedPlaceholder = resolvePlaceholder(hasSourcePlaceholder(placeholder) ? defaultSource : placeholder !== null && placeholder !== void 0 ? placeholder : defaultSource);
|
|
348
|
+
const resolvedPlaceholder = (_placeholderSource = placeholderSource(placeholder)) !== null && _placeholderSource !== void 0 ? _placeholderSource : resolvePlaceholder(hasSourcePlaceholder(placeholder) ? defaultSource : placeholder !== null && placeholder !== void 0 ? placeholder : defaultSource);
|
|
343
349
|
return /* @__PURE__ */ React.createElement(FastImageViewNativeComponent_default, {
|
|
344
350
|
...props,
|
|
345
351
|
ref: forwardedRef,
|
package/dist/index.js.flow
CHANGED
|
@@ -110,6 +110,13 @@ export type PreloadResult = PreloadSuccess | PreloadFailure
|
|
|
110
110
|
export type PreloadFn = (
|
|
111
111
|
sources: Array<FastImageSource>,
|
|
112
112
|
) => Promise<Array<PreloadResult>>
|
|
113
|
+
export type PlaceholderSource = {
|
|
114
|
+
uri?: string,
|
|
115
|
+
headers?: Object,
|
|
116
|
+
cacheKey?: string,
|
|
117
|
+
cache?: CacheControls,
|
|
118
|
+
}
|
|
119
|
+
|
|
113
120
|
export type SourcePlaceholder = {
|
|
114
121
|
thumbhash?: string,
|
|
115
122
|
blurDataUri?: string,
|
|
@@ -139,7 +146,7 @@ export type FastImageProps = $ReadOnly<{|
|
|
|
139
146
|
onProgress?: ?(event: OnProgressEvent) => void,
|
|
140
147
|
|
|
141
148
|
source?: ?(FastImageSource | Array<FastImageSource> | number),
|
|
142
|
-
placeholder?: ?(number | string | SourcePlaceholder),
|
|
149
|
+
placeholder?: ?(number | string | SourcePlaceholder | PlaceholderSource),
|
|
143
150
|
// Deprecated: use placeholder, which is the same.
|
|
144
151
|
defaultSource?: ?number,
|
|
145
152
|
|
|
@@ -151,6 +158,7 @@ export type FastImageProps = $ReadOnly<{|
|
|
|
151
158
|
imageRendering?: ?('auto' | 'smooth' | 'pixelated'),
|
|
152
159
|
loading?: ?('lazy' | 'eager'),
|
|
153
160
|
sizes?: ?string,
|
|
161
|
+
dynamicRangeLimit?: ?('standard' | 'constrained' | 'no-limit'),
|
|
154
162
|
paused?: ?boolean,
|
|
155
163
|
transition?: ?(boolean | number | Transition),
|
|
156
164
|
downsample?: ?boolean,
|
package/dist/index.web.js
CHANGED
|
@@ -241,13 +241,18 @@ function cssPosition({ x, y }) {
|
|
|
241
241
|
}
|
|
242
242
|
//#endregion
|
|
243
243
|
//#region src/placeholders.ts
|
|
244
|
+
function placeholderSource(value) {
|
|
245
|
+
const uri = typeof value === "string" ? value : value && typeof value === "object" ? value.uri : void 0;
|
|
246
|
+
if (typeof uri !== "string" || !/^https?:/i.test(uri)) return void 0;
|
|
247
|
+
return typeof value === "string" ? { uri } : value;
|
|
248
|
+
}
|
|
244
249
|
function hasSourcePlaceholder(value) {
|
|
245
250
|
return !!value && typeof value === "object" && ("thumbhash" in value || "blurDataUri" in value);
|
|
246
251
|
}
|
|
247
252
|
function dataUri(value) {
|
|
248
253
|
if (typeof value !== "string" || value === "") return void 0;
|
|
249
254
|
if (/^data:/i.test(value)) return value;
|
|
250
|
-
if (typeof __DEV__ !== "undefined" && __DEV__) warnOnce("placeholder-url", `react-native-fast-image: \`
|
|
255
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) warnOnce("placeholder-url", `react-native-fast-image: \`blurDataUri\` takes a data uri (data:image/…): "${value.slice(0, 60)}" is ignored. For a placeholder loaded from a url, use \`placeholder\`.`, "warn");
|
|
251
256
|
}
|
|
252
257
|
//#endregion
|
|
253
258
|
//#region src/index.web.tsx
|
|
@@ -256,8 +261,8 @@ const notSupported = {
|
|
|
256
261
|
error: "Not supported on the web"
|
|
257
262
|
};
|
|
258
263
|
const useClientLayoutEffect = globalThis.document === void 0 ? useEffect : useLayoutEffect;
|
|
259
|
-
function FastImageBase({ source, placeholder, defaultSource, tintColor, blurRadius, onLoadStart, onLoad, onError, onLoadEnd, style, children, objectFit, objectPosition, loading, sizes, forwardedRef, onLayout, pointerEvents, recyclingKey: _recyclingKey, loop: _loop, imageRendering: _imageRendering, paused: _paused, transition: _transition, downsample: _downsample, onProgress: _onProgress, ...props }) {
|
|
260
|
-
var _resolveUri;
|
|
264
|
+
function FastImageBase({ source, placeholder, defaultSource, tintColor, blurRadius, onLoadStart, onLoad, onError, onLoadEnd, style, children, objectFit, objectPosition, loading, sizes, dynamicRangeLimit, forwardedRef, onLayout, pointerEvents, recyclingKey: _recyclingKey, loop: _loop, imageRendering: _imageRendering, paused: _paused, transition: _transition, downsample: _downsample, onProgress: _onProgress, ...props }) {
|
|
265
|
+
var _resolveUri, _placeholderSource;
|
|
261
266
|
if (typeof __DEV__ !== "undefined" && __DEV__) warnIfChildren(children);
|
|
262
267
|
const { accessibilityLabel, "aria-label": ariaLabel, resizeMode: _resizeMode, ...viewProps } = props;
|
|
263
268
|
const label = ariaLabel || accessibilityLabel || void 0;
|
|
@@ -269,7 +274,9 @@ function FastImageBase({ source, placeholder, defaultSource, tintColor, blurRadi
|
|
|
269
274
|
const priority = sourcePriority(source);
|
|
270
275
|
const preview = hasSourcePlaceholder(placeholder) ? placeholder : void 0;
|
|
271
276
|
const blurUri = (_resolveUri = resolveUri(dataUri(shared(source, "blurDataUri", preview)))) !== null && _resolveUri !== void 0 ? _resolveUri : thumbhashUri(shared(source, "thumbhash", preview));
|
|
272
|
-
const
|
|
277
|
+
const urlPlaceholder = (_placeholderSource = placeholderSource(placeholder)) === null || _placeholderSource === void 0 ? void 0 : _placeholderSource.uri;
|
|
278
|
+
const [failedPlaceholder, setFailedPlaceholder] = useState();
|
|
279
|
+
const defaultUri = blurUri !== null && blurUri !== void 0 ? blurUri : resolveUri(preview || urlPlaceholder ? defaultSource : placeholder !== null && placeholder !== void 0 ? placeholder : defaultSource);
|
|
273
280
|
const [result, setResult] = useState();
|
|
274
281
|
const ok = result && result.key === key ? result.ok : void 0;
|
|
275
282
|
const svgId = useId().replace(/[^\w-]/g, "");
|
|
@@ -278,7 +285,7 @@ function FastImageBase({ source, placeholder, defaultSource, tintColor, blurRadi
|
|
|
278
285
|
const fit = resolveObjectFit(objectFit, style);
|
|
279
286
|
const position = cssPosition(objectPositionOrCentered(objectPosition));
|
|
280
287
|
const filter = [blurRadius ? `blur(${blurRadius}px)` : "", tintColor ? `url(#${tintId})` : ""].filter(Boolean).join(" ") || void 0;
|
|
281
|
-
const showDefault =
|
|
288
|
+
const showDefault = ok !== true;
|
|
282
289
|
useClientLayoutEffect(() => {
|
|
283
290
|
if (key) onLoadStart === null || onLoadStart === void 0 || onLoadStart();
|
|
284
291
|
}, [key]);
|
|
@@ -294,10 +301,23 @@ function FastImageBase({ source, placeholder, defaultSource, tintColor, blurRadi
|
|
|
294
301
|
src: defaultUri,
|
|
295
302
|
loading,
|
|
296
303
|
priority,
|
|
304
|
+
dynamicRangeLimit,
|
|
297
305
|
fit: blurUri && (fit === "scale-down" || fit === "none") ? "contain" : fit,
|
|
298
306
|
position,
|
|
299
307
|
filter: blurUri ? [`url(#${blurId})`, tintColor ? `url(#${tintId})` : ""].filter(Boolean).join(" ") : filter,
|
|
300
308
|
alt: key ? "" : label !== null && label !== void 0 ? label : ""
|
|
309
|
+
}) : null, urlPlaceholder && showDefault ? /* @__PURE__ */ React.createElement(Picture, {
|
|
310
|
+
key: `placeholder ${urlPlaceholder}`,
|
|
311
|
+
src: urlPlaceholder,
|
|
312
|
+
loading,
|
|
313
|
+
priority: "high",
|
|
314
|
+
dynamicRangeLimit,
|
|
315
|
+
fit: fit === "scale-down" || fit === "none" ? "contain" : fit,
|
|
316
|
+
position,
|
|
317
|
+
filter: tintColor ? `url(#${tintId})` : void 0,
|
|
318
|
+
hidden: failedPlaceholder === urlPlaceholder,
|
|
319
|
+
onError: () => setFailedPlaceholder(urlPlaceholder),
|
|
320
|
+
alt: ""
|
|
301
321
|
}) : null, key && src ? /* @__PURE__ */ React.createElement(Picture, {
|
|
302
322
|
key: several ? "sizes" : key,
|
|
303
323
|
src,
|
|
@@ -305,6 +325,7 @@ function FastImageBase({ source, placeholder, defaultSource, tintColor, blurRadi
|
|
|
305
325
|
sizes,
|
|
306
326
|
loading,
|
|
307
327
|
priority,
|
|
328
|
+
dynamicRangeLimit,
|
|
308
329
|
fit,
|
|
309
330
|
position,
|
|
310
331
|
filter,
|
|
@@ -411,7 +432,7 @@ const fill = {
|
|
|
411
432
|
width: "100%",
|
|
412
433
|
height: "100%"
|
|
413
434
|
};
|
|
414
|
-
function Picture({ src, srcSet, sizes, loading, priority, fit, position, filter, hidden, alt, onLoad, onError }) {
|
|
435
|
+
function Picture({ src, srcSet, sizes, loading, priority, dynamicRangeLimit, fit, position, filter, hidden, alt, onLoad, onError }) {
|
|
415
436
|
const image = useRef(null);
|
|
416
437
|
const mounted = useRef(true);
|
|
417
438
|
const handled = useRef(void 0);
|
|
@@ -458,7 +479,8 @@ function Picture({ src, srcSet, sizes, loading, priority, fit, position, filter,
|
|
|
458
479
|
objectFit: fit,
|
|
459
480
|
objectPosition: position,
|
|
460
481
|
filter,
|
|
461
|
-
opacity: hidden ? 0 : void 0
|
|
482
|
+
opacity: hidden ? 0 : void 0,
|
|
483
|
+
dynamicRangeLimit
|
|
462
484
|
},
|
|
463
485
|
onLoad: (event) => loaded(event.currentTarget),
|
|
464
486
|
onError: (event) => {
|
package/dist/index.web.js.flow
CHANGED
|
@@ -110,6 +110,13 @@ export type PreloadResult = PreloadSuccess | PreloadFailure
|
|
|
110
110
|
export type PreloadFn = (
|
|
111
111
|
sources: Array<FastImageSource>,
|
|
112
112
|
) => Promise<Array<PreloadResult>>
|
|
113
|
+
export type PlaceholderSource = {
|
|
114
|
+
uri?: string,
|
|
115
|
+
headers?: Object,
|
|
116
|
+
cacheKey?: string,
|
|
117
|
+
cache?: CacheControls,
|
|
118
|
+
}
|
|
119
|
+
|
|
113
120
|
export type SourcePlaceholder = {
|
|
114
121
|
thumbhash?: string,
|
|
115
122
|
blurDataUri?: string,
|
|
@@ -139,7 +146,7 @@ export type FastImageProps = $ReadOnly<{|
|
|
|
139
146
|
onProgress?: ?(event: OnProgressEvent) => void,
|
|
140
147
|
|
|
141
148
|
source?: ?(FastImageSource | Array<FastImageSource> | number),
|
|
142
|
-
placeholder?: ?(number | string | SourcePlaceholder),
|
|
149
|
+
placeholder?: ?(number | string | SourcePlaceholder | PlaceholderSource),
|
|
143
150
|
// Deprecated: use placeholder, which is the same.
|
|
144
151
|
defaultSource?: ?number,
|
|
145
152
|
|
|
@@ -151,6 +158,7 @@ export type FastImageProps = $ReadOnly<{|
|
|
|
151
158
|
imageRendering?: ?('auto' | 'smooth' | 'pixelated'),
|
|
152
159
|
loading?: ?('lazy' | 'eager'),
|
|
153
160
|
sizes?: ?string,
|
|
161
|
+
dynamicRangeLimit?: ?('standard' | 'constrained' | 'no-limit'),
|
|
154
162
|
paused?: ?boolean,
|
|
155
163
|
transition?: ?(boolean | number | Transition),
|
|
156
164
|
downsample?: ?boolean,
|
package/dist/placeholders.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { SourcePlaceholder } from './index';
|
|
1
|
+
import type { PlaceholderSource, SourcePlaceholder } from './index';
|
|
2
2
|
export declare function isImageName(value: string): boolean;
|
|
3
|
+
export declare function placeholderSource(value: unknown): PlaceholderSource | undefined;
|
|
3
4
|
export declare function hasSourcePlaceholder(value: unknown): value is SourcePlaceholder;
|
|
4
5
|
export declare function dataUri(value: unknown): string | undefined;
|
|
@@ -37,6 +37,7 @@ export interface NativeProps extends ViewProps {
|
|
|
37
37
|
transitionBetweenImages?: boolean;
|
|
38
38
|
transitionSkipOnCacheHit?: string;
|
|
39
39
|
downsample?: CodegenTypes.WithDefault<boolean, true>;
|
|
40
|
+
dynamicRangeLimit?: string;
|
|
40
41
|
blurRadius?: CodegenTypes.Float;
|
|
41
42
|
handledEvents?: CodegenTypes.Int32;
|
|
42
43
|
onFastImageLoadStart?: CodegenTypes.DirectEventHandler<LoadStartEvent>;
|
|
@@ -25,12 +25,15 @@
|
|
|
25
25
|
// loaded this way was decoded from, for onLoad, or zero for other images.
|
|
26
26
|
+ (CGSize) sourceSizeOfImage: (UIImage*)image;
|
|
27
27
|
|
|
28
|
-
//
|
|
29
|
-
//
|
|
30
|
-
//
|
|
31
|
-
//
|
|
32
|
-
//
|
|
33
|
-
//
|
|
34
|
-
|
|
28
|
+
// Drops the memory cache's image for a load (call it before the load) when
|
|
29
|
+
// the load can't use it, so it decodes the file from the disk cache:
|
|
30
|
+
// - for a full-size load (a view that doesn't downsample, or a preload), a
|
|
31
|
+
// smaller image: SDWebImage puts an image it decoded smaller from the disk
|
|
32
|
+
// cache, for a view that downsamples, under the full-size image's key too
|
|
33
|
+
// (SDWebImageManager writes what its original cache query finds back
|
|
34
|
+
// there), which would show blurry, or be a preload's size.
|
|
35
|
+
// - one decoded the other way, to HDR or SDR (dynamicRangeLimit), since
|
|
36
|
+
// SDWebImage's memory cache key is the same for both.
|
|
37
|
+
+ (void) forgetUnusableImageForURL: (NSURL*)url context: (SDWebImageContext*)context;
|
|
35
38
|
|
|
36
39
|
@end
|
|
@@ -77,7 +77,7 @@ static CGSize FFFPixelSize(NSData* data) {
|
|
|
77
77
|
return [sourceSize isKindOfClass: [FFFSourceSize class]] ? ((FFFSourceSize*) sourceSize).size : CGSizeZero;
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
+ (void)
|
|
80
|
+
+ (void) forgetUnusableImageForURL: (NSURL*)url context: (SDWebImageContext*)context {
|
|
81
81
|
SDWebImageManager* manager = [SDWebImageManager sharedManager];
|
|
82
82
|
if (!url || ![manager.imageCache isKindOfClass: [SDImageCache class]] || ![manager respondsToSelector: @selector(cacheKeyForURL:context:)]) {
|
|
83
83
|
return;
|
|
@@ -85,12 +85,34 @@ static CGSize FFFPixelSize(NSData* data) {
|
|
|
85
85
|
SDImageCache* cache = (SDImageCache*) manager.imageCache;
|
|
86
86
|
NSString* key = [manager cacheKeyForURL: url context: context];
|
|
87
87
|
UIImage* image = [cache imageFromMemoryCacheForKey: key];
|
|
88
|
-
|
|
89
|
-
if (image && fullSize.width > 0 && fullSize.height > 0 && !CGSizeEqualToSize(image.size, fullSize)) {
|
|
88
|
+
if (image && ([self isSmallerFullSizeImage: image context: context] || [self isOtherDynamicRange: image context: context])) {
|
|
90
89
|
[cache removeImageFromMemoryForKey: key];
|
|
91
90
|
}
|
|
92
91
|
}
|
|
93
92
|
|
|
93
|
+
// A smaller image under a full-size load's key.
|
|
94
|
+
+ (BOOL) isSmallerFullSizeImage: (UIImage*)image context: (SDWebImageContext*)context {
|
|
95
|
+
if (context[SDWebImageContextImageThumbnailPixelSize]) {
|
|
96
|
+
return NO;
|
|
97
|
+
}
|
|
98
|
+
CGSize fullSize = [self sourceSizeOfImage: image];
|
|
99
|
+
return fullSize.width > 0 && fullSize.height > 0 && !CGSizeEqualToSize(image.size, fullSize);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// An image decoded to SDR for an HDR load, or to HDR for an SDR load. Only
|
|
103
|
+
// images SDWebImage decoded say how: not a photo library's, or an app's own
|
|
104
|
+
// loader's, which are kept. One decoded to HDR that came out SDR (most images
|
|
105
|
+
// have no HDR) is the same as an SDR decode, and an HDR file decoded without
|
|
106
|
+
// asking is HDR either way (e.g. an HDR10 HEIC on iOS 15 and 16).
|
|
107
|
+
+ (BOOL) isOtherDynamicRange: (UIImage*)image context: (SDWebImageContext*)context {
|
|
108
|
+
if (!image.sd_decodeOptions) {
|
|
109
|
+
return NO;
|
|
110
|
+
}
|
|
111
|
+
BOOL wantsHDR = [context[SDWebImageContextImageDecodeToHDR] boolValue];
|
|
112
|
+
BOOL decodedToHDR = [image.sd_decodeOptions[SDImageCoderDecodeToHDR] boolValue];
|
|
113
|
+
return wantsHDR ? !decodedToHDR : decodedToHDR && image.sd_isHighDynamicRange;
|
|
114
|
+
}
|
|
115
|
+
|
|
94
116
|
- (instancetype) initWithData: (NSData*)data scale: (CGFloat)scale options: (SDImageCoderOptions*)options {
|
|
95
117
|
// An SVG isn't decoded smaller: it's a vector image, drawn at any size.
|
|
96
118
|
// This class can't decode it, and SDWebImage would then give it to the
|
|
@@ -305,7 +305,7 @@ static NSDictionary *FFFFile(NSString *path)
|
|
|
305
305
|
SDWebImageOptions options = FFFPreloadOptions(source);
|
|
306
306
|
SDWebImageMutableContext *context = FFFPreloadContext(source);
|
|
307
307
|
// It looks in the memory cache first, for the full-size image.
|
|
308
|
-
[FFFDownsampledImage
|
|
308
|
+
[FFFDownsampledImage forgetUnusableImageForURL:source.url context:context];
|
|
309
309
|
if (!source.memoryCache) {
|
|
310
310
|
// Not decoded (only its header is read, for the size), and not
|
|
311
311
|
// kept in memory, also when it comes from the disk cache.
|
|
@@ -34,6 +34,10 @@ typedef NS_ENUM(NSInteger, FFFObjectFit) {
|
|
|
34
34
|
@property (nonatomic, copy) NSArray<FFFastImageSource *> *sources;
|
|
35
35
|
// The `placeholder` prop.
|
|
36
36
|
@property (nonatomic, strong) UIImage *placeholder;
|
|
37
|
+
// `placeholder` as a url (a source): loaded apart from the
|
|
38
|
+
// image, at a high priority (or only from the cache, with cache cacheOnly),
|
|
39
|
+
// it shows over the other placeholders once it has.
|
|
40
|
+
@property (nonatomic, strong) FFFastImageSource *placeholderSource;
|
|
37
41
|
// The `sourcePlaceholders` prop, by the source's index (an empty string for
|
|
38
42
|
// none; one for a single source): the picked source's ThumbHash or
|
|
39
43
|
// blurDataUri (a data uri) shows instead of placeholder. JS sends them apart
|
|
@@ -59,6 +63,10 @@ typedef NS_ENUM(NSInteger, FFFObjectFit) {
|
|
|
59
63
|
@property (nonatomic, copy) NSString *transitionSkipOnCacheHit;
|
|
60
64
|
// Decodes images at about the view's size instead of at full size.
|
|
61
65
|
@property (nonatomic, assign) BOOL downsample;
|
|
66
|
+
// The dynamicRangeLimit prop: standard, constrained or no-limit (nil when
|
|
67
|
+
// not set). With constrained and no-limit, HDR images are decoded to HDR and
|
|
68
|
+
// shown in HDR (iOS and tvOS 17+).
|
|
69
|
+
@property (nonatomic, copy) NSString *dynamicRangeLimit;
|
|
62
70
|
// Blurs the loaded image by this radius, in points (0 is no blur).
|
|
63
71
|
@property (nonatomic, assign) CGFloat blurRadius;
|
|
64
72
|
// objectPosition, as CSS computes it: on each axis the image's left or top
|