color add segment button with next seg color

closes #2609
pull/2640/head
Mikael Finstad 9 months ago
parent 25111307d7
commit 251113d617
No known key found for this signature in database
GPG Key ID: 25AB36E3E81CBC26

@ -24,7 +24,7 @@ import useFrameCapture from './hooks/useFrameCapture';
import useSegments from './hooks/useSegments';
import useDirectoryAccess from './hooks/useDirectoryAccess';
import { UserSettingsContext, SegColorsContext, UserSettingsContextType, AppContext, AppContextType } from './contexts';
import { UserSettingsContext, SegColorsContext, UserSettingsContextType, AppContext, AppContextType, SegColorsContextType } from './contexts';
import NoFileLoaded from './NoFileLoaded';
import MediaSourcePlayer from './MediaSourcePlayer';
@ -80,7 +80,7 @@ import { adjustRate } from './util/rate-calculator';
import { askExtractFramesAsImages } from './dialogs/extractFrames';
import { askForOutDir, askForImportChapters, askForFileOpenAction, showDiskFull, showExportFailedDialog, showConcatFailedDialog, openYouTubeChaptersDialog, showRefuseToOverwrite, showOpenDialog, showMuxNotSupported, promptDownloadMediaUrl, CleanupChoicesType, showOutputNotWritable, deleteFiles, mustDisallowVob, toastError } from './dialogs';
import { openSendReportDialog } from './reporting';
import { sortSegments, convertSegmentsToChaptersWithGaps, hasAnySegmentOverlap, isDurationValid, getPlaybackAction, getSegmentTags, filterNonMarkers } from './segments';
import { sortSegments, convertSegmentsToChaptersWithGaps, hasAnySegmentOverlap, isDurationValid, getPlaybackAction, getSegmentTags, filterNonMarkers, isInitialSegment } from './segments';
import { generateCutFileNames as generateCutFileNamesRaw, generateCutMergedFileNames as generateCutMergedFileNamesRaw, generateMergedFileNames as generateMergedFileNamesRaw, defaultCutFileTemplate, defaultCutMergedFileTemplate, defaultMergedFileTemplate, GenerateMergedOutFileNamesParams, GeneratedOutFileNames } from './util/outputNameTemplate';
import { rightBarWidth, leftBarWidth, ffmpegExtractWindow, zoomMax } from './util/constants';
import BigWaveform from './components/BigWaveform';
@ -323,7 +323,7 @@ function App() {
}, [isFileOpened]);
const {
cutSegments, cutSegmentsHistory, createSegmentsFromKeyframes, shuffleSegments, detectBlackScenes, detectSilentScenes, detectSceneChanges, removeSegment, invertAllSegments, fillSegmentsGaps, combineOverlappingSegments, combineSelectedSegments, shiftAllSegmentTimes, alignSegmentTimesToKeyframes, updateSegOrder, updateSegOrders, reorderSegsByStartTime, addSegment, setCutStart, setCutEnd, labelSegment, splitCurrentSegment, focusSegmentAtCursor, selectSegmentsAtCursor, createNumSegments, createFixedDurationSegments, createFixedByteSizedSegments, createRandomSegments, haveInvalidSegs, currentSegIndexSafe, currentCutSeg, inverseCutSegments, clearSegments, clearSegColorCounter, loadCutSegments, setCutTime, setCurrentSegIndex, labelSelectedSegments, deselectAllSegments, selectAllSegments, selectOnlyCurrentSegment, toggleCurrentSegmentSelected, invertSelectedSegments, removeSelectedSegments, selectSegmentsByLabel, selectSegmentsByExpr, selectAllMarkers, mutateSegmentsByExpr, toggleSegmentSelected, selectOnlySegment, selectedSegments, segmentsOrInverse, segmentsToExport, duplicateCurrentSegment, duplicateSegment, updateSegAtIndex, findSegmentsAtCursor, maybeCreateFullLengthSegment, currentCutSegOrWholeTimeline,
cutSegments, cutSegmentsHistory, createSegmentsFromKeyframes, shuffleSegments, detectBlackScenes, detectSilentScenes, detectSceneChanges, removeSegment, invertAllSegments, fillSegmentsGaps, combineOverlappingSegments, combineSelectedSegments, shiftAllSegmentTimes, alignSegmentTimesToKeyframes, updateSegOrder, updateSegOrders, reorderSegsByStartTime, addSegment, setCutStart, setCutEnd, labelSegment, splitCurrentSegment, focusSegmentAtCursor, selectSegmentsAtCursor, createNumSegments, createFixedDurationSegments, createFixedByteSizedSegments, createRandomSegments, haveInvalidSegs, currentSegIndexSafe, currentCutSeg, inverseCutSegments, clearSegments, clearSegColorCounter, loadCutSegments, setCutTime, setCurrentSegIndex, labelSelectedSegments, deselectAllSegments, selectAllSegments, selectOnlyCurrentSegment, toggleCurrentSegmentSelected, invertSelectedSegments, removeSelectedSegments, selectSegmentsByLabel, selectSegmentsByExpr, selectAllMarkers, mutateSegmentsByExpr, toggleSegmentSelected, selectOnlySegment, selectedSegments, segmentsOrInverse, segmentsToExport, duplicateCurrentSegment, duplicateSegment, updateSegAtIndex, findSegmentsAtCursor, maybeCreateFullLengthSegment, currentCutSegOrWholeTimeline, segColorCounter,
} = useSegments({ filePath, workingRef, setWorking, setProgress, videoStream: activeVideoStream, fileDuration, getRelevantTime, maxLabelLength, checkFileOpened, invertCutSegments, segmentsToChaptersOnly, timecodePlaceholder, parseTimecode, appendFfmpegCommandLog, fileDurationNonZero, mainFileMeta, seekAbs, activeVideoStreamIndex, activeAudioStreamIndexes, handleError, showGenericDialog });
const { getEdlFilePath, projectFileSavePath, getProjectFileSavePath } = useSegmentsAutoSave({ autoSaveProjectFile, storeProjectInWorkingDir, filePath, customOutDir, cutSegments });
@ -463,12 +463,13 @@ function App() {
};
}, [allUserSettings, changeOutDir, effectiveExportMode, toggleCaptureFormat, toggleExportConfirmEnabled, toggleKeyframeCut, toggleSafeOutputFileName, toggleSimpleMode]);
const segColorsContext = useMemo(() => ({
const segColorsContext = useMemo<SegColorsContextType>(() => ({
getSegColor: (seg: SegmentColorIndex | undefined) => {
const color = getSegColor(seg);
return preferStrongColors ? color.desaturate(0.2) : color.desaturate(0.6);
},
}), [preferStrongColors]);
nextSegColorIndex: isInitialSegment(cutSegments) ? segColorCounter : segColorCounter + 1,
}), [cutSegments, preferStrongColors, segColorCounter]);
const onActiveSubtitleChange = useCallback(async (index?: number) => {
if (index == null) {

@ -16,7 +16,7 @@ import { saveColor, controlsBackground, primaryTextColor, darkModeTransition } f
import { useSegColors } from './contexts';
import { getSegmentTags } from './segments';
import TagEditor from './components/TagEditor';
import { ContextMenuTemplate, DefiniteSegmentBase, FormatTimecode, GetFrameCount, InverseCutSegment, SegmentBase, SegmentTags, StateSegment } from './types';
import { ContextMenuTemplate, DefiniteSegmentBase, FormatTimecode, GetFrameCount, InverseCutSegment, SegmentBase, SegmentColorIndex, SegmentTags, StateSegment } from './types';
import { UseSegments } from './hooks/useSegments';
import * as Dialog from './components/Dialog';
import { DialogButton } from './components/Button';
@ -363,14 +363,15 @@ function SegmentList({
onEditSegmentTags: (index: number) => void,
}) {
const { t } = useTranslation();
const { getSegColor } = useSegColors();
const { getSegColor, nextSegColorIndex } = useSegColors();
const [draggingId, setDraggingId] = useState<UniqueIdentifier | undefined>();
const { invertCutSegments, simpleMode, darkMode, springAnimation } = useUserSettings();
const getButtonColor = useCallback((seg: StateSegment | undefined, next?: boolean) => getSegColor(seg ? { segColorIndex: next ? seg.segColorIndex + 1 : seg.segColorIndex } : undefined).desaturate(0.3).lightness(darkMode ? 45 : 55).string(), [darkMode, getSegColor]);
const getButtonColor = useCallback((seg: SegmentColorIndex | undefined, next?: boolean) => getSegColor(seg ? { segColorIndex: next ? seg.segColorIndex + 1 : seg.segColorIndex } : undefined).desaturate(0.3).lightness(darkMode ? 45 : 55).string(), [darkMode, getSegColor]);
const currentSegColor = useMemo(() => getButtonColor(currentCutSeg), [currentCutSeg, getButtonColor]);
const segAtCursorColor = useMemo(() => getButtonColor(firstSegmentAtCursor), [getButtonColor, firstSegmentAtCursor]);
const nextSegmentColor = useMemo(() => getButtonColor({ segColorIndex: nextSegColorIndex }, false), [getButtonColor, nextSegColorIndex]);
const segmentsTotal = useMemo(() => selectedSegments.reduce((acc, seg) => (seg.end == null ? 0 : seg.end - seg.start) + acc, 0), [selectedSegments]);
@ -420,7 +421,7 @@ function SegmentList({
<div style={{ display: 'flex', padding: '5px 0', alignItems: 'center', justifyContent: 'center', borderBottom: '1px solid var(--gray-6)' }}>
<FaPlus
size={24}
style={{ ...buttonBaseStyle, background: neutralButtonColor }}
style={{ ...buttonBaseStyle, background: nextSegmentColor }}
role="button"
title={t('Add segment')}
onClick={addSegment}

@ -19,8 +19,9 @@ export type UserSettingsContextType = Omit<UserSettingsRoot, 'settings'> & UserS
effectiveExportMode: ExportMode,
}
interface SegColorsContextType {
getSegColor: (seg: SegmentColorIndex | undefined) => Color
export interface SegColorsContextType {
getSegColor: (seg: SegmentColorIndex | undefined) => Color,
nextSegColorIndex: number,
}
export type HandleError = (error: GenericError) => void;

@ -62,15 +62,22 @@ function useSegments({ filePath, workingRef, setWorking, setProgress, videoStrea
const { t } = useTranslation();
// Segment related state
const [segColorCounter, setSegColorCounterState] = useState(0);
const segColorCounterRef = useRef(0);
const setSegColorCounter = useCallback((v: number) => {
segColorCounterRef.current = v;
setSegColorCounterState(v);
}, []);
const createIndexedSegment = useCallback(({ segment, incrementCount }: {
segment?: Parameters<typeof createSegment>[0],
incrementCount?: boolean,
} = {}) => {
if (incrementCount) segColorCounterRef.current += 1;
if (incrementCount) {
setSegColorCounter(segColorCounterRef.current + 1);
}
return addSegmentColorIndex(createSegment(segment), segColorCounterRef.current);
}, []);
}, [setSegColorCounter]);
const [cutSegments, setCutSegments, cutSegmentsHistory] = useStateWithHistory<StateSegment[], StateSegment[]>(
[],
@ -95,8 +102,8 @@ function useSegments({ filePath, workingRef, setWorking, setProgress, videoStrea
const clearSegColorCounter = useCallback(() => {
// eslint-disable-next-line no-param-reassign
segColorCounterRef.current = 0;
}, [segColorCounterRef]);
setSegColorCounter(0);
}, [setSegColorCounter]);
const safeSetCutSegments = useCallback((newSegmentsOrFn: StateSegment[] | ((a: StateSegment[]) => StateSegment[]), clampDuration?: number) => {
function clampValue(val: number | undefined) {
@ -1003,6 +1010,7 @@ function useSegments({ filePath, workingRef, setWorking, setProgress, videoStrea
updateSegAtIndex,
findSegmentsAtCursor,
currentCutSegOrWholeTimeline,
segColorCounter,
};
}

Loading…
Cancel
Save