diff --git a/src/TimelineSeg.jsx b/src/TimelineSeg.jsx
index 47a257f9..d3cf8599 100644
--- a/src/TimelineSeg.jsx
+++ b/src/TimelineSeg.jsx
@@ -8,7 +8,7 @@ const { formatDuration } = require('./util');
const TimelineSeg = ({
- duration, cutStart, cutEnd, isActive, segNum,
+ duration, cutStart, cutEnd, isActive, segNum, name,
onSegClick, invertCutSegments, segBgColor, segActiveBgColor, segBorderColor,
}) => {
const cutSectionWidth = `${((cutEnd - cutStart) / duration) * 100}%`;
@@ -42,6 +42,9 @@ const TimelineSeg = ({
const onThisSegClick = () => onSegClick(segNum);
+ const durationStr = cutEnd > cutStart ? `${formatDuration({ seconds: cutEnd - cutStart })} ` : '';
+ const title = `${durationStr}${name}`;
+
return (
cutStart ? formatDuration({ seconds: cutEnd - cutStart }) : undefined}
+ title={title}
>
{segNum + 1}
@@ -71,6 +74,10 @@ const TimelineSeg = ({
)}
+ {name && }
+
+ {name && {name}
}
+
);
diff --git a/src/renderer.jsx b/src/renderer.jsx
index e95f500d..bbf24a32 100644
--- a/src/renderer.jsx
+++ b/src/renderer.jsx
@@ -1,6 +1,6 @@
import React, { memo, useEffect, useState, useCallback, useRef, Fragment } from 'react';
import { IoIosHelpCircle, IoIosCamera } from 'react-icons/io';
-import { FaPlus, FaMinus, FaHandPointRight, FaHandPointLeft, FaTrashAlt, FaVolumeMute, FaVolumeUp, FaYinYang, FaFileExport } from 'react-icons/fa';
+import { FaPlus, FaMinus, FaHandPointRight, FaHandPointLeft, FaTrashAlt, FaVolumeMute, FaVolumeUp, FaYinYang, FaFileExport, FaTag } from 'react-icons/fa';
import { MdRotate90DegreesCcw, MdCallSplit, MdCallMerge } from 'react-icons/md';
import { FiScissors } from 'react-icons/fi';
import { AnimatePresence, motion } from 'framer-motion';
@@ -64,6 +64,7 @@ function createSegment({ start, end } = {}) {
return {
start,
end,
+ name: '',
color: generateColor(),
uuid: uuid.v4(),
};
@@ -302,7 +303,6 @@ const App = memo(() => {
})();
const setCutTime = useCallback((type, time) => {
- const cloned = cloneDeep(cutSegments);
const currentSeg = currentCutSeg;
if (type === 'start' && time >= getSegApparentEnd(currentSeg)) {
throw new Error('Start time must precede end time');
@@ -310,12 +310,19 @@ const App = memo(() => {
if (type === 'end' && time <= getSegApparentStart(currentSeg)) {
throw new Error('Start time must precede end time');
}
+ const cloned = cloneDeep(cutSegments);
cloned[currentSegIndexSafe][type] = Math.min(Math.max(time, 0), duration);
setCutSegments(cloned);
}, [
currentSegIndexSafe, getSegApparentEnd, cutSegments, currentCutSeg, setCutSegments, duration,
]);
+ const setCurrentSegmentName = (name) => {
+ const cloned = cloneDeep(cutSegments);
+ cloned[currentSegIndexSafe].name = name;
+ setCutSegments(cloned);
+ };
+
function formatTimecode(sec) {
return formatDuration({ seconds: sec, fps: timecodeShowFrames ? detectedFps : undefined });
}
@@ -1063,10 +1070,21 @@ const App = memo(() => {
const otherFormatsMap = fromPairs(Object.entries(allOutFormats)
.filter(([f]) => ![...commonFormats, detectedFileFormat].includes(f)));
- const segColor = (currentCutSeg || {}).color;
- const segBgColor = segColor.alpha(0.5).string();
- const segActiveBgColor = segColor.lighten(0.5).alpha(0.5).string();
- const segBorderColor = segColor.lighten(0.5).string();
+ function getSegColors(seg) {
+ if (!seg) return {};
+ const { color } = seg;
+ return {
+ segBgColor: color.alpha(0.5).string(),
+ segActiveBgColor: color.lighten(0.5).alpha(0.5).string(),
+ segBorderColor: color.lighten(0.5).string(),
+ };
+ }
+
+ const {
+ segBgColor: currentSegBgColor,
+ segActiveBgColor: currentSegActiveBgColor,
+ segBorderColor: currentSegBorderColor,
+ } = getSegColors(currentCutSeg);
const jumpCutButtonStyle = {
position: 'absolute', color: 'black', bottom: 0, top: 0, padding: '2px 8px',
@@ -1277,16 +1295,27 @@ const App = memo(() => {
return () => window.removeEventListener('keydown', keyScrollPreventer);
}, []);
+ async function onLabelSegmentPress() {
+ const { value } = await Swal.fire({
+ showCancelButton: true,
+ title: 'Label current segment',
+ inputValue: currentCutSeg.name,
+ input: 'text',
+ });
+
+ if (value != null) setCurrentSegmentName(value);
+ }
+
function renderSetCutpointButton(side) {
const start = side === 'start';
const Icon = start ? FaHandPointLeft : FaHandPointRight;
- const border = `4px solid ${segBorderColor}`;
+ const border = `4px solid ${currentSegBorderColor}`;
return (
);
@@ -1485,22 +1514,29 @@ const App = memo(() => {
{currentTimePos !== undefined && }
{commandedTimePos !== undefined &&
}
- {apparentCutSegments.map((seg, i) => (
- setCurrentSegIndex(currentSegIndexNew)}
- isActive={i === currentSegIndexSafe}
- duration={durationSafe}
- cutStart={seg.start}
- cutEnd={seg.end}
- invertCutSegments={invertCutSegments}
- zoomed={zoomed}
- />
- ))}
+ {apparentCutSegments.map((seg, i) => {
+ const {
+ segBgColor, segActiveBgColor, segBorderColor,
+ } = getSegColors(seg);
+
+ return (
+ setCurrentSegIndex(currentSegIndexNew)}
+ isActive={i === currentSegIndexSafe}
+ duration={durationSafe}
+ name={seg.name}
+ cutStart={seg.start}
+ cutEnd={seg.end}
+ invertCutSegments={invertCutSegments}
+ zoomed={zoomed}
+ />
+ );
+ })}
{inverseCutSegments && inverseCutSegments.map((seg, i) => (
{
{
);
})}
+
+
+