@technotoil/image-video-editor 0.1.1 → 0.1.3

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 (47) hide show
  1. package/README.md +17 -3
  2. package/android/src/main/java/com/technotoil/image_videoeditor/FrameGrabberModule.kt +2 -6
  3. package/android/src/main/java/com/technotoil/image_videoeditor/MediaEditorModule.kt +103 -37
  4. package/android/src/main/java/com/technotoil/image_videoeditor/MediaLibraryModule.kt +51 -35
  5. package/android/src/main/java/com/technotoil/image_videoeditor/RNVideoPreviewManager.kt +98 -117
  6. package/ios/RNMediaEditor.m +38 -7
  7. package/ios/RNMediaLibrary.m +19 -15
  8. package/ios/RNVideoPreviewManager.m +2 -0
  9. package/lib/commonjs/components/Icon.js +31 -0
  10. package/lib/commonjs/components/Icon.js.map +1 -0
  11. package/lib/commonjs/components/VideoEditor.js +97 -32
  12. package/lib/commonjs/components/VideoEditor.js.map +1 -1
  13. package/lib/commonjs/icons.js +35 -0
  14. package/lib/commonjs/icons.js.map +1 -0
  15. package/lib/commonjs/screens/CropScreen.js +5 -3
  16. package/lib/commonjs/screens/CropScreen.js.map +1 -1
  17. package/lib/commonjs/screens/EditorScreen.js +269 -84
  18. package/lib/commonjs/screens/EditorScreen.js.map +1 -1
  19. package/lib/commonjs/screens/PickScreen.js +221 -129
  20. package/lib/commonjs/screens/PickScreen.js.map +1 -1
  21. package/lib/module/components/Icon.js +25 -0
  22. package/lib/module/components/Icon.js.map +1 -0
  23. package/lib/module/components/VideoEditor.js +98 -33
  24. package/lib/module/components/VideoEditor.js.map +1 -1
  25. package/lib/module/icons.js +31 -0
  26. package/lib/module/icons.js.map +1 -0
  27. package/lib/module/screens/CropScreen.js +5 -3
  28. package/lib/module/screens/CropScreen.js.map +1 -1
  29. package/lib/module/screens/EditorScreen.js +230 -45
  30. package/lib/module/screens/EditorScreen.js.map +1 -1
  31. package/lib/module/screens/PickScreen.js +216 -124
  32. package/lib/module/screens/PickScreen.js.map +1 -1
  33. package/lib/typescript/src/components/Icon.d.ts +11 -0
  34. package/lib/typescript/src/components/VideoEditor.d.ts +10 -2
  35. package/lib/typescript/src/icons.d.ts +28 -0
  36. package/lib/typescript/src/screens/CropScreen.d.ts +2 -1
  37. package/lib/typescript/src/screens/EditorScreen.d.ts +2 -1
  38. package/lib/typescript/src/screens/PickScreen.d.ts +4 -1
  39. package/lib/typescript/src/types.d.ts +1 -0
  40. package/package.json +4 -4
  41. package/src/components/Icon.tsx +19 -0
  42. package/src/components/VideoEditor.tsx +67 -11
  43. package/src/icons.ts +28 -0
  44. package/src/screens/CropScreen.tsx +8 -3
  45. package/src/screens/EditorScreen.tsx +228 -62
  46. package/src/screens/PickScreen.tsx +198 -120
  47. package/src/types.ts +1 -0
@@ -11,7 +11,7 @@ var _FrameGrabber = require("../native/FrameGrabber");
11
11
  var _MediaLibrary = require("../native/MediaLibrary");
12
12
  var _VideoPreview = require("../native/VideoPreview");
13
13
  var _reactNativeVideo = _interopRequireDefault(require("react-native-video"));
14
- var _Ionicons = _interopRequireDefault(require("react-native-vector-icons/Ionicons"));
14
+ var _Icon = require("../components/Icon");
15
15
  var _jsxRuntime = require("react/jsx-runtime");
16
16
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
17
17
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
@@ -174,12 +174,16 @@ function EditorScreen({
174
174
  onBack,
175
175
  onSaved,
176
176
  onOpenCrop,
177
- musicList
177
+ musicList,
178
+ maxVideoDurationMs
178
179
  }) {
179
180
  const [activeIndex, setActiveIndex] = (0, _react.useState)(initialIndex);
180
181
  const currentItem = items[activeIndex] || items[0];
181
182
  const item = currentItem; // Aliasing to 'item' for ease of compatibility
182
183
 
184
+ (0, _react.useEffect)(() => {
185
+ setActiveIndex(initialIndex);
186
+ }, [initialIndex]);
183
187
  const [activeFilter, setActiveFilter] = (0, _react.useState)('none');
184
188
  const [imageOptions, setImageOptions] = (0, _react.useState)({
185
189
  rotateDegrees: 0,
@@ -190,13 +194,21 @@ function EditorScreen({
190
194
  saturation: 1,
191
195
  grayscale: false
192
196
  });
197
+ const [panel, setPanel] = (0, _react.useState)(item.type === 'video' ? 'trim' : 'filter');
193
198
  const [trimStart, setTrimStart] = (0, _react.useState)(0);
194
- const [trimEnd, setTrimEnd] = (0, _react.useState)(item.durationMs || 10000);
199
+ const [trimEnd, setTrimEnd] = (0, _react.useState)(() => {
200
+ const end = item.durationMs || 10000;
201
+ return maxVideoDurationMs ? Math.min(end, maxVideoDurationMs) : end;
202
+ });
195
203
  (0, _react.useEffect)(() => {
196
204
  setTrimStart(0);
197
- setTrimEnd(item.durationMs || 10000);
205
+ const end = item.durationMs || maxVideoDurationMs || 10000;
206
+ setTrimEnd(maxVideoDurationMs ? Math.min(end, maxVideoDurationMs) : end);
198
207
  setThumbnails([]);
199
- }, [item.id, item.durationMs]);
208
+ if (item.type === 'video' && maxVideoDurationMs && end > maxVideoDurationMs) {
209
+ setPanel('trim');
210
+ }
211
+ }, [item.id, item.durationMs, maxVideoDurationMs]);
200
212
  const [editsHistory, setEditsHistory] = (0, _react.useState)({});
201
213
  const editsHistoryRef = (0, _react.useRef)({});
202
214
  const [dimensionsMap, setDimensionsMap] = (0, _react.useState)({});
@@ -253,7 +265,7 @@ function EditorScreen({
253
265
  setCropOffset(saved.cropOffset);
254
266
  setZoomScale(saved.zoomScale);
255
267
  setStraightenAngle(saved.straightenAngle);
256
- setIsMuted(saved.isMuted);
268
+ setIsMuted(selectedMusic ? true : saved.isMuted);
257
269
  } else {
258
270
  setActiveFilter('none');
259
271
  setImageOptions({
@@ -266,7 +278,8 @@ function EditorScreen({
266
278
  grayscale: false
267
279
  });
268
280
  setTrimStart(0);
269
- setTrimEnd(targetItem.durationMs || 10000);
281
+ const end = targetItem.durationMs || 10000;
282
+ setTrimEnd(maxVideoDurationMs ? Math.min(end, maxVideoDurationMs) : end);
270
283
  setOverlays([]);
271
284
  setCropRatio(null);
272
285
  setCropOffset({
@@ -275,7 +288,14 @@ function EditorScreen({
275
288
  });
276
289
  setZoomScale(1);
277
290
  setStraightenAngle(0);
278
- setIsMuted(false);
291
+ setIsMuted(selectedMusic ? true : false);
292
+ }
293
+
294
+ // Force trim panel if video is too long
295
+ if (targetItem.type === 'video' && maxVideoDurationMs && targetItem.durationMs && targetItem.durationMs > maxVideoDurationMs) {
296
+ setPanel('trim');
297
+ } else if (!saved) {
298
+ setPanel(targetItem.type === 'video' ? 'trim' : 'filter');
279
299
  }
280
300
  };
281
301
  const handleScrollEnd = e => {
@@ -334,13 +354,13 @@ function EditorScreen({
334
354
  y: (o.y + 8) * renderScale,
335
355
  color: o.color,
336
356
  fontSize: o.fontSize * renderScale
337
- }))
357
+ })),
358
+ frameUri: edits.imageOptions.frame && FRAME_IMAGES[edits.imageOptions.frame] ? _reactNative.Image.resolveAssetSource(FRAME_IMAGES[edits.imageOptions.frame]).uri : undefined
338
359
  };
339
360
  };
340
361
  const [saving, setSaving] = (0, _react.useState)(false);
341
362
  const [videoPaused, setVideoPaused] = (0, _react.useState)(false);
342
- const [panel, setPanel] = (0, _react.useState)(item.type === 'video' ? 'trim' : 'filter');
343
- const resolvedMusicList = musicList || DUMMY_MUSIC_LIST;
363
+ const resolvedMusicList = musicList || [];
344
364
  const [selectedMusic, setSelectedMusic] = (0, _react.useState)(null);
345
365
  const [musicPaused, setMusicPaused] = (0, _react.useState)(false);
346
366
  const [showMusicModal, setShowMusicModal] = (0, _react.useState)(false);
@@ -1119,13 +1139,18 @@ function EditorScreen({
1119
1139
  y: (o.y + 8) * renderScale,
1120
1140
  color: o.color,
1121
1141
  fontSize: o.fontSize * renderScale
1122
- }))
1142
+ })),
1143
+ frameUri: imageOptions.frame && FRAME_IMAGES[imageOptions.frame] ? _reactNative.Image.resolveAssetSource(FRAME_IMAGES[imageOptions.frame]).uri : undefined
1123
1144
  };
1124
1145
  }, [imageOptions, cropOffset, maxPan, dimensions, cropRatio, straightenAngle, overlays]);
1125
1146
 
1126
1147
  // For visual trim
1127
1148
 
1128
1149
  const duration = item.durationMs ?? 10_000;
1150
+ const durationRef = (0, _react.useRef)(duration);
1151
+ (0, _react.useEffect)(() => {
1152
+ durationRef.current = duration;
1153
+ }, [duration]);
1129
1154
  const formatTime = ms => {
1130
1155
  const totalSec = Math.floor(ms / 1000);
1131
1156
  const mins = Math.floor(totalSec / 60);
@@ -1187,6 +1212,39 @@ function EditorScreen({
1187
1212
  generateThumbs();
1188
1213
  }
1189
1214
  }, [item.type, item.uri, duration, thumbnails.length]);
1215
+ const leftOverlayRef = (0, _react.useRef)(null);
1216
+ const rightOverlayRef = (0, _react.useRef)(null);
1217
+ const selectionRangeRef = (0, _react.useRef)(null);
1218
+ const leftHandleRef = (0, _react.useRef)(null);
1219
+ const rightHandleRef = (0, _react.useRef)(null);
1220
+ const updateNativeRefs = (newStartX, newEndX) => {
1221
+ leftOverlayRef.current?.setNativeProps({
1222
+ style: {
1223
+ width: newStartX
1224
+ }
1225
+ });
1226
+ rightOverlayRef.current?.setNativeProps({
1227
+ style: {
1228
+ left: newEndX
1229
+ }
1230
+ });
1231
+ selectionRangeRef.current?.setNativeProps({
1232
+ style: {
1233
+ left: newStartX,
1234
+ width: newEndX - newStartX
1235
+ }
1236
+ });
1237
+ leftHandleRef.current?.setNativeProps({
1238
+ style: {
1239
+ left: newStartX - 16
1240
+ }
1241
+ });
1242
+ rightHandleRef.current?.setNativeProps({
1243
+ style: {
1244
+ left: newEndX - 16
1245
+ }
1246
+ });
1247
+ };
1190
1248
  const startPanOffset = (0, _react.useRef)(0);
1191
1249
  const startPan = (0, _react.useRef)(_reactNative.PanResponder.create({
1192
1250
  onStartShouldSetPanResponder: () => true,
@@ -1200,20 +1258,76 @@ function EditorScreen({
1200
1258
  setScrollEnabled(false);
1201
1259
  },
1202
1260
  onPanResponderMove: (_, gesture) => {
1203
- const newX = Math.max(0, Math.min(endX.current - 32, startPanOffset.current + gesture.dx));
1261
+ let newX = Math.max(0, Math.min(endX.current - 32, startPanOffset.current + gesture.dx));
1262
+ let newTime = newX / TIMELINE_WIDTH * durationRef.current;
1263
+ const currentTrimEnd = endX.current / TIMELINE_WIDTH * durationRef.current;
1264
+ if (maxVideoDurationMs && currentTrimEnd - newTime > maxVideoDurationMs) {
1265
+ newTime = currentTrimEnd - maxVideoDurationMs;
1266
+ newX = newTime / durationRef.current * TIMELINE_WIDTH;
1267
+ }
1204
1268
  startX.current = newX;
1205
- const newTime = newX / TIMELINE_WIDTH * duration;
1206
- setTrimStart(newTime);
1269
+ updateNativeRefs(newX, endX.current);
1207
1270
  throttledSeek(newTime);
1208
1271
  },
1209
1272
  onPanResponderRelease: () => {
1210
1273
  isDraggingHandle.current = false;
1211
1274
  setScrollEnabled(true);
1275
+ setTrimStart(startX.current / TIMELINE_WIDTH * durationRef.current);
1276
+ setTrimEnd(endX.current / TIMELINE_WIDTH * durationRef.current);
1212
1277
  setSeekToMs(-1);
1213
1278
  },
1214
1279
  onPanResponderTerminate: () => {
1215
1280
  isDraggingHandle.current = false;
1216
1281
  setScrollEnabled(true);
1282
+ setTrimStart(startX.current / TIMELINE_WIDTH * durationRef.current);
1283
+ setTrimEnd(endX.current / TIMELINE_WIDTH * durationRef.current);
1284
+ setSeekToMs(-1);
1285
+ }
1286
+ })).current;
1287
+ const middlePanOffsetStart = (0, _react.useRef)(0);
1288
+ const middlePanOffsetEnd = (0, _react.useRef)(0);
1289
+ const middlePan = (0, _react.useRef)(_reactNative.PanResponder.create({
1290
+ onStartShouldSetPanResponder: () => true,
1291
+ onStartShouldSetPanResponderCapture: () => true,
1292
+ onMoveShouldSetPanResponder: () => true,
1293
+ onMoveShouldSetPanResponderCapture: () => true,
1294
+ onPanResponderGrant: () => {
1295
+ pushToHistory();
1296
+ middlePanOffsetStart.current = startX.current;
1297
+ middlePanOffsetEnd.current = endX.current;
1298
+ isDraggingHandle.current = true;
1299
+ setScrollEnabled(false);
1300
+ },
1301
+ onPanResponderMove: (_, gesture) => {
1302
+ const windowWidth = middlePanOffsetEnd.current - middlePanOffsetStart.current;
1303
+ let newStartX = middlePanOffsetStart.current + gesture.dx;
1304
+ let newEndX = middlePanOffsetEnd.current + gesture.dx;
1305
+ if (newStartX < 0) {
1306
+ newStartX = 0;
1307
+ newEndX = windowWidth;
1308
+ }
1309
+ if (newEndX > TIMELINE_WIDTH) {
1310
+ newEndX = TIMELINE_WIDTH;
1311
+ newStartX = TIMELINE_WIDTH - windowWidth;
1312
+ }
1313
+ startX.current = newStartX;
1314
+ endX.current = newEndX;
1315
+ const newStartTime = newStartX / TIMELINE_WIDTH * durationRef.current;
1316
+ updateNativeRefs(newStartX, newEndX);
1317
+ throttledSeek(newStartTime);
1318
+ },
1319
+ onPanResponderRelease: () => {
1320
+ isDraggingHandle.current = false;
1321
+ setScrollEnabled(true);
1322
+ setTrimStart(startX.current / TIMELINE_WIDTH * durationRef.current);
1323
+ setTrimEnd(endX.current / TIMELINE_WIDTH * durationRef.current);
1324
+ setSeekToMs(-1);
1325
+ },
1326
+ onPanResponderTerminate: () => {
1327
+ isDraggingHandle.current = false;
1328
+ setScrollEnabled(true);
1329
+ setTrimStart(startX.current / TIMELINE_WIDTH * durationRef.current);
1330
+ setTrimEnd(endX.current / TIMELINE_WIDTH * durationRef.current);
1217
1331
  setSeekToMs(-1);
1218
1332
  }
1219
1333
  })).current;
@@ -1230,20 +1344,29 @@ function EditorScreen({
1230
1344
  setScrollEnabled(false);
1231
1345
  },
1232
1346
  onPanResponderMove: (_, gesture) => {
1233
- const newX = Math.min(TIMELINE_WIDTH, Math.max(startX.current + 32, endPanOffset.current + gesture.dx));
1347
+ let newX = Math.min(TIMELINE_WIDTH, Math.max(startX.current + 32, endPanOffset.current + gesture.dx));
1348
+ let newTime = newX / TIMELINE_WIDTH * durationRef.current;
1349
+ const currentTrimStart = startX.current / TIMELINE_WIDTH * durationRef.current;
1350
+ if (maxVideoDurationMs && newTime - currentTrimStart > maxVideoDurationMs) {
1351
+ newTime = currentTrimStart + maxVideoDurationMs;
1352
+ newX = newTime / durationRef.current * TIMELINE_WIDTH;
1353
+ }
1234
1354
  endX.current = newX;
1235
- const newTime = newX / TIMELINE_WIDTH * duration;
1236
- setTrimEnd(newTime);
1355
+ updateNativeRefs(startX.current, newX);
1237
1356
  throttledSeek(newTime);
1238
1357
  },
1239
1358
  onPanResponderRelease: () => {
1240
1359
  isDraggingHandle.current = false;
1241
1360
  setScrollEnabled(true);
1361
+ setTrimStart(startX.current / TIMELINE_WIDTH * durationRef.current);
1362
+ setTrimEnd(endX.current / TIMELINE_WIDTH * durationRef.current);
1242
1363
  setSeekToMs(-1);
1243
1364
  },
1244
1365
  onPanResponderTerminate: () => {
1245
1366
  isDraggingHandle.current = false;
1246
1367
  setScrollEnabled(true);
1368
+ setTrimStart(startX.current / TIMELINE_WIDTH * durationRef.current);
1369
+ setTrimEnd(endX.current / TIMELINE_WIDTH * durationRef.current);
1247
1370
  setSeekToMs(-1);
1248
1371
  }
1249
1372
  })).current;
@@ -2018,11 +2141,16 @@ function EditorScreen({
2018
2141
  });
2019
2142
  }
2020
2143
  } else {
2144
+ const safeEndMs = Math.min(trimEnd, item.durationMs || 10000);
2145
+ const safeStartMs = Math.min(trimStart, Math.max(0, safeEndMs - 100));
2146
+ const isFullTrim = trimStart === 0 && trimEnd >= (item.durationMs || 10000);
2021
2147
  exportUri = await (0, _MediaEditor.trimVideo)(item.uri, {
2022
- startMs: trimStart,
2023
- endMs: trimEnd,
2148
+ startMs: safeStartMs,
2149
+ endMs: safeEndMs,
2024
2150
  mute: isMuted,
2025
- musicUri: selectedMusic?.url || undefined,
2151
+ ...(selectedMusic?.url ? {
2152
+ musicUri: selectedMusic.url
2153
+ } : {}),
2026
2154
  ...activeOptions
2027
2155
  });
2028
2156
  }
@@ -2039,6 +2167,7 @@ function EditorScreen({
2039
2167
  setSaving(true);
2040
2168
  saveEditsForIndex(activeIndex);
2041
2169
  const updatedItems = [...items];
2170
+ let cumulativeMusicOffsetMs = 0;
2042
2171
  for (let i = 0; i < items.length; i++) {
2043
2172
  const targetItem = items[i];
2044
2173
  let edits = editsHistoryRef.current[targetItem.id];
@@ -2064,6 +2193,7 @@ function EditorScreen({
2064
2193
  outUri = await (0, _MediaEditor.trimVideo)(outUri, {
2065
2194
  isImage: true,
2066
2195
  musicUri: selectedMusic.url,
2196
+ musicOffsetMs: cumulativeMusicOffsetMs,
2067
2197
  rotateDegrees: 0,
2068
2198
  flipX: false,
2069
2199
  flipY: false,
@@ -2078,12 +2208,20 @@ function EditorScreen({
2078
2208
  uri: outUri,
2079
2209
  thumbnailUri: outUri
2080
2210
  };
2211
+ cumulativeMusicOffsetMs += 10000; // Images are 10s by default
2081
2212
  } else {
2213
+ const originalDuration = targetItem.durationMs || maxVideoDurationMs || 10000;
2214
+ const safeEndMs = Math.min(edits.trimEnd, originalDuration);
2215
+ const safeStartMs = Math.min(edits.trimStart, Math.max(0, safeEndMs - 100));
2216
+ const isFullTrim = edits.trimStart === 0 && edits.trimEnd >= originalDuration;
2082
2217
  const outUri = await (0, _MediaEditor.trimVideo)(targetItem.uri, {
2083
- startMs: edits.trimStart,
2084
- endMs: edits.trimEnd,
2218
+ startMs: safeStartMs,
2219
+ endMs: safeEndMs,
2085
2220
  mute: edits.isMuted,
2086
- musicUri: selectedMusic?.url || undefined,
2221
+ ...(selectedMusic?.url ? {
2222
+ musicUri: selectedMusic.url,
2223
+ musicOffsetMs: cumulativeMusicOffsetMs
2224
+ } : {}),
2087
2225
  ...opts
2088
2226
  });
2089
2227
  let newThumb = undefined;
@@ -2101,6 +2239,7 @@ function EditorScreen({
2101
2239
  thumbnailUri: newThumb ? newThumb : targetItem.thumbnailUri,
2102
2240
  durationMs: newDuration
2103
2241
  };
2242
+ cumulativeMusicOffsetMs += newDuration;
2104
2243
  }
2105
2244
  } else {
2106
2245
  if (selectedMusic) {
@@ -2109,6 +2248,7 @@ function EditorScreen({
2109
2248
  outUri = await (0, _MediaEditor.trimVideo)(targetItem.uri, {
2110
2249
  isImage: true,
2111
2250
  musicUri: selectedMusic.url,
2251
+ musicOffsetMs: cumulativeMusicOffsetMs,
2112
2252
  rotateDegrees: 0,
2113
2253
  flipX: false,
2114
2254
  flipY: false,
@@ -2117,12 +2257,17 @@ function EditorScreen({
2117
2257
  saturation: 1,
2118
2258
  grayscale: false
2119
2259
  });
2260
+ cumulativeMusicOffsetMs += 10000;
2120
2261
  } else {
2262
+ const safeEndMs = targetItem.durationMs || 10000;
2121
2263
  outUri = await (0, _MediaEditor.trimVideo)(targetItem.uri, {
2122
2264
  startMs: 0,
2123
- endMs: targetItem.durationMs || 10000,
2265
+ endMs: safeEndMs,
2124
2266
  mute: isMuted,
2125
- musicUri: selectedMusic.url,
2267
+ ...(selectedMusic?.url ? {
2268
+ musicUri: selectedMusic.url,
2269
+ musicOffsetMs: cumulativeMusicOffsetMs
2270
+ } : {}),
2126
2271
  rotateDegrees: 0,
2127
2272
  flipX: false,
2128
2273
  flipY: false,
@@ -2131,6 +2276,7 @@ function EditorScreen({
2131
2276
  saturation: 1,
2132
2277
  grayscale: false
2133
2278
  });
2279
+ cumulativeMusicOffsetMs += safeEndMs;
2134
2280
  }
2135
2281
  updatedItems[i] = {
2136
2282
  ...targetItem,
@@ -2258,7 +2404,7 @@ function EditorScreen({
2258
2404
  style: styles.previewOverlay,
2259
2405
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
2260
2406
  style: styles.playPauseCircle,
2261
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Ionicons.default, {
2407
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.Icon, {
2262
2408
  name: "play",
2263
2409
  size: 22,
2264
2410
  color: "#fff"
@@ -2382,7 +2528,7 @@ function EditorScreen({
2382
2528
  }), isActive && cardItem.type === 'image' && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
2383
2529
  style: styles.cropIconBtn,
2384
2530
  onPress: () => onOpenCrop(cardItem),
2385
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Ionicons.default, {
2531
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.Icon, {
2386
2532
  name: "crop-outline",
2387
2533
  size: 20,
2388
2534
  color: "#fff"
@@ -2417,7 +2563,7 @@ function EditorScreen({
2417
2563
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
2418
2564
  onPress: () => setIsEditingVideo(false),
2419
2565
  style: styles.editModeBackBtn,
2420
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Ionicons.default, {
2566
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.Icon, {
2421
2567
  name: "chevron-down",
2422
2568
  size: 22,
2423
2569
  color: "#fff"
@@ -2429,7 +2575,7 @@ function EditorScreen({
2429
2575
  children: saving ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ActivityIndicator, {
2430
2576
  size: "small",
2431
2577
  color: "#fff"
2432
- }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_Ionicons.default, {
2578
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.Icon, {
2433
2579
  name: "arrow-forward",
2434
2580
  size: 20,
2435
2581
  color: "#fff"
@@ -2556,7 +2702,7 @@ function EditorScreen({
2556
2702
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
2557
2703
  onPress: () => setVideoPaused(!videoPaused),
2558
2704
  style: styles.editPlayPauseBtn,
2559
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Ionicons.default, {
2705
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.Icon, {
2560
2706
  name: videoPaused ? 'play' : 'pause',
2561
2707
  size: 20,
2562
2708
  color: "#fff"
@@ -2572,7 +2718,7 @@ function EditorScreen({
2572
2718
  }],
2573
2719
  onPress: handleUndo,
2574
2720
  disabled: undoStack.length === 0,
2575
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Ionicons.default, {
2721
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.Icon, {
2576
2722
  name: "arrow-undo",
2577
2723
  size: 18,
2578
2724
  color: "#fff"
@@ -2583,7 +2729,7 @@ function EditorScreen({
2583
2729
  }],
2584
2730
  onPress: handleRedo,
2585
2731
  disabled: redoStack.length === 0,
2586
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Ionicons.default, {
2732
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.Icon, {
2587
2733
  name: "arrow-redo",
2588
2734
  size: 18,
2589
2735
  color: "#fff"
@@ -2672,7 +2818,15 @@ function EditorScreen({
2672
2818
  },
2673
2819
  style: styles.filmstripImage
2674
2820
  }, idx)), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
2675
- style: styles.timelineOverlay
2821
+ style: [styles.timelineOverlay, {
2822
+ left: 0,
2823
+ width: trimStart / duration * TIMELINE_WIDTH
2824
+ }]
2825
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
2826
+ style: [styles.timelineOverlay, {
2827
+ left: trimEnd / duration * TIMELINE_WIDTH,
2828
+ right: 0
2829
+ }]
2676
2830
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
2677
2831
  style: [styles.selectionRange, {
2678
2832
  left: trimStart / duration * TIMELINE_WIDTH,
@@ -2683,20 +2837,18 @@ function EditorScreen({
2683
2837
  style: [styles.customHandle, styles.customHandleLeft, {
2684
2838
  left: trimStart / duration * TIMELINE_WIDTH - 16
2685
2839
  }],
2686
- ...startPan.panHandlers,
2687
2840
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
2688
2841
  style: styles.handleBarLine
2689
2842
  })
2690
2843
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
2691
2844
  style: [styles.customHandle, styles.customHandleRight, {
2692
- left: trimEnd / duration * TIMELINE_WIDTH
2845
+ left: trimEnd / duration * TIMELINE_WIDTH - 16
2693
2846
  }],
2694
- ...endPan.panHandlers,
2695
2847
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
2696
2848
  style: styles.handleBarLine
2697
2849
  })
2698
2850
  })]
2699
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Pressable, {
2851
+ }), resolvedMusicList.length > 0 && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Pressable, {
2700
2852
  style: styles.subTrackRow,
2701
2853
  onPress: () => setShowMusicModal(true),
2702
2854
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
@@ -2893,7 +3045,7 @@ function EditorScreen({
2893
3045
  justifyContent: 'center',
2894
3046
  alignItems: 'center'
2895
3047
  },
2896
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Ionicons.default, {
3048
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.Icon, {
2897
3049
  name: "close",
2898
3050
  size: 20,
2899
3051
  color: "#fff"
@@ -2968,7 +3120,7 @@ function EditorScreen({
2968
3120
  onPress: addTextOverlay,
2969
3121
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
2970
3122
  style: styles.toolIconContainer,
2971
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Ionicons.default, {
3123
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.Icon, {
2972
3124
  name: "text",
2973
3125
  size: 22,
2974
3126
  color: "#fff"
@@ -2977,12 +3129,12 @@ function EditorScreen({
2977
3129
  style: styles.toolLabel,
2978
3130
  children: "Text"
2979
3131
  })]
2980
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Pressable, {
3132
+ }), resolvedMusicList.length > 0 && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Pressable, {
2981
3133
  style: [styles.toolButton, showMusicModal && styles.toolButtonActive],
2982
3134
  onPress: () => setShowMusicModal(true),
2983
3135
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
2984
3136
  style: styles.toolIconContainer,
2985
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Ionicons.default, {
3137
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.Icon, {
2986
3138
  name: "musical-notes",
2987
3139
  size: 22,
2988
3140
  color: "#fff"
@@ -2996,7 +3148,7 @@ function EditorScreen({
2996
3148
  onPress: () => setPanel(panel === 'transform' ? 'trim' : 'transform'),
2997
3149
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
2998
3150
  style: styles.toolIconContainer,
2999
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Ionicons.default, {
3151
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.Icon, {
3000
3152
  name: "crop",
3001
3153
  size: 22,
3002
3154
  color: "#fff"
@@ -3010,7 +3162,7 @@ function EditorScreen({
3010
3162
  onPress: () => setPanel(panel === 'filter' ? 'trim' : 'filter'),
3011
3163
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
3012
3164
  style: styles.toolIconContainer,
3013
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Ionicons.default, {
3165
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.Icon, {
3014
3166
  name: "color-palette",
3015
3167
  size: 22,
3016
3168
  color: "#fff"
@@ -3024,7 +3176,7 @@ function EditorScreen({
3024
3176
  onPress: () => setPanel(panel === 'frame' ? 'trim' : 'frame'),
3025
3177
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
3026
3178
  style: styles.toolIconContainer,
3027
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Ionicons.default, {
3179
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.Icon, {
3028
3180
  name: "images",
3029
3181
  size: 22,
3030
3182
  color: "#fff"
@@ -3038,7 +3190,7 @@ function EditorScreen({
3038
3190
  onPress: () => setPanel(panel === 'edit' ? 'trim' : 'edit'),
3039
3191
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
3040
3192
  style: styles.toolIconContainer,
3041
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Ionicons.default, {
3193
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.Icon, {
3042
3194
  name: "settings-outline",
3043
3195
  size: 22,
3044
3196
  color: "#fff"
@@ -3061,7 +3213,7 @@ function EditorScreen({
3061
3213
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
3062
3214
  onPress: onBack,
3063
3215
  style: styles.fullscreenCloseBtn,
3064
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Ionicons.default, {
3216
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.Icon, {
3065
3217
  name: "close",
3066
3218
  size: 24,
3067
3219
  color: "#fff"
@@ -3069,7 +3221,7 @@ function EditorScreen({
3069
3221
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
3070
3222
  onPress: () => setIsMuted(!isMuted),
3071
3223
  style: styles.fullscreenSoundBtn,
3072
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Ionicons.default, {
3224
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.Icon, {
3073
3225
  name: isMuted ? 'volume-mute' : 'volume-high',
3074
3226
  size: 22,
3075
3227
  color: "#fff"
@@ -3139,12 +3291,12 @@ function EditorScreen({
3139
3291
  contentContainerStyle: [styles.toolButtonsRow, {
3140
3292
  flexGrow: 1
3141
3293
  }],
3142
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Pressable, {
3294
+ children: [resolvedMusicList.length > 0 && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Pressable, {
3143
3295
  style: [styles.toolButton, showMusicModal && styles.toolButtonActive],
3144
3296
  onPress: () => setShowMusicModal(true),
3145
3297
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
3146
3298
  style: styles.toolIconContainer,
3147
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Ionicons.default, {
3299
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.Icon, {
3148
3300
  name: "musical-notes",
3149
3301
  size: 22,
3150
3302
  color: "#fff"
@@ -3158,7 +3310,7 @@ function EditorScreen({
3158
3310
  onPress: addTextOverlay,
3159
3311
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
3160
3312
  style: styles.toolIconContainer,
3161
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Ionicons.default, {
3313
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.Icon, {
3162
3314
  name: "text",
3163
3315
  size: 22,
3164
3316
  color: "#fff"
@@ -3175,7 +3327,7 @@ function EditorScreen({
3175
3327
  },
3176
3328
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
3177
3329
  style: styles.toolIconContainer,
3178
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Ionicons.default, {
3330
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.Icon, {
3179
3331
  name: "crop",
3180
3332
  size: 22,
3181
3333
  color: "#fff"
@@ -3189,7 +3341,7 @@ function EditorScreen({
3189
3341
  onPress: () => setIsEditingVideo(true),
3190
3342
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
3191
3343
  style: styles.toolIconContainer,
3192
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Ionicons.default, {
3344
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.Icon, {
3193
3345
  name: "cut",
3194
3346
  size: 22,
3195
3347
  color: "#fff"
@@ -3206,7 +3358,7 @@ function EditorScreen({
3206
3358
  },
3207
3359
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
3208
3360
  style: styles.toolIconContainer,
3209
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Ionicons.default, {
3361
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.Icon, {
3210
3362
  name: "images",
3211
3363
  size: 22,
3212
3364
  color: "#fff"
@@ -3223,7 +3375,7 @@ function EditorScreen({
3223
3375
  },
3224
3376
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
3225
3377
  style: styles.toolIconContainer,
3226
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Ionicons.default, {
3378
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.Icon, {
3227
3379
  name: "color-palette",
3228
3380
  size: 22,
3229
3381
  color: "#fff"
@@ -3240,7 +3392,7 @@ function EditorScreen({
3240
3392
  },
3241
3393
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
3242
3394
  style: styles.toolIconContainer,
3243
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Ionicons.default, {
3395
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.Icon, {
3244
3396
  name: "settings-outline",
3245
3397
  size: 22,
3246
3398
  color: "#fff"
@@ -3279,7 +3431,7 @@ function EditorScreen({
3279
3431
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
3280
3432
  onPress: onBack,
3281
3433
  style: styles.backButton,
3282
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Ionicons.default, {
3434
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.Icon, {
3283
3435
  name: "close",
3284
3436
  size: 22,
3285
3437
  color: "#fff"
@@ -3289,7 +3441,7 @@ function EditorScreen({
3289
3441
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
3290
3442
  onPress: () => setIsMuted(!isMuted),
3291
3443
  style: styles.soundButton,
3292
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Ionicons.default, {
3444
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.Icon, {
3293
3445
  name: isMuted ? 'volume-mute' : 'volume-high',
3294
3446
  size: 22,
3295
3447
  color: "#fff"
@@ -3308,6 +3460,12 @@ function EditorScreen({
3308
3460
  data: items,
3309
3461
  extraData: [overlays, editingTextId, editsHistory, activeFilter, imageOptions, trimStart, trimEnd, isMuted, activeIndex],
3310
3462
  keyExtractor: it => it.id,
3463
+ initialScrollIndex: activeIndex,
3464
+ getItemLayout: (_, index) => ({
3465
+ length: SCREEN_WIDTH,
3466
+ offset: SCREEN_WIDTH * index,
3467
+ index
3468
+ }),
3311
3469
  horizontal: true,
3312
3470
  pagingEnabled: false,
3313
3471
  showsHorizontalScrollIndicator: false,
@@ -3418,7 +3576,7 @@ function EditorScreen({
3418
3576
  fontWeight: '700'
3419
3577
  },
3420
3578
  children: (() => {
3421
- const selMs = trimEnd - trimStart;
3579
+ const selMs = (endX.current - startX.current) / TIMELINE_WIDTH * duration;
3422
3580
  const totalSec = Math.floor(selMs / 1000);
3423
3581
  return totalSec >= 60 ? `${Math.floor(totalSec / 60)}:${(totalSec % 60).toString().padStart(2, '0')} selected` : `${(selMs / 1000).toFixed(1)}s selected`;
3424
3582
  })()
@@ -3429,30 +3587,54 @@ function EditorScreen({
3429
3587
  }],
3430
3588
  children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
3431
3589
  style: styles.filmstrip,
3432
- children: [thumbnails.map((uri, idx) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Image, {
3590
+ children: [thumbnails.length === 0 ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
3591
+ style: {
3592
+ flex: 1,
3593
+ justifyContent: 'center',
3594
+ alignItems: 'center'
3595
+ },
3596
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ActivityIndicator, {
3597
+ color: "#ffffff",
3598
+ size: "small"
3599
+ })
3600
+ }) : thumbnails.map((uri, idx) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Image, {
3433
3601
  source: {
3434
3602
  uri
3435
3603
  },
3436
3604
  style: styles.filmstripImage
3437
3605
  }, idx)), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
3438
- style: styles.timelineOverlay
3606
+ ref: leftOverlayRef,
3607
+ style: [styles.timelineOverlay, {
3608
+ left: 0,
3609
+ width: startX.current
3610
+ }]
3439
3611
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
3440
- style: [styles.selectionRange, {
3441
- left: trimStart / duration * TIMELINE_WIDTH,
3442
- width: (trimEnd - trimStart) / duration * TIMELINE_WIDTH
3612
+ ref: rightOverlayRef,
3613
+ style: [styles.timelineOverlay, {
3614
+ left: endX.current,
3615
+ right: 0
3443
3616
  }]
3617
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
3618
+ ref: selectionRangeRef,
3619
+ style: [styles.selectionRange, {
3620
+ left: startX.current,
3621
+ width: endX.current - startX.current
3622
+ }],
3623
+ ...middlePan.panHandlers
3444
3624
  })]
3445
3625
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
3626
+ ref: leftHandleRef,
3446
3627
  style: [styles.customHandle, styles.customHandleLeft, {
3447
- left: trimStart / duration * TIMELINE_WIDTH - 16
3628
+ left: startX.current - 16
3448
3629
  }],
3449
3630
  ...startPan.panHandlers,
3450
3631
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
3451
3632
  style: styles.handleBarLine
3452
3633
  })
3453
3634
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
3635
+ ref: rightHandleRef,
3454
3636
  style: [styles.customHandle, styles.customHandleRight, {
3455
- left: trimEnd / duration * TIMELINE_WIDTH
3637
+ left: endX.current - 16
3456
3638
  }],
3457
3639
  ...endPan.panHandlers,
3458
3640
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
@@ -3479,7 +3661,7 @@ function EditorScreen({
3479
3661
  justifyContent: 'center',
3480
3662
  alignItems: 'center'
3481
3663
  }],
3482
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Ionicons.default, {
3664
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.Icon, {
3483
3665
  name: "close",
3484
3666
  size: 24,
3485
3667
  color: "#fff"
@@ -3581,7 +3763,7 @@ function EditorScreen({
3581
3763
  fontSize: 20
3582
3764
  },
3583
3765
  children: s.emoji
3584
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Ionicons.default, {
3766
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.Icon, {
3585
3767
  name: "close-circle",
3586
3768
  size: 14,
3587
3769
  color: "#ff6b6b",
@@ -3689,7 +3871,7 @@ function EditorScreen({
3689
3871
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
3690
3872
  onPress: () => removeCaption(c.id),
3691
3873
  style: styles.captionRemoveBtn,
3692
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Ionicons.default, {
3874
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.Icon, {
3693
3875
  name: "close",
3694
3876
  size: 14,
3695
3877
  color: "#ff6b6b"
@@ -3730,12 +3912,12 @@ function EditorScreen({
3730
3912
  contentContainerStyle: [styles.toolButtonsRow, {
3731
3913
  flexGrow: 1
3732
3914
  }],
3733
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Pressable, {
3915
+ children: [resolvedMusicList.length > 0 && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Pressable, {
3734
3916
  style: [styles.toolButton, showMusicModal && styles.toolButtonActive],
3735
3917
  onPress: () => setShowMusicModal(true),
3736
3918
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
3737
3919
  style: styles.toolIconContainer,
3738
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Ionicons.default, {
3920
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.Icon, {
3739
3921
  name: "musical-notes",
3740
3922
  size: 22,
3741
3923
  color: "#fff"
@@ -3749,7 +3931,7 @@ function EditorScreen({
3749
3931
  onPress: () => setPanel('text'),
3750
3932
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
3751
3933
  style: styles.toolIconContainer,
3752
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Ionicons.default, {
3934
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.Icon, {
3753
3935
  name: "text",
3754
3936
  size: 22,
3755
3937
  color: "#fff"
@@ -3763,7 +3945,7 @@ function EditorScreen({
3763
3945
  onPress: handleOpenTransform,
3764
3946
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
3765
3947
  style: styles.toolIconContainer,
3766
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Ionicons.default, {
3948
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.Icon, {
3767
3949
  name: "crop",
3768
3950
  size: 22,
3769
3951
  color: "#fff"
@@ -3777,7 +3959,7 @@ function EditorScreen({
3777
3959
  onPress: () => setPanel('trim'),
3778
3960
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
3779
3961
  style: styles.toolIconContainer,
3780
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Ionicons.default, {
3962
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.Icon, {
3781
3963
  name: "cut",
3782
3964
  size: 22,
3783
3965
  color: "#fff"
@@ -3791,7 +3973,7 @@ function EditorScreen({
3791
3973
  onPress: () => setPanel('frame'),
3792
3974
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
3793
3975
  style: styles.toolIconContainer,
3794
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Ionicons.default, {
3976
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.Icon, {
3795
3977
  name: "images",
3796
3978
  size: 22,
3797
3979
  color: "#fff"
@@ -3805,7 +3987,7 @@ function EditorScreen({
3805
3987
  onPress: () => setPanel('filter'),
3806
3988
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
3807
3989
  style: styles.toolIconContainer,
3808
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Ionicons.default, {
3990
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.Icon, {
3809
3991
  name: "color-palette",
3810
3992
  size: 22,
3811
3993
  color: "#fff"
@@ -3819,7 +4001,7 @@ function EditorScreen({
3819
4001
  onPress: () => setPanel('edit'),
3820
4002
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
3821
4003
  style: styles.toolIconContainer,
3822
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Ionicons.default, {
4004
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.Icon, {
3823
4005
  name: "settings-outline",
3824
4006
  size: 22,
3825
4007
  color: "#fff"
@@ -3846,7 +4028,7 @@ function EditorScreen({
3846
4028
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
3847
4029
  style: styles.nextBlueText,
3848
4030
  children: "Next"
3849
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Ionicons.default, {
4031
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.Icon, {
3850
4032
  name: "arrow-forward",
3851
4033
  size: 16,
3852
4034
  color: "#fff",
@@ -3881,7 +4063,7 @@ function EditorScreen({
3881
4063
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
3882
4064
  onPress: () => setShowMusicModal(false),
3883
4065
  style: styles.musicModalCloseBtn,
3884
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Ionicons.default, {
4066
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.Icon, {
3885
4067
  name: "close",
3886
4068
  size: 24,
3887
4069
  color: "#fff"
@@ -3902,7 +4084,7 @@ function EditorScreen({
3902
4084
  }), musicSearchQuery.length > 0 && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
3903
4085
  onPress: () => setMusicSearchQuery(''),
3904
4086
  style: styles.musicSearchClearBtn,
3905
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Ionicons.default, {
4087
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.Icon, {
3906
4088
  name: "close-circle",
3907
4089
  size: 18,
3908
4090
  color: "#8e8e93"
@@ -4038,6 +4220,7 @@ function EditorScreen({
4038
4220
  onPress: () => {
4039
4221
  setSelectedMusic(null);
4040
4222
  setMusicPaused(true);
4223
+ setIsMuted(false);
4041
4224
  },
4042
4225
  style: styles.musicFooterRemoveBtn,
4043
4226
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
@@ -4156,7 +4339,7 @@ function EditorScreen({
4156
4339
  scale: 1.15
4157
4340
  }]
4158
4341
  } : {}],
4159
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Ionicons.default, {
4342
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.Icon, {
4160
4343
  name: isOverTrash ? "trash" : "trash-outline",
4161
4344
  size: 20,
4162
4345
  color: "#fff"
@@ -4805,7 +4988,9 @@ const styles = _reactNative.StyleSheet.create({
4805
4988
  height: 60
4806
4989
  },
4807
4990
  timelineOverlay: {
4808
- ..._reactNative.StyleSheet.absoluteFillObject,
4991
+ position: 'absolute',
4992
+ top: 0,
4993
+ bottom: 0,
4809
4994
  backgroundColor: 'rgba(0,0,0,0.6)'
4810
4995
  },
4811
4996
  selectionRange: {
@@ -4815,7 +5000,7 @@ const styles = _reactNative.StyleSheet.create({
4815
5000
  backgroundColor: 'transparent',
4816
5001
  borderTopWidth: 2,
4817
5002
  borderBottomWidth: 2,
4818
- borderColor: '#fff'
5003
+ borderColor: '#FFD60A'
4819
5004
  },
4820
5005
  handle: {
4821
5006
  position: 'absolute',
@@ -4841,7 +5026,7 @@ const styles = _reactNative.StyleSheet.create({
4841
5026
  top: 0,
4842
5027
  width: 16,
4843
5028
  height: 60,
4844
- backgroundColor: '#FFFFFF',
5029
+ backgroundColor: '#FFD60A',
4845
5030
  justifyContent: 'center',
4846
5031
  alignItems: 'center',
4847
5032
  zIndex: 20