@granite-js/image 0.1.34 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/CHANGELOG.md +4 -276
  2. package/GraniteImage.podspec +72 -0
  3. package/android/build.gradle +178 -0
  4. package/android/gradle.properties +5 -0
  5. package/android/src/coil/java/run/granite/image/providers/CoilImageProvider.kt +156 -0
  6. package/android/src/glide/java/run/granite/image/providers/GlideImageProvider.kt +168 -0
  7. package/android/src/main/AndroidManifest.xml +2 -0
  8. package/android/src/main/java/run/granite/image/GraniteImage.kt +277 -0
  9. package/android/src/main/java/run/granite/image/GraniteImageEvents.kt +83 -0
  10. package/android/src/main/java/run/granite/image/GraniteImageManager.kt +100 -0
  11. package/android/src/main/java/run/granite/image/GraniteImageModule.kt +131 -0
  12. package/android/src/main/java/run/granite/image/GraniteImagePackage.kt +59 -0
  13. package/android/src/main/java/run/granite/image/GraniteImageProvider.kt +105 -0
  14. package/android/src/main/java/run/granite/image/GraniteImageRegistry.kt +29 -0
  15. package/android/src/okhttp/java/run/granite/image/providers/OkHttpImageProvider.kt +228 -0
  16. package/dist/module/GraniteImage.js +127 -0
  17. package/dist/module/GraniteImage.js.map +1 -0
  18. package/dist/module/GraniteImageNativeComponent.ts +56 -0
  19. package/dist/module/NativeGraniteImageModule.js +5 -0
  20. package/dist/module/NativeGraniteImageModule.js.map +1 -0
  21. package/dist/module/index.js +6 -0
  22. package/dist/module/index.js.map +1 -0
  23. package/dist/module/package.json +1 -0
  24. package/dist/typescript/GraniteImage.d.ts +35 -0
  25. package/dist/typescript/GraniteImageNativeComponent.d.ts +37 -0
  26. package/dist/typescript/NativeGraniteImageModule.d.ts +16 -0
  27. package/dist/typescript/index.d.ts +4 -0
  28. package/example/react-native.config.js +21 -0
  29. package/ios/GraniteImageComponentView.h +14 -0
  30. package/ios/GraniteImageComponentView.mm +388 -0
  31. package/ios/GraniteImageModule.swift +107 -0
  32. package/ios/GraniteImageModuleBridge.m +15 -0
  33. package/ios/GraniteImageProvider.swift +70 -0
  34. package/ios/GraniteImageRegistry.swift +30 -0
  35. package/ios/Providers/SDWebImageProvider.swift +175 -0
  36. package/package.json +71 -32
  37. package/src/GraniteImage.tsx +215 -0
  38. package/src/GraniteImageNativeComponent.ts +56 -0
  39. package/src/NativeGraniteImageModule.ts +16 -0
  40. package/src/index.ts +21 -0
  41. package/dist/index.d.mts +0 -70
  42. package/dist/index.d.ts +0 -70
  43. package/dist/index.js +0 -204
  44. package/dist/index.mjs +0 -180
@@ -0,0 +1,131 @@
1
+ package run.granite.image
2
+
3
+ import android.util.Log
4
+ import com.facebook.react.bridge.Promise
5
+ import com.facebook.react.bridge.ReactApplicationContext
6
+ import com.facebook.react.bridge.ReactContextBaseJavaModule
7
+ import com.facebook.react.bridge.ReactMethod
8
+ import com.facebook.react.module.annotations.ReactModule
9
+ import org.json.JSONArray
10
+ import org.json.JSONObject
11
+ import java.util.concurrent.Executors
12
+ import java.util.concurrent.atomic.AtomicInteger
13
+
14
+ @ReactModule(name = GraniteImageModule.NAME)
15
+ class GraniteImageModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
16
+
17
+ companion object {
18
+ const val NAME = "GraniteImageModule"
19
+ private const val TAG = "GraniteImageModule"
20
+ }
21
+
22
+ private val executor = Executors.newFixedThreadPool(4)
23
+
24
+ override fun getName(): String = NAME
25
+
26
+ @ReactMethod
27
+ fun preload(sourcesJson: String, promise: Promise) {
28
+ Log.d(TAG, "preload called with: $sourcesJson")
29
+
30
+ val provider = GraniteImageRegistry.provider
31
+ if (provider == null) {
32
+ Log.w(TAG, "No provider registered, cannot preload")
33
+ promise.reject("NO_PROVIDER", "No provider registered, cannot preload")
34
+ return
35
+ }
36
+
37
+ executor.execute {
38
+ try {
39
+ val sources = JSONArray(sourcesJson)
40
+ val totalCount = sources.length()
41
+ val completedCount = AtomicInteger(0)
42
+ val successCount = AtomicInteger(0)
43
+ val failCount = AtomicInteger(0)
44
+
45
+ if (totalCount == 0) {
46
+ promise.resolve(null)
47
+ return@execute
48
+ }
49
+
50
+ for (i in 0 until sources.length()) {
51
+ val source = sources.getJSONObject(i)
52
+ val uri = source.optString("uri", "")
53
+ if (uri.isEmpty()) {
54
+ if (completedCount.incrementAndGet() == totalCount) {
55
+ Log.d(TAG, "Preload completed: ${successCount.get()} succeeded, ${failCount.get()} failed")
56
+ promise.resolve(null)
57
+ }
58
+ continue
59
+ }
60
+
61
+ val headersObj = source.optJSONObject("headers")
62
+ val headers = mutableMapOf<String, String>()
63
+ headersObj?.let {
64
+ val keys = it.keys()
65
+ while (keys.hasNext()) {
66
+ val key = keys.next()
67
+ headers[key] = it.getString(key)
68
+ }
69
+ }
70
+
71
+ val priorityStr = source.optString("priority", "normal")
72
+ val priority = when (priorityStr) {
73
+ "high" -> GraniteImagePriority.HIGH
74
+ "low" -> GraniteImagePriority.LOW
75
+ else -> GraniteImagePriority.NORMAL
76
+ }
77
+
78
+ val cacheStr = source.optString("cache", "")
79
+ val cachePolicy = when (cacheStr) {
80
+ "cacheOnly" -> GraniteImageCachePolicy.DISK
81
+ "web" -> GraniteImageCachePolicy.NONE
82
+ else -> GraniteImageCachePolicy.DISK
83
+ }
84
+
85
+ Log.d(TAG, "Preloading: $uri")
86
+
87
+ // Call provider's preload method (loadImage with null view for preload)
88
+ provider.loadImage(
89
+ url = uri,
90
+ imageView = null,
91
+ contentMode = "cover",
92
+ headers = headers.ifEmpty { null },
93
+ priority = priority,
94
+ cachePolicy = cachePolicy,
95
+ onProgress = null,
96
+ onCompletion = { success, width, height, error ->
97
+ if (success) {
98
+ Log.d(TAG, "Preloaded successfully: $uri (${width}x${height})")
99
+ successCount.incrementAndGet()
100
+ } else {
101
+ Log.d(TAG, "Preload failed for $uri: $error")
102
+ failCount.incrementAndGet()
103
+ }
104
+ if (completedCount.incrementAndGet() == totalCount) {
105
+ Log.d(TAG, "Preload completed: ${successCount.get()} succeeded, ${failCount.get()} failed")
106
+ promise.resolve(null)
107
+ }
108
+ }
109
+ )
110
+ }
111
+ } catch (e: Exception) {
112
+ Log.e(TAG, "Failed to parse sources JSON: ${e.message}")
113
+ promise.reject("PARSE_ERROR", "Failed to parse sources JSON: ${e.message}")
114
+ }
115
+ }
116
+ }
117
+
118
+ @ReactMethod
119
+ fun clearMemoryCache(promise: Promise) {
120
+ Log.d(TAG, "clearMemoryCache called")
121
+ // Memory cache clearing depends on provider implementation
122
+ promise.resolve(null)
123
+ }
124
+
125
+ @ReactMethod
126
+ fun clearDiskCache(promise: Promise) {
127
+ Log.d(TAG, "clearDiskCache called")
128
+ // Disk cache clearing depends on provider implementation
129
+ promise.resolve(null)
130
+ }
131
+ }
@@ -0,0 +1,59 @@
1
+ package run.granite.image
2
+
3
+ import android.util.Log
4
+ import com.facebook.react.ReactPackage
5
+ import com.facebook.react.bridge.NativeModule
6
+ import com.facebook.react.bridge.ReactApplicationContext
7
+ import com.facebook.react.uimanager.ViewManager
8
+
9
+ /**
10
+ * React Native Package that registers the GraniteImage component and GraniteImageModule.
11
+ */
12
+ class GraniteImagePackage : ReactPackage {
13
+ companion object {
14
+ private const val TAG = "GraniteImagePackage"
15
+ private var providerRegistered = false
16
+
17
+ init {
18
+ registerDefaultProvider()
19
+ }
20
+
21
+ private fun registerDefaultProvider() {
22
+ if (providerRegistered) return
23
+
24
+ // Try to auto-register a provider based on available implementations
25
+ val providerClasses = listOf(
26
+ "run.granite.image.providers.OkHttpImageProvider",
27
+ "run.granite.image.providers.GlideImageProvider",
28
+ "run.granite.image.providers.CoilImageProvider"
29
+ )
30
+
31
+ for (className in providerClasses) {
32
+ try {
33
+ val clazz = Class.forName(className)
34
+ val provider = clazz.getDeclaredConstructor().newInstance() as GraniteImageProvider
35
+ GraniteImageRegistry.registerProvider(provider)
36
+ Log.d(TAG, "Auto-registered provider: $className")
37
+ providerRegistered = true
38
+ break
39
+ } catch (e: ClassNotFoundException) {
40
+ // Provider not available, try next
41
+ } catch (e: Exception) {
42
+ Log.e(TAG, "Failed to instantiate provider $className: ${e.message}")
43
+ }
44
+ }
45
+
46
+ if (!providerRegistered) {
47
+ Log.w(TAG, "No image provider found. Make sure to include one of: okhttp, glide, or coil flavor.")
48
+ }
49
+ }
50
+ }
51
+
52
+ override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
53
+ return listOf(GraniteImageModule(reactContext))
54
+ }
55
+
56
+ override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
57
+ return listOf(GraniteImageManager())
58
+ }
59
+ }
@@ -0,0 +1,105 @@
1
+ package run.granite.image
2
+
3
+ import android.content.Context
4
+ import android.graphics.Bitmap
5
+ import android.view.View
6
+ import android.widget.ImageView
7
+
8
+ /**
9
+ * Priority levels for image loading
10
+ */
11
+ enum class GraniteImagePriority {
12
+ LOW, NORMAL, HIGH
13
+ }
14
+
15
+ /**
16
+ * Cache policy for image loading
17
+ */
18
+ enum class GraniteImageCachePolicy {
19
+ MEMORY, DISK, NONE
20
+ }
21
+
22
+ /**
23
+ * Progress callback
24
+ */
25
+ typealias GraniteImageProgressCallback = (loaded: Long, total: Long) -> Unit
26
+
27
+ /**
28
+ * Completion callback with image dimensions
29
+ */
30
+ typealias GraniteImageCompletionCallback = (bitmap: Bitmap?, error: Exception?, width: Int, height: Int) -> Unit
31
+
32
+ /**
33
+ * Interface that defines the contract for image loading providers.
34
+ * Implementations can use any image loading library (OkHttp, Glide, Coil, etc.)
35
+ */
36
+ interface GraniteImageProvider {
37
+ /**
38
+ * Creates and returns a new View that will be used to display the image.
39
+ * The returned view should be capable of displaying images (typically ImageView).
40
+ */
41
+ fun createImageView(context: Context): View
42
+
43
+ /**
44
+ * Loads an image from the given URL into the provided view.
45
+ * @param url The URL string of the image to load
46
+ * @param view The view returned from createImageView where the image should be displayed
47
+ * @param scaleType The scale type to use when displaying the image
48
+ */
49
+ fun loadImage(url: String, into: View, scaleType: ImageView.ScaleType)
50
+
51
+ /**
52
+ * Cancels any ongoing image load for the given view.
53
+ * @param view The view whose image load should be cancelled
54
+ */
55
+ fun cancelLoad(view: View)
56
+
57
+ /**
58
+ * Loads an image with full options support including headers, priority, cache policy, and callbacks.
59
+ * Default implementation delegates to simple loadImage.
60
+ */
61
+ fun loadImage(
62
+ url: String,
63
+ into: View?,
64
+ scaleType: ImageView.ScaleType,
65
+ headers: Map<String, String>?,
66
+ priority: GraniteImagePriority,
67
+ cachePolicy: GraniteImageCachePolicy,
68
+ defaultSource: String?,
69
+ progressCallback: GraniteImageProgressCallback?,
70
+ completionCallback: GraniteImageCompletionCallback?
71
+ ) {
72
+ if (into != null) {
73
+ // Default implementation - just use simple load
74
+ loadImage(url, into, scaleType)
75
+ }
76
+ // Notify completion with unknown dimensions
77
+ completionCallback?.invoke(null, null, 0, 0)
78
+ }
79
+
80
+ /**
81
+ * Preloads an image without displaying it.
82
+ * Uses the extended loadImage with null view.
83
+ */
84
+ fun loadImage(
85
+ url: String,
86
+ imageView: Nothing?,
87
+ contentMode: String,
88
+ headers: Map<String, String>?,
89
+ priority: GraniteImagePriority,
90
+ cachePolicy: GraniteImageCachePolicy,
91
+ onProgress: GraniteImageProgressCallback?,
92
+ onCompletion: ((success: Boolean, width: Int, height: Int, error: String?) -> Unit)?
93
+ ) {
94
+ // Default implementation does nothing for preload
95
+ onCompletion?.invoke(false, 0, 0, "Provider does not support preloading")
96
+ }
97
+
98
+ /**
99
+ * Applies a tint color to the image view.
100
+ * Default implementation does nothing.
101
+ */
102
+ fun applyTintColor(color: Int, view: View) {
103
+ // Default implementation - do nothing
104
+ }
105
+ }
@@ -0,0 +1,29 @@
1
+ package run.granite.image
2
+
3
+ /**
4
+ * Singleton registry for managing the current GraniteImageProvider.
5
+ * Applications should register their provider implementation at app startup.
6
+ */
7
+ object GraniteImageRegistry {
8
+ /**
9
+ * The currently registered image provider.
10
+ * If null, GraniteImage will display an error state.
11
+ */
12
+ var provider: GraniteImageProvider? = null
13
+ private set
14
+
15
+ /**
16
+ * Registers an image provider to be used by all GraniteImage instances.
17
+ * @param provider The provider implementation to register
18
+ */
19
+ fun registerProvider(provider: GraniteImageProvider) {
20
+ this.provider = provider
21
+ }
22
+
23
+ /**
24
+ * Clears the currently registered provider.
25
+ */
26
+ fun clearProvider() {
27
+ this.provider = null
28
+ }
29
+ }
@@ -0,0 +1,228 @@
1
+ package run.granite.image.providers
2
+
3
+ import android.content.Context
4
+ import android.graphics.Bitmap
5
+ import android.graphics.BitmapFactory
6
+ import android.graphics.PorterDuff
7
+ import android.graphics.PorterDuffColorFilter
8
+ import android.os.Handler
9
+ import android.os.Looper
10
+ import android.util.Log
11
+ import android.view.View
12
+ import android.widget.ImageView
13
+ import run.granite.image.GraniteImageProvider
14
+ import run.granite.image.GraniteImagePriority
15
+ import run.granite.image.GraniteImageCachePolicy
16
+ import run.granite.image.GraniteImageProgressCallback
17
+ import run.granite.image.GraniteImageCompletionCallback
18
+ import okhttp3.Call
19
+ import okhttp3.Callback
20
+ import okhttp3.CacheControl
21
+ import okhttp3.OkHttpClient
22
+ import okhttp3.Request
23
+ import okhttp3.Response
24
+ import java.io.IOException
25
+ import java.util.WeakHashMap
26
+ import java.util.concurrent.TimeUnit
27
+
28
+ /**
29
+ * GraniteImageProvider implementation using OkHttp.
30
+ * This is analogous to iOS's URLSessionImageProvider.
31
+ */
32
+ class OkHttpImageProvider : GraniteImageProvider {
33
+ companion object {
34
+ private const val TAG = "OkHttpImageProvider"
35
+ }
36
+
37
+ private val client = OkHttpClient.Builder()
38
+ .connectTimeout(30, TimeUnit.SECONDS)
39
+ .readTimeout(30, TimeUnit.SECONDS)
40
+ .build()
41
+ private val activeCalls = WeakHashMap<View, Call>()
42
+ private val mainHandler = Handler(Looper.getMainLooper())
43
+
44
+ override fun createImageView(context: Context): View {
45
+ return ImageView(context).apply {
46
+ setBackgroundColor(android.graphics.Color.LTGRAY)
47
+ }
48
+ }
49
+
50
+ override fun loadImage(url: String, into: View, scaleType: ImageView.ScaleType) {
51
+ loadImage(url, into, scaleType, null, GraniteImagePriority.NORMAL, GraniteImageCachePolicy.DISK, null, null, null)
52
+ }
53
+
54
+ override fun loadImage(
55
+ url: String,
56
+ into: View?,
57
+ scaleType: ImageView.ScaleType,
58
+ headers: Map<String, String>?,
59
+ priority: GraniteImagePriority,
60
+ cachePolicy: GraniteImageCachePolicy,
61
+ defaultSource: String?,
62
+ progressCallback: GraniteImageProgressCallback?,
63
+ completionCallback: GraniteImageCompletionCallback?
64
+ ) {
65
+ // Allow null view for preloading
66
+ val imageView: ImageView? = if (into != null) {
67
+ if (into !is ImageView) {
68
+ Log.e(TAG, "View is not an ImageView")
69
+ completionCallback?.invoke(null, Exception("View is not an ImageView"), 0, 0)
70
+ return
71
+ }
72
+ into.scaleType = scaleType
73
+ // Cancel any existing request for this view
74
+ cancelLoad(into)
75
+ into
76
+ } else {
77
+ null
78
+ }
79
+
80
+ // Apply default source (placeholder) before loading
81
+ if (imageView != null && !defaultSource.isNullOrEmpty()) {
82
+ val resourceId = imageView.context.resources.getIdentifier(defaultSource, "drawable", imageView.context.packageName)
83
+ if (resourceId != 0) {
84
+ imageView.setImageResource(resourceId)
85
+ }
86
+ }
87
+
88
+ val requestBuilder = Request.Builder().url(url)
89
+
90
+ // Add headers
91
+ headers?.forEach { (key, value) ->
92
+ requestBuilder.addHeader(key, value)
93
+ }
94
+
95
+ // Apply cache policy
96
+ when (cachePolicy) {
97
+ GraniteImageCachePolicy.NONE -> {
98
+ requestBuilder.cacheControl(CacheControl.FORCE_NETWORK)
99
+ }
100
+ GraniteImageCachePolicy.MEMORY, GraniteImageCachePolicy.DISK -> {
101
+ // Use default caching
102
+ }
103
+ }
104
+
105
+ val request = requestBuilder.build()
106
+ val call = client.newCall(request)
107
+ if (into != null) {
108
+ activeCalls[into] = call
109
+ }
110
+
111
+ call.enqueue(object : Callback {
112
+ override fun onFailure(call: Call, e: IOException) {
113
+ Log.e(TAG, "Error loading image: ${e.message}")
114
+ if (into != null) {
115
+ activeCalls.remove(into)
116
+ }
117
+ mainHandler.post {
118
+ completionCallback?.invoke(null, e, 0, 0)
119
+ }
120
+ }
121
+
122
+ override fun onResponse(call: Call, response: Response) {
123
+ if (into != null) {
124
+ activeCalls.remove(into)
125
+ }
126
+
127
+ if (!response.isSuccessful) {
128
+ val error = Exception("HTTP error: ${response.code}")
129
+ Log.e(TAG, "HTTP error: ${response.code}")
130
+ mainHandler.post {
131
+ completionCallback?.invoke(null, error, 0, 0)
132
+ }
133
+ return
134
+ }
135
+
136
+ val body = response.body
137
+ if (body == null) {
138
+ val error = Exception("No data received")
139
+ Log.e(TAG, "No data received")
140
+ mainHandler.post {
141
+ completionCallback?.invoke(null, error, 0, 0)
142
+ }
143
+ return
144
+ }
145
+
146
+ // Get content length for progress
147
+ val contentLength = body.contentLength()
148
+
149
+ // Read bytes with progress reporting
150
+ val inputStream = body.byteStream()
151
+ val bytes = ByteArray(contentLength.toInt().coerceAtLeast(1024))
152
+ var totalBytesRead = 0L
153
+ val buffer = ByteArray(8192)
154
+ var bytesRead: Int
155
+
156
+ try {
157
+ val outputStream = java.io.ByteArrayOutputStream()
158
+ while (inputStream.read(buffer).also { bytesRead = it } != -1) {
159
+ outputStream.write(buffer, 0, bytesRead)
160
+ totalBytesRead += bytesRead
161
+ if (contentLength > 0) {
162
+ progressCallback?.invoke(totalBytesRead, contentLength)
163
+ }
164
+ }
165
+ val imageBytes = outputStream.toByteArray()
166
+
167
+ val bitmap = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.size)
168
+ if (bitmap == null) {
169
+ val error = Exception("Failed to decode image data")
170
+ Log.e(TAG, "Failed to decode image data")
171
+ mainHandler.post {
172
+ completionCallback?.invoke(null, error, 0, 0)
173
+ }
174
+ return
175
+ }
176
+
177
+ mainHandler.post {
178
+ imageView?.setImageBitmap(bitmap)
179
+ Log.d(TAG, "Loaded with OkHttp: $url")
180
+ completionCallback?.invoke(bitmap, null, bitmap.width, bitmap.height)
181
+ }
182
+ } catch (e: Exception) {
183
+ Log.e(TAG, "Error reading image data: ${e.message}")
184
+ mainHandler.post {
185
+ completionCallback?.invoke(null, e, 0, 0)
186
+ }
187
+ }
188
+ }
189
+ })
190
+ }
191
+
192
+ override fun cancelLoad(view: View) {
193
+ activeCalls[view]?.cancel()
194
+ activeCalls.remove(view)
195
+ }
196
+
197
+ override fun applyTintColor(color: Int, view: View) {
198
+ if (view is ImageView) {
199
+ view.colorFilter = PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN)
200
+ }
201
+ }
202
+
203
+ override fun loadImage(
204
+ url: String,
205
+ imageView: Nothing?,
206
+ contentMode: String,
207
+ headers: Map<String, String>?,
208
+ priority: GraniteImagePriority,
209
+ cachePolicy: GraniteImageCachePolicy,
210
+ onProgress: GraniteImageProgressCallback?,
211
+ onCompletion: ((success: Boolean, width: Int, height: Int, error: String?) -> Unit)?
212
+ ) {
213
+ // Preload implementation - load without displaying
214
+ loadImage(
215
+ url = url,
216
+ into = null,
217
+ scaleType = ImageView.ScaleType.CENTER_CROP,
218
+ headers = headers,
219
+ priority = priority,
220
+ cachePolicy = cachePolicy,
221
+ defaultSource = null,
222
+ progressCallback = onProgress,
223
+ completionCallback = { bitmap, error, width, height ->
224
+ onCompletion?.invoke(bitmap != null, width, height, error?.message)
225
+ }
226
+ )
227
+ }
228
+ }
@@ -0,0 +1,127 @@
1
+ "use strict";
2
+
3
+ import React, { useCallback } from 'react';
4
+ import { NativeModules } from 'react-native';
5
+ import GraniteImageNativeComponent from './GraniteImageNativeComponent';
6
+ import { jsx as _jsx } from "react/jsx-runtime";
7
+ const {
8
+ GraniteImageModule
9
+ } = NativeModules;
10
+
11
+ // Source types matching GraniteImage
12
+
13
+ // Map resizeMode to contentMode for native
14
+ const resizeModeToContentMode = resizeMode => {
15
+ return resizeMode || 'cover';
16
+ };
17
+
18
+ // Map GraniteImage cache to native cachePolicy
19
+ const mapCachePolicy = cache => {
20
+ switch (cache) {
21
+ case 'cacheOnly':
22
+ return 'disk';
23
+ case 'web':
24
+ return 'none';
25
+ case 'immutable':
26
+ default:
27
+ return 'disk';
28
+ }
29
+ };
30
+
31
+ // Type declarations for static methods
32
+
33
+ // Static methods for cache management
34
+ const clearMemoryCache = () => {
35
+ if (GraniteImageModule?.clearMemoryCache) {
36
+ return GraniteImageModule.clearMemoryCache();
37
+ }
38
+ console.warn('GraniteImage.clearMemoryCache: Native module not available');
39
+ return Promise.resolve();
40
+ };
41
+ const clearDiskCache = () => {
42
+ if (GraniteImageModule?.clearDiskCache) {
43
+ return GraniteImageModule.clearDiskCache();
44
+ }
45
+ console.warn('GraniteImage.clearDiskCache: Native module not available');
46
+ return Promise.resolve();
47
+ };
48
+ const preload = sources => {
49
+ if (GraniteImageModule?.preload) {
50
+ const sourcesJson = JSON.stringify(sources);
51
+ return GraniteImageModule.preload(sourcesJson);
52
+ } else {
53
+ console.warn('GraniteImage.preload: Native module not available');
54
+ return Promise.resolve();
55
+ }
56
+ };
57
+ const GraniteImageBase = ({
58
+ source,
59
+ resizeMode = 'cover',
60
+ tintColor,
61
+ style,
62
+ defaultSource,
63
+ fallbackSource,
64
+ priority = 'normal',
65
+ cachePolicy = 'disk',
66
+ onLoadStart,
67
+ onProgress,
68
+ onLoad,
69
+ onError,
70
+ onLoadEnd,
71
+ ...viewProps
72
+ }) => {
73
+ // Parse source
74
+ const uri = typeof source === 'string' ? source : (source && typeof source === 'object' ? source.uri : '') ?? '';
75
+ const headers = typeof source === 'object' && source.headers ? JSON.stringify(source.headers) : undefined;
76
+ const sourcePriority = typeof source === 'object' ? source.priority : undefined;
77
+ const sourceCache = typeof source === 'object' ? source.cache : undefined;
78
+
79
+ // Handle defaultSource
80
+ const defaultSourceUri = typeof defaultSource === 'string' ? defaultSource : typeof defaultSource === 'number' ? undefined // Local require() - need native handling
81
+ : undefined;
82
+
83
+ // Handle fallbackSource
84
+ const fallbackSourceUri = typeof fallbackSource === 'string' ? fallbackSource : typeof fallbackSource === 'number' ? undefined // Local require() - need native handling
85
+ : undefined;
86
+
87
+ // Event handlers
88
+ const handleLoadStart = useCallback(event => {
89
+ onLoadStart?.(event);
90
+ }, [onLoadStart]);
91
+ const handleProgress = useCallback(event => {
92
+ onProgress?.(event);
93
+ }, [onProgress]);
94
+ const handleLoad = useCallback(event => {
95
+ onLoad?.(event);
96
+ }, [onLoad]);
97
+ const handleError = useCallback(event => {
98
+ onError?.(event);
99
+ }, [onError]);
100
+ const handleLoadEnd = useCallback(event => {
101
+ onLoadEnd?.(event);
102
+ }, [onLoadEnd]);
103
+ return /*#__PURE__*/_jsx(GraniteImageNativeComponent, {
104
+ ...viewProps,
105
+ uri: uri,
106
+ headers: headers,
107
+ contentMode: resizeModeToContentMode(resizeMode),
108
+ tintColor: tintColor,
109
+ defaultSource: defaultSourceUri,
110
+ fallbackSource: fallbackSourceUri,
111
+ priority: sourcePriority || priority,
112
+ cachePolicy: sourceCache ? mapCachePolicy(sourceCache) : cachePolicy,
113
+ style: style,
114
+ onGraniteLoadStart: onLoadStart ? handleLoadStart : undefined,
115
+ onGraniteProgress: onProgress ? handleProgress : undefined,
116
+ onGraniteLoad: onLoad ? handleLoad : undefined,
117
+ onGraniteError: onError ? handleError : undefined,
118
+ onGraniteLoadEnd: onLoadEnd ? handleLoadEnd : undefined
119
+ });
120
+ };
121
+ export const GraniteImage = Object.assign(GraniteImageBase, {
122
+ clearMemoryCache,
123
+ clearDiskCache,
124
+ preload
125
+ });
126
+ export default GraniteImage;
127
+ //# sourceMappingURL=GraniteImage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["React","useCallback","NativeModules","GraniteImageNativeComponent","jsx","_jsx","GraniteImageModule","resizeModeToContentMode","resizeMode","mapCachePolicy","cache","clearMemoryCache","console","warn","Promise","resolve","clearDiskCache","preload","sources","sourcesJson","JSON","stringify","GraniteImageBase","source","tintColor","style","defaultSource","fallbackSource","priority","cachePolicy","onLoadStart","onProgress","onLoad","onError","onLoadEnd","viewProps","uri","headers","undefined","sourcePriority","sourceCache","defaultSourceUri","fallbackSourceUri","handleLoadStart","event","handleProgress","handleLoad","handleError","handleLoadEnd","contentMode","onGraniteLoadStart","onGraniteProgress","onGraniteLoad","onGraniteError","onGraniteLoadEnd","GraniteImage","Object","assign"],"sourceRoot":"../../src","sources":["GraniteImage.tsx"],"mappings":"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","ignoreList":[]}