@granite-js/image 0.1.33 → 1.0.0

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 +3 -270
  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
package/CHANGELOG.md CHANGED
@@ -1,274 +1,7 @@
1
1
  # @granite-js/image
2
2
 
3
- ## 0.1.33
3
+ ## 1.0.0
4
4
 
5
- ### Patch Changes
5
+ ### Major Changes
6
6
 
7
- - Updated dependencies [fdf55a6]
8
- - @granite-js/native@0.1.33
9
-
10
- ## 0.1.32
11
-
12
- ### Patch Changes
13
-
14
- - 7572713: bump version up babel
15
- - Updated dependencies [74b2223]
16
- - Updated dependencies [7572713]
17
- - @granite-js/native@0.1.32
18
-
19
- ## 0.1.31
20
-
21
- ### Patch Changes
22
-
23
- - Updated dependencies [0ff9b13]
24
- - Updated dependencies [37ae3f3]
25
- - @granite-js/native@0.1.31
26
-
27
- ## 0.1.30
28
-
29
- ### Patch Changes
30
-
31
- - @granite-js/native@0.1.30
32
-
33
- ## 0.1.29
34
-
35
- ### Patch Changes
36
-
37
- - @granite-js/native@0.1.29
38
-
39
- ## 0.1.28
40
-
41
- ### Patch Changes
42
-
43
- - 1d958cc: ci: provenance
44
- - Updated dependencies [1d958cc]
45
- - @granite-js/native@0.1.28
46
-
47
- ## 0.1.27
48
-
49
- ### Patch Changes
50
-
51
- - e32b020: ci: oidc
52
- - Updated dependencies [e32b020]
53
- - Updated dependencies [1dd9179]
54
- - @granite-js/native@0.1.27
55
-
56
- ## 0.1.26
57
-
58
- ### Patch Changes
59
-
60
- - 41f9ab3: ensure polyfill setup during initialization and update package.json config for improve tree shaking
61
- - @granite-js/native@0.1.26
62
-
63
- ## 0.1.25
64
-
65
- ### Patch Changes
66
-
67
- - @granite-js/native@0.1.25
68
-
69
- ## 0.1.24
70
-
71
- ### Patch Changes
72
-
73
- - @granite-js/native@0.1.24
74
-
75
- ## 0.1.23
76
-
77
- ### Patch Changes
78
-
79
- - @granite-js/native@0.1.23
80
-
81
- ## 0.1.22
82
-
83
- ### Patch Changes
84
-
85
- - @granite-js/native@0.1.22
86
-
87
- ## 0.1.21
88
-
89
- ### Patch Changes
90
-
91
- - @granite-js/native@0.1.21
92
-
93
- ## 0.1.20
94
-
95
- ### Patch Changes
96
-
97
- - 1df5883: update package.json meta to supports any moduleResolutions
98
- - Updated dependencies [1df5883]
99
- - @granite-js/native@0.1.20
100
-
101
- ## 0.1.19
102
-
103
- ### Patch Changes
104
-
105
- - @granite-js/native@0.1.19
106
-
107
- ## 0.1.18
108
-
109
- ### Patch Changes
110
-
111
- - @granite-js/native@0.1.18
112
-
113
- ## 0.1.17
114
-
115
- ### Patch Changes
116
-
117
- - @granite-js/native@0.1.17
118
-
119
- ## 0.1.16
120
-
121
- ### Patch Changes
122
-
123
- - @granite-js/native@0.1.16
124
-
125
- ## 0.1.15
126
-
127
- ### Patch Changes
128
-
129
- - d16ee87: Add useInitialProps, useInitialSearchParams hook.
130
- - Updated dependencies [d16ee87]
131
- - @granite-js/native@0.1.15
132
-
133
- ## 0.1.14
134
-
135
- ### Patch Changes
136
-
137
- - @granite-js/native@0.1.14
138
-
139
- ## 0.1.13
140
-
141
- ### Patch Changes
142
-
143
- - @granite-js/native@0.1.13
144
-
145
- ## 0.1.12
146
-
147
- ### Patch Changes
148
-
149
- - d1e6585: fix module resolutions
150
- - Updated dependencies [d1e6585]
151
- - @granite-js/native@0.1.12
152
-
153
- ## 0.1.11
154
-
155
- ### Patch Changes
156
-
157
- - @granite-js/native@0.1.11
158
-
159
- ## 0.1.10
160
-
161
- ### Patch Changes
162
-
163
- - @granite-js/native@0.1.10
164
-
165
- ## 0.1.9
166
-
167
- ### Patch Changes
168
-
169
- - @granite-js/native@0.1.9
170
-
171
- ## 0.1.8
172
-
173
- ### Patch Changes
174
-
175
- - @granite-js/native@0.1.8
176
-
177
- ## 0.1.7
178
-
179
- ### Patch Changes
180
-
181
- - @granite-js/native@0.1.7
182
-
183
- ## 0.1.6
184
-
185
- ### Patch Changes
186
-
187
- - @granite-js/native@0.1.6
188
-
189
- ## 0.1.5
190
-
191
- ### Patch Changes
192
-
193
- - @granite-js/native@0.1.5
194
-
195
- ## 0.1.4
196
-
197
- ### Patch Changes
198
-
199
- - @granite-js/native@0.1.4
200
-
201
- ## 0.1.3
202
-
203
- ### Patch Changes
204
-
205
- - @granite-js/native@0.1.3
206
-
207
- ## 0.1.2
208
-
209
- ### Patch Changes
210
-
211
- - Updated dependencies [e1384cf]
212
- - @granite-js/native@0.1.2
213
-
214
- ## 0.1.1
215
-
216
- ### Patch Changes
217
-
218
- - d675415: Improve scaffolding to provide a better showcase UI
219
- - 10a5f3f: empty
220
- - Updated dependencies [d675415]
221
- - Updated dependencies [10a5f3f]
222
- - @granite-js/native@0.1.1
223
-
224
- ## 0.1.0
225
-
226
- ### Minor Changes
227
-
228
- - 561a3ed: fix: docs deadlink
229
-
230
- ### Patch Changes
231
-
232
- - Updated dependencies [561a3ed]
233
- - @granite-js/native@0.1.0
234
-
235
- ## 0.0.3
236
-
237
- ### Patch Changes
238
-
239
- - ed4d356: changeset
240
- - Updated dependencies [ed4d356]
241
- - @granite-js/native@0.0.3
242
-
243
- ## 0.0.2
244
-
245
- ### Patch Changes
246
-
247
- - 0ae09b7: deploy guide
248
- - 0ae09b7: type fix
249
- - 0ae09b7: guide
250
- - 0ae09b7: fix comment
251
- - 0ae09b7: showcase
252
- - 0ae09b7: refactor interface names
253
- - 0ae09b7: fix hemres
254
- - 0ae09b7: CanGoBackGuard 수정, typecheck fix, lint fix
255
- - 0ae09b7: counter
256
- - Updated dependencies [0ae09b7]
257
- - Updated dependencies [0ae09b7]
258
- - Updated dependencies [0ae09b7]
259
- - Updated dependencies [0ae09b7]
260
- - Updated dependencies [0ae09b7]
261
- - Updated dependencies [0ae09b7]
262
- - Updated dependencies [0ae09b7]
263
- - Updated dependencies [0ae09b7]
264
- - Updated dependencies [0ae09b7]
265
- - Updated dependencies [0ae09b7]
266
- - @granite-js/native@0.0.2
267
-
268
- ## 0.0.1
269
-
270
- ### Patch Changes
271
-
272
- - f47ca39: first release
273
- - Updated dependencies [f47ca39]
274
- - @granite-js/native@0.0.1
7
+ - 260daab: feat: introduce support react native 0.84
@@ -0,0 +1,72 @@
1
+ require "json"
2
+
3
+ package = JSON.parse(File.read(File.join(__dir__, "package.json")))
4
+
5
+ # ============================================================
6
+ # GraniteImage Default Provider Configuration
7
+ # ============================================================
8
+ # Priority: GRANITE_IMAGE_DEFAULT_PROVIDER > GRANITE_DEFAULT_PROVIDER_ALL > true (default)
9
+ #
10
+ # Examples:
11
+ # Include default provider (default):
12
+ # pod install
13
+ #
14
+ # Exclude default provider for image only:
15
+ # GRANITE_IMAGE_DEFAULT_PROVIDER=false pod install
16
+ #
17
+ # Exclude default providers for all Granite packages:
18
+ # GRANITE_DEFAULT_PROVIDER_ALL=false pod install
19
+ #
20
+ # Exclude all but override image to include:
21
+ # GRANITE_DEFAULT_PROVIDER_ALL=false GRANITE_IMAGE_DEFAULT_PROVIDER=true pod install
22
+ # ============================================================
23
+ resolve_default_provider = lambda do |specific_key, fallback_key, default_value|
24
+ if ENV.key?(specific_key)
25
+ ENV[specific_key] == 'true'
26
+ elsif ENV.key?(fallback_key)
27
+ ENV[fallback_key] == 'true'
28
+ else
29
+ default_value
30
+ end
31
+ end
32
+
33
+ use_default_provider = resolve_default_provider.call(
34
+ 'GRANITE_IMAGE_DEFAULT_PROVIDER',
35
+ 'GRANITE_DEFAULT_PROVIDER_ALL',
36
+ true
37
+ )
38
+
39
+ exclude_patterns = []
40
+ exclude_patterns << "ios/Providers/SDWebImageProvider.swift" unless use_default_provider
41
+
42
+ Pod::Spec.new do |s|
43
+ s.name = "GraniteImage"
44
+ s.version = package["version"]
45
+ s.summary = package["description"]
46
+ s.homepage = package["homepage"]
47
+ s.license = package["license"]
48
+ s.authors = package["author"]
49
+
50
+ s.platforms = { :ios => min_ios_version_supported }
51
+ s.source = { :git => "https://github.com/toss/granite.git", :tag => "#{s.version}" }
52
+
53
+ s.source_files = "ios/**/*.{h,m,mm,swift,cpp}"
54
+ s.exclude_files = exclude_patterns if exclude_patterns.any?
55
+
56
+ # Set preprocessor macros
57
+ swift_flags = []
58
+ swift_flags << 'GRANITE_IMAGE_DEFAULT_PROVIDER' if use_default_provider
59
+
60
+ s.pod_target_xcconfig = {
61
+ 'SWIFT_ACTIVE_COMPILATION_CONDITIONS' => swift_flags.join(' '),
62
+ 'CLANG_ENABLE_MODULES' => 'YES',
63
+ 'SWIFT_OBJC_INTERFACE_HEADER_NAME' => 'GraniteImage-Swift.h'
64
+ }
65
+
66
+ install_modules_dependencies(s)
67
+
68
+ # Include SDWebImage dependency only when using default provider
69
+ if use_default_provider
70
+ s.dependency "SDWebImage", "~> 5.18"
71
+ end
72
+ end
@@ -0,0 +1,178 @@
1
+ buildscript {
2
+ ext.safeExtGet = {prop, fallback ->
3
+ rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
4
+ }
5
+ ext.getExtOrDefault = {name ->
6
+ return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties['GraniteImage_' + name]
7
+ }
8
+
9
+ repositories {
10
+ google()
11
+ mavenCentral()
12
+ }
13
+
14
+ dependencies {
15
+ classpath "com.android.tools.build:gradle:8.7.2"
16
+ // noinspection DifferentKotlinGradleVersion
17
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${getExtOrDefault('kotlinVersion')}"
18
+ }
19
+ }
20
+
21
+
22
+ apply plugin: "com.android.library"
23
+ apply plugin: "kotlin-android"
24
+
25
+ apply plugin: "com.facebook.react"
26
+
27
+ // ============================================================
28
+ // GraniteImage Default Provider Configuration
29
+ // ============================================================
30
+ // Priority: Environment Variable > gradle.properties > default (true)
31
+ //
32
+ // Environment Variables:
33
+ // GRANITE_IMAGE_DEFAULT_PROVIDER - Image specific override
34
+ // GRANITE_DEFAULT_PROVIDER_ALL - Global default for all Granite packages
35
+ //
36
+ // gradle.properties (alternative):
37
+ // GRANITE_IMAGE_DEFAULT_PROVIDER=false
38
+ // GRANITE_DEFAULT_PROVIDER_ALL=false
39
+ //
40
+ // Examples:
41
+ // Include default provider (default):
42
+ // ./gradlew assembleDebug
43
+ //
44
+ // Exclude default provider for image only (env var):
45
+ // GRANITE_IMAGE_DEFAULT_PROVIDER=false ./gradlew assembleDebug
46
+ //
47
+ // Exclude default provider via gradle.properties:
48
+ // # In gradle.properties:
49
+ // GRANITE_IMAGE_DEFAULT_PROVIDER=false
50
+ //
51
+ // Exclude all but override image to include:
52
+ // GRANITE_DEFAULT_PROVIDER_ALL=false GRANITE_IMAGE_DEFAULT_PROVIDER=true ./gradlew assembleDebug
53
+ //
54
+ // Provider Selection (when default provider is enabled):
55
+ // GRANITE_PROVIDER=okhttp - OkHttp (default, minimal dependencies)
56
+ // GRANITE_PROVIDER=glide - Glide library
57
+ // GRANITE_PROVIDER=coil - Coil library
58
+ //
59
+ // Example: ./gradlew assembleDebug -PGRANITE_PROVIDER=glide
60
+ // ============================================================
61
+ def resolveDefaultProvider(String specificKey, String fallbackKey, boolean defaultValue) {
62
+ // Priority: Environment Variable > gradle.properties > default
63
+
64
+ // Check specific key
65
+ def specificEnvValue = System.getenv(specificKey)
66
+ if (specificEnvValue != null) {
67
+ return specificEnvValue == 'true'
68
+ }
69
+ def specificPropValue = project.findProperty(specificKey)
70
+ if (specificPropValue != null) {
71
+ return specificPropValue.toString() == 'true'
72
+ }
73
+
74
+ // Check fallback key
75
+ def fallbackEnvValue = System.getenv(fallbackKey)
76
+ if (fallbackEnvValue != null) {
77
+ return fallbackEnvValue == 'true'
78
+ }
79
+ def fallbackPropValue = project.findProperty(fallbackKey)
80
+ if (fallbackPropValue != null) {
81
+ return fallbackPropValue.toString() == 'true'
82
+ }
83
+
84
+ return defaultValue
85
+ }
86
+
87
+ def includeDefaultProvider = resolveDefaultProvider(
88
+ 'GRANITE_IMAGE_DEFAULT_PROVIDER',
89
+ 'GRANITE_DEFAULT_PROVIDER_ALL',
90
+ true
91
+ )
92
+
93
+ def graniteProvider = project.hasProperty('GRANITE_PROVIDER') ? project.property('GRANITE_PROVIDER') : 'okhttp'
94
+ println "GraniteImage: includeDefaultProvider=${includeDefaultProvider}, provider=${graniteProvider}"
95
+
96
+ def getExtOrIntegerDefault(name) {
97
+ return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties["GraniteImage_" + name]).toInteger()
98
+ }
99
+
100
+ android {
101
+ namespace "run.granite.image"
102
+
103
+ compileSdkVersion getExtOrIntegerDefault("compileSdkVersion")
104
+
105
+ defaultConfig {
106
+ minSdkVersion getExtOrIntegerDefault("minSdkVersion")
107
+ targetSdkVersion getExtOrIntegerDefault("targetSdkVersion")
108
+
109
+ buildConfigField "boolean", "INCLUDE_DEFAULT_PROVIDER", "${includeDefaultProvider}"
110
+ buildConfigField "String", "GRANITE_PROVIDER", "\"${graniteProvider}\""
111
+ }
112
+
113
+ buildFeatures {
114
+ buildConfig true
115
+ }
116
+
117
+ buildTypes {
118
+ release {
119
+ minifyEnabled false
120
+ }
121
+ }
122
+
123
+ lintOptions {
124
+ disable "GradleCompatible"
125
+ }
126
+
127
+ compileOptions {
128
+ sourceCompatibility JavaVersion.VERSION_17
129
+ targetCompatibility JavaVersion.VERSION_17
130
+ }
131
+
132
+ kotlinOptions {
133
+ jvmTarget = '17'
134
+ }
135
+
136
+ sourceSets {
137
+ main {
138
+ if (includeDefaultProvider) {
139
+ java.srcDirs += [
140
+ "generated/java",
141
+ "generated/jni",
142
+ "src/${graniteProvider}/java"
143
+ ]
144
+ } else {
145
+ java.srcDirs += [
146
+ "generated/java",
147
+ "generated/jni"
148
+ ]
149
+ }
150
+ }
151
+ }
152
+ }
153
+
154
+ repositories {
155
+ mavenCentral()
156
+ google()
157
+ }
158
+
159
+ def kotlin_version = getExtOrDefault("kotlinVersion")
160
+
161
+ dependencies {
162
+ implementation "com.facebook.react:react-android"
163
+ implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
164
+
165
+ // Provider-specific dependencies (only included when default provider is enabled)
166
+ if (includeDefaultProvider) {
167
+ if (graniteProvider == 'okhttp') {
168
+ implementation "com.squareup.okhttp3:okhttp:4.12.0"
169
+ }
170
+ if (graniteProvider == 'glide') {
171
+ implementation "com.github.bumptech.glide:glide:4.16.0"
172
+ annotationProcessor "com.github.bumptech.glide:compiler:4.16.0"
173
+ }
174
+ if (graniteProvider == 'coil') {
175
+ implementation "io.coil-kt:coil:2.5.0"
176
+ }
177
+ }
178
+ }
@@ -0,0 +1,5 @@
1
+ GraniteImage_kotlinVersion=2.0.21
2
+ GraniteImage_minSdkVersion=24
3
+ GraniteImage_targetSdkVersion=34
4
+ GraniteImage_compileSdkVersion=35
5
+ GraniteImage_ndkVersion=27.1.12297006
@@ -0,0 +1,156 @@
1
+ package run.granite.image.providers
2
+
3
+ import android.content.Context
4
+ import android.graphics.Bitmap
5
+ import android.graphics.PorterDuff
6
+ import android.graphics.PorterDuffColorFilter
7
+ import android.util.Log
8
+ import android.view.View
9
+ import android.widget.ImageView
10
+ import run.granite.image.GraniteImageProvider
11
+ import run.granite.image.GraniteImagePriority
12
+ import run.granite.image.GraniteImageCachePolicy
13
+ import run.granite.image.GraniteImageProgressCallback
14
+ import run.granite.image.GraniteImageCompletionCallback
15
+ import coil.load
16
+ import coil.request.CachePolicy
17
+ import coil.request.ErrorResult
18
+ import coil.request.SuccessResult
19
+
20
+ /**
21
+ * GraniteImageProvider implementation using Coil.
22
+ */
23
+ class CoilImageProvider : GraniteImageProvider {
24
+ companion object {
25
+ private const val TAG = "CoilImageProvider"
26
+ }
27
+
28
+ override fun createImageView(context: Context): View {
29
+ return ImageView(context).apply {
30
+ setBackgroundColor(android.graphics.Color.LTGRAY)
31
+ }
32
+ }
33
+
34
+ override fun loadImage(url: String, into: View, scaleType: ImageView.ScaleType) {
35
+ loadImage(url, into, scaleType, null, GraniteImagePriority.NORMAL, GraniteImageCachePolicy.DISK, null, null, null)
36
+ }
37
+
38
+ private fun isValidImageUrl(url: String): Boolean {
39
+ return try {
40
+ val uri = android.net.Uri.parse(url)
41
+ val scheme = uri.scheme?.lowercase()
42
+ scheme == "http" || scheme == "https"
43
+ } catch (e: Exception) {
44
+ false
45
+ }
46
+ }
47
+
48
+ override fun loadImage(
49
+ url: String,
50
+ into: View?,
51
+ scaleType: ImageView.ScaleType,
52
+ headers: Map<String, String>?,
53
+ priority: GraniteImagePriority,
54
+ cachePolicy: GraniteImageCachePolicy,
55
+ defaultSource: String?,
56
+ progressCallback: GraniteImageProgressCallback?,
57
+ completionCallback: GraniteImageCompletionCallback?
58
+ ) {
59
+ val imageView: ImageView? = if (into != null) {
60
+ if (into !is ImageView) {
61
+ Log.e(TAG, "View is not an ImageView")
62
+ completionCallback?.invoke(null, Exception("View is not an ImageView"), 0, 0)
63
+ return
64
+ }
65
+ into.scaleType = scaleType
66
+ into
67
+ } else {
68
+ null
69
+ }
70
+
71
+ if (imageView == null) {
72
+ completionCallback?.invoke(null, Exception("No view provided"), 0, 0)
73
+ return
74
+ }
75
+
76
+ if (!isValidImageUrl(url)) {
77
+ Log.e(TAG, "Invalid URL: $url")
78
+ completionCallback?.invoke(null, Exception("Invalid URL: $url"), 0, 0)
79
+ return
80
+ }
81
+
82
+ imageView.load(url) {
83
+ // Add headers if provided
84
+ headers?.forEach { (key, value) ->
85
+ addHeader(key, value)
86
+ }
87
+
88
+ // Apply cache policy
89
+ when (cachePolicy) {
90
+ GraniteImageCachePolicy.NONE -> {
91
+ memoryCachePolicy(CachePolicy.DISABLED)
92
+ diskCachePolicy(CachePolicy.DISABLED)
93
+ }
94
+ GraniteImageCachePolicy.MEMORY -> {
95
+ memoryCachePolicy(CachePolicy.ENABLED)
96
+ diskCachePolicy(CachePolicy.DISABLED)
97
+ }
98
+ GraniteImageCachePolicy.DISK -> {
99
+ memoryCachePolicy(CachePolicy.ENABLED)
100
+ diskCachePolicy(CachePolicy.ENABLED)
101
+ }
102
+ }
103
+
104
+ // Apply default source (placeholder)
105
+ if (!defaultSource.isNullOrEmpty()) {
106
+ val resourceId = imageView.context.resources.getIdentifier(defaultSource, "drawable", imageView.context.packageName)
107
+ if (resourceId != 0) {
108
+ placeholder(resourceId)
109
+ }
110
+ }
111
+
112
+ listener(
113
+ onStart = {
114
+ Log.d(TAG, "Loading started: $url")
115
+ },
116
+ onSuccess = { _, result ->
117
+ val bitmap = (result.drawable as? android.graphics.drawable.BitmapDrawable)?.bitmap
118
+ val width = bitmap?.width ?: 0
119
+ val height = bitmap?.height ?: 0
120
+ Log.d(TAG, "Loaded with Coil: $url")
121
+ completionCallback?.invoke(bitmap, null, width, height)
122
+ },
123
+ onError = { _, result ->
124
+ Log.e(TAG, "Error loading image: ${result.throwable.message}")
125
+ completionCallback?.invoke(null, result.throwable as? Exception, 0, 0)
126
+ }
127
+ )
128
+ }
129
+ }
130
+
131
+ override fun cancelLoad(view: View) {
132
+ if (view is ImageView) {
133
+ view.load(null as String?)
134
+ }
135
+ }
136
+
137
+ override fun applyTintColor(color: Int, view: View) {
138
+ if (view is ImageView) {
139
+ view.colorFilter = PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN)
140
+ }
141
+ }
142
+
143
+ override fun loadImage(
144
+ url: String,
145
+ imageView: Nothing?,
146
+ contentMode: String,
147
+ headers: Map<String, String>?,
148
+ priority: GraniteImagePriority,
149
+ cachePolicy: GraniteImageCachePolicy,
150
+ onProgress: GraniteImageProgressCallback?,
151
+ onCompletion: ((success: Boolean, width: Int, height: Int, error: String?) -> Unit)?
152
+ ) {
153
+ // Coil preload is not directly supported without a context
154
+ onCompletion?.invoke(false, 0, 0, "Preload not supported without context")
155
+ }
156
+ }