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       OnViewDidUpdateProps { view in
69         view.reload()
70       }
71     }
72 
73     Function("prefetch") { (urls: [URL]) in
74       SDWebImagePrefetcher.shared.prefetchURLs(urls)
75     }
76 
77     AsyncFunction("clearMemoryCache") { () -> Bool in
78       SDImageCache.shared.clearMemory()
79       return true
80     }
81 
82     AsyncFunction("clearDiskCache") { (promise: Promise) in
83       SDImageCache.shared.clearDisk {
84         promise.resolve(true)
85       }
86     }
87   }
88 
89   static func registerCoders() {
90     SDImageCodersManager.shared.addCoder(SDImageWebPCoder.shared)
91     SDImageCodersManager.shared.addCoder(SDImageAVIFCoder.shared)
92     SDImageCodersManager.shared.addCoder(SDImageSVGCoder.shared)
93     SDImageCodersManager.shared.addCoder(SDImageHEICCoder.shared)
94   }
95 
96   static func registerLoaders() {
97     SDImageLoadersManager.shared.addLoader(BlurhashLoader())
98     SDImageLoadersManager.shared.addLoader(PhotoLibraryAssetLoader())
99   }
100 }
101