@nativescript-community/ui-image
Version:
Advanced and efficient image display plugin which uses Fresco (Android) and SDWebImage (iOS) to implement caching, placeholders, image effects, and much more.
785 lines • 30.6 kB
JavaScript
var _a, _b, _c, _d;
export * from './image-common';
import { ImageAsset, ImageSource, Trace, knownFolders, path } from '@nativescript/core';
import { android as androidApp } from '@nativescript/core/application';
import { isString } from '@nativescript/core/utils/types';
import { RESOURCE_PREFIX, ad, isFileOrResourcePath, isFontIconURI } from '@nativescript/core/utils/utils';
import { CLog, CLogTypes, EventData, ImageBase, ScaleType } from './image-common';
let initialized = false;
let initializeConfig;
export function initialize(config) {
if (!initialized) {
const context = androidApp.context;
if (!context) {
initializeConfig = config;
return;
}
const builder = com.facebook.imagepipeline.core.ImagePipelineConfig.newBuilder(context);
if (config && config.isDownsampleEnabled) {
builder.setDownsampleEnabled(true);
}
if (config && config.leakTracker) {
builder.setCloseableReferenceLeakTracker(config.leakTracker);
}
const imagePipelineConfig = builder.build();
com.facebook.drawee.backends.pipeline.Fresco.initialize(context, imagePipelineConfig);
initialized = true;
initializeConfig = null;
}
}
export function getImagePipeline() {
if (androidApp) {
const nativePipe = com.facebook.drawee.backends.pipeline.Fresco.getImagePipeline();
const imagePineLine = new ImagePipeline();
imagePineLine.android = nativePipe;
return imagePineLine;
}
return null;
}
export function shutDown() {
if (!initialized) {
return;
}
initialized = false;
com.facebook.drawee.view.SimpleDraweeView.shutDown();
com.facebook.drawee.backends.pipeline.Fresco.shutDown();
}
function getUri(src) {
let uri;
let imagePath;
if (src instanceof ImageAsset) {
imagePath = src.android;
}
else {
imagePath = src;
}
if (isFileOrResourcePath(imagePath)) {
const res = ad.getApplicationContext().getResources();
if (!res) {
return null;
}
if (imagePath.indexOf(RESOURCE_PREFIX) === 0) {
const resName = imagePath.substr(RESOURCE_PREFIX.length);
const identifier = res.getIdentifier(resName, 'drawable', ad.getApplication().getPackageName());
if (0 < identifier) {
uri = new android.net.Uri.Builder().scheme(com.facebook.common.util.UriUtil.LOCAL_RESOURCE_SCHEME).path(java.lang.String.valueOf(identifier)).build();
}
}
else if (imagePath.indexOf('~/') === 0) {
uri = android.net.Uri.parse(`file:${path.join(knownFolders.currentApp().path, imagePath.replace('~/', ''))}`);
}
else if (imagePath.indexOf('/') === 0) {
uri = android.net.Uri.parse(`file:${imagePath}`);
}
}
else {
uri = android.net.Uri.parse(imagePath);
}
return uri;
}
export class ImagePipeline {
toUri(value) {
if (value instanceof android.net.Uri) {
return value;
}
return android.net.Uri.parse(value);
}
isInDiskCache(uri) {
return this._android.isInDiskCacheSync(this.toUri(uri));
}
isInBitmapMemoryCache(uri) {
return this._android.isInBitmapMemoryCache(this.toUri(uri));
}
evictFromMemoryCache(uri) {
this._android.evictFromMemoryCache(this.toUri(uri));
}
evictFromDiskCache(uri) {
this._android.evictFromDiskCache(this.toUri(uri));
}
evictFromCache(uri) {
this._android.evictFromCache(this.toUri(uri));
}
clearCaches() {
this._android.clearCaches();
}
clearMemoryCaches() {
this._android.clearMemoryCaches();
}
clearDiskCaches() {
this._android.clearDiskCaches();
}
prefetchToDiskCache(uri) {
return this.prefetchToCache(uri, true);
}
prefetchToMemoryCache(uri) {
return this.prefetchToCache(uri, false);
}
prefetchToCache(uri, toDiskCache) {
return new Promise((resolve, reject) => {
try {
const nativeUri = android.net.Uri.parse(uri);
const request = com.facebook.imagepipeline.request.ImageRequestBuilder.newBuilderWithSource(nativeUri).build();
let datasource;
if (toDiskCache) {
datasource = this._android.prefetchToDiskCache(request, uri);
}
else {
datasource = this._android.prefetchToBitmapCache(request, uri);
}
datasource.subscribe(new com.nativescript.image.BaseDataSubscriber(new com.nativescript.image.BaseDataSubscriberListener({
onFailure: reject,
onNewResult: resolve,
})), com.facebook.common.executors.CallerThreadExecutor.getInstance());
}
catch (error) {
reject(error);
}
});
}
get android() {
return this._android;
}
set android(value) {
this._android = value;
}
fetchImage() {
}
}
export class ImageError {
constructor(throwable) {
this._message = throwable.getMessage();
this._errorType = throwable.getClass().getName();
this._stringValue = throwable.toString();
}
getMessage() {
return this._message;
}
getErrorType() {
return this._errorType;
}
toString() {
return this._stringValue;
}
}
export class ImageInfo {
constructor(imageInfo) {
this._nativeImageInfo = imageInfo;
}
getHeight() {
return this._nativeImageInfo.getHeight();
}
getWidth() {
return this._nativeImageInfo.getWidth();
}
getQualityInfo() {
return this._nativeImageInfo.getQualityInfo();
}
}
export class FinalEventData extends EventData {
get imageInfo() {
return this._imageInfo;
}
set imageInfo(value) {
this._imageInfo = value;
}
get animatable() {
return this._animatable;
}
set animatable(value) {
this._animatable = value;
}
get android() {
return this._animatable;
}
}
export class IntermediateEventData extends EventData {
get imageInfo() {
return this._imageInfo;
}
set imageInfo(value) {
this._imageInfo = value;
}
}
export class FailureEventData extends EventData {
get error() {
return this._error;
}
set error(value) {
this._error = value;
}
}
export const needRequestImage = function (target, propertyKey, descriptor) {
const originalMethod = descriptor.value;
descriptor.value = function (...args) {
if (!this._canRequestImage) {
this._needRequestImage = true;
this._needUpdateHierarchy = true;
return;
}
return originalMethod.apply(this, args);
};
};
export class Img extends ImageBase {
constructor() {
super(...arguments);
this.isLoading = false;
this._canRequestImage = true;
this._canUpdateHierarchy = true;
this._needUpdateHierarchy = true;
this._needRequestImage = false;
}
onResumeNativeUpdates() {
this._canRequestImage = false;
this._canUpdateHierarchy = false;
super.onResumeNativeUpdates();
this._canUpdateHierarchy = true;
this._canRequestImage = true;
if (this._needUpdateHierarchy) {
this._needUpdateHierarchy = false;
this.updateHierarchy();
}
if (this._needRequestImage) {
this._needRequestImage = false;
this.initImage();
}
}
createNativeView() {
if (!initialized) {
initialize(initializeConfig);
}
const view = new com.nativescript.image.DraweeView(this._context);
return view;
}
updateViewSize(imageInfo) {
const draweeView = this.nativeViewProtected;
if (!draweeView) {
return;
}
if (imageInfo != null) {
draweeView.imageWidth = imageInfo.getWidth();
draweeView.imageHeight = imageInfo.getHeight();
}
if (!this.aspectRatio && imageInfo != null) {
const ratio = imageInfo.getWidth() / imageInfo.getHeight();
draweeView.setAspectRatio(ratio);
}
else if (this.aspectRatio) {
draweeView.setAspectRatio(this.aspectRatio);
}
else {
draweeView.setAspectRatio(0);
}
}
updateImageUri() {
const imagePipeLine = getImagePipeline();
const src = this.src;
if (!(src instanceof ImageSource)) {
const uri = getUri(src);
const isInCache = imagePipeLine.isInBitmapMemoryCache(uri);
if (isInCache) {
imagePipeLine.evictFromCache(uri);
}
}
this.src = null;
this.src = src;
}
[ImageBase.placeholderImageUriProperty.setNative]() {
this.updateHierarchy();
}
[ImageBase.failureImageUriProperty.setNative]() {
this.updateHierarchy();
}
[ImageBase.stretchProperty.setNative]() {
this.updateHierarchy();
}
[ImageBase.fadeDurationProperty.setNative]() {
this.updateHierarchy();
}
[ImageBase.backgroundUriProperty.setNative]() {
this.updateHierarchy();
}
[ImageBase.showProgressBarProperty.setNative]() {
this.updateHierarchy();
}
[ImageBase.progressBarColorProperty.setNative]() {
this.updateHierarchy();
}
[ImageBase.roundAsCircleProperty.setNative]() {
this.updateHierarchy();
}
[ImageBase.roundTopLeftRadiusProperty.setNative]() {
this.updateHierarchy();
}
[ImageBase.roundTopRightRadiusProperty.setNative]() {
this.updateHierarchy();
}
[ImageBase.roundBottomLeftRadiusProperty.setNative]() {
this.updateHierarchy();
}
[ImageBase.roundBottomRightRadiusProperty.setNative]() {
this.updateHierarchy();
}
[ImageBase.tintColorProperty.setNative](value) {
this.updateHierarchy();
}
[ImageBase.blurRadiusProperty.setNative]() {
this.initImage();
}
[_a = ImageBase.srcProperty.setNative]() {
this.initImage();
}
[_b = ImageBase.lowerResSrcProperty.setNative]() {
this.initImage();
}
[_c = ImageBase.blurDownSamplingProperty.setNative]() {
this.initImage();
}
[_d = ImageBase.aspectRatioProperty.setNative]() {
this.initImage();
}
initImage() {
if (this.nativeViewProtected) {
const src = this.src;
if (src) {
let drawable;
if (src instanceof ImageSource) {
drawable = new android.graphics.drawable.BitmapDrawable(ad.getApplicationContext().getResources(), src.android);
this.updateViewSize(src.android);
}
else if (isFontIconURI(src)) {
const fontIconCode = src.split('//')[1];
if (fontIconCode !== undefined) {
const font = this.style.fontInternal;
const color = this.style.color;
drawable = new android.graphics.drawable.BitmapDrawable(ad.getApplicationContext().getResources(), ImageSource.fromFontIconCodeSync(fontIconCode, font, color).android);
}
}
if (drawable) {
const hierarchy = this.nativeViewProtected.getHierarchy();
hierarchy.setImage(drawable, 1, hierarchy.getFadeDuration() === 0);
return;
}
if (this.noCache) {
const uri = getUri(src);
const imagePipeLine = getImagePipeline();
const isInCache = imagePipeLine.isInBitmapMemoryCache(uri);
if (isInCache) {
imagePipeLine.evictFromCache(uri);
}
}
this.isLoading = true;
const uri = getUri(src);
if (!uri) {
console.log(`Error: 'src' not valid: ${src}`);
return;
}
let requestBuilder = com.facebook.imagepipeline.request.ImageRequestBuilder.newBuilderWithSource(uri).setRotationOptions(com.facebook.imagepipeline.common.RotationOptions.autoRotate());
if (this.progressiveRenderingEnabled === true) {
requestBuilder = requestBuilder.setProgressiveRenderingEnabled(this.progressiveRenderingEnabled);
}
if (this.localThumbnailPreviewsEnabled === true) {
requestBuilder = requestBuilder.setLocalThumbnailPreviewsEnabled(this.localThumbnailPreviewsEnabled);
}
if (this.decodeWidth && this.decodeHeight) {
requestBuilder = requestBuilder.setResizeOptions(new com.facebook.imagepipeline.common.ResizeOptions(this.decodeWidth, this.decodeHeight));
}
if (this.blurRadius) {
const postProcessor = new com.nativescript.image.ScalingBlurPostprocessor(2, this.blurRadius, this.blurDownSampling || 1);
requestBuilder = requestBuilder.setPostprocessor(postProcessor);
}
const request = requestBuilder.build();
const that = new WeakRef(this);
const listener = new com.facebook.drawee.controller.ControllerListener({
onFinalImageSet(id, imageInfo, animatable) {
if (Trace.isEnabled()) {
CLog(CLogTypes.info, 'onFinalImageSet', id, imageInfo, animatable);
}
const nativeView = that && that.get();
if (nativeView) {
nativeView.updateViewSize(imageInfo);
nativeView.isLoading = false;
const info = new ImageInfo(imageInfo);
const args = {
eventName: ImageBase.finalImageSetEvent,
object: nativeView,
imageInfo: info,
animatable: animatable,
};
nativeView.notify(args);
}
else {
console.log("Warning: WeakRef<Image> was GC and no '" + ImageBase.finalImageSetEvent + "' callback will be raised.");
}
},
onFailure(id, throwable) {
if (Trace.isEnabled()) {
CLog(CLogTypes.info, 'onFailure', id, throwable);
}
const nativeView = that && that.get();
if (nativeView) {
nativeView.isLoading = false;
const imageError = new ImageError(throwable);
const args = {
eventName: ImageBase.failureEvent,
object: nativeView,
error: imageError,
};
that.get().notify(args);
}
else {
console.log("Warning: WeakRef<Image> was GC and no '" + ImageBase.failureEvent + "' callback will be raised.");
}
},
onIntermediateImageFailed(id, throwable) {
if (Trace.isEnabled()) {
CLog(CLogTypes.info, 'onIntermediateImageFailed', id, throwable);
}
const nativeView = that && that.get();
if (nativeView) {
const imageError = new ImageError(throwable);
const args = {
eventName: ImageBase.intermediateImageFailedEvent,
object: nativeView,
error: imageError,
};
that.get().notify(args);
}
else {
console.log("Warning: WeakRef<Image> was GC and no '" + ImageBase.intermediateImageFailedEvent + "' callback will be raised.");
}
},
onIntermediateImageSet(id, imageInfo) {
if (Trace.isEnabled()) {
CLog(CLogTypes.info, 'onIntermediateImageSet', id, imageInfo);
}
const nativeView = that && that.get();
if (nativeView) {
nativeView.updateViewSize(imageInfo);
const info = new ImageInfo(imageInfo);
const args = {
eventName: ImageBase.intermediateImageSetEvent,
object: nativeView,
imageInfo: info,
};
that.get().notify(args);
}
else {
console.log("Warning: WeakRef<Image> was GC and no '" + ImageBase.intermediateImageSetEvent + "' callback will be raised.");
}
},
onRelease(id) {
if (Trace.isEnabled()) {
CLog(CLogTypes.info, 'onRelease', id);
}
const nativeView = that && that.get();
if (nativeView) {
const args = {
eventName: ImageBase.releaseEvent,
object: nativeView,
};
that.get().notify(args);
}
else {
console.log("Warning: WeakRef<Image> was GC and no '" + ImageBase.releaseEvent + "' callback will be raised.");
}
},
onSubmit(id, callerContext) {
if (Trace.isEnabled()) {
CLog(CLogTypes.info, 'onSubmit', id, callerContext);
}
const nativeView = that && that.get();
if (nativeView) {
const args = {
eventName: ImageBase.submitEvent,
object: nativeView,
};
that.get().notify(args);
}
else {
console.log("Warning: WeakRef<Image> was GC and no 'submitEvent' callback will be raised.");
}
},
});
const builder = com.facebook.drawee.backends.pipeline.Fresco.newDraweeControllerBuilder();
builder.setImageRequest(request);
builder.setCallerContext(src);
builder.setControllerListener(listener);
builder.setOldController(this.nativeViewProtected.getController());
if (Trace.isEnabled()) {
builder.setPerfDataListener(new com.facebook.drawee.backends.pipeline.info.ImagePerfDataListener({
onImageLoadStatusUpdated(param0, param1) {
CLog(CLogTypes.info, 'onImageLoadStatusUpdated', param0, param1);
},
onImageVisibilityUpdated(param0, param1) {
CLog(CLogTypes.info, 'onImageVisibilityUpdated', param0, param1);
},
}));
}
if (this.lowerResSrc) {
builder.setLowResImageRequest(com.facebook.imagepipeline.request.ImageRequest.fromUri(getUri(this.lowerResSrc)));
}
if (this.autoPlayAnimations) {
builder.setAutoPlayAnimations(this.autoPlayAnimations);
}
if (this.tapToRetryEnabled) {
builder.setTapToRetryEnabled(this.tapToRetryEnabled);
}
const controller = builder.build();
this.nativeViewProtected.setController(controller);
}
else {
this.nativeViewProtected.setController(null);
this.nativeViewProtected.setImageBitmap(null);
}
}
}
updateHierarchy() {
if (!this._canUpdateHierarchy) {
this._needUpdateHierarchy = true;
return;
}
if (this.nativeViewProtected) {
let failureImageDrawable;
let placeholderImageDrawable;
let backgroundDrawable;
if (this.failureImageUri) {
failureImageDrawable = this.getDrawable(this.failureImageUri);
}
if (this.placeholderImageUri) {
placeholderImageDrawable = this.getDrawable(this.placeholderImageUri);
}
if (this.backgroundUri) {
backgroundDrawable = this.getDrawable(this.backgroundUri);
}
const builder = new GenericDraweeHierarchyBuilder();
if (this.failureImageUri && failureImageDrawable) {
builder.setFailureImage(failureImageDrawable, this.stretch);
}
if (this.tintColor) {
builder.setActualImageColorFilter(new android.graphics.PorterDuffColorFilter(this.tintColor.android, android.graphics.PorterDuff.Mode.MULTIPLY));
}
if (this.placeholderImageUri && placeholderImageDrawable) {
builder.setPlaceholderImage(placeholderImageDrawable, this.stretch);
}
if (this.stretch) {
builder.setActualImageScaleType(this.stretch);
}
if (this.fadeDuration) {
builder.setFadeDuration(this.fadeDuration);
}
else {
builder.setFadeDuration(0);
}
if (this.backgroundUri && backgroundDrawable) {
builder.setBackground(backgroundDrawable);
}
if (this.showProgressBar) {
builder.setProgressBarImage(this.progressBarColor, this.stretch);
}
if (this.roundAsCircle) {
builder.setRoundingParamsAsCircle();
}
if (this.roundBottomLeftRadius || this.roundBottomRightRadius || this.roundTopLeftRadius || this.roundTopRightRadius) {
const topLeftRadius = this.roundTopLeftRadius || 0;
const topRightRadius = this.roundTopRightRadius || 0;
const bottomRightRadius = this.roundBottomRightRadius || 0;
const bottomLeftRadius = this.roundBottomLeftRadius || 0;
builder.setCornersRadii(topLeftRadius, topRightRadius, bottomRightRadius, bottomLeftRadius);
}
const hierarchy = builder.build();
this.nativeViewProtected.setHierarchy(hierarchy);
}
}
getDrawable(path) {
let drawable;
if (typeof path === 'string') {
if (isFontIconURI(path)) {
const fontIconCode = (path).split('//')[1];
if (fontIconCode !== undefined) {
const font = this.style.fontInternal;
const color = this.style.color;
drawable = new android.graphics.drawable.BitmapDrawable(ad.getApplicationContext().getResources(), ImageSource.fromFontIconCodeSync(fontIconCode, font, color).android);
}
}
else if (isFileOrResourcePath(path)) {
if (path.indexOf(RESOURCE_PREFIX) === 0) {
return this.getDrawableFromResource(path);
}
else {
drawable = this.getDrawableFromLocalFile(path);
}
}
}
else {
drawable = new android.graphics.drawable.BitmapDrawable(ad.getApplicationContext().getResources(), path.android);
}
return drawable;
}
getDrawableFromLocalFile(localFilePath) {
const img = ImageSource.fromFileSync(localFilePath);
let drawable = null;
if (img) {
drawable = new android.graphics.drawable.BitmapDrawable(ad.getApplicationContext().getResources(), img.android);
}
return drawable;
}
getDrawableFromResource(resourceName) {
const identifier = ad.getApplication().getResources().getIdentifier(resourceName.substr(RESOURCE_PREFIX.length), 'drawable', ad.getApplication().getPackageName());
return identifier;
}
startAnimating() {
if (this.nativeViewProtected) {
const controller = this.nativeViewProtected.getController();
if (controller) {
const animatable = controller.getAnimatable();
if (animatable) {
animatable.start();
}
}
}
}
stopAnimating() {
if (this.nativeViewProtected) {
const controller = this.nativeViewProtected.getController();
if (controller) {
const animatable = controller.getAnimatable();
if (animatable) {
animatable.stop();
}
}
}
}
}
__decorate([
needRequestImage
], Img.prototype, _a, null);
__decorate([
needRequestImage
], Img.prototype, _b, null);
__decorate([
needRequestImage
], Img.prototype, _c, null);
__decorate([
needRequestImage
], Img.prototype, _d, null);
class GenericDraweeHierarchyBuilder {
constructor() {
const res = androidApp.context.getResources();
this.nativeBuilder = new com.facebook.drawee.generic.GenericDraweeHierarchyBuilder(res);
}
setPlaceholderImage(drawable, scaleType) {
if (!this.nativeBuilder) {
return this;
}
if (scaleType) {
this.nativeBuilder.setPlaceholderImage(drawable, getScaleType(scaleType));
}
else {
this.nativeBuilder.setPlaceholderImage(drawable);
}
return this;
}
setActualImageColorFilter(filter) {
if (!this.nativeBuilder) {
return this;
}
this.nativeBuilder.setActualImageColorFilter(filter);
return this;
}
setFailureImage(drawable, scaleType) {
if (!this.nativeBuilder) {
return null;
}
if (scaleType) {
this.nativeBuilder.setFailureImage(drawable, getScaleType(scaleType));
}
else {
this.nativeBuilder.setFailureImage(drawable);
}
return this;
}
setActualImageScaleType(scaleType) {
if (!this.nativeBuilder) {
return this;
}
this.nativeBuilder.setActualImageScaleType(getScaleType(scaleType));
return this;
}
build() {
if (!this.nativeBuilder) {
return null;
}
return this.nativeBuilder.build();
}
setFadeDuration(duration) {
if (!this.nativeBuilder) {
return null;
}
this.nativeBuilder.setFadeDuration(duration);
return this;
}
setBackground(drawable) {
if (!this.nativeBuilder) {
return this;
}
this.nativeBuilder.setBackground(drawable);
return this;
}
setProgressBarImage(color, stretch) {
if (!this.nativeBuilder) {
return null;
}
const drawable = new com.facebook.drawee.drawable.ProgressBarDrawable();
if (color) {
drawable.setColor(android.graphics.Color.parseColor(color));
}
this.nativeBuilder.setProgressBarImage(drawable, getScaleType(stretch));
return this;
}
setRoundingParamsAsCircle() {
if (!this.nativeBuilder) {
return this;
}
const params = com.facebook.drawee.generic.RoundingParams.asCircle();
this.nativeBuilder.setRoundingParams(params);
return this;
}
setCornersRadii(topLeft, topRight, bottomRight, bottomLeft) {
if (!this.nativeBuilder) {
return this;
}
const params = new com.facebook.drawee.generic.RoundingParams();
params.setCornersRadii(topLeft, topRight, bottomRight, bottomLeft);
this.nativeBuilder.setRoundingParams(params);
return this;
}
}
function getScaleType(scaleType) {
if (isString(scaleType)) {
switch (scaleType) {
case ScaleType.Center:
return com.facebook.drawee.drawable.ScalingUtils.ScaleType.CENTER;
case ScaleType.AspectFill:
case ScaleType.CenterCrop:
return com.facebook.drawee.drawable.ScalingUtils.ScaleType.CENTER_CROP;
case ScaleType.CenterInside:
return com.facebook.drawee.drawable.ScalingUtils.ScaleType.CENTER_INSIDE;
case ScaleType.FitCenter:
case ScaleType.AspectFit:
return com.facebook.drawee.drawable.ScalingUtils.ScaleType.FIT_CENTER;
case ScaleType.FitEnd:
return com.facebook.drawee.drawable.ScalingUtils.ScaleType.FIT_END;
case ScaleType.FitStart:
return com.facebook.drawee.drawable.ScalingUtils.ScaleType.FIT_START;
case ScaleType.Fill:
case ScaleType.FitXY:
return com.facebook.drawee.drawable.ScalingUtils.ScaleType.FIT_XY;
case ScaleType.FocusCrop:
return com.facebook.drawee.drawable.ScalingUtils.ScaleType.FOCUS_CROP;
default:
break;
}
}
return null;
}
//# sourceMappingURL=image.android.js.map