@imgly/editor-react-native 1.47.0 → 1.49.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.
package/android/build.gradle
CHANGED
|
@@ -6,16 +6,38 @@ buildscript {
|
|
|
6
6
|
google()
|
|
7
7
|
gradlePluginPortal()
|
|
8
8
|
}
|
|
9
|
-
dependencies {
|
|
10
|
-
classpath("com.android.tools.build:gradle:7.3.1")
|
|
11
|
-
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.22")
|
|
12
|
-
}
|
|
13
9
|
}
|
|
14
10
|
|
|
15
11
|
def isNewArchitectureEnabled() {
|
|
16
12
|
return rootProject.hasProperty("newArchEnabled") && rootProject.getProperty("newArchEnabled") == "true"
|
|
17
13
|
}
|
|
18
14
|
|
|
15
|
+
def getKotlinVersion() {
|
|
16
|
+
return project.plugins.findPlugin("kotlin-android")?.class?.package?.implementationVersion
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
def isKotlin2OrHigher() {
|
|
20
|
+
def kotlinVersion = getKotlinVersion()
|
|
21
|
+
if (kotlinVersion) {
|
|
22
|
+
def mainVersion = kotlinVersion.split('-')[0]
|
|
23
|
+
def versionParts = mainVersion.tokenize('.').collect { it.toInteger() }
|
|
24
|
+
return versionParts[0] >= 2
|
|
25
|
+
}
|
|
26
|
+
return false
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
def getComposeVersion() {
|
|
30
|
+
if (isKotlin2OrHigher()) {
|
|
31
|
+
def mainVersion = getKotlinVersion().split('-')[0]
|
|
32
|
+
return mainVersion
|
|
33
|
+
}
|
|
34
|
+
return gradle.ext.has("kotlinCompilerExtensionVersion") ? gradle.ext.kotlinCompilerExtensionVersion : "1.5.10"
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (isKotlin2OrHigher()) {
|
|
38
|
+
project.plugins.apply('org.jetbrains.kotlin.plugin.compose')
|
|
39
|
+
}
|
|
40
|
+
|
|
19
41
|
apply plugin: 'com.android.library'
|
|
20
42
|
apply plugin: 'com.facebook.react'
|
|
21
43
|
apply plugin: 'org.jetbrains.kotlin.android'
|
|
@@ -44,8 +66,10 @@ android {
|
|
|
44
66
|
compose true
|
|
45
67
|
}
|
|
46
68
|
|
|
47
|
-
|
|
48
|
-
|
|
69
|
+
if (!isKotlin2OrHigher()) {
|
|
70
|
+
composeOptions {
|
|
71
|
+
kotlinCompilerExtensionVersion = getComposeVersion()
|
|
72
|
+
}
|
|
49
73
|
}
|
|
50
74
|
}
|
|
51
75
|
|
|
@@ -55,7 +79,7 @@ repositories {
|
|
|
55
79
|
}
|
|
56
80
|
|
|
57
81
|
dependencies {
|
|
58
|
-
implementation findProject(":editor") ?: "ly.img:editor:1.
|
|
82
|
+
implementation findProject(":editor") ?: "ly.img:editor:1.49.0"
|
|
59
83
|
implementation platform("androidx.compose:compose-bom:2023.05.01")
|
|
60
84
|
implementation "androidx.activity:activity-compose:1.6.1"
|
|
61
85
|
implementation "androidx.activity:activity:1.7.0"
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
package ly.img.editor.reactnative.module.builder
|
|
2
2
|
|
|
3
|
+
import android.graphics.Bitmap
|
|
3
4
|
import android.net.Uri
|
|
5
|
+
import android.util.Log
|
|
4
6
|
import androidx.compose.runtime.Composable
|
|
5
7
|
import kotlinx.coroutines.Dispatchers
|
|
6
8
|
import kotlinx.coroutines.Job
|
|
@@ -30,10 +32,12 @@ import ly.img.engine.DemoAssetSource
|
|
|
30
32
|
import ly.img.engine.DesignBlock
|
|
31
33
|
import ly.img.engine.DesignBlockType
|
|
32
34
|
import ly.img.engine.Engine
|
|
35
|
+
import ly.img.engine.FillType
|
|
33
36
|
import ly.img.engine.MimeType
|
|
34
37
|
import ly.img.engine.addDefaultAssetSources
|
|
35
38
|
import ly.img.engine.addDemoAssetSources
|
|
36
39
|
import java.io.File
|
|
40
|
+
import java.io.FileOutputStream
|
|
37
41
|
import java.util.UUID
|
|
38
42
|
import kotlin.coroutines.cancellation.CancellationException
|
|
39
43
|
|
|
@@ -370,10 +374,15 @@ object EditorBuilderDefaults {
|
|
|
370
374
|
val tempFile = EditorDefaults.writeToTempFile(blob, mimeType)
|
|
371
375
|
val scene = engine.scene.get()
|
|
372
376
|
val sceneString = scene?.let {
|
|
373
|
-
engine
|
|
377
|
+
checkForContentUris(engine)
|
|
378
|
+
engine.scene.saveToString(
|
|
379
|
+
scene = it,
|
|
380
|
+
allowedResourceSchemes = listOf("blob", "bundle", "file", "http", "https", "content"),
|
|
381
|
+
)
|
|
374
382
|
}
|
|
375
383
|
val sceneUri = sceneString?.let { saveScene(it) }
|
|
376
384
|
val firstPage = engine.scene.getPages().first()
|
|
385
|
+
engine.block.setVisible(firstPage, true)
|
|
377
386
|
val thumbnail = saveThumbnail(firstPage, engine, thumbnailHeight)
|
|
378
387
|
eventHandler.send(HideLoading)
|
|
379
388
|
return EditorResult(
|
|
@@ -406,7 +415,11 @@ object EditorBuilderDefaults {
|
|
|
406
415
|
val thumbnail = saveThumbnail(page, engine, thumbnailHeight)
|
|
407
416
|
val scene = engine.scene.get()
|
|
408
417
|
val sceneString = scene?.let {
|
|
409
|
-
engine
|
|
418
|
+
checkForContentUris(engine)
|
|
419
|
+
engine.scene.saveToString(
|
|
420
|
+
scene = it,
|
|
421
|
+
allowedResourceSchemes = listOf("blob", "bundle", "file", "http", "https", "content"),
|
|
422
|
+
)
|
|
410
423
|
}
|
|
411
424
|
|
|
412
425
|
val buffer = engine.block.exportVideo(
|
|
@@ -447,7 +460,55 @@ object EditorBuilderDefaults {
|
|
|
447
460
|
val frames = engine.block.generateVideoThumbnailSequence(id, height, timeBegin = 0.0, timeEnd = 0.1, numberOfFrames = 1).toList()
|
|
448
461
|
val firstFrame = frames.first()
|
|
449
462
|
val buffer = firstFrame.imageData
|
|
450
|
-
val
|
|
451
|
-
|
|
463
|
+
val bitmap = Bitmap.createBitmap(firstFrame.width, firstFrame.height, Bitmap.Config.ARGB_8888)
|
|
464
|
+
buffer.rewind()
|
|
465
|
+
bitmap.copyPixelsFromBuffer(buffer)
|
|
466
|
+
return withContext(Dispatchers.IO) {
|
|
467
|
+
val file = File.createTempFile(UUID.randomUUID().toString(), ".png")
|
|
468
|
+
FileOutputStream(file).use { out ->
|
|
469
|
+
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out)
|
|
470
|
+
}
|
|
471
|
+
Uri.fromFile(file)
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
private fun checkForContentUris(engine: Engine) = runCatching {
|
|
476
|
+
fun isContentUri(uri: String) = uri.startsWith("content://")
|
|
477
|
+
|
|
478
|
+
val graphicBlocks = engine.block.findByType(DesignBlockType.Graphic)
|
|
479
|
+
for (block in graphicBlocks) {
|
|
480
|
+
val fill = if (engine.block.supportsFill(block)) {
|
|
481
|
+
engine.block.getFill(block).takeIf { engine.block.isValid(it) }
|
|
482
|
+
} else {
|
|
483
|
+
null
|
|
484
|
+
}
|
|
485
|
+
fill ?: continue
|
|
486
|
+
val fillType = FillType.get(engine.block.getType(fill))
|
|
487
|
+
val contentUriFound = when (fillType) {
|
|
488
|
+
FillType.Image -> {
|
|
489
|
+
isContentUri(engine.block.getString(fill, "fill/image/imageFileURI")) ||
|
|
490
|
+
isContentUri(engine.block.getString(fill, "fill/image/previewFileURI"))
|
|
491
|
+
}
|
|
492
|
+
FillType.Video -> {
|
|
493
|
+
isContentUri(engine.block.getString(fill, "fill/video/fileURI"))
|
|
494
|
+
}
|
|
495
|
+
else -> continue
|
|
496
|
+
}
|
|
497
|
+
if (contentUriFound) {
|
|
498
|
+
Log.w(
|
|
499
|
+
"IMG.LY",
|
|
500
|
+
"""
|
|
501
|
+
This scene contains block(s) that reference `content://` Uri(s)
|
|
502
|
+
(e.g. when media is picked from gallery or camera). These may not be
|
|
503
|
+
resolvable when loading the scene again, especially outside the
|
|
504
|
+
original app context. If you need to support reloading such scenes,
|
|
505
|
+
consider using a custom implementation with
|
|
506
|
+
`EngineConfiguration.onUpload` and `engine.editor.setUriResolver`
|
|
507
|
+
to handle these Uri(s) appropriately.
|
|
508
|
+
""".trimIndent(),
|
|
509
|
+
)
|
|
510
|
+
break
|
|
511
|
+
}
|
|
512
|
+
}
|
|
452
513
|
}
|
|
453
514
|
}
|
|
@@ -21,6 +21,7 @@ public extension OnExport {
|
|
|
21
21
|
|
|
22
22
|
var thumbnail: URL?
|
|
23
23
|
if let firstPage = try engine.scene.getPages().first {
|
|
24
|
+
try engine.block.setVisible(firstPage, visible: true)
|
|
24
25
|
thumbnail = try await helper.saveThumbnail(firstPage, engine, thumbnailHeight)
|
|
25
26
|
}
|
|
26
27
|
return EditorResult(
|
package/ios/IMGLYEditorModule.mm
CHANGED
|
@@ -37,13 +37,9 @@ RCT_EXPORT_MODULE(IMGLYEditor)
|
|
|
37
37
|
return std::make_shared<facebook::react::NativeIMGLYEditorSpecJSI>(params);
|
|
38
38
|
}
|
|
39
39
|
#else
|
|
40
|
-
RCT_EXPORT_METHOD(openEditor
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
: (NSString*)preset metadata
|
|
44
|
-
: (NSDictionary*)metadata resolve
|
|
45
|
-
: (RCTPromiseResolveBlock)resolve reject
|
|
46
|
-
: (RCTPromiseRejectBlock)reject) {
|
|
40
|
+
RCT_EXPORT_METHOD(openEditor : (nonnull NSDictionary*)settings source : (nullable NSDictionary*)
|
|
41
|
+
source preset : (NSString*)preset metadata : (NSDictionary*)
|
|
42
|
+
metadata resolve : (RCTPromiseResolveBlock)resolve reject : (RCTPromiseRejectBlock)reject) {
|
|
47
43
|
NSMutableDictionary* mergedSettings = [settings mutableCopy];
|
|
48
44
|
mergedSettings[@"source"] = source;
|
|
49
45
|
[self open:mergedSettings preset:preset metadata:metadata resolve:resolve reject:reject];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@imgly/editor-react-native",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.49.0",
|
|
4
4
|
"description": "CreativeEditor SDK for React Native - enable photo, video and design editing for your users on iOS and Android.",
|
|
5
5
|
"react-native": "index.js",
|
|
6
6
|
"source": "index.js",
|
package/src/NativeIMGLYEditor.ts
CHANGED
|
@@ -24,7 +24,16 @@ export enum EditorPreset {
|
|
|
24
24
|
* information.
|
|
25
25
|
*/
|
|
26
26
|
export interface EditorResult {
|
|
27
|
-
/** The scene.
|
|
27
|
+
/** The scene.
|
|
28
|
+
* ⚠️ On Android, this scene might contain blocks that reference
|
|
29
|
+
* `content://` Uri(s) (e.g. when media is picked from gallery or camera).
|
|
30
|
+
* These may not be resolvable when loading the scene again, especially
|
|
31
|
+
* outside the original app context.
|
|
32
|
+
*
|
|
33
|
+
* If you need to support reloading such scenes, consider using a custom
|
|
34
|
+
* implementation with `EngineConfiguration.onUpload` and
|
|
35
|
+
* `engine.editor.setUriResolver` to handle these Uri(s) appropriately.
|
|
36
|
+
*/
|
|
28
37
|
scene?: string;
|
|
29
38
|
|
|
30
39
|
/** The path of the exported image/video/pdf. */
|