@imgly/editor-react-native 1.80.0 → 1.81.0-rc.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 +1 -1
- package/android/src/main/assets/ly.img.memories.style/content.json +50 -0
- package/android/src/main/assets/ly.img.memories.style/thumbnails/bubblegum.png +0 -0
- package/android/src/main/assets/ly.img.memories.style/thumbnails/hologram.png +0 -0
- package/android/src/main/assets/ly.img.memories.style/thumbnails/noir.png +0 -0
- package/android/src/main/assets/ly.img.memories.style/videos/bubblegum.mp4 +0 -0
- package/android/src/main/assets/ly.img.memories.style/videos/hologram.mp4 +0 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/MemoriesApp.kt +77 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/MemoriesConfiguration.kt +38 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/MemoriesEditor.kt +79 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/MemoriesViewModel.kt +469 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/callback/OnCreate.kt +69 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/callback/OnExport.kt +46 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/component/BottomPanel.kt +151 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/component/Dock.kt +145 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/component/ExportOverlay.kt +229 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/component/NavigationBar.kt +80 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/component/Overlay.kt +138 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/extension/EditorScopeExt.kt +111 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/iconPack/AddPhotoAlternate.kt +79 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/iconPack/ArrowForward.kt +45 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/iconPack/Audiotrack.kt +43 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/iconPack/Check.kt +39 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/iconPack/CheckCircle.kt +44 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/iconPack/Close.kt +43 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/iconPack/Delete.kt +54 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/iconPack/DeleteOutline.kt +53 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/iconPack/Fullscreen.kt +74 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/iconPack/Image.kt +51 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/iconPack/Info.kt +48 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/iconPack/Pause.kt +46 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/iconPack/PlayArrow.kt +38 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/iconPack/RepeatOff.kt +80 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/iconPack/RepeatOn.kt +59 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/iconPack/SkipPrevious.kt +46 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/iconPack/Sort.kt +55 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/iconPack/Style.kt +59 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/iconPack/Title.kt +43 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/iconPack/TouchTriple.kt +134 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/iconPack/VolumeDown.kt +48 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/iconPack/VolumeUp.kt +60 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/model/ExportStatus.kt +20 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/model/ImageItem.kt +8 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/model/TimelineImage.kt +18 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/scene/Events.kt +59 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/scene/Playback.kt +29 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/scene/SceneSetup.kt +79 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/scene/Timeline.kt +27 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/scene/Title.kt +162 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/scene/TrackEditor.kt +740 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/screen/ImageSelectionScreen.kt +387 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/screen/LoadingScreen.kt +258 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/sheet/FilterStylesSheet.kt +167 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/sheet/FilterStylesSheetType.kt +21 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/sheet/VolumeSheet.kt +104 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/style/StyleApplier.kt +220 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/style/StyleAssetSource.kt +43 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/style/VideoStyle.kt +118 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/util/Animations.kt +58 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/util/Constants.kt +20 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/util/ImageDate.kt +81 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/util/Utils.kt +27 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/widget/CenteredAddImageButton.kt +82 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/widget/DraggableImageItem.kt +145 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/widget/FullscreenVideoControls.kt +136 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/widget/ImageGrid.kt +122 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/widget/ImageGridOverlay.kt +149 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/widget/ImageTimelineStrip.kt +323 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/widget/ImageToolbar.kt +401 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/widget/ReorderableGridState.kt +183 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/widget/VideoControlPanel.kt +180 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/memories/widget/VideoThumbnail.kt +110 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/video/callback/OnCreate.kt +0 -7
- package/android/src/main/kotlin/ly/img/editor/configuration/video/component/InspectorBar.kt +2 -0
- package/ios/StarterKits/Video/callbacks/OnCreate+Video.swift +1 -1
- package/ios/StarterKits/Video/components/Dock+Video.swift +1 -0
- package/ios/StarterKits/Video/components/InspectorBar+Video.swift +4 -0
- package/package.json +1 -1
- package/src/NativeIMGLYEditor.ts +1 -1
package/android/build.gradle
CHANGED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "1.0.0",
|
|
3
|
+
"id": "ly.img.memories.style",
|
|
4
|
+
"assets": [
|
|
5
|
+
{
|
|
6
|
+
"id": "noir",
|
|
7
|
+
"label": { "en": "Noir" },
|
|
8
|
+
"tags": { "en": ["style", "noir"] },
|
|
9
|
+
"meta": {
|
|
10
|
+
"uri": "{{base_url}}/ly.img.memories.style/thumbnails/noir.png",
|
|
11
|
+
"thumbUri": "{{base_url}}/ly.img.memories.style/thumbnails/noir.png",
|
|
12
|
+
"kind": "image",
|
|
13
|
+
"fillType": "//ly.img.ubq/fill/image",
|
|
14
|
+
"mimeType": "image/png",
|
|
15
|
+
"width": 256,
|
|
16
|
+
"height": 256
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"id": "hologram",
|
|
21
|
+
"label": { "en": "Hologram" },
|
|
22
|
+
"tags": { "en": ["style", "background", "video"] },
|
|
23
|
+
"meta": {
|
|
24
|
+
"uri": "{{base_url}}/ly.img.memories.style/videos/hologram.mp4",
|
|
25
|
+
"thumbUri": "{{base_url}}/ly.img.memories.style/thumbnails/hologram.png",
|
|
26
|
+
"kind": "video",
|
|
27
|
+
"fillType": "//ly.img.ubq/fill/video",
|
|
28
|
+
"mimeType": "video/mp4",
|
|
29
|
+
"width": 1080,
|
|
30
|
+
"height": 1920,
|
|
31
|
+
"duration": "10"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"id": "bubblegum",
|
|
36
|
+
"label": { "en": "Bubblegum" },
|
|
37
|
+
"tags": { "en": ["style", "background", "video"] },
|
|
38
|
+
"meta": {
|
|
39
|
+
"uri": "{{base_url}}/ly.img.memories.style/videos/bubblegum.mp4",
|
|
40
|
+
"thumbUri": "{{base_url}}/ly.img.memories.style/thumbnails/bubblegum.png",
|
|
41
|
+
"kind": "video",
|
|
42
|
+
"fillType": "//ly.img.ubq/fill/video",
|
|
43
|
+
"mimeType": "video/mp4",
|
|
44
|
+
"width": 1080,
|
|
45
|
+
"height": 1920,
|
|
46
|
+
"duration": "10"
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
]
|
|
50
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
package ly.img.editor.configuration.memories
|
|
2
|
+
|
|
3
|
+
import androidx.activity.compose.BackHandler
|
|
4
|
+
import androidx.compose.foundation.layout.padding
|
|
5
|
+
import androidx.compose.material3.Scaffold
|
|
6
|
+
import androidx.compose.runtime.Composable
|
|
7
|
+
import androidx.compose.runtime.LaunchedEffect
|
|
8
|
+
import androidx.compose.runtime.getValue
|
|
9
|
+
import androidx.compose.runtime.mutableStateOf
|
|
10
|
+
import androidx.compose.runtime.saveable.rememberSaveable
|
|
11
|
+
import androidx.compose.runtime.setValue
|
|
12
|
+
import androidx.compose.ui.Modifier
|
|
13
|
+
import androidx.compose.ui.platform.LocalContext
|
|
14
|
+
import androidx.lifecycle.viewmodel.compose.viewModel
|
|
15
|
+
import ly.img.editor.configuration.memories.screen.ImageSelectionScreen
|
|
16
|
+
|
|
17
|
+
enum class AppScreen {
|
|
18
|
+
ImageSelection,
|
|
19
|
+
VideoEditor,
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* The complete Memories experience: photo picker (device images and videos) →
|
|
24
|
+
* loading/analysis → cinematic slideshow editor.
|
|
25
|
+
*
|
|
26
|
+
* This is the single entry point used by every host — the standalone app, the examples app, and
|
|
27
|
+
* the showcases app — so the flow is identical everywhere.
|
|
28
|
+
*
|
|
29
|
+
* @param license CE.SDK license key, or null for evaluation mode (adds a watermark).
|
|
30
|
+
* @param onExit invoked when the user navigates back from the picker (the root of the flow) —
|
|
31
|
+
* e.g. finish the activity (standalone) or pop the back stack (demo apps).
|
|
32
|
+
*/
|
|
33
|
+
@Composable
|
|
34
|
+
fun MemoriesApp(
|
|
35
|
+
license: String?,
|
|
36
|
+
onExit: () -> Unit,
|
|
37
|
+
modifier: Modifier = Modifier,
|
|
38
|
+
viewModel: MemoriesViewModel = viewModel(),
|
|
39
|
+
) {
|
|
40
|
+
val context = LocalContext.current
|
|
41
|
+
var currentScreen by rememberSaveable { mutableStateOf(AppScreen.ImageSelection) }
|
|
42
|
+
|
|
43
|
+
LaunchedEffect(viewModel) {
|
|
44
|
+
viewModel.setContext(context)
|
|
45
|
+
// After process death the saved screen can restore to the editor while the ViewModel is
|
|
46
|
+
// recreated empty — don't land in the editor with no media; return to the picker instead.
|
|
47
|
+
if (currentScreen == AppScreen.VideoEditor && viewModel.selectedImages.value.isEmpty()) {
|
|
48
|
+
currentScreen = AppScreen.ImageSelection
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
when (currentScreen) {
|
|
53
|
+
AppScreen.ImageSelection -> {
|
|
54
|
+
// Back from the picker leaves the flow. ImageSelectionScreen registers its own
|
|
55
|
+
// (higher-priority) BackHandler for multi-select mode, so this only fires otherwise.
|
|
56
|
+
BackHandler { onExit() }
|
|
57
|
+
Scaffold { paddingValues ->
|
|
58
|
+
ImageSelectionScreen(
|
|
59
|
+
viewModel = viewModel,
|
|
60
|
+
onProceedToEditor = {
|
|
61
|
+
viewModel.setEditorLoading(true)
|
|
62
|
+
currentScreen = AppScreen.VideoEditor
|
|
63
|
+
},
|
|
64
|
+
modifier = modifier.padding(paddingValues),
|
|
65
|
+
)
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
AppScreen.VideoEditor -> {
|
|
69
|
+
MemoriesEditor(
|
|
70
|
+
license = license,
|
|
71
|
+
viewModel = viewModel,
|
|
72
|
+
onCloseEditor = { currentScreen = AppScreen.ImageSelection },
|
|
73
|
+
modifier = modifier,
|
|
74
|
+
)
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
package ly.img.editor.configuration.memories
|
|
2
|
+
|
|
3
|
+
import androidx.compose.runtime.getValue
|
|
4
|
+
import androidx.compose.runtime.setValue
|
|
5
|
+
import ly.img.editor.BasicConfigurationBuilder
|
|
6
|
+
import ly.img.editor.configuration.memories.callback.onCreateConfiguration
|
|
7
|
+
import ly.img.editor.configuration.memories.callback.onExport
|
|
8
|
+
import ly.img.editor.configuration.memories.component.bottomPanelConfiguration
|
|
9
|
+
import ly.img.editor.configuration.memories.component.dockConfiguration
|
|
10
|
+
import ly.img.editor.configuration.memories.component.navigationBarConfiguration
|
|
11
|
+
import ly.img.editor.configuration.memories.component.rememberOverlay
|
|
12
|
+
import ly.img.editor.configuration.memories.model.ExportStatus
|
|
13
|
+
|
|
14
|
+
class MemoriesConfiguration(
|
|
15
|
+
private val viewModel: MemoriesViewModel,
|
|
16
|
+
) : BasicConfigurationBuilder() {
|
|
17
|
+
/** Drives the export progress overlay; null when no export is running. */
|
|
18
|
+
var exportStatus: ExportStatus? by editorContext.mutableStateOf(key = KEY_EXPORT_STATUS, initial = null)
|
|
19
|
+
|
|
20
|
+
init {
|
|
21
|
+
onCreate = onCreateConfiguration(viewModel)
|
|
22
|
+
dock = dockConfiguration(viewModel)
|
|
23
|
+
bottomPanel = bottomPanelConfiguration(viewModel)
|
|
24
|
+
navigationBar = navigationBarConfiguration(viewModel)
|
|
25
|
+
overlay = { rememberOverlay(viewModel) }
|
|
26
|
+
onExport = { onExport() }
|
|
27
|
+
// If onCreate (or any editor step) fails, never leave the loading overlay stuck: dismiss it
|
|
28
|
+
// and surface the failure through the standard error dialog (BasicConfigurationBuilder.Overlay).
|
|
29
|
+
onError = {
|
|
30
|
+
viewModel.setEditorLoading(false)
|
|
31
|
+
error = it
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
private companion object {
|
|
36
|
+
const val KEY_EXPORT_STATUS = "ly.img.editor.configuration.memories.exportStatus"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
package ly.img.editor.configuration.memories
|
|
2
|
+
|
|
3
|
+
import androidx.activity.compose.BackHandler
|
|
4
|
+
import androidx.compose.animation.core.animateFloatAsState
|
|
5
|
+
import androidx.compose.foundation.layout.Box
|
|
6
|
+
import androidx.compose.foundation.layout.fillMaxSize
|
|
7
|
+
import androidx.compose.runtime.Composable
|
|
8
|
+
import androidx.compose.runtime.DisposableEffect
|
|
9
|
+
import androidx.compose.runtime.collectAsState
|
|
10
|
+
import androidx.compose.runtime.getValue
|
|
11
|
+
import androidx.compose.ui.Modifier
|
|
12
|
+
import androidx.compose.ui.draw.alpha
|
|
13
|
+
import ly.img.editor.Editor
|
|
14
|
+
import ly.img.editor.configuration.memories.screen.LoadingScreen
|
|
15
|
+
import ly.img.editor.core.configuration.EditorConfiguration
|
|
16
|
+
import ly.img.editor.core.configuration.remember
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Hosts the slideshow [Editor] for the images staged in [viewModel], with the loading overlay
|
|
20
|
+
* shown while the scene is built and back handling for preview / image-grid overlay.
|
|
21
|
+
*
|
|
22
|
+
* @param license CE.SDK license key, or null for evaluation mode (adds a watermark).
|
|
23
|
+
*/
|
|
24
|
+
@Composable
|
|
25
|
+
fun MemoriesEditor(
|
|
26
|
+
license: String?,
|
|
27
|
+
viewModel: MemoriesViewModel,
|
|
28
|
+
onCloseEditor: () -> Unit,
|
|
29
|
+
modifier: Modifier = Modifier,
|
|
30
|
+
) {
|
|
31
|
+
val selectedImages by viewModel.selectedImages.collectAsState()
|
|
32
|
+
val isLoading by viewModel.isEditorLoading.collectAsState()
|
|
33
|
+
val showImageGrid by viewModel.showImageGrid.collectAsState()
|
|
34
|
+
val isPreviewMode by viewModel.isPreviewMode.collectAsState()
|
|
35
|
+
|
|
36
|
+
val alpha by animateFloatAsState(
|
|
37
|
+
targetValue = if (isLoading) 0f else 1f,
|
|
38
|
+
label = "editor_alpha",
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
// Release the editor context when the editor leaves composition (back, close, process death),
|
|
42
|
+
// so the ViewModel doesn't keep acting on a disposed editor afterwards.
|
|
43
|
+
DisposableEffect(viewModel) {
|
|
44
|
+
onDispose { viewModel.clearEditorContext() }
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Factory typed as Function0 so it binds to the generic remember(builder, block) overload.
|
|
48
|
+
val configurationBuilder: () -> MemoriesConfiguration = { MemoriesConfiguration(viewModel) }
|
|
49
|
+
|
|
50
|
+
Box(modifier = modifier.fillMaxSize().alpha(alpha)) {
|
|
51
|
+
Editor(
|
|
52
|
+
license = license,
|
|
53
|
+
configuration = { EditorConfiguration.remember(configurationBuilder) },
|
|
54
|
+
onClose = { onCloseEditor() },
|
|
55
|
+
)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (isLoading) {
|
|
59
|
+
LoadingScreen(
|
|
60
|
+
selectedImages = selectedImages,
|
|
61
|
+
modifier = modifier.fillMaxSize(),
|
|
62
|
+
)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Back handling (registered after the Editor, so these intercept first).
|
|
66
|
+
// In fullscreen/preview: exit preview (applies nothing).
|
|
67
|
+
BackHandler(enabled = isPreviewMode) {
|
|
68
|
+
viewModel.togglePreviewMode()
|
|
69
|
+
}
|
|
70
|
+
// Image grid overlay open: close it, discarding staged edits.
|
|
71
|
+
BackHandler(enabled = !isPreviewMode && showImageGrid) {
|
|
72
|
+
viewModel.cancelOverlay()
|
|
73
|
+
}
|
|
74
|
+
BackHandler(enabled = !isPreviewMode && !showImageGrid) {
|
|
75
|
+
onCloseEditor()
|
|
76
|
+
}
|
|
77
|
+
// Otherwise the editor handles back internally (closing sheets), falling back to onClose,
|
|
78
|
+
// which returns to the image selection screen.
|
|
79
|
+
}
|