@imgly/editor-react-native 1.44.0 → 1.46.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 +40 -40
- package/android/src/main/kotlin/ly/img/editor/reactnative/module/IMGLYEditorModule.kt +25 -26
- package/android/src/main/kotlin/ly/img/editor/reactnative/module/IMGLYEditorPackage.kt +19 -21
- package/android/src/main/kotlin/ly/img/editor/reactnative/module/activity/EditorActivity.kt +34 -39
- package/android/src/main/kotlin/ly/img/editor/reactnative/module/builder/EditorBuilder.kt +175 -200
- package/android/src/main/kotlin/ly/img/editor/reactnative/module/model/EditorSettings.kt +10 -11
- package/android/src/main/kotlin/ly/img/editor/reactnative/module/model/Source.kt +10 -11
- package/package.json +1 -1
package/android/build.gradle
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
buildscript {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
2
|
+
ext.safeExtGet = { prop, fallback ->
|
|
3
|
+
rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
|
|
4
|
+
}
|
|
5
|
+
repositories {
|
|
6
|
+
google()
|
|
7
|
+
gradlePluginPortal()
|
|
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
13
|
}
|
|
14
14
|
|
|
15
15
|
def isNewArchitectureEnabled() {
|
|
16
|
-
|
|
16
|
+
return rootProject.hasProperty("newArchEnabled") && rootProject.getProperty("newArchEnabled") == "true"
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
apply plugin: 'com.android.library'
|
|
@@ -21,45 +21,45 @@ apply plugin: 'com.facebook.react'
|
|
|
21
21
|
apply plugin: 'org.jetbrains.kotlin.android'
|
|
22
22
|
|
|
23
23
|
android {
|
|
24
|
-
|
|
24
|
+
compileSdkVersion safeExtGet('compileSdkVersion', 34)
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
namespace "ly.img.editor.reactnative.module"
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
defaultConfig {
|
|
29
|
+
minSdk = 24
|
|
30
|
+
buildConfigField("boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString())
|
|
31
|
+
}
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
33
|
+
sourceSets {
|
|
34
|
+
main {
|
|
35
|
+
if (isNewArchitectureEnabled()) {
|
|
36
|
+
java.srcDirs += ['src/newarch']
|
|
37
|
+
} else {
|
|
38
|
+
java.srcDirs += ['src/oldarch']
|
|
39
|
+
}
|
|
40
|
+
}
|
|
40
41
|
}
|
|
41
|
-
}
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
buildFeatures {
|
|
44
|
+
compose true
|
|
45
|
+
}
|
|
46
46
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
47
|
+
composeOptions {
|
|
48
|
+
kotlinCompilerExtensionVersion = "1.5.10"
|
|
49
|
+
}
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
repositories {
|
|
53
|
-
|
|
54
|
-
|
|
53
|
+
mavenCentral()
|
|
54
|
+
google()
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
dependencies {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
58
|
+
implementation findProject(":editor") ?: "ly.img:editor:1.46.0"
|
|
59
|
+
implementation platform("androidx.compose:compose-bom:2023.05.01")
|
|
60
|
+
implementation "androidx.activity:activity-compose:1.6.1"
|
|
61
|
+
implementation "androidx.activity:activity:1.7.0"
|
|
62
|
+
implementation "com.google.android.material:material:1.8.0"
|
|
63
63
|
|
|
64
|
-
|
|
64
|
+
implementation 'com.facebook.react:react-native'
|
|
65
65
|
}
|
|
@@ -134,12 +134,11 @@ class IMGLYEditorModule(
|
|
|
134
134
|
val activity = this.currentActivity ?: return
|
|
135
135
|
this.completion = completion
|
|
136
136
|
|
|
137
|
-
val intent =
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
}
|
|
137
|
+
val intent = Intent(activity, EditorActivity::class.java).apply {
|
|
138
|
+
putExtra(EditorActivity.INTENT_EXTRA_CONFIG, config)
|
|
139
|
+
putExtra(EditorActivity.INTENT_EXTRA_PRESET, preset as Parcelable)
|
|
140
|
+
putExtra(EditorActivity.INTENT_EXTRA_METADATA, IntentHelper.mapToBundle(metadata))
|
|
141
|
+
}
|
|
143
142
|
activity.startActivityForResult(intent, EditorActivity.INTENT_REQUEST_CODE)
|
|
144
143
|
}
|
|
145
144
|
|
|
@@ -204,22 +203,21 @@ class IMGLYEditorModule(
|
|
|
204
203
|
value: WritableMap?,
|
|
205
204
|
) = this.putMap(id, value)
|
|
206
205
|
|
|
207
|
-
private fun reactMap(vararg pairs: Pair<String, Any?>) =
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
else -> error("Unsupported type for WritableMap: ${value::class.simpleName}")
|
|
220
|
-
}
|
|
206
|
+
private fun reactMap(vararg pairs: Pair<String, Any?>) = Arguments.createMap().apply {
|
|
207
|
+
pairs.forEach { (id, value) ->
|
|
208
|
+
when (value) {
|
|
209
|
+
null -> putNull(id)
|
|
210
|
+
is String -> putString(id, value)
|
|
211
|
+
is Boolean -> putBoolean(id, value)
|
|
212
|
+
is Double -> putDouble(id, value)
|
|
213
|
+
is Float -> putDouble(id, value.toDouble())
|
|
214
|
+
is Int -> putInt(id, value)
|
|
215
|
+
is WritableMap -> putMap(id, value)
|
|
216
|
+
is WritableArray -> putArray(id, value)
|
|
217
|
+
else -> error("Unsupported type for WritableMap: ${value::class.simpleName}")
|
|
221
218
|
}
|
|
222
219
|
}
|
|
220
|
+
}
|
|
223
221
|
|
|
224
222
|
private fun convertToWritableMap(map: Map<*, *>): WritableMap {
|
|
225
223
|
val writableMap = Arguments.createMap()
|
|
@@ -243,10 +241,11 @@ class IMGLYEditorModule(
|
|
|
243
241
|
return writableMap
|
|
244
242
|
}
|
|
245
243
|
|
|
246
|
-
private inline fun <reified T : Serializable> Intent.getSerializableExtraCompat(key: String): T? =
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
244
|
+
private inline fun <reified T : Serializable> Intent.getSerializableExtraCompat(key: String): T? = if (Build.VERSION.SDK_INT >=
|
|
245
|
+
Build.VERSION_CODES.TIRAMISU
|
|
246
|
+
) {
|
|
247
|
+
getSerializableExtra(key, T::class.java)
|
|
248
|
+
} else {
|
|
249
|
+
getSerializableExtra(key) as T
|
|
250
|
+
}
|
|
252
251
|
}
|
|
@@ -10,26 +10,24 @@ class IMGLYEditorPackage : TurboReactPackage() {
|
|
|
10
10
|
override fun getModule(
|
|
11
11
|
name: String,
|
|
12
12
|
reactContext: ReactApplicationContext,
|
|
13
|
-
): NativeModule? =
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
13
|
+
): NativeModule? = if (name == IMGLYEditorModule.NAME) {
|
|
14
|
+
IMGLYEditorModule(reactContext)
|
|
15
|
+
} else {
|
|
16
|
+
null
|
|
17
|
+
}
|
|
19
18
|
|
|
20
|
-
override fun getReactModuleInfoProvider() =
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
19
|
+
override fun getReactModuleInfoProvider() = ReactModuleInfoProvider {
|
|
20
|
+
mapOf(
|
|
21
|
+
IMGLYEditorModule.NAME to
|
|
22
|
+
ReactModuleInfo(
|
|
23
|
+
IMGLYEditorModule.NAME,
|
|
24
|
+
IMGLYEditorModule.NAME,
|
|
25
|
+
false, // canOverrideExistingModule
|
|
26
|
+
false, // needsEagerInit
|
|
27
|
+
true, // hasConstants
|
|
28
|
+
false, // isCxxModule
|
|
29
|
+
true, // isTurboModule
|
|
30
|
+
),
|
|
31
|
+
)
|
|
32
|
+
}
|
|
35
33
|
}
|
|
@@ -44,9 +44,7 @@ class EditorActivity : ComponentActivity() {
|
|
|
44
44
|
override fun onCreate(savedInstanceState: Bundle?) {
|
|
45
45
|
super.onCreate(savedInstanceState)
|
|
46
46
|
|
|
47
|
-
val config =
|
|
48
|
-
intent.extras?.getParcelableCompat<EditorSettings>(INTENT_EXTRA_CONFIG)
|
|
49
|
-
?: return
|
|
47
|
+
val config = intent.extras?.getParcelableCompat<EditorSettings>(INTENT_EXTRA_CONFIG) ?: return
|
|
50
48
|
val preset = intent.extras?.getParcelableCompat<EditorPreset>(INTENT_EXTRA_PRESET) ?: EditorPreset.DESIGN
|
|
51
49
|
val metadataBundle = intent.extras?.getParcelableCompat<Bundle>(INTENT_EXTRA_METADATA)
|
|
52
50
|
val metadata = IntentHelper.bundleToMap(metadataBundle)
|
|
@@ -55,37 +53,34 @@ class EditorActivity : ComponentActivity() {
|
|
|
55
53
|
setContent {
|
|
56
54
|
builder(
|
|
57
55
|
CustomBuilderScope(config, preset, metadata, { result ->
|
|
58
|
-
val (resolvedResult, resultCode) =
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
)
|
|
56
|
+
val (resolvedResult, resultCode) = result.fold(
|
|
57
|
+
onFailure = { error ->
|
|
58
|
+
Pair(error, INTENT_RESULT_ERROR_CODE)
|
|
59
|
+
},
|
|
60
|
+
onSuccess = { value ->
|
|
61
|
+
Pair(value, Activity.RESULT_OK)
|
|
62
|
+
},
|
|
63
|
+
)
|
|
67
64
|
|
|
68
|
-
val resultIntent =
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}
|
|
65
|
+
val resultIntent = Intent().apply {
|
|
66
|
+
when (resultCode) {
|
|
67
|
+
INTENT_RESULT_ERROR_CODE -> {
|
|
68
|
+
putExtra(INTENT_EXTRA_RESULT, resolvedResult as Serializable)
|
|
69
|
+
}
|
|
74
70
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
}
|
|
71
|
+
Activity.RESULT_OK -> {
|
|
72
|
+
putExtra(INTENT_EXTRA_RESULT, resolvedResult as Parcelable)
|
|
78
73
|
}
|
|
79
74
|
}
|
|
75
|
+
}
|
|
80
76
|
|
|
81
77
|
setResult(resultCode, resultIntent)
|
|
82
78
|
finish()
|
|
83
79
|
}, {
|
|
84
80
|
if (it != null) {
|
|
85
|
-
val resultIntent =
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
81
|
+
val resultIntent = Intent().apply {
|
|
82
|
+
putExtra(INTENT_EXTRA_RESULT, it)
|
|
83
|
+
}
|
|
89
84
|
setResult(INTENT_RESULT_ERROR_CODE, resultIntent)
|
|
90
85
|
}
|
|
91
86
|
finish()
|
|
@@ -94,19 +89,19 @@ class EditorActivity : ComponentActivity() {
|
|
|
94
89
|
}
|
|
95
90
|
}
|
|
96
91
|
|
|
97
|
-
private fun builderForPreset(preset: EditorPreset): Builder =
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
}
|
|
92
|
+
private fun builderForPreset(preset: EditorPreset): Builder = when (preset) {
|
|
93
|
+
EditorPreset.APPAREL -> EditorBuilder.apparel()
|
|
94
|
+
EditorPreset.POSTCARD -> EditorBuilder.postcard()
|
|
95
|
+
EditorPreset.PHOTO -> EditorBuilder.photo()
|
|
96
|
+
EditorPreset.DESIGN -> EditorBuilder.design()
|
|
97
|
+
EditorPreset.VIDEO -> EditorBuilder.video()
|
|
98
|
+
}
|
|
105
99
|
|
|
106
|
-
private inline fun <reified T : Parcelable> Bundle.getParcelableCompat(key: String): T? =
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
100
|
+
private inline fun <reified T : Parcelable> Bundle.getParcelableCompat(key: String): T? = if (Build.VERSION.SDK_INT >=
|
|
101
|
+
Build.VERSION_CODES.TIRAMISU
|
|
102
|
+
) {
|
|
103
|
+
getParcelable(key, T::class.java)
|
|
104
|
+
} else {
|
|
105
|
+
getParcelable(key)
|
|
106
|
+
}
|
|
112
107
|
}
|
|
@@ -62,45 +62,39 @@ data class CustomBuilderScope(
|
|
|
62
62
|
class EditorBuilder {
|
|
63
63
|
companion object {
|
|
64
64
|
/** The default design editor. */
|
|
65
|
-
fun design(): Builder =
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
}
|
|
65
|
+
fun design(): Builder = {
|
|
66
|
+
ModalDesignEditor(settings, result, onClose)
|
|
67
|
+
}
|
|
69
68
|
|
|
70
69
|
/** The default postcard editor. */
|
|
71
|
-
fun postcard(): Builder =
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
}
|
|
70
|
+
fun postcard(): Builder = {
|
|
71
|
+
ModalPostcardEditor(settings, result, onClose)
|
|
72
|
+
}
|
|
75
73
|
|
|
76
74
|
/** The default apparel editor. */
|
|
77
|
-
fun apparel(): Builder =
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
}
|
|
75
|
+
fun apparel(): Builder = {
|
|
76
|
+
ModalApparelEditor(settings, result, onClose)
|
|
77
|
+
}
|
|
81
78
|
|
|
82
79
|
/** The default photo editor. */
|
|
83
|
-
fun photo(): Builder =
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
}
|
|
80
|
+
fun photo(): Builder = {
|
|
81
|
+
ModalPhotoEditor(settings, result, onClose)
|
|
82
|
+
}
|
|
87
83
|
|
|
88
84
|
/** The default video editor. */
|
|
89
|
-
fun video(): Builder =
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
}
|
|
85
|
+
fun video(): Builder = {
|
|
86
|
+
ModalVideoEditor(settings, result, onClose)
|
|
87
|
+
}
|
|
93
88
|
|
|
94
89
|
/**
|
|
95
90
|
* A custom editor implementation.
|
|
96
91
|
* @param contentProvider A closure to provide a custom view.
|
|
97
92
|
* @return A [Builder] providing the custom view.
|
|
98
93
|
*/
|
|
99
|
-
fun custom(contentProvider: @Composable CustomBuilderScope.() -> Unit): Builder =
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}
|
|
94
|
+
fun custom(contentProvider: @Composable CustomBuilderScope.() -> Unit): Builder = {
|
|
95
|
+
val scope = CustomBuilderScope(settings, preset, metadata, result, onClose)
|
|
96
|
+
scope.contentProvider()
|
|
97
|
+
}
|
|
104
98
|
|
|
105
99
|
@Composable
|
|
106
100
|
private fun ModalPhotoEditor(
|
|
@@ -108,30 +102,28 @@ class EditorBuilder {
|
|
|
108
102
|
result: EditorBuilderResult,
|
|
109
103
|
onClose: (Throwable?) -> Unit,
|
|
110
104
|
) {
|
|
111
|
-
val engineConfiguration =
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
onCreate
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
},
|
|
134
|
-
)
|
|
105
|
+
val engineConfiguration = EngineConfiguration.remember(
|
|
106
|
+
license = settings.license,
|
|
107
|
+
baseUri = Uri.parse(settings.baseUri),
|
|
108
|
+
userId = settings.userId,
|
|
109
|
+
onCreate = {
|
|
110
|
+
EditorBuilderDefaults.onCreate(
|
|
111
|
+
engine = editorContext.engine,
|
|
112
|
+
eventHandler = editorContext.eventHandler,
|
|
113
|
+
settings = settings,
|
|
114
|
+
defaultScene = EditorBuilderDefaults.defaultPhotoUri,
|
|
115
|
+
sourceType = EditorSourceType.IMAGE,
|
|
116
|
+
)
|
|
117
|
+
},
|
|
118
|
+
onExport = {
|
|
119
|
+
val export = EditorBuilderDefaults.onExport(
|
|
120
|
+
engine = editorContext.engine,
|
|
121
|
+
eventHandler = editorContext.eventHandler,
|
|
122
|
+
mimeType = MimeType.PNG,
|
|
123
|
+
)
|
|
124
|
+
result(Result.success(export))
|
|
125
|
+
},
|
|
126
|
+
)
|
|
135
127
|
PhotoEditor(engineConfiguration = engineConfiguration) {
|
|
136
128
|
onClose(it)
|
|
137
129
|
}
|
|
@@ -143,29 +135,27 @@ class EditorBuilder {
|
|
|
143
135
|
result: EditorBuilderResult,
|
|
144
136
|
onClose: (Throwable?) -> Unit,
|
|
145
137
|
) {
|
|
146
|
-
val engineConfiguration =
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
onCreate
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
},
|
|
168
|
-
)
|
|
138
|
+
val engineConfiguration = EngineConfiguration.remember(
|
|
139
|
+
license = settings.license,
|
|
140
|
+
baseUri = Uri.parse(settings.baseUri),
|
|
141
|
+
userId = settings.userId,
|
|
142
|
+
onCreate = {
|
|
143
|
+
EditorBuilderDefaults.onCreate(
|
|
144
|
+
engine = editorContext.engine,
|
|
145
|
+
eventHandler = editorContext.eventHandler,
|
|
146
|
+
settings = settings,
|
|
147
|
+
defaultScene = EngineConfiguration.defaultApparelSceneUri,
|
|
148
|
+
)
|
|
149
|
+
},
|
|
150
|
+
onExport = {
|
|
151
|
+
val export = EditorBuilderDefaults.onExport(
|
|
152
|
+
engine = editorContext.engine,
|
|
153
|
+
eventHandler = editorContext.eventHandler,
|
|
154
|
+
mimeType = MimeType.PDF,
|
|
155
|
+
)
|
|
156
|
+
result(Result.success(export))
|
|
157
|
+
},
|
|
158
|
+
)
|
|
169
159
|
ApparelEditor(engineConfiguration = engineConfiguration) {
|
|
170
160
|
onClose(it)
|
|
171
161
|
}
|
|
@@ -177,29 +167,27 @@ class EditorBuilder {
|
|
|
177
167
|
result: EditorBuilderResult,
|
|
178
168
|
onClose: (Throwable?) -> Unit,
|
|
179
169
|
) {
|
|
180
|
-
val engineConfiguration =
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
onCreate
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
},
|
|
202
|
-
)
|
|
170
|
+
val engineConfiguration = EngineConfiguration.remember(
|
|
171
|
+
license = settings.license,
|
|
172
|
+
baseUri = Uri.parse(settings.baseUri),
|
|
173
|
+
userId = settings.userId,
|
|
174
|
+
onCreate = {
|
|
175
|
+
EditorBuilderDefaults.onCreate(
|
|
176
|
+
engine = editorContext.engine,
|
|
177
|
+
eventHandler = editorContext.eventHandler,
|
|
178
|
+
settings = settings,
|
|
179
|
+
defaultScene = EngineConfiguration.defaultDesignSceneUri,
|
|
180
|
+
)
|
|
181
|
+
},
|
|
182
|
+
onExport = {
|
|
183
|
+
val export = EditorBuilderDefaults.onExport(
|
|
184
|
+
engine = editorContext.engine,
|
|
185
|
+
eventHandler = editorContext.eventHandler,
|
|
186
|
+
mimeType = MimeType.PDF,
|
|
187
|
+
)
|
|
188
|
+
result(Result.success(export))
|
|
189
|
+
},
|
|
190
|
+
)
|
|
203
191
|
|
|
204
192
|
DesignEditor(engineConfiguration = engineConfiguration) {
|
|
205
193
|
onClose(it)
|
|
@@ -212,29 +200,27 @@ class EditorBuilder {
|
|
|
212
200
|
result: EditorBuilderResult,
|
|
213
201
|
onClose: (Throwable?) -> Unit,
|
|
214
202
|
) {
|
|
215
|
-
val engineConfiguration =
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
onCreate
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
},
|
|
237
|
-
)
|
|
203
|
+
val engineConfiguration = EngineConfiguration.remember(
|
|
204
|
+
license = settings.license,
|
|
205
|
+
baseUri = Uri.parse(settings.baseUri),
|
|
206
|
+
userId = settings.userId,
|
|
207
|
+
onCreate = {
|
|
208
|
+
EditorBuilderDefaults.onCreate(
|
|
209
|
+
engine = editorContext.engine,
|
|
210
|
+
eventHandler = editorContext.eventHandler,
|
|
211
|
+
settings = settings,
|
|
212
|
+
defaultScene = EngineConfiguration.defaultPostcardSceneUri,
|
|
213
|
+
)
|
|
214
|
+
},
|
|
215
|
+
onExport = {
|
|
216
|
+
val export = EditorBuilderDefaults.onExport(
|
|
217
|
+
engine = editorContext.engine,
|
|
218
|
+
eventHandler = editorContext.eventHandler,
|
|
219
|
+
mimeType = MimeType.PDF,
|
|
220
|
+
)
|
|
221
|
+
result(Result.success(export))
|
|
222
|
+
},
|
|
223
|
+
)
|
|
238
224
|
|
|
239
225
|
PostcardEditor(engineConfiguration = engineConfiguration) {
|
|
240
226
|
onClose(it)
|
|
@@ -247,37 +233,35 @@ class EditorBuilder {
|
|
|
247
233
|
result: EditorBuilderResult,
|
|
248
234
|
onClose: (Throwable?) -> Unit,
|
|
249
235
|
) {
|
|
250
|
-
val engineConfiguration =
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
onCreate
|
|
256
|
-
|
|
236
|
+
val engineConfiguration = EngineConfiguration.remember(
|
|
237
|
+
license = settings.license,
|
|
238
|
+
baseUri = Uri.parse(settings.baseUri),
|
|
239
|
+
userId = settings.userId,
|
|
240
|
+
onCreate = {
|
|
241
|
+
EditorBuilderDefaults.onCreate(
|
|
242
|
+
engine = editorContext.engine,
|
|
243
|
+
eventHandler = editorContext.eventHandler,
|
|
244
|
+
settings = settings,
|
|
245
|
+
defaultScene = EngineConfiguration.defaultVideoSceneUri,
|
|
246
|
+
)
|
|
247
|
+
},
|
|
248
|
+
onExport = {
|
|
249
|
+
try {
|
|
250
|
+
val export = EditorBuilderDefaults.onExportVideo(
|
|
257
251
|
engine = editorContext.engine,
|
|
258
252
|
eventHandler = editorContext.eventHandler,
|
|
259
|
-
|
|
260
|
-
defaultScene = EngineConfiguration.defaultVideoSceneUri,
|
|
253
|
+
mimeType = MimeType.MP4,
|
|
261
254
|
)
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
eventHandler = editorContext.eventHandler,
|
|
269
|
-
mimeType = MimeType.MP4,
|
|
270
|
-
)
|
|
271
|
-
result(Result.success(export))
|
|
272
|
-
} catch (e: Exception) {
|
|
273
|
-
if (e !is CancellationException) {
|
|
274
|
-
result(Result.failure(e))
|
|
275
|
-
} else {
|
|
276
|
-
editorContext.eventHandler.send(DismissVideoExportEvent)
|
|
277
|
-
}
|
|
255
|
+
result(Result.success(export))
|
|
256
|
+
} catch (e: Exception) {
|
|
257
|
+
if (e !is CancellationException) {
|
|
258
|
+
result(Result.failure(e))
|
|
259
|
+
} else {
|
|
260
|
+
editorContext.eventHandler.send(DismissVideoExportEvent)
|
|
278
261
|
}
|
|
279
|
-
}
|
|
280
|
-
|
|
262
|
+
}
|
|
263
|
+
},
|
|
264
|
+
)
|
|
281
265
|
VideoEditor(engineConfiguration = engineConfiguration) {
|
|
282
266
|
onClose(it)
|
|
283
267
|
}
|
|
@@ -305,24 +289,22 @@ object EditorBuilderDefaults {
|
|
|
305
289
|
defaultScene: Uri,
|
|
306
290
|
sourceType: EditorSourceType = EditorSourceType.SCENE,
|
|
307
291
|
) = coroutineScope {
|
|
308
|
-
fun isValidUri(uri: Uri): Boolean =
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
}
|
|
292
|
+
fun isValidUri(uri: Uri): Boolean = try {
|
|
293
|
+
uri.scheme != null && uri.path != null
|
|
294
|
+
} catch (e: Exception) {
|
|
295
|
+
false
|
|
296
|
+
}
|
|
314
297
|
|
|
315
|
-
val uri =
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
throw IllegalArgumentException("The specified source is not a valid Uri.")
|
|
321
|
-
}
|
|
322
|
-
sourceUri
|
|
323
|
-
} else {
|
|
324
|
-
defaultScene
|
|
298
|
+
val uri = if (settings.source != null) {
|
|
299
|
+
val sourceUri = Uri.parse(settings.source?.source)
|
|
300
|
+
val isValid = isValidUri(sourceUri)
|
|
301
|
+
if (!isValid) {
|
|
302
|
+
throw IllegalArgumentException("The specified source is not a valid Uri.")
|
|
325
303
|
}
|
|
304
|
+
sourceUri
|
|
305
|
+
} else {
|
|
306
|
+
defaultScene
|
|
307
|
+
}
|
|
326
308
|
|
|
327
309
|
when (settings.source?.type ?: sourceType) {
|
|
328
310
|
EditorSourceType.IMAGE -> {
|
|
@@ -376,22 +358,20 @@ object EditorBuilderDefaults {
|
|
|
376
358
|
): EditorResult {
|
|
377
359
|
EditorBuilderDefaults.run {
|
|
378
360
|
eventHandler.send(ShowLoading)
|
|
379
|
-
val blob =
|
|
380
|
-
engine.
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
) {
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
block.setVisible(it, visible = true)
|
|
387
|
-
}
|
|
361
|
+
val blob = engine.block.export(
|
|
362
|
+
block = requireNotNull(engine.scene.get()),
|
|
363
|
+
mimeType = mimeType,
|
|
364
|
+
) {
|
|
365
|
+
scene.getPages().forEach {
|
|
366
|
+
block.setScopeEnabled(it, key = "layer/visibility", enabled = true)
|
|
367
|
+
block.setVisible(it, visible = true)
|
|
388
368
|
}
|
|
369
|
+
}
|
|
389
370
|
val tempFile = EditorDefaults.writeToTempFile(blob, mimeType)
|
|
390
371
|
val scene = engine.scene.get()
|
|
391
|
-
val sceneString =
|
|
392
|
-
scene
|
|
393
|
-
|
|
394
|
-
}
|
|
372
|
+
val sceneString = scene?.let {
|
|
373
|
+
engine.scene.saveToString(it)
|
|
374
|
+
}
|
|
395
375
|
val sceneUri = sceneString?.let { saveScene(it) }
|
|
396
376
|
val firstPage = engine.scene.getPages().first()
|
|
397
377
|
val thumbnail = saveThumbnail(firstPage, engine, thumbnailHeight)
|
|
@@ -425,23 +405,21 @@ object EditorBuilderDefaults {
|
|
|
425
405
|
val page = engine.scene.getCurrentPage() ?: engine.scene.getPages().first()
|
|
426
406
|
val thumbnail = saveThumbnail(page, engine, thumbnailHeight)
|
|
427
407
|
val scene = engine.scene.get()
|
|
428
|
-
val sceneString =
|
|
429
|
-
scene
|
|
430
|
-
|
|
431
|
-
}
|
|
408
|
+
val sceneString = scene?.let {
|
|
409
|
+
engine.scene.saveToString(it)
|
|
410
|
+
}
|
|
432
411
|
|
|
433
|
-
val buffer =
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
)
|
|
412
|
+
val buffer = engine.block.exportVideo(
|
|
413
|
+
block = page,
|
|
414
|
+
timeOffset = 0.0,
|
|
415
|
+
duration = engine.block.getDuration(page),
|
|
416
|
+
mimeType = mimeType,
|
|
417
|
+
progressCallback = { progress ->
|
|
418
|
+
eventHandler.send(
|
|
419
|
+
ShowVideoExportProgressEvent(progress.encodedFrames.toFloat() / progress.totalFrames),
|
|
420
|
+
)
|
|
421
|
+
},
|
|
422
|
+
)
|
|
445
423
|
|
|
446
424
|
val tempFile = EditorDefaults.writeToTempFile(buffer, mimeType)
|
|
447
425
|
eventHandler.send(DismissVideoExportEvent)
|
|
@@ -454,22 +432,19 @@ object EditorBuilderDefaults {
|
|
|
454
432
|
}
|
|
455
433
|
}
|
|
456
434
|
|
|
457
|
-
private suspend fun saveScene(scene: String): Uri =
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
Uri.fromFile(file)
|
|
464
|
-
}
|
|
435
|
+
private suspend fun saveScene(scene: String): Uri = withContext(Dispatchers.IO) {
|
|
436
|
+
val file = File
|
|
437
|
+
.createTempFile("cesdk_export_scene_" + UUID.randomUUID().toString(), ".scene")
|
|
438
|
+
file.writeText(scene)
|
|
439
|
+
Uri.fromFile(file)
|
|
440
|
+
}
|
|
465
441
|
|
|
466
442
|
private suspend fun saveThumbnail(
|
|
467
443
|
id: DesignBlock,
|
|
468
444
|
engine: Engine,
|
|
469
445
|
height: Int,
|
|
470
446
|
): Uri {
|
|
471
|
-
val frames =
|
|
472
|
-
engine.block.generateVideoThumbnailSequence(id, height, timeBegin = 0.0, timeEnd = 0.1, numberOfFrames = 1).toList()
|
|
447
|
+
val frames = engine.block.generateVideoThumbnailSequence(id, height, timeBegin = 0.0, timeEnd = 0.1, numberOfFrames = 1).toList()
|
|
473
448
|
val firstFrame = frames.first()
|
|
474
449
|
val buffer = firstFrame.imageData
|
|
475
450
|
val tempFile = EditorDefaults.writeToTempFile(buffer, MimeType.PNG)
|
|
@@ -48,16 +48,15 @@ data class EditorSettings(
|
|
|
48
48
|
|
|
49
49
|
override fun newArray(size: Int): Array<EditorSettings?> = arrayOfNulls(size)
|
|
50
50
|
|
|
51
|
-
fun createFromMap(map: Map<String, Any>): EditorSettings? =
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
}
|
|
51
|
+
fun createFromMap(map: Map<String, Any>): EditorSettings? = try {
|
|
52
|
+
val license = map["license"] as? String ?: throw (Exception("Missing value for key 'license.'"))
|
|
53
|
+
val sceneBaseUri = map["sceneBaseUri"] as? String ?: throw (Exception("Missing value for key 'sceneBaseUri.'"))
|
|
54
|
+
val assetBaseUri = map["assetBaseUri"] as? String
|
|
55
|
+
val userId = map["userId"] as? String
|
|
56
|
+
val source = (map["source"] as? Map<String, Any>)?.let { Source.createFromMap(it) }
|
|
57
|
+
EditorSettings(license, sceneBaseUri, assetBaseUri, userId, source)
|
|
58
|
+
} catch (e: Exception) {
|
|
59
|
+
null
|
|
60
|
+
}
|
|
62
61
|
}
|
|
63
62
|
}
|
|
@@ -27,18 +27,17 @@ data class Source(
|
|
|
27
27
|
|
|
28
28
|
override fun newArray(size: Int): Array<Source?> = arrayOfNulls(size)
|
|
29
29
|
|
|
30
|
-
fun createFromMap(map: Map<String, Any>): Source? =
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
Source(s, type)
|
|
39
|
-
}
|
|
30
|
+
fun createFromMap(map: Map<String, Any>): Source? = runCatching {
|
|
31
|
+
val source = map["source"] as? String
|
|
32
|
+
val typeRaw = map["type"] as? String
|
|
33
|
+
|
|
34
|
+
source?.let { s ->
|
|
35
|
+
typeRaw?.let { t ->
|
|
36
|
+
EditorSourceType.fromValue(t)?.let { type ->
|
|
37
|
+
Source(s, type)
|
|
40
38
|
}
|
|
41
39
|
}
|
|
42
|
-
}
|
|
40
|
+
}
|
|
41
|
+
}.getOrNull()
|
|
43
42
|
}
|
|
44
43
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@imgly/editor-react-native",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.46.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",
|