@granite-js/image 0.1.34 → 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 -277
  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,281 +1,7 @@
1
1
  # @granite-js/image
2
2
 
3
- ## 0.1.34
3
+ ## 1.0.0
4
4
 
5
- ### Patch Changes
5
+ ### Major Changes
6
6
 
7
- - Updated dependencies [9c39997]
8
- - @granite-js/native@0.1.34
9
-
10
- ## 0.1.33
11
-
12
- ### Patch Changes
13
-
14
- - Updated dependencies [fdf55a6]
15
- - @granite-js/native@0.1.33
16
-
17
- ## 0.1.32
18
-
19
- ### Patch Changes
20
-
21
- - 7572713: bump version up babel
22
- - Updated dependencies [74b2223]
23
- - Updated dependencies [7572713]
24
- - @granite-js/native@0.1.32
25
-
26
- ## 0.1.31
27
-
28
- ### Patch Changes
29
-
30
- - Updated dependencies [0ff9b13]
31
- - Updated dependencies [37ae3f3]
32
- - @granite-js/native@0.1.31
33
-
34
- ## 0.1.30
35
-
36
- ### Patch Changes
37
-
38
- - @granite-js/native@0.1.30
39
-
40
- ## 0.1.29
41
-
42
- ### Patch Changes
43
-
44
- - @granite-js/native@0.1.29
45
-
46
- ## 0.1.28
47
-
48
- ### Patch Changes
49
-
50
- - 1d958cc: ci: provenance
51
- - Updated dependencies [1d958cc]
52
- - @granite-js/native@0.1.28
53
-
54
- ## 0.1.27
55
-
56
- ### Patch Changes
57
-
58
- - e32b020: ci: oidc
59
- - Updated dependencies [e32b020]
60
- - Updated dependencies [1dd9179]
61
- - @granite-js/native@0.1.27
62
-
63
- ## 0.1.26
64
-
65
- ### Patch Changes
66
-
67
- - 41f9ab3: ensure polyfill setup during initialization and update package.json config for improve tree shaking
68
- - @granite-js/native@0.1.26
69
-
70
- ## 0.1.25
71
-
72
- ### Patch Changes
73
-
74
- - @granite-js/native@0.1.25
75
-
76
- ## 0.1.24
77
-
78
- ### Patch Changes
79
-
80
- - @granite-js/native@0.1.24
81
-
82
- ## 0.1.23
83
-
84
- ### Patch Changes
85
-
86
- - @granite-js/native@0.1.23
87
-
88
- ## 0.1.22
89
-
90
- ### Patch Changes
91
-
92
- - @granite-js/native@0.1.22
93
-
94
- ## 0.1.21
95
-
96
- ### Patch Changes
97
-
98
- - @granite-js/native@0.1.21
99
-
100
- ## 0.1.20
101
-
102
- ### Patch Changes
103
-
104
- - 1df5883: update package.json meta to supports any moduleResolutions
105
- - Updated dependencies [1df5883]
106
- - @granite-js/native@0.1.20
107
-
108
- ## 0.1.19
109
-
110
- ### Patch Changes
111
-
112
- - @granite-js/native@0.1.19
113
-
114
- ## 0.1.18
115
-
116
- ### Patch Changes
117
-
118
- - @granite-js/native@0.1.18
119
-
120
- ## 0.1.17
121
-
122
- ### Patch Changes
123
-
124
- - @granite-js/native@0.1.17
125
-
126
- ## 0.1.16
127
-
128
- ### Patch Changes
129
-
130
- - @granite-js/native@0.1.16
131
-
132
- ## 0.1.15
133
-
134
- ### Patch Changes
135
-
136
- - d16ee87: Add useInitialProps, useInitialSearchParams hook.
137
- - Updated dependencies [d16ee87]
138
- - @granite-js/native@0.1.15
139
-
140
- ## 0.1.14
141
-
142
- ### Patch Changes
143
-
144
- - @granite-js/native@0.1.14
145
-
146
- ## 0.1.13
147
-
148
- ### Patch Changes
149
-
150
- - @granite-js/native@0.1.13
151
-
152
- ## 0.1.12
153
-
154
- ### Patch Changes
155
-
156
- - d1e6585: fix module resolutions
157
- - Updated dependencies [d1e6585]
158
- - @granite-js/native@0.1.12
159
-
160
- ## 0.1.11
161
-
162
- ### Patch Changes
163
-
164
- - @granite-js/native@0.1.11
165
-
166
- ## 0.1.10
167
-
168
- ### Patch Changes
169
-
170
- - @granite-js/native@0.1.10
171
-
172
- ## 0.1.9
173
-
174
- ### Patch Changes
175
-
176
- - @granite-js/native@0.1.9
177
-
178
- ## 0.1.8
179
-
180
- ### Patch Changes
181
-
182
- - @granite-js/native@0.1.8
183
-
184
- ## 0.1.7
185
-
186
- ### Patch Changes
187
-
188
- - @granite-js/native@0.1.7
189
-
190
- ## 0.1.6
191
-
192
- ### Patch Changes
193
-
194
- - @granite-js/native@0.1.6
195
-
196
- ## 0.1.5
197
-
198
- ### Patch Changes
199
-
200
- - @granite-js/native@0.1.5
201
-
202
- ## 0.1.4
203
-
204
- ### Patch Changes
205
-
206
- - @granite-js/native@0.1.4
207
-
208
- ## 0.1.3
209
-
210
- ### Patch Changes
211
-
212
- - @granite-js/native@0.1.3
213
-
214
- ## 0.1.2
215
-
216
- ### Patch Changes
217
-
218
- - Updated dependencies [e1384cf]
219
- - @granite-js/native@0.1.2
220
-
221
- ## 0.1.1
222
-
223
- ### Patch Changes
224
-
225
- - d675415: Improve scaffolding to provide a better showcase UI
226
- - 10a5f3f: empty
227
- - Updated dependencies [d675415]
228
- - Updated dependencies [10a5f3f]
229
- - @granite-js/native@0.1.1
230
-
231
- ## 0.1.0
232
-
233
- ### Minor Changes
234
-
235
- - 561a3ed: fix: docs deadlink
236
-
237
- ### Patch Changes
238
-
239
- - Updated dependencies [561a3ed]
240
- - @granite-js/native@0.1.0
241
-
242
- ## 0.0.3
243
-
244
- ### Patch Changes
245
-
246
- - ed4d356: changeset
247
- - Updated dependencies [ed4d356]
248
- - @granite-js/native@0.0.3
249
-
250
- ## 0.0.2
251
-
252
- ### Patch Changes
253
-
254
- - 0ae09b7: deploy guide
255
- - 0ae09b7: type fix
256
- - 0ae09b7: guide
257
- - 0ae09b7: fix comment
258
- - 0ae09b7: showcase
259
- - 0ae09b7: refactor interface names
260
- - 0ae09b7: fix hemres
261
- - 0ae09b7: CanGoBackGuard 수정, typecheck fix, lint fix
262
- - 0ae09b7: counter
263
- - Updated dependencies [0ae09b7]
264
- - Updated dependencies [0ae09b7]
265
- - Updated dependencies [0ae09b7]
266
- - Updated dependencies [0ae09b7]
267
- - Updated dependencies [0ae09b7]
268
- - Updated dependencies [0ae09b7]
269
- - Updated dependencies [0ae09b7]
270
- - Updated dependencies [0ae09b7]
271
- - Updated dependencies [0ae09b7]
272
- - Updated dependencies [0ae09b7]
273
- - @granite-js/native@0.0.2
274
-
275
- ## 0.0.1
276
-
277
- ### Patch Changes
278
-
279
- - f47ca39: first release
280
- - Updated dependencies [f47ca39]
281
- - @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
+ }