1 // Copyright 2022-present 650 Industries. All rights reserved.
2 
3 import ABI49_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 
definitionnull12   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
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       Prop("recyclingKey") { (view, key: String?) in
85         view.recyclingKey = key
86       }
87 
88       OnViewDidUpdateProps { view in
89         view.reload()
90       }
91     }
92 
93     Function("prefetch") { (urls: [URL]) in
94       SDWebImagePrefetcher.shared.prefetchURLs(urls)
95     }
96 
97     AsyncFunction("clearMemoryCache") { () -> Bool in
98       SDImageCache.shared.clearMemory()
99       return true
100     }
101 
102     AsyncFunction("clearDiskCache") { (promise: Promise) in
103       SDImageCache.shared.clearDisk {
104         promise.resolve(true)
105       }
106     }
107   }
108 
registerCodersnull109   static func registerCoders() {
110     if #available(iOS 14.0, *) {
111       // By default Animated WebP is not supported
112       SDImageCodersManager.shared.addCoder(SDImageAWebPCoder.shared)
113     } else {
114       // This coder is much slower, but it's the only one that works in iOS 13
115       SDImageCodersManager.shared.addCoder(SDImageWebPCoder.shared)
116     }
117     SDImageCodersManager.shared.addCoder(SDImageAVIFCoder.shared)
118     SDImageCodersManager.shared.addCoder(SDImageSVGCoder.shared)
119     SDImageCodersManager.shared.addCoder(SDImageHEICCoder.shared)
120   }
121 
registerLoadersnull122   static func registerLoaders() {
123     SDImageLoadersManager.shared.addLoader(BlurhashLoader())
124     SDImageLoadersManager.shared.addLoader(ThumbhashLoader())
125     SDImageLoadersManager.shared.addLoader(PhotoLibraryAssetLoader())
126   }
127 }
128