1 // Copyright 2022-present 650 Industries. All rights reserved. 2 3 import ExpoModulesCore 4 import SDWebImage 5 import SDWebImageWebPCoder 6 import SDWebImageAVIFCoder 7 import SDWebImageSVGCoder 8 9 public final class ImageModule: Module { 10 lazy var prefetcher = SDWebImagePrefetcher.shared 11 12 public func definition() -> ModuleDefinition { 13 Name("ExpoImage") 14 15 OnCreate { 16 ImageModule.registerCoders() 17 ImageModule.registerLoaders() 18 } 19 20 View(ImageView.self) { 21 Events( 22 "onLoadStart", 23 "onProgress", 24 "onError", 25 "onLoad" 26 ) 27 28 Prop("source") { (view, sources: [ImageSource]?) in 29 view.sources = sources 30 } 31 32 Prop("placeholder") { (view, placeholders: [ImageSource]?) in 33 view.placeholderSources = placeholders ?? [] 34 } 35 36 Prop("contentFit") { (view, contentFit: ContentFit?) in 37 view.contentFit = contentFit ?? .cover 38 } 39 40 Prop("contentPosition") { (view, contentPosition: ContentPosition?) in 41 view.contentPosition = contentPosition ?? .center 42 } 43 44 Prop("transition") { (view, transition: ImageTransition?) in 45 view.transition = transition 46 } 47 48 Prop("blurRadius") { (view, blurRadius: Double?) in 49 view.blurRadius = blurRadius ?? .zero 50 } 51 52 Prop("tintColor") { (view, tintColor: UIColor?) in 53 view.imageTintColor = tintColor ?? .clear 54 } 55 56 Prop("priority") { (view, priority: ImagePriority?) in 57 view.loadingOptions.remove([.lowPriority, .highPriority]) 58 59 if let priority = priority?.toSDWebImageOptions() { 60 view.loadingOptions.insert(priority) 61 } 62 } 63 64 Prop("cachePolicy") { (view, cachePolicy: ImageCachePolicy?) in 65 view.cachePolicy = cachePolicy ?? .disk 66 } 67 68 Prop("enableLiveTextInteraction") { (view, enableLiveTextInteraction: Bool?) in 69 view.enableLiveTextInteraction = enableLiveTextInteraction ?? false 70 } 71 72 Prop("accessible") { (view, accessible: Bool?) in 73 view.sdImageView.isAccessibilityElement = accessible ?? false 74 } 75 76 Prop("accessibilityLabel") { (view, label: String?) in 77 view.sdImageView.accessibilityLabel = label 78 } 79 80 OnViewDidUpdateProps { view in 81 view.reload() 82 } 83 } 84 85 Function("prefetch") { (urls: [URL]) in 86 SDWebImagePrefetcher.shared.prefetchURLs(urls) 87 } 88 89 AsyncFunction("clearMemoryCache") { () -> Bool in 90 SDImageCache.shared.clearMemory() 91 return true 92 } 93 94 AsyncFunction("clearDiskCache") { (promise: Promise) in 95 SDImageCache.shared.clearDisk { 96 promise.resolve(true) 97 } 98 } 99 } 100 101 static func registerCoders() { 102 if #available(iOS 14.0, *) { 103 // By default Animated WebP is not supported 104 SDImageCodersManager.shared.addCoder(SDImageAWebPCoder.shared) 105 } else { 106 // This coder is much slower, but it's the only one that works in iOS 13 107 SDImageCodersManager.shared.addCoder(SDImageWebPCoder.shared) 108 } 109 SDImageCodersManager.shared.addCoder(SDImageAVIFCoder.shared) 110 SDImageCodersManager.shared.addCoder(SDImageSVGCoder.shared) 111 SDImageCodersManager.shared.addCoder(SDImageHEICCoder.shared) 112 } 113 114 static func registerLoaders() { 115 SDImageLoadersManager.shared.addLoader(BlurhashLoader()) 116 SDImageLoadersManager.shared.addLoader(PhotoLibraryAssetLoader()) 117 } 118 } 119