import { memo, useMemo } from 'react'; import { motion, AnimatePresence, MotionStyle } from 'framer-motion'; import { FaTrashAlt } from 'react-icons/fa'; import { mySpring } from './animations'; import useUserSettings from './hooks/useUserSettings'; import { useSegColors } from './contexts'; import { ApparentCutSegment, FormatTimecode } from './types'; const TimelineSeg = memo(({ seg, duration, isActive, segNum, onSegClick, invertCutSegments, formatTimecode, selected, } : { seg: ApparentCutSegment, duration: number, isActive: boolean, segNum: number, onSegClick: (a: number) => void, invertCutSegments: boolean, formatTimecode: FormatTimecode, selected: boolean, }) => { const { darkMode } = useUserSettings(); const { getSegColor } = useSegColors(); const segColor = useMemo(() => getSegColor(seg), [getSegColor, seg]); const { name, start: cutStart, end: cutEnd } = seg; const cutSectionWidth = `${((cutEnd - cutStart) / duration) * 100}%`; const startTimePos = `${(cutStart / duration) * 100}%`; const markerBorder = useMemo(() => { if (!isActive) return '2px solid transparent'; return `1.5px solid ${darkMode ? segColor.desaturate(0.1).lightness(70).string() : segColor.desaturate(0.2).lightness(40).string()}`; }, [darkMode, isActive, segColor]); const backgroundColor = useMemo(() => { // we use both transparency and lightness, so that segments can be visible when overlapping if (invertCutSegments || !selected) return darkMode ? segColor.desaturate(0.3).lightness(30).alpha(0.5).string() : segColor.desaturate(0.3).lightness(70).alpha(0.5).string(); if (isActive) return darkMode ? segColor.saturate(0.2).lightness(60).alpha(0.7).string() : segColor.saturate(0.2).lightness(40).alpha(0.8).string(); return darkMode ? segColor.desaturate(0.2).lightness(50).alpha(0.7).string() : segColor.lightness(35).alpha(0.6).string(); }, [darkMode, invertCutSegments, isActive, segColor, selected]); const markerBorderRadius = 5; const wrapperStyle: MotionStyle = { position: 'absolute', top: 0, bottom: 0, left: startTimePos, width: cutSectionWidth, display: 'flex', alignItems: 'center', justifyContent: 'space-between', originX: 0, boxSizing: 'border-box', color: 'white', overflow: 'hidden', borderLeft: markerBorder, borderTopLeftRadius: markerBorderRadius, borderBottomLeftRadius: markerBorderRadius, borderRight: markerBorder, borderTopRightRadius: markerBorderRadius, borderBottomRightRadius: markerBorderRadius, }; const onThisSegClick = () => onSegClick(segNum); const title: string[] = []; if (cutEnd > cutStart) title.push(`${formatTimecode({ seconds: cutEnd - cutStart, shorten: true })}`); if (name) title.push(name); return (
{segNum + 1}
{invertCutSegments && ( )} {name &&
} {name &&
{name}
}
); }); export default TimelineSeg;