11export * from './index-common' ;
2- import { Color , ImageAsset , ImageSource , Screen , Trace , Utils , knownFolders , path } from '@nativescript/core' ;
2+ import { ApplicationSettings , Color , ImageAsset , ImageSource , Screen , Trace , Utils , knownFolders , path } from '@nativescript/core' ;
3+ import { debounce } from '@nativescript/core/utils' ;
34import { layout } from '@nativescript/core/utils/layout-helper' ;
45import { isString } from '@nativescript/core/utils/types' ;
56import {
@@ -106,9 +107,9 @@ export function initialize(config?: ImagePipelineConfigSetting): void {
106107}
107108export function shutDown ( ) : void { }
108109
109- let pluginsGetContextFromOptions = new Set < GetContextFromOptionsCallback > ( ) ;
110+ const pluginsGetContextFromOptions = new Set < GetContextFromOptionsCallback > ( ) ;
110111export function registerPluginGetContextFromOptions ( callback : GetContextFromOptionsCallback ) {
111- pluginsGetContextFromOptions . add ( callback )
112+ pluginsGetContextFromOptions . add ( callback ) ;
112113}
113114function getContextFromOptions ( options : Partial < Img > ) {
114115 const context : NSDictionary < string , any > = NSMutableDictionary . dictionary ( ) ;
@@ -141,14 +142,30 @@ function getContextFromOptions(options: Partial<Img>) {
141142 )
142143 ) ;
143144 }
145+ pluginsGetContextFromOptions . forEach ( ( c ) => c ( context , transformers , options ) ) ;
146+
144147 if ( transformers . length > 0 ) {
145148 context . setValueForKey ( SDImagePipelineTransformer . transformerWithTransformers ( transformers ) , SDWebImageContextImageTransformer ) ;
146149 }
147- pluginsGetContextFromOptions . forEach ( c => c ( context , transformers , options ) ) ;
148150 return context ;
149151}
150152
153+ // This is not the best solution as their might be a lot of corner cases
154+ // for example if an image is removed from cache without going through ImagePipeline
155+ // we wont know it and the cacheKeyMap will grow
156+ // but i dont see a better way right now
157+ const CACHE_KEYS_SETTING_KEY = 'NS_ui_image_cache_keys' ;
158+ let cacheKeyMap = JSON . parse ( ApplicationSettings . getString ( CACHE_KEYS_SETTING_KEY , '{}' ) ) ;
159+
160+ const saveCacheKeys = debounce ( ( ) => ApplicationSettings . setString ( CACHE_KEYS_SETTING_KEY , JSON . stringify ( cacheKeyMap ) ) , 500 ) ;
161+ function registerCacheKey ( cacheKey : string , uri : any ) {
162+ const set = new Set ( cacheKeyMap [ uri ] || [ ] ) ;
163+ set . add ( cacheKey ) ;
164+ cacheKeyMap [ uri ] = [ ...set ] ;
165+ saveCacheKeys ( ) ;
166+ }
151167export class ImagePipeline {
168+ static iosComplexCacheEviction = false ;
152169 private mIos : SDImageCache = SDImageCache . sharedImageCache ;
153170 constructor ( ) { }
154171
@@ -166,22 +183,32 @@ export class ImagePipeline {
166183 }
167184
168185 evictFromMemoryCache ( key : string ) : void {
169- this . mIos . removeImageFromMemoryForKey ( key ) ;
170- }
171-
172- async evictFromDiskCache ( key : string ) {
173- return new Promise < void > ( ( resolve ) => {
174- this . mIos . removeImageForKeyCacheTypeCompletion ( key , SDImageCacheType . Disk , resolve ) ;
186+ const cachekKeys = ( cacheKeyMap [ key ] || [ ] ) . concat ( [ key ] ) ;
187+ cachekKeys . forEach ( ( k ) => {
188+ this . mIos . removeImageFromMemoryForKey ( k ) ;
175189 } ) ;
176190 }
177191
178- async evictFromCache ( key : string ) {
179- return new Promise < void > ( ( resolve ) => {
180- this . mIos . removeImageForKeyCacheTypeCompletion ( key , SDImageCacheType . All , resolve ) ;
181- } ) ;
192+ async evictFromDiskCache ( key : string ) {
193+ return this . evictFromCache ( key , SDImageCacheType . Disk ) ;
194+ }
195+
196+ async evictFromCache ( key : string , type = SDImageCacheType . All ) {
197+ const cachekKeys = ( cacheKeyMap [ key ] || [ ] ) . concat ( [ key ] ) ;
198+ delete cacheKeyMap [ key ] ;
199+ return Promise . all (
200+ cachekKeys . map (
201+ ( k ) =>
202+ new Promise < void > ( ( resolve ) => {
203+ this . mIos . removeImageForKeyCacheTypeCompletion ( k , type , resolve ) ;
204+ } )
205+ )
206+ ) ;
182207 }
183208
184209 clearCaches ( ) {
210+ cacheKeyMap = { } ;
211+ ApplicationSettings . remove ( CACHE_KEYS_SETTING_KEY ) ;
185212 this . mIos . clearMemory ( ) ;
186213 this . mIos . clearDiskOnCompletion ( null ) ;
187214 }
@@ -347,10 +374,9 @@ export class Img extends ImageBase {
347374 const src = this . src ;
348375 const srcType = typeof src ;
349376 if ( src && ( srcType === 'string' || src instanceof ImageAsset ) ) {
350- const cachekKey = this . mCacheKey || getUri ( src as string | ImageAsset ) . absoluteString ;
351377 // const isInCache = imagePipeLine.isInBitmapMemoryCache(cachekKey);
352378 // if (isInCache) {
353- await imagePipeLine . evictFromCache ( cachekKey ) ;
379+ await imagePipeLine . evictFromCache ( getUri ( src as string | ImageAsset ) . absoluteString ) ;
354380 // }
355381 }
356382 // this.src = null;
@@ -539,11 +565,14 @@ export class Img extends ImageBase {
539565 }
540566
541567 this . mCacheKey = SDWebImageManager . sharedManager . cacheKeyForURLContext ( uri , context ) ;
568+ if ( ImagePipeline . iosComplexCacheEviction ) {
569+ registerCacheKey ( this . mCacheKey , uri ) ;
570+ }
542571 if ( this . showProgressBar ) {
543572 try {
544573 if ( this . progressBarColor ) {
545574 const indicator = new SDWebImageActivityIndicator ( ) ;
546- indicator . indicatorView . color = this . progressBarColor . ios ;
575+ indicator . indicatorView . color = ( this . progressBarColor as Color ) . ios ;
547576 this . nativeImageViewProtected . sd_imageIndicator = indicator ;
548577 } else {
549578 this . nativeImageViewProtected . sd_imageIndicator = SDWebImageActivityIndicator . grayIndicator ;
@@ -590,8 +619,7 @@ export class Img extends ImageBase {
590619 }
591620
592621 @needRequestImage
593- [ headersProperty . setNative ] ( value ) {
594- }
622+ [ headersProperty . setNative ] ( value ) { }
595623
596624 [ failureImageUriProperty . setNative ] ( ) {
597625 // this.updateHierarchy();
0 commit comments