1 // Copyright 2022-present 650 Industries. All rights reserved. 2 3 import ABI48_0_0ExpoModulesCore 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("placeholderContentFit") { (view, placeholderContentFit: ContentFit?) in 41 view.placeholderContentFit = placeholderContentFit ?? .scaleDown 42 } 43 44 Prop("contentPosition") { (view, contentPosition: ContentPosition?) in 45 view.contentPosition = contentPosition ?? .center 46 } 47 48 Prop("transition") { (view, transition: ImageTransition?) in 49 view.transition = transition 50 } 51 52 Prop("blurRadius") { (view, blurRadius: Double?) in 53 view.blurRadius = blurRadius ?? .zero 54 } 55 56 Prop("tintColor") { (view, tintColor: UIColor?) in 57 view.imageTintColor = tintColor ?? .clear 58 } 59 60 Prop("priority") { (view, priority: ImagePriority?) in 61 view.loadingOptions.remove([.lowPriority, .highPriority]) 62 63 if let priority = priority?.toSDWebImageOptions() { 64 view.loadingOptions.insert(priority) 65 } 66 } 67 68 Prop("cachePolicy") { (view, cachePolicy: ImageCachePolicy?) in 69 view.cachePolicy = cachePolicy ?? .disk 70 } 71 72 Prop("enableLiveTextInteraction") { (view, enableLiveTextInteraction: Bool?) in 73 view.enableLiveTextInteraction = enableLiveTextInteraction ?? false 74 } 75 76 Prop("accessible") { (view, accessible: Bool?) in 77 view.sdImageView.isAccessibilityElement = accessible ?? false 78 } 79 80 Prop("accessibilityLabel") { (view, label: String?) in 81 view.sdImageView.accessibilityLabel = label 82 } 83 84 OnViewDidUpdateProps { view in 85 view.reload() 86 } 87 } 88 89 Function("prefetch") { (urls: [URL]) in 90 SDWebImagePrefetcher.shared.prefetchURLs(urls) 91 } 92 93 AsyncFunction("clearMemoryCache") { () -> Bool in 94 SDImageCache.shared.clearMemory() 95 return true 96 } 97 98 AsyncFunction("clearDiskCache") { (promise: Promise) in 99 SDImageCache.shared.clearDisk { 100 promise.resolve(true) 101 } 102 } 103 } 104 105 static func registerCoders() { 106 if #available(iOS 14.0, *) { 107 // By default Animated WebP is not supported 108 SDImageCodersManager.shared.addCoder(SDImageAWebPCoder.shared) 109 } else { 110 // This coder is much slower, but it's the only one that works in iOS 13 111 SDImageCodersManager.shared.addCoder(SDImageWebPCoder.shared) 112 } 113 SDImageCodersManager.shared.addCoder(SDImageAVIFCoder.shared) 114 SDImageCodersManager.shared.addCoder(SDImageSVGCoder.shared) 115 SDImageCodersManager.shared.addCoder(SDImageHEICCoder.shared) 116 } 117 118 static func registerLoaders() { 119 SDImageLoadersManager.shared.addLoader(BlurhashLoader()) 120 SDImageLoadersManager.shared.addLoader(PhotoLibraryAssetLoader()) 121 } 122 } 123