diff --git a/src/image.android.ts b/src/image.android.ts index 2d12bee..00d2884 100644 --- a/src/image.android.ts +++ b/src/image.android.ts @@ -7,6 +7,38 @@ import * as imageSource from 'tns-core-modules/image-source'; import * as fs from 'tns-core-modules/file-system'; import { Color } from 'tns-core-modules/color/color'; +let BaseDataSubscriber: new (onNewResult: () => void, onFailure: () => void) => com.facebook.datasource.BaseDataSubscriber; + +function initializeBaseDataSubscriber() { + if (BaseDataSubscriber) { + return; + } + class BaseDataSubscriberImpl extends com.facebook.datasource.BaseDataSubscriber { + private _onNewResult: () => void; + private _onFailure: () => void; + constructor(onNewResult: () => void, onFailure: () => void) { + super(); + this._onNewResult = onNewResult; + this._onFailure = onFailure; + return global.__native(this); + } + public onNewResultImpl(_dataSource: com.facebook.datasource.DataSource): void { + // Store image ref to be released later. + //const mCloseableImageRef = _dataSource.getResult(); + if (this._onNewResult) { + this._onNewResult(); + } + } + + public onFailureImpl(_dataSource: com.facebook.datasource.DataSource): void { + if (this._onFailure) { + this._onFailure(); + } + } + }; + BaseDataSubscriber = BaseDataSubscriberImpl; +} + export function initialize(config?: ImagePipelineConfigSetting): void { if (application.android) { if (config && config.isDownsampleEnabled) { @@ -17,6 +49,7 @@ export function initialize(config?: ImagePipelineConfigSetting): void { } else { com.facebook.drawee.backends.pipeline.Fresco.initialize(application.android.context); } + initializeBaseDataSubscriber(); } } @@ -101,6 +134,35 @@ export class ImagePipeline { this._android.clearDiskCaches(); } + prefetchToDiskCache(uri: string): Promise { + return this.prefetchToCache(uri, true); + } + + prefetchToMemoryCache(uri: string): Promise { + return this.prefetchToCache(uri, false); + } + + private prefetchToCache(uri: string, toDiskCache: boolean): Promise { + 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: com.facebook.datasource.DataSource; + if (toDiskCache) { + datasource = this._android.prefetchToDiskCache(request, null); + } else { + datasource = this._android.prefetchToBitmapCache(request, null); + } + datasource.subscribe( + new BaseDataSubscriber(resolve, reject), + com.facebook.common.executors.CallerThreadExecutor.getInstance() + ); + } catch (error) { + reject(error); + } + }); + } + get android(): any { return this._android; } diff --git a/src/image.d.ts b/src/image.d.ts index b411c22..79947a9 100644 --- a/src/image.d.ts +++ b/src/image.d.ts @@ -387,6 +387,16 @@ export class ImagePipeline { * Clear disk caches. */ clearDiskCaches(): void; + + /** + * Prefetch to disk cache. + */ + prefetchToDiskCache(uri: string): Promise; + + /** + * Prefetch to memory cache. + */ + prefetchToMemoryCache(uri: string): Promise; } /** diff --git a/src/image.ios.ts b/src/image.ios.ts index 36e770b..e169835 100644 --- a/src/image.ios.ts +++ b/src/image.ios.ts @@ -200,6 +200,30 @@ export class ImagePipeline { clearDiskCaches() { this._ios.clearDiskOnCompletion(null); } + + prefetchToDiskCache(uri: string): Promise { + return this.prefetchToCacheType(uri, SDImageCacheType.Disk); + } + + prefetchToMemoryCache(uri: string): Promise { + return this.prefetchToCacheType(uri, SDImageCacheType.Memory); + } + + private prefetchToCacheType(uri: string, cacheType: SDImageCacheType): Promise { + return new Promise((resolve, reject) => { + const context = NSMutableDictionary.alloc().initWithCapacity(1); + context.setObjectForKey(cacheType, SDWebImageContextStoreCacheType); + SDWebImagePrefetcher.sharedImagePrefetcher.context = context; + SDWebImagePrefetcher.sharedImagePrefetcher.prefetchURLsProgressCompleted([getUri(uri)], null, (finished, skipped) => { + if (finished && !skipped) { + resolve(); + } else { + reject(`prefetch failed for URI: ${uri}`); + } + }); + }); + } + get ios() { return this._ios; }