Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/i18n/locales/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,8 @@
"jumpToSegmentAbove": "Jump to segment above",
"jumpToSegmentBelow": "Jump to segment below",
"deleteSegment": "Delete segment",
"addCue": "Add segment at current time"
"addCue": "Add segment at current time",
"copyTime": "Copy the current play time into this field"
},

"subtitleVideoArea": {
Expand Down
1 change: 1 addition & 0 deletions src/main/Chapter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ const Chapter: React.FC = () => {
isChapterInputs={true}
selectSelectedSubtitleById={selectSelectedSubtitleById}
selectSelectedSubtitleId={selectSelectedSubtitleId}
selectCurrentlyAt={selectCurrentlyAt}
selectFocusSegmentId={selectFocusSegmentId}
selectFocusSegmentTriggered={selectFocusSegmentTriggered}
selectFocusSegmentTriggered2={selectFocusSegmentTriggered2}
Expand Down
1 change: 1 addition & 0 deletions src/main/SubtitleEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ const SubtitleEditor: React.FC = () => {
<SubtitleListEditor
selectSelectedSubtitleById={selectSelectedSubtitleById}
selectSelectedSubtitleId={selectSelectedSubtitleId}
selectCurrentlyAt={selectCurrentlyAt}
selectFocusSegmentId={selectFocusSegmentId}
selectFocusSegmentTriggered={selectFocusSegmentTriggered}
selectFocusSegmentTriggered2={selectFocusSegmentTriggered2}
Expand Down
87 changes: 68 additions & 19 deletions src/main/SubtitleListEditor.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { css, SerializedStyles } from "@emotion/react";
import { IconType } from "react-icons";
import { LuPlus, LuTrash } from "react-icons/lu";
import { LuCopyPlus, LuPlus, LuTrash } from "react-icons/lu";
import { memoize } from "lodash";
import React, { useRef } from "react";
import { useEffect, useState } from "react";
Expand Down Expand Up @@ -34,6 +34,7 @@ const SubtitleListEditor: React.FC<{
isChapterInputs?: boolean,
selectSelectedSubtitleById: (state: RootState) => SubtitlesInEditor,
selectSelectedSubtitleId: (state: RootState) => string,
selectCurrentlyAt: (state: RootState) => number,
selectFocusSegmentId: (state: RootState) => string,
selectFocusSegmentTriggered: (state: RootState) => boolean,
selectFocusSegmentTriggered2: (state: RootState) => boolean,
Expand All @@ -60,6 +61,7 @@ const SubtitleListEditor: React.FC<{
isChapterInputs = false,
selectSelectedSubtitleById,
selectSelectedSubtitleId,
selectCurrentlyAt,
selectFocusSegmentId,
selectFocusSegmentTriggered,
selectFocusSegmentTriggered2,
Expand Down Expand Up @@ -145,6 +147,7 @@ const SubtitleListEditor: React.FC<{
textAreaHeight={segmentTextHeight}
isFunctionButtonEnabled={isFunctionButtonEnabled}
isChapterInputs={isChapterInputs}
selectCurrentlyAt={selectCurrentlyAt}
selectFocusSegmentId={selectFocusSegmentId}
selectFocusSegmentTriggered2={selectFocusSegmentTriggered2}
addCueAtIndex={addCueAtIndex}
Expand All @@ -162,6 +165,7 @@ const SubtitleListEditor: React.FC<{
segmentTextHeight,
isFunctionButtonEnabled,
isChapterInputs,
selectCurrentlyAt,
selectFocusSegmentId,
selectFocusSegmentTriggered2,
addCueAtIndex,
Expand Down Expand Up @@ -246,6 +250,7 @@ const SubtitleListSegment : React.FC<{
textAreaHeight?: string,
isFunctionButtonEnabled?: boolean,
isChapterInputs?: boolean,
selectCurrentlyAt: (state: RootState) => number,
selectFocusSegmentId: (state: RootState) => string,
selectFocusSegmentTriggered2: (state: RootState) => boolean,
addCueAtIndex: ActionCreatorWithPayload<{
Expand All @@ -272,6 +277,7 @@ const SubtitleListSegment : React.FC<{
const textAreaHeight = props.textAreaHeight;
const isFunctionButtonEnabled = props.isFunctionButtonEnabled;
const isChapterInputs = props.isChapterInputs;
const selectCurrentlyAt = props.selectCurrentlyAt;
const selectFocusSegmentId = props.selectFocusSegmentId;
const selectFocusSegmentTriggered2 = props.selectFocusSegmentTriggered2;
const addCueAtIndex = props.addCueAtIndex;
Expand All @@ -288,6 +294,7 @@ const SubtitleListSegment : React.FC<{
const dispatch = useAppDispatch();

const duration = useAppSelector(selectDuration);
const currentlyAt = useAppSelector(selectCurrentlyAt);
// Unfortunately, the focus selectors will cause every element to rerender,
// even if they are not the ones that are focused
// However, since the number of list segments rendered is severly limited
Expand Down Expand Up @@ -512,6 +519,28 @@ const SubtitleListSegment : React.FC<{
color: `${theme.text}`,
});

const timeWrapperStyle = css({
display: "flex",
});

const timeInputStyle = css({
fontSize: "1em",
padding: "10px",
borderRight: "none",
borderRadius: "5px 0 0 5px",
background: `${theme.element_bg}`,
border: "1px solid #ccc",
color: `${theme.text}`,
});

const copyTimeButtonStyle = css({
padding: "0 8px",
border: "1px solid #ccc",
borderLeft: "none",
borderRadius: "0 5px 5px 0",
background: `${theme.element_bg}`,
});

const textFieldStyle = css({
flexGrow: "7",
height: textAreaHeight, // 80% per default
Expand Down Expand Up @@ -549,22 +578,42 @@ const SubtitleListSegment : React.FC<{

{!isChapterInputs ?
<div css={timeAreaStyle}>
<TimeInput
generalFieldStyle={[fieldStyle,
css({ ...(cue.startTime > cue.endTime && { borderColor: "red", borderWidth: "2px" }) })]}
value={cue.startTime}
changeCallback={updateCueStart}
tooltip={t("subtitleList.startTime-tooltip")}
tooltipAria={t("subtitleList.startTime-tooltip-aria") + ": " + convertMsToReadableString(cue.startTime)}
/>
<TimeInput
generalFieldStyle={[fieldStyle,
css({ ...(cue.startTime > cue.endTime && { borderColor: "red", borderWidth: "2px" }) })]}
value={cue.endTime}
changeCallback={updateCueEnd}
tooltip={t("subtitleList.endTime-tooltip")}
tooltipAria={t("subtitleList.endTime-tooltip-aria") + ": " + convertMsToReadableString(cue.endTime)}
/>
<div css={timeWrapperStyle}>
<TimeInput
generalFieldStyle={[timeInputStyle,
css({ ...(cue.startTime > cue.endTime && { borderColor: "red", borderWidth: "2px" }) })]}
value={cue.startTime}
changeCallback={updateCueStart}
tooltip={t("subtitleList.startTime-tooltip")}
tooltipAria={t("subtitleList.startTime-tooltip-aria") + ": " + convertMsToReadableString(cue.startTime)}
/>
<ThemedTooltip title={t("subtitleList.copyTime")}>
<ProtoButton
onClick={() => updateCueStart(currentlyAt)}
css={[basicButtonStyle(theme), copyTimeButtonStyle]}
>
<LuCopyPlus />
</ProtoButton>
</ThemedTooltip>
</div>
<div css={timeWrapperStyle}>
<TimeInput
generalFieldStyle={[timeInputStyle,
css({ ...(cue.startTime > cue.endTime && { borderColor: "red", borderWidth: "2px" }) })]}
value={cue.endTime}
changeCallback={updateCueEnd}
tooltip={t("subtitleList.endTime-tooltip")}
tooltipAria={t("subtitleList.endTime-tooltip-aria") + ": " + convertMsToReadableString(cue.endTime)}
/>
<ThemedTooltip title={t("subtitleList.copyTime")}>
<ProtoButton
onClick={() => updateCueEnd(currentlyAt)}
css={[basicButtonStyle(theme), copyTimeButtonStyle]}
>
<LuCopyPlus />
</ProtoButton>
</ThemedTooltip>
</div>
</div>
:
<TimeInput
Expand Down Expand Up @@ -719,8 +768,8 @@ const TimeInput: React.FC<{
};

const timeFieldStyle = css({
height: isChapterInputs ? "20px" : "20%",
width: "100px",
height: isChapterInputs ? "20px" : "16px",
width: "96px",
...(parsingError && { borderColor: "red", borderWidth: "2px" }),
});

Expand Down
Loading