diff --git a/.eslintrc.js b/.eslintrc.js index c08c3fbdf..196521403 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -17,10 +17,6 @@ module.exports = { // Many multiline lists do not have a trailing comma right now "comma-dangle": ["warn", "only-multiline"], - // Currently there are quite a lot of lines longer than 120 chars (85 ones). - // And 34 even longer than 140 chars. - "max-len": "off", - // Currently 120 warnings. "@typescript-eslint/no-explicit-any": "off", diff --git a/src/config.ts b/src/config.ts index cb977caab..1ce4ca06a 100644 --- a/src/config.ts +++ b/src/config.ts @@ -245,7 +245,11 @@ const validate = (obj: Record | null, allowParse: boolean, src: str // Validate a settings value with a validation function. Returns the final // value of the setting or `null` if it should be ignored. - const validateValue = (validation: (arg0: any, arg1: boolean, arg2: string) => any, value: Record | null, path: string) => { + const validateValue = ( + validation: (arg0: any, arg1: boolean, arg2: string) => any, + value: Record | null, + path: string + ) => { try { const newValue = validation(value, allowParse, src); return newValue === undefined ? value : newValue; diff --git a/src/main/Cutting.tsx b/src/main/Cutting.tsx index 4e1641d41..6a54b077b 100644 --- a/src/main/Cutting.tsx +++ b/src/main/Cutting.tsx @@ -1,7 +1,22 @@ import React, { useEffect } from "react"; import CuttingActions from "./CuttingActions" import Timeline from './Timeline'; -import { fetchVideoInformation, selectCurrentlyAt, selectDuration, selectIsPlaying, selectIsMuted, selectVolume, selectIsPlayPreview, selectTitle, setClickTriggered, setCurrentlyAt, setIsPlaying, setIsMuted, setVolume, setIsPlayPreview } from '../redux/videoSlice'; +import { + fetchVideoInformation, + selectCurrentlyAt, + selectDuration, + selectIsPlaying, + selectIsMuted, + selectVolume, + selectIsPlayPreview, + selectTitle, + setClickTriggered, + setCurrentlyAt, + setIsPlaying, + setIsMuted, + setVolume, + setIsPlayPreview +} from '../redux/videoSlice'; import { useTranslation } from 'react-i18next'; import { useDispatch, useSelector } from 'react-redux'; import { AppDispatch } from '../redux/store'; @@ -21,11 +36,13 @@ const Cutting: React.FC = () => { // Init redux variables const dispatch = useDispatch() - const videoURLStatus = useSelector((state: { videoState: { status: httpRequestState["status"] } }) => state.videoState.status); + const videoURLStatus = useSelector((state: { videoState: { status: httpRequestState["status"] } }) => + state.videoState.status); const error = useSelector((state: { videoState: { error: httpRequestState["error"] } }) => state.videoState.error) const duration = useSelector(selectDuration) const theme = useTheme(); - const errorReason = useSelector((state: { videoState: { errorReason: httpRequestState["errorReason"] } }) => state.videoState.errorReason) + const errorReason = useSelector((state: { videoState: { errorReason: httpRequestState["errorReason"] } }) => + state.videoState.errorReason) // Try to fetch URL from external API useEffect(() => { @@ -33,13 +50,26 @@ const Cutting: React.FC = () => { dispatch(fetchVideoInformation()) } else if (videoURLStatus === 'failed') { if (errorReason === 'workflowActive') { - dispatch(setError({error: true, errorTitle: t("error.workflowActive-errorTitle"), errorMessage: t("error.workflowActive-errorMessage"), errorIcon: LuMoreHorizontal})) + dispatch(setError({ + error: true, + errorTitle: t("error.workflowActive-errorTitle"), + errorMessage: t("error.workflowActive-errorMessage"), + errorIcon: LuMoreHorizontal + })) } else { - dispatch(setError({error: true, errorMessage: t("video.comError-text"), errorDetails: error})) + dispatch(setError({ + error: true, + errorMessage: t("video.comError-text"), + errorDetails: error + })) } } else if (videoURLStatus === 'success') { if (duration === null) { - dispatch(setError({error: true, errorMessage: t("video.durationError-text"), errorDetails: error})) + dispatch(setError({ + error: true, + errorMessage: t("video.durationError-text"), + errorDetails: error + })) } } }, [videoURLStatus, dispatch, error, t, errorReason, duration]) diff --git a/src/main/CuttingActions.tsx b/src/main/CuttingActions.tsx index 101d1475e..958a7a039 100644 --- a/src/main/CuttingActions.tsx +++ b/src/main/CuttingActions.tsx @@ -46,10 +46,30 @@ const CuttingActions: React.FC = () => { } // Maps functions to hotkeys - useHotkeys(KEYMAP.cutting.cut.key, () => dispatchAction(cut), {preventDefault: true}, [cut]); - useHotkeys(KEYMAP.cutting.delete.key, () => dispatchAction(markAsDeletedOrAlive), {preventDefault: true}, [markAsDeletedOrAlive]); - useHotkeys(KEYMAP.cutting.mergeLeft.key, () => dispatchAction(mergeLeft), {preventDefault: true}, [mergeLeft]); - useHotkeys(KEYMAP.cutting.mergeRight.key, () => dispatchAction(mergeRight), {preventDefault: true}, [mergeRight]); + useHotkeys( + KEYMAP.cutting.cut.key, + () => dispatchAction(cut), + {preventDefault: true}, + [cut] + ); + useHotkeys( + KEYMAP.cutting.delete.key, + () => dispatchAction(markAsDeletedOrAlive), + {preventDefault: true}, + [markAsDeletedOrAlive] + ); + useHotkeys( + KEYMAP.cutting.mergeLeft.key, + () => dispatchAction(mergeLeft), + {preventDefault: true}, + [mergeLeft] + ); + useHotkeys( + KEYMAP.cutting.mergeRight.key, + () => dispatchAction(mergeRight), + {preventDefault: true}, + [mergeRight] + ); const cuttingStyle = css({ display: 'flex', @@ -66,7 +86,9 @@ const CuttingActions: React.FC = () => { return (
@@ -76,19 +98,29 @@ const CuttingActions: React.FC = () => { />
@@ -126,7 +158,14 @@ interface cuttingActionsButtonInterface { * A button representing a single action a user can take while cutting * @param param0 */ -const CuttingActionsButton: React.FC = ({Icon, actionName, actionHandler, action, tooltip, ariaLabelText}) => { +const CuttingActionsButton: React.FC = ({ + Icon, + actionName, + actionHandler, + action, + tooltip, + ariaLabelText +}) => { const ref = React.useRef(null) const theme = useTheme(); @@ -156,7 +195,11 @@ interface markAsDeleteButtonInterface { /** * Button that changes its function based on context */ -const MarkAsDeletedButton : React.FC = ({actionHandler, action, hotKeyName}) => { +const MarkAsDeletedButton : React.FC = ({ + actionHandler, + action, + hotKeyName +}) => { const { t } = useTranslation(); const isCurrentSegmentAlive = useSelector(selectIsCurrentSegmentAlive) const ref = React.useRef(null) diff --git a/src/main/Finish.tsx b/src/main/Finish.tsx index 728fc6672..2c86c6c3c 100644 --- a/src/main/Finish.tsx +++ b/src/main/Finish.tsx @@ -58,7 +58,15 @@ const Finish : React.FC = () => { /** * Takes you to a different page */ -export const PageButton : React.FC<{pageNumber: number, label: string, Icon: IconType}> = ({pageNumber, label, Icon}) => { +export const PageButton : React.FC<{ + pageNumber: number, + label: string, + Icon: IconType +}> = ({ + pageNumber, + label, + Icon +}) => { const theme = useTheme(); @@ -113,7 +121,12 @@ export const CallbackButton : React.FC = () => { openCallbackUrl() } }}> - {settings.callbackSystem ? t("various.callback-button-system", {system: settings.callbackSystem}) : t("various.callback-button-generic")} + + {settings.callbackSystem ? + t("various.callback-button-system", {system: settings.callbackSystem}) : + t("various.callback-button-generic") + } +
} diff --git a/src/main/Lock.tsx b/src/main/Lock.tsx index c3dda7897..932401007 100644 --- a/src/main/Lock.tsx +++ b/src/main/Lock.tsx @@ -14,9 +14,12 @@ const Lock: React.FC = () => { const endpoint = `${settings.opencast.url}/editor/${settings.id}/lock` const dispatch = useDispatch(); - const lockingActive = useSelector((state: { videoState: { lockingActive: video["lockingActive"] } }) => state.videoState.lockingActive); - const lockRefresh = useSelector((state: { videoState: { lockRefresh: video["lockRefresh"] } }) => state.videoState.lockRefresh); - const lockState = useSelector((state: { videoState: { lockState: video["lockState"] } }) => state.videoState.lockState); + const lockingActive = useSelector((state: { videoState: { lockingActive: video["lockingActive"] } }) => + state.videoState.lockingActive); + const lockRefresh = useSelector((state: { videoState: { lockRefresh: video["lockRefresh"] } }) => + state.videoState.lockRefresh); + const lockState = useSelector((state: { videoState: { lockState: video["lockState"] } }) => + state.videoState.lockState); const lock = useSelector((state: { videoState: { lock: video["lock"] } }) => state.videoState.lock); const isEnd = useSelector(selectIsEnd) diff --git a/src/main/Metadata.tsx b/src/main/Metadata.tsx index 302d9ddfe..e44f0dc9e 100644 --- a/src/main/Metadata.tsx +++ b/src/main/Metadata.tsx @@ -5,8 +5,17 @@ import { calendarStyle, errorBoxStyle, selectFieldStyle, titleStyle, titleStyleB import { useSelector, useDispatch } from 'react-redux'; import { - fetchMetadata, postMetadata, selectCatalogs, - Catalog, MetadataField, setFieldValue, selectGetError, selectGetStatus, selectPostError, selectPostStatus, setFieldReadonly + fetchMetadata, + postMetadata, + selectCatalogs, + Catalog, + MetadataField, + setFieldValue, + selectGetError, + selectGetStatus, + selectPostError, + selectPostStatus, + setFieldReadonly } from '../redux/metadataSlice' import { Form, Field, FieldInputProps } from 'react-final-form' @@ -391,7 +400,8 @@ const Metadata: React.FC = () => { } // For these fields, the value needs to be inside an array - if (field && (field.type === "date" || field.type === "time") && Object.prototype.toString.call(returnValue) === '[object Date]') { + if (field && (field.type === "date" || field.type === "time") && + Object.prototype.toString.call(returnValue) === '[object Date]') { // If invalid date if ((isNaN(returnValue.getTime()))) { // Do nothing @@ -614,7 +624,8 @@ const Metadata: React.FC = () => { {({ input, meta }) => (
@@ -699,7 +710,9 @@ const Metadata: React.FC = () => { })} {/* -
{t("metadata.submit-helpertext", { buttonName: t("metadata.submit-button") })}
+
+ {t("metadata.submit-helpertext", { buttonName: t("metadata.submit-button") })} +
diff --git a/src/main/Save.tsx b/src/main/Save.tsx index 87346b29a..df4bd57c6 100644 --- a/src/main/Save.tsx +++ b/src/main/Save.tsx @@ -8,7 +8,12 @@ import { LuLoader, LuCheckCircle, LuAlertCircle, LuChevronLeft, LuSave, LuCheck} import { useDispatch, useSelector } from 'react-redux'; import { selectFinishState } from '../redux/finishSlice' -import { selectHasChanges, selectSegments, selectTracks, setHasChanges as videoSetHasChanges } from '../redux/videoSlice' +import { + selectHasChanges, + selectSegments, + selectTracks, + setHasChanges as videoSetHasChanges +} from '../redux/videoSlice' import { postVideoInformation, selectStatus, selectError } from '../redux/workflowPostSlice' import { CallbackButton, PageButton } from './Finish' @@ -87,7 +92,9 @@ const Save : React.FC = () => {
{t("various.error-text")}
- {postMetadataError ? t("various.error-details-text", {errorMessage: postMetadataError}) : t("various.error-text")}
+ {postMetadataError ? + t("various.error-details-text", {errorMessage: postMetadataError}) : t("various.error-text") + }
); diff --git a/src/main/SubtitleEditor.tsx b/src/main/SubtitleEditor.tsx index 8f5f08b74..8ed9155fb 100644 --- a/src/main/SubtitleEditor.tsx +++ b/src/main/SubtitleEditor.tsx @@ -39,9 +39,13 @@ const SubtitleEditor : React.FC = () => { // Prepare subtitle in redux useEffect(() => { // Parse subtitle data from Opencast - if (subtitle?.cues === undefined && captionTrack !== undefined && captionTrack.subtitle !== undefined && selectedId) { + if (subtitle?.cues === undefined && captionTrack !== undefined && captionTrack.subtitle !== undefined + && selectedId) { try { - dispatch(setSubtitle({identifier: selectedId, subtitles: { cues: parseSubtitle(captionTrack.subtitle), tags: captionTrack.tags } })) + dispatch(setSubtitle({ + identifier: selectedId, + subtitles: { cues: parseSubtitle(captionTrack.subtitle), tags: captionTrack.tags } + })) } catch (error) { if (error instanceof Error) { setGetError(error.message) diff --git a/src/main/SubtitleListEditor.tsx b/src/main/SubtitleListEditor.tsx index 3f91ffabc..931288770 100644 --- a/src/main/SubtitleListEditor.tsx +++ b/src/main/SubtitleListEditor.tsx @@ -353,7 +353,9 @@ const SubtitleListSegment = React.memo((props: subtitleListSegmentProps) => { ...(flexGapReplacementStyle(10, false)), flexGrow: '0.5', minWidth: '20px', - height: '132px', // Hackily moves buttons beyond the segment border. Specific value causes buttons from neighboring segments to overlay + // Hackily moves buttons beyond the segment border. + // Specific value causes buttons from neighboring segments to overlay. + height: '132px', visibility: 'hidden', }) @@ -382,8 +384,10 @@ const SubtitleListSegment = React.memo((props: subtitleListSegmentProps) => {
diff --git a/src/main/SubtitleSelect.tsx b/src/main/SubtitleSelect.tsx index f11fafecf..592e94581 100644 --- a/src/main/SubtitleSelect.tsx +++ b/src/main/SubtitleSelect.tsx @@ -1,6 +1,12 @@ import React, { useEffect } from "react"; import { css } from "@emotion/react"; -import { basicButtonStyle, flexGapReplacementStyle, tileButtonStyle, disableButtonAnimation, subtitleSelectStyle } from "../cssStyles"; +import { + basicButtonStyle, + flexGapReplacementStyle, + tileButtonStyle, + disableButtonAnimation, + subtitleSelectStyle +} from "../cssStyles"; import { settings, subtitleTags } from '../config' import { selectSubtitles, setSelectedSubtitleId, setSubtitle } from "../redux/subtitleSlice"; import { useDispatch, useSelector } from "react-redux"; @@ -259,7 +265,8 @@ const SubtitleAddButton: React.FC<{
setIsPlusDisplay(false)} onKeyDown={(event: React.KeyboardEvent) => { if (event.key === " " || event.key === "Enter") { setIsPlusDisplay(false) diff --git a/src/main/SubtitleTimeline.tsx b/src/main/SubtitleTimeline.tsx index 8dd6a64f9..9af7b264a 100644 --- a/src/main/SubtitleTimeline.tsx +++ b/src/main/SubtitleTimeline.tsx @@ -44,7 +44,8 @@ const SubtitleTimeline: React.FC = () => { const refTop = useRef(null); const { ref: refMini, width: widthMiniTimeline = 1 } = useResizeObserver(); - const timelineCutoutInMs = 10000 // How much of the timeline should be visible in milliseconds. Aka a specific zoom level + // How much of the timeline should be visible in milliseconds. Aka a specific zoom level + const timelineCutoutInMs = 10000 const timelineStyle = css({ position: 'relative', // Need to set position for Draggable bounds to work @@ -123,15 +124,22 @@ const SubtitleTimeline: React.FC = () => { vertical={false} horizontal={true} onEndScroll={onEndScroll} - ignoreElements={"#no-scrolling"} // dom elements with this id in the container will not trigger scrolling when dragged + // dom elements with this id in the container will not trigger scrolling when dragged + ignoreElements={"#no-scrolling"} > {/* Container. Overflows. Width based on parent times zoom level*/}
-
{/* Fake padding. TODO: Figure out a better way to pad absolutely positioned elements*/} + {/* Fake padding. TODO: Figure out a better way to pad absolutely positioned elements*/} +
- +
@@ -143,13 +151,21 @@ const SubtitleTimeline: React.FC = () => { position: 'relative', width: '100%', height: '15px', - background: `linear-gradient(to right, grey ${(currentlyAt / duration) * 100}%, lightgrey ${(currentlyAt / duration) * 100}%)`, + background: `linear-gradient(to right, grey ${(currentlyAt / duration) * 100}%, + lightgrey ${(currentlyAt / duration) * 100}%)`, borderRadius: '3px', }} ref={refMini} >
@@ -190,7 +206,13 @@ const TimelineSubtitleSegmentsList: React.FC<{timelineWidth: number}> = ({timeli
{subtitle?.cues?.map((item, i) => { return ( - + ) })}
@@ -449,7 +471,10 @@ const TimelineSubtitleSegment: React.FC<{ // margin: `${absoluteTop}px 0px 0px ${absoluteLeft}px`, // }} // > -// {"Raw use of element with controlled position. Resize and reposition in all directions" + absoluteLeft} +// +// {"Raw use of element with controlled position. +// Resize and reposition in all directions" + absoluteLeft} +// //
// // ); diff --git a/src/main/Thumbnail.tsx b/src/main/Thumbnail.tsx index 6fb8c90af..cf8277611 100644 --- a/src/main/Thumbnail.tsx +++ b/src/main/Thumbnail.tsx @@ -8,11 +8,28 @@ import { settings } from "../config"; import { basicButtonStyle, deactivatedButtonStyle, flexGapReplacementStyle, titleStyle, titleStyleBold, videosStyle, backgroundBoxStyle } from "../cssStyles"; import { Theme, useTheme } from "../themes"; -import { selectOriginalThumbnails, selectVideos, selectTracks, setHasChanges, setThumbnail, setThumbnails } from "../redux/videoSlice"; +import { + selectOriginalThumbnails, + selectVideos, + selectTracks, + setHasChanges, + setThumbnail, + setThumbnails +} from "../redux/videoSlice"; import { Track } from "../types"; import Timeline from "./Timeline"; import { - selectIsPlaying, selectIsMuted, selectVolume, selectCurrentlyAt, setIsPlaying, selectIsPlayPreview, setIsPlayPreview, setClickTriggered, setIsMuted, setVolume, setCurrentlyAt + selectIsPlaying, + selectIsMuted, + selectVolume, + selectCurrentlyAt, + setIsPlaying, + selectIsPlayPreview, + setIsPlayPreview, + setClickTriggered, + setIsMuted, + setVolume, + setCurrentlyAt } from '../redux/videoSlice' import { ThemedTooltip } from "./Tooltip"; import VideoPlayers from "./VideoPlayers"; diff --git a/src/main/Timeline.tsx b/src/main/Timeline.tsx index 6ca99eedf..cc84e5b60 100644 --- a/src/main/Timeline.tsx +++ b/src/main/Timeline.tsx @@ -82,7 +82,12 @@ const Timeline: React.FC<{ />
- +
); @@ -183,10 +188,30 @@ export const Scrubber: React.FC<{ // Callbacks for keyboard controls // TODO: Better increases and decreases than ten intervals // TODO: Additional helpful controls (e.g. jump to start/end of segment/next segment) - useHotkeys(KEYMAP.timeline.left.key, () => dispatch(setCurrentlyAt(Math.max(currentlyAt - keyboardJumpDelta, 0))), {}, [currentlyAt, keyboardJumpDelta]); - useHotkeys(KEYMAP.timeline.right.key, () => dispatch(setCurrentlyAt(Math.min(currentlyAt + keyboardJumpDelta, duration))), {}, [currentlyAt, keyboardJumpDelta, duration]); - useHotkeys(KEYMAP.timeline.increase.key, () => setKeyboardJumpDelta(keyboardJumpDelta => Math.min(keyboardJumpDelta * 10, 1000000)), {}, [keyboardJumpDelta]); - useHotkeys(KEYMAP.timeline.decrease.key, () => setKeyboardJumpDelta(keyboardJumpDelta => Math.max(keyboardJumpDelta / 10, 1)), {}, [keyboardJumpDelta]); + useHotkeys( + KEYMAP.timeline.left.key, + () => dispatch(setCurrentlyAt(Math.max(currentlyAt - keyboardJumpDelta, 0))), + {}, + [currentlyAt, keyboardJumpDelta] + ); + useHotkeys( + KEYMAP.timeline.right.key, + () => dispatch(setCurrentlyAt(Math.min(currentlyAt + keyboardJumpDelta, duration))), + {}, + [currentlyAt, keyboardJumpDelta, duration] + ); + useHotkeys( + KEYMAP.timeline.increase.key, + () => setKeyboardJumpDelta(keyboardJumpDelta => Math.min(keyboardJumpDelta * 10, 1000000)), + {}, + [keyboardJumpDelta] + ); + useHotkeys( + KEYMAP.timeline.decrease.key, + () => setKeyboardJumpDelta(keyboardJumpDelta => Math.max(keyboardJumpDelta / 10, 1)), + {}, + [keyboardJumpDelta] + ); const scrubberStyle = css({ backgroundColor: `${theme.scrubber}`, @@ -361,7 +386,8 @@ export const Waveforms: React.FC<{timelineHeight: number}> = ({timelineHeight}) const dispatch = useDispatch(); const videoURLs = useSelector(selectVideoURL) - const videoURLStatus = useSelector((state: { videoState: { status: httpRequestState["status"] } }) => state.videoState.status); + const videoURLStatus = useSelector((state: { videoState: { status: httpRequestState["status"] } }) => + state.videoState.status); const theme = useTheme(); // Update based on current fetching status @@ -410,7 +436,9 @@ export const Waveforms: React.FC<{timelineHeight: number}> = ({timelineHeight}) const file = new File([blob], blob) // Start waveform worker with blob - const waveformWorker : any = new Waveform({type: 'img', width: '2000', height: '230', samples: 100000, media: file}) + const waveformWorker : any = new Waveform({ + type: 'img', width: '2000', height: '230', samples: 100000, media: file + }) waveformWorker.onerror = (error: string) => { setWaveformWorkerError(true) diff --git a/src/main/TrackSelection.tsx b/src/main/TrackSelection.tsx index 533ad38e2..fc5a094c3 100644 --- a/src/main/TrackSelection.tsx +++ b/src/main/TrackSelection.tsx @@ -9,7 +9,15 @@ import ReactPlayer from 'react-player' import { Track } from '../types' import { useSelector, useDispatch } from 'react-redux'; import { selectVideos, setTrackEnabled } from '../redux/videoSlice' -import { backgroundBoxStyle, basicButtonStyle, customIconStyle, deactivatedButtonStyle, flexGapReplacementStyle, titleStyle, titleStyleBold } from '../cssStyles' +import { + backgroundBoxStyle, + basicButtonStyle, + customIconStyle, + deactivatedButtonStyle, + flexGapReplacementStyle, + titleStyle, + titleStyleBold +} from '../cssStyles' import { useTranslation } from 'react-i18next'; import { useTheme } from "../themes"; diff --git a/src/main/VideoControls.tsx b/src/main/VideoControls.tsx index e0ea82f9f..3200f6797 100644 --- a/src/main/VideoControls.tsx +++ b/src/main/VideoControls.tsx @@ -119,7 +119,12 @@ const PreviewMode: React.FC<{ } // Maps functions to hotkeys - useHotkeys(KEYMAP.videoPlayer.preview.key, () => switchPlayPreview(undefined), {preventDefault: true}, [isPlayPreview]); + useHotkeys( + KEYMAP.videoPlayer.preview.key, + () => switchPlayPreview(undefined), + {preventDefault: true}, + [isPlayPreview] + ); const previewModeStyle = css({ cursor: "pointer", diff --git a/src/main/VideoPlayers.tsx b/src/main/VideoPlayers.tsx index 1375f67b9..702898dcb 100644 --- a/src/main/VideoPlayers.tsx +++ b/src/main/VideoPlayers.tsx @@ -4,9 +4,21 @@ import { css } from '@emotion/react' import { useSelector, useDispatch } from 'react-redux'; import { - selectIsPlaying, selectCurrentlyAtInSeconds, setIsPlaying, selectIsMuted, selectVolume, - selectVideoURL, selectVideoCount, selectDurationInSeconds, - setPreviewTriggered, selectPreviewTriggered, setAspectRatio, selectAspectRatio, setClickTriggered, selectClickTriggered, setCurrentlyAt + selectIsPlaying, + selectCurrentlyAtInSeconds, + setIsPlaying, + selectIsMuted, + selectVolume, + selectVideoURL, + selectVideoCount, + selectDurationInSeconds, + setPreviewTriggered, + selectPreviewTriggered, + setAspectRatio, + selectAspectRatio, + setClickTriggered, + selectClickTriggered, + setCurrentlyAt } from '../redux/videoSlice' import ReactPlayer, { Config } from 'react-player' @@ -150,7 +162,9 @@ export const VideoPlayer = React.forwardRef( const [isAspectRatioUpdated, setIsAspectRatioUpdated] = useState(false); // Callback for when the video is playing - const onProgressCallback = (state: { played: number, playedSeconds: number, loaded: number, loadedSeconds: number }) => { + const onProgressCallback = (state: { + played: number, playedSeconds: number, loaded: number, loadedSeconds: number + }) => { if (isPrimary) { // Only update redux if there was a substantial change if (roundToDecimalPlace(currentlyAt, 3) !== roundToDecimalPlace(state.playedSeconds, 3) && @@ -196,7 +210,8 @@ export const VideoPlayer = React.forwardRef( const onEndedCallback = () => { if (isPrimary && currentlyAt !== 0) { dispatch(setIsPlaying(false)); - dispatch(setCurrentlyAt(duration * 1000)); // It seems onEnded is called before the full duration is reached, so we set currentlyAt to the very end + // It seems onEnded is called before the full duration is reached, so we set currentlyAt to the very end + dispatch(setCurrentlyAt(duration * 1000)); } } diff --git a/src/main/WorkflowConfiguration.tsx b/src/main/WorkflowConfiguration.tsx index 46e48138b..9fbfec41a 100644 --- a/src/main/WorkflowConfiguration.tsx +++ b/src/main/WorkflowConfiguration.tsx @@ -1,19 +1,35 @@ import React, { useEffect, useState } from "react"; import { css } from '@emotion/react' -import { basicButtonStyle, backOrContinueStyle, errorBoxStyle, flexGapReplacementStyle, spinningStyle } from '../cssStyles' +import { + basicButtonStyle, + backOrContinueStyle, + errorBoxStyle, + flexGapReplacementStyle, + spinningStyle +} from '../cssStyles' import { LuLoader, LuCheck, LuAlertCircle, LuChevronLeft, LuDatabase, LuMoreHorizontal} from "react-icons/lu"; import { useDispatch, useSelector } from 'react-redux'; -import { selectSegments, selectTracks, setHasChanges as videoSetHasChanges, selectSelectedWorkflowId } from '../redux/videoSlice' +import { + selectSegments, + selectTracks, + setHasChanges as videoSetHasChanges, + selectSelectedWorkflowId +} from '../redux/videoSlice' import { postVideoInformationWithWorkflow, selectStatus, selectError } from '../redux/workflowPostAndProcessSlice' import { PageButton } from './Finish' import { setEnd } from "../redux/endSlice"; import { useTranslation } from 'react-i18next'; -import { postMetadata, selectPostError, selectPostStatus, setHasChanges as metadataSetHasChanges } from "../redux/metadataSlice"; +import { + postMetadata, + selectPostError, + selectPostStatus, + setHasChanges as metadataSetHasChanges +} from "../redux/metadataSlice"; import { AppDispatch } from "../redux/store"; import { selectSubtitles } from "../redux/subtitleSlice"; import { serializeSubtitle } from "../util/utilityFunctions"; @@ -52,11 +68,15 @@ const WorkflowConfiguration : React.FC = () => {
{t("various.error-text")}
- {postAndProcessError ? t("various.error-details-text", {errorMessage: postAndProcessError}) : t("various.error-text")}
+ {postAndProcessError ? t("various.error-details-text", + {errorMessage: postAndProcessError}) : + t("various.error-text")}
{t("various.error-text")}
- {postMetadataError ? t("various.error-details-text", {errorMessage: postMetadataError}) : t("various.error-text")}
+ {postMetadataError ? t("various.error-details-text", + {errorMessage: postMetadataError}) : + t("various.error-text")}
); diff --git a/src/main/WorkflowSelection.tsx b/src/main/WorkflowSelection.tsx index 5102e450f..a881b7337 100644 --- a/src/main/WorkflowSelection.tsx +++ b/src/main/WorkflowSelection.tsx @@ -90,7 +90,12 @@ const WorkflowSelection : React.FC = () => { onChange={handleWorkflowSelectChange} > {workflows.map((workflow: Workflow, _index: number) => ( - + ))} } @@ -101,7 +106,9 @@ const WorkflowSelection : React.FC = () => {
{t("various.error-text")}
- {errorMessage ? t("various.error-details-text", {errorMessage: postAndProcessError}) : t("various.error-text")}
+ {errorMessage ? + t("various.error-details-text", {errorMessage: postAndProcessError}) : + t("various.error-text")}
); @@ -158,7 +165,15 @@ const WorkflowSelection : React.FC = () => { ); } -const WorkflowButton: React.FC<{stateName: string, workflowId: string, workflowDescription: string}> = ({stateName, workflowId, workflowDescription}) => { +const WorkflowButton: React.FC<{ + stateName: string, + workflowId: string, + workflowDescription: string +}> = ({ + stateName, + workflowId, + workflowDescription +}) => { // Note: Styling the Radio Button is done in WorkflowSelectRadio diff --git a/src/redux/errorSlice.ts b/src/redux/errorSlice.ts index cf3416a33..4c95e0c68 100644 --- a/src/redux/errorSlice.ts +++ b/src/redux/errorSlice.ts @@ -43,10 +43,15 @@ export const errorSlice = createSlice({ export const { setError } = errorSlice.actions // Export Selectors -export const selectIsError = (state: { errorState: { error: error["error"] }; }) => state.errorState.error -export const selectErrorTitle = (state: { errorState: { errorTitle: error["errorTitle"] }; }) => state.errorState.errorTitle -export const selectErrorMessage = (state: { errorState: { errorMessage: error["errorMessage"] }; }) => state.errorState.errorMessage -export const selectErrorDetails = (state: { errorState: { errorDetails: error["errorDetails"] }; }) => state.errorState.errorDetails -export const selectErrorIcon = (state: { errorState: { errorIcon: error["errorIcon"] }; }) => state.errorState.errorIcon +export const selectIsError = (state: { errorState: { error: error["error"] }; }) => + state.errorState.error +export const selectErrorTitle = (state: { errorState: { errorTitle: error["errorTitle"] }; }) => + state.errorState.errorTitle +export const selectErrorMessage = (state: { errorState: { errorMessage: error["errorMessage"] }; }) => + state.errorState.errorMessage +export const selectErrorDetails = (state: { errorState: { errorDetails: error["errorDetails"] }; }) => + state.errorState.errorDetails +export const selectErrorIcon = (state: { errorState: { errorIcon: error["errorIcon"] }; }) => + state.errorState.errorIcon export default errorSlice.reducer diff --git a/src/redux/finishSlice.ts b/src/redux/finishSlice.ts index 4e741a308..0795528a2 100644 --- a/src/redux/finishSlice.ts +++ b/src/redux/finishSlice.ts @@ -30,7 +30,9 @@ export const finishSlice = createSlice({ export const { setState, setPageNumber } = finishSlice.actions // Export Selectors -export const selectFinishState = (state: { finishState: { value: finish["value"]; }; }) => state.finishState.value -export const selectPageNumber = (state: { finishState: { pageNumber: finish["pageNumber"]; }; }) => state.finishState.pageNumber +export const selectFinishState = (state: { finishState: { value: finish["value"]; }; }) => + state.finishState.value +export const selectPageNumber = (state: { finishState: { pageNumber: finish["pageNumber"]; }; }) => + state.finishState.pageNumber export default finishSlice.reducer diff --git a/src/redux/mainMenuSlice.ts b/src/redux/mainMenuSlice.ts index 4969ec8be..89bfda27d 100644 --- a/src/redux/mainMenuSlice.ts +++ b/src/redux/mainMenuSlice.ts @@ -28,6 +28,7 @@ export const { setState } = mainMenuSlice.actions // The function below is called a selector and allows us to select a value from // the state. Selectors can also be defined inline where they're used instead of // in the slice file. For example: `useSelector((state) => state.counter.value)` -export const selectMainMenuState = (state: { mainMenuState: { value: mainMenu["value"]; }; }) => state.mainMenuState.value +export const selectMainMenuState = (state: { mainMenuState: { value: mainMenu["value"]; }; }) => + state.mainMenuState.value export default mainMenuSlice.reducer diff --git a/src/redux/subtitleSlice.ts b/src/redux/subtitleSlice.ts index 6c4ce43eb..d3bf64dee 100644 --- a/src/redux/subtitleSlice.ts +++ b/src/redux/subtitleSlice.ts @@ -16,7 +16,8 @@ export interface subtitle { aspectRatios: {width: number, height: number}[], // Aspect ratios of every video focusSegmentTriggered: boolean, // a segment in the timeline was clicked focusSegmentId: string, // which segment in the timeline was clicked - focusSegmentTriggered2: boolean, // a different trigger for a child component, to avoid additional rerenders from the parent + // a different trigger for a child component, to avoid additional rerenders from the parent + focusSegmentTriggered2: boolean, hasChanges: boolean // Did user make changes to metadata view since last save } @@ -78,7 +79,8 @@ export const subtitleSlice = createSlice({ state.subtitles[action.payload.identifier] = action.payload.subtitles }, setCueAtIndex: (state, action: PayloadAction<{identifier: string, cueIndex: number, newCue: SubtitleCue}>) => { - if (action.payload.cueIndex < 0 || action.payload.cueIndex >= state.subtitles[action.payload.identifier].cues.length) { + if (action.payload.cueIndex < 0 || + action.payload.cueIndex >= state.subtitles[action.payload.identifier].cues.length) { console.log("WARNING: Tried to set segment for subtitle " + action.payload.identifier + " but was out of range") return } @@ -97,7 +99,10 @@ export const subtitleSlice = createSlice({ sortSubtitle(state, action.payload.identifier) state.hasChanges = true }, - addCueAtIndex: (state, action: PayloadAction<{identifier: string, cueIndex: number, text: string, startTime: number, endTime: number}>) => { + addCueAtIndex: ( + state, + action: PayloadAction<{identifier: string, cueIndex: number, text: string, startTime: number, endTime: number}> + ) => { const startTime = action.payload.startTime >= 0 ? action.payload.startTime : 0 const cue: SubtitleCue = { id: undefined, @@ -117,7 +122,8 @@ export const subtitleSlice = createSlice({ state.subtitles[action.payload.identifier].cues.splice(0, 0, cue); } - if (action.payload.cueIndex >= 0 || action.payload.cueIndex < state.subtitles[action.payload.identifier].cues.length) { + if (action.payload.cueIndex >= 0 || + action.payload.cueIndex < state.subtitles[action.payload.identifier].cues.length) { state.subtitles[action.payload.identifier].cues.splice(action.payload.cueIndex, 0, cue); } @@ -129,7 +135,9 @@ export const subtitleSlice = createSlice({ state.hasChanges = true }, removeCue: (state, action: PayloadAction<{identifier: string, cue: SubtitleCue}>) => { - const cueIndex = state.subtitles[action.payload.identifier].cues.findIndex(i => i.idInternal === action.payload.cue.idInternal); + const cueIndex = state.subtitles[action.payload.identifier].cues.findIndex( + i => i.idInternal === action.payload.cue.idInternal + ); if (cueIndex > -1) { state.subtitles[action.payload.identifier].cues.splice(cueIndex, 1); } @@ -150,16 +158,26 @@ export const subtitleSlice = createSlice({ setFocusSegmentTriggered2: (state, action: PayloadAction) => { state.focusSegmentTriggered2 = action.payload }, - setFocusToSegmentAboveId: (state, action: PayloadAction<{identifier: string, segmentId: subtitle["focusSegmentId"]}>) => { - let cueIndex = state.subtitles[action.payload.identifier].cues.findIndex(i => i.idInternal === action.payload.segmentId); + setFocusToSegmentAboveId: ( + state, + action: PayloadAction<{identifier: string, segmentId: subtitle["focusSegmentId"]}> + ) => { + let cueIndex = state.subtitles[action.payload.identifier].cues.findIndex( + i => i.idInternal === action.payload.segmentId + ); cueIndex = cueIndex - 1 if (cueIndex < 0) { cueIndex = 0 } state.focusSegmentId = state.subtitles[action.payload.identifier].cues[cueIndex].idInternal }, - setFocusToSegmentBelowId: (state, action: PayloadAction<{identifier: string, segmentId: subtitle["focusSegmentId"]}>) => { - let cueIndex = state.subtitles[action.payload.identifier].cues.findIndex(i => i.idInternal === action.payload.segmentId); + setFocusToSegmentBelowId: ( + state, + action: PayloadAction<{identifier: string, segmentId: subtitle["focusSegmentId"]}> + ) => { + let cueIndex = state.subtitles[action.payload.identifier].cues.findIndex( + i => i.idInternal === action.payload.segmentId + ); cueIndex = cueIndex + 1 if (cueIndex >= state.subtitles[action.payload.identifier].cues.length) { cueIndex = state.subtitles[action.payload.identifier].cues.length - 1 @@ -201,12 +219,14 @@ export const selectCurrentlyAtInSeconds = (state: { subtitleState: { currentlyAt state.subtitleState.currentlyAt / 1000 export const selectClickTriggered = (state: { subtitleState: { clickTriggered: subtitle["clickTriggered"] } }) => state.subtitleState.clickTriggered -export const selectFocusSegmentTriggered = (state: { subtitleState: { focusSegmentTriggered: subtitle["focusSegmentTriggered"] } }) => - state.subtitleState.focusSegmentTriggered +export const selectFocusSegmentTriggered = + (state: { subtitleState: { focusSegmentTriggered: subtitle["focusSegmentTriggered"] } }) => + state.subtitleState.focusSegmentTriggered export const selectFocusSegmentId = (state: { subtitleState: { focusSegmentId: subtitle["focusSegmentId"] } }) => state.subtitleState.focusSegmentId -export const selectFocusSegmentTriggered2 = (state: { subtitleState: { focusSegmentTriggered2: subtitle["focusSegmentTriggered2"] } }) => - state.subtitleState.focusSegmentTriggered2 +export const selectFocusSegmentTriggered2 = + (state: { subtitleState: { focusSegmentTriggered2: subtitle["focusSegmentTriggered2"] } }) => + state.subtitleState.focusSegmentTriggered2 // Hardcoding this value to achieve a desired size for the video player // TODO: Don't hardcode this value, instead make the video player component more flexible export const selectAspectRatio = (_state: { subtitleState: { aspectRatios: subtitle["aspectRatios"] } }) => @@ -214,8 +234,9 @@ export const selectAspectRatio = (_state: { subtitleState: { aspectRatios: subti export const selectSubtitles = (state: { subtitleState: { subtitles: subtitle["subtitles"] } }) => state.subtitleState.subtitles -export const selectSelectedSubtitleId = (state: { subtitleState: { selectedSubtitleId: subtitle["selectedSubtitleId"] } }) => - state.subtitleState.selectedSubtitleId +export const selectSelectedSubtitleId = + (state: { subtitleState: { selectedSubtitleId: subtitle["selectedSubtitleId"] } }) => + state.subtitleState.selectedSubtitleId export const selectSelectedSubtitleById = (state: { subtitleState: { subtitles: subtitle["subtitles"]; selectedSubtitleId: subtitle["selectedSubtitleId"]; }; }) => state.subtitleState.subtitles[state.subtitleState.selectedSubtitleId] diff --git a/src/redux/videoSlice.ts b/src/redux/videoSlice.ts index c9c230fb0..78bb5ad2f 100644 --- a/src/redux/videoSlice.ts +++ b/src/redux/videoSlice.ts @@ -241,13 +241,16 @@ const videoSlice = createSlice({ // eslint-disable-next-line no-sequences state.videoURLs = videos.reduce((a: string[], o: { uri: string }) => (a.push(o.uri), a), []) state.videoCount = state.videoURLs.length - state.subtitlesFromOpencast = action.payload.subtitles ? state.subtitlesFromOpencast = action.payload.subtitles : [] + state.subtitlesFromOpencast = action.payload.subtitles ? + state.subtitlesFromOpencast = action.payload.subtitles : [] state.duration = action.payload.duration state.title = action.payload.title state.segments = parseSegments(action.payload.segments, action.payload.duration) state.workflows = action.payload.workflows state.waveformImages = action.payload.waveformURIs ? action.payload.waveformURIs : state.waveformImages - state.originalThumbnails = state.tracks.map((track: Track) => { return {id: track.id, uri: track.thumbnailUri} }) + state.originalThumbnails = state.tracks.map( + (track: Track) => { return {id: track.id, uri: track.thumbnailUri} } + ) state.aspectRatios = new Array(state.videoCount) state.lockingActive = action.payload.locking_active @@ -378,10 +381,10 @@ const setThumbnailHelper = (state: video, id: Track["id"], uri: Track["thumbnail } } -export const { setTrackEnabled, setIsPlaying, setIsPlayPreview, setIsMuted, setVolume, setCurrentlyAt, setCurrentlyAtInSeconds, - addSegment, setAspectRatio, setHasChanges, setWaveformImages, setThumbnails, setThumbnail, removeThumbnail, - setLock, cut, markAsDeletedOrAlive, setSelectedWorkflowIndex, mergeLeft, mergeRight, mergeAll, setPreviewTriggered, - setClickTriggered } = videoSlice.actions +export const { setTrackEnabled, setIsPlaying, setIsPlayPreview, setIsMuted, setVolume, setCurrentlyAt, + setCurrentlyAtInSeconds, addSegment, setAspectRatio, setHasChanges, setWaveformImages, setThumbnails, setThumbnail, + removeThumbnail, setLock, cut, markAsDeletedOrAlive, setSelectedWorkflowIndex, mergeLeft, mergeRight, mergeAll, + setPreviewTriggered, setClickTriggered } = videoSlice.actions // Export selectors // Selectors mainly pertaining to the video state @@ -403,8 +406,9 @@ export const selectCurrentlyAtInSeconds = (state: { videoState: { currentlyAt: v state.videoState.currentlyAt / 1000 export const selectSegments = (state: { videoState: { segments: video["segments"] } }) => state.videoState.segments -export const selectActiveSegmentIndex = (state: { videoState: { activeSegmentIndex: video["activeSegmentIndex"]; }; }) => - state.videoState.activeSegmentIndex +export const selectActiveSegmentIndex = + (state: { videoState: { activeSegmentIndex: video["activeSegmentIndex"]; }; }) => + state.videoState.activeSegmentIndex export const selectIsCurrentSegmentAlive = (state: { videoState: { segments: { [x: number]: { deleted: boolean; }; }; activeSegmentIndex: video["activeSegmentIndex"]; }; }) => !state.videoState.segments[state.videoState.activeSegmentIndex].deleted @@ -415,30 +419,40 @@ export const selectHasChanges = (state: { videoState: { hasChanges: video["hasCh state.videoState.hasChanges export const selectWaveformImages = (state: { videoState: { waveformImages: video["waveformImages"]; }; }) => state.videoState.waveformImages -export const selectOriginalThumbnails = (state: { videoState: { originalThumbnails: video["originalThumbnails"]; }; }) => - state.videoState.originalThumbnails +export const selectOriginalThumbnails = + (state: { videoState: { originalThumbnails: video["originalThumbnails"]; }; }) => + state.videoState.originalThumbnails // Selectors mainly pertaining to the information fetched from Opencast export const selectVideos = (state: { videoState: { tracks: video["tracks"] } }) => state.videoState.tracks.filter((track: Track) => track.video_stream.available === true) -export const selectVideoURL = (state: { videoState: { videoURLs: video["videoURLs"] } }) => state.videoState.videoURLs -export const selectVideoCount = (state: { videoState: { videoCount: video["videoCount"] } }) => state.videoState.videoCount -export const selectDuration = (state: { videoState: { duration: video["duration"] } }) => state.videoState.duration -export const selectDurationInSeconds = (state: { videoState: { duration: video["duration"] } }) => state.videoState.duration / 1000 -export const selectTitle = (state: { videoState: { title: video["title"] } }) => state.videoState.title -export const selectTracks = (state: { videoState: { tracks: video["tracks"] } }) => state.videoState.tracks -export const selectWorkflows = (state: { videoState: { workflows: video["workflows"] } }) => state.videoState.workflows +export const selectVideoURL = (state: { videoState: { videoURLs: video["videoURLs"] } }) => + state.videoState.videoURLs +export const selectVideoCount = (state: { videoState: { videoCount: video["videoCount"] } }) => + state.videoState.videoCount +export const selectDuration = (state: { videoState: { duration: video["duration"] } }) => + state.videoState.duration +export const selectDurationInSeconds = (state: { videoState: { duration: video["duration"] } }) => + state.videoState.duration / 1000 +export const selectTitle = (state: { videoState: { title: video["title"] } }) => + state.videoState.title +export const selectTracks = (state: { videoState: { tracks: video["tracks"] } }) => + state.videoState.tracks +export const selectWorkflows = (state: { videoState: { workflows: video["workflows"] } }) => + state.videoState.workflows export const selectAspectRatio = (state: { videoState: { aspectRatios: video["aspectRatios"] } }) => calculateTotalAspectRatio(state.videoState.aspectRatios) -export const selectSubtitlesFromOpencast = (state: { videoState: { subtitlesFromOpencast: video["subtitlesFromOpencast"]; }; }) => - state.videoState.subtitlesFromOpencast -export const selectSubtitlesFromOpencastById = (id: string) => (state: { videoState: { subtitlesFromOpencast: video["subtitlesFromOpencast"]; }; }) => { - for (const cap of state.videoState.subtitlesFromOpencast) { - if (cap.id === id) { - return cap +export const selectSubtitlesFromOpencast = + (state: { videoState: { subtitlesFromOpencast: video["subtitlesFromOpencast"]; }; }) => + state.videoState.subtitlesFromOpencast +export const selectSubtitlesFromOpencastById = (id: string) => + (state: { videoState: { subtitlesFromOpencast: video["subtitlesFromOpencast"]; }; }) => { + for (const cap of state.videoState.subtitlesFromOpencast) { + if (cap.id === id) { + return cap + } } + return undefined } - return undefined -} export default videoSlice.reducer diff --git a/src/redux/workflowPostAndProcessSlice.ts b/src/redux/workflowPostAndProcessSlice.ts index 1149096c6..eebe93aa2 100644 --- a/src/redux/workflowPostAndProcessSlice.ts +++ b/src/redux/workflowPostAndProcessSlice.ts @@ -11,7 +11,8 @@ const initialState: httpRequestState = { errorReason: 'unknown', } -export const postVideoInformationWithWorkflow = createAsyncThunk('video/postVideoInformationWithWorkflow', async (argument: PostAndProcessEditArgument) => { +export const postVideoInformationWithWorkflow = +createAsyncThunk('video/postVideoInformationWithWorkflow', async (argument: PostAndProcessEditArgument) => { if (!settings.id) { throw new Error("Missing media package identifier") } diff --git a/src/redux/workflowPostSlice.ts b/src/redux/workflowPostSlice.ts index 9dea8ba04..7481bd841 100644 --- a/src/redux/workflowPostSlice.ts +++ b/src/redux/workflowPostSlice.ts @@ -9,7 +9,8 @@ const initialState: httpRequestState = { errorReason: 'unknown', } -export const postVideoInformation = createAsyncThunk('video/postVideoInformation', async (argument: PostEditArgument) => { +export const postVideoInformation = +createAsyncThunk('video/postVideoInformation', async (argument: PostEditArgument) => { if (!settings.id) { throw new Error("Missing media package id") } diff --git a/src/themes.ts b/src/themes.ts index 7b18195f2..f30270392 100644 --- a/src/themes.ts +++ b/src/themes.ts @@ -86,7 +86,8 @@ export const lightMode: Theme = { singleKey_border: COLORS.neutral20, singleKey_boxShadow: `0 2px 2px 0px rgba(150, 150, 150, 0.2)`, invert_wave: 'invert(0%)', - inverted_text: COLORS.neutral90, // for "Generating waveform" text: in lightMode it's not inverted, so it has to be black + // for "Generating waveform" text: in lightMode it's not inverted, so it has to be black + inverted_text: COLORS.neutral90, tooltip: COLORS.neutral80, tooltip_text: COLORS.neutral05, element_outline: '2px solid transparent', @@ -103,7 +104,8 @@ export const lightMode: Theme = { background_finish_menu_icon: COLORS.neutral15, background_play_icon: COLORS.neutral70, background_preview_icon: COLORS.neutral70, - waveform_filter: 'invert(44%) sepia(8%) saturate(3893%) hue-rotate(169deg) brightness(99%) contrast(90%)', // All this just to turn the black part of the waveform image blue. Generated with: https://isotropic.co/tool/hex-color-to-css-filter/ + // All this just to turn the black part of the waveform image blue. Generated with: https://isotropic.co/tool/hex-color-to-css-filter/ + waveform_filter: 'invert(44%) sepia(8%) saturate(3893%) hue-rotate(169deg) brightness(99%) contrast(90%)', waveform_bg: '', scrubber: COLORS.neutral60, scrubber_handle: COLORS.neutral05, @@ -120,8 +122,10 @@ export const lightMode: Theme = { clock_hands: COLORS.neutral50, clock_focus: COLORS.neutral90, digit_selected: COLORS.neutral90, - text_shadow: `2px 0 ${COLORS.neutral15}, -2px 0 ${COLORS.neutral15}, 0 2px ${COLORS.neutral15}, 0 -2px ${COLORS.neutral15},` + - `1px 1px ${COLORS.neutral15}, -1px -1px ${COLORS.neutral15}, 1px -1px ${COLORS.neutral15}, -1px 1px ${COLORS.neutral15}`, + text_shadow: `2px 0 ${COLORS.neutral15}, -2px 0 ${COLORS.neutral15},` + + `0 2px ${COLORS.neutral15}, 0 -2px ${COLORS.neutral15},` + + `1px 1px ${COLORS.neutral15}, -1px -1px ${COLORS.neutral15},` + + `1px -1px ${COLORS.neutral15}, -1px 1px ${COLORS.neutral15}`, }; export const darkMode: Theme = { @@ -176,8 +180,10 @@ export const darkMode: Theme = { clock_hands: COLORS.neutral50, clock_focus: COLORS.neutral90, digit_selected: COLORS.neutral90, - text_shadow: `2px 0 ${COLORS.neutral15}, -2px 0 ${COLORS.neutral15}, 0 2px ${COLORS.neutral15}, 0 -2px ${COLORS.neutral15},` + - `1px 1px ${COLORS.neutral15}, -1px -1px ${COLORS.neutral15}, 1px -1px ${COLORS.neutral15}, -1px 1px ${COLORS.neutral15}`, + text_shadow: `2px 0 ${COLORS.neutral15}, -2px 0 ${COLORS.neutral15},` + + `0 2px ${COLORS.neutral15}, 0 -2px ${COLORS.neutral15},` + + `1px 1px ${COLORS.neutral15}, -1px -1px ${COLORS.neutral15},` + + `1px -1px ${COLORS.neutral15}, -1px 1px ${COLORS.neutral15}`, }; export const highContrastDarkMode: Theme = { diff --git a/src/types.ts b/src/types.ts index 0a9723f85..8b29b8680 100644 --- a/src/types.ts +++ b/src/types.ts @@ -49,7 +49,8 @@ export interface SubtitleCue { text: string, startTime: number, endTime: number, - tree: {children: [{type: string, value: string}]} // Odditiy of the webvtt parser. Changes to text also need to be applied to tree.children[0].value + // Odditiy of the webvtt parser. Changes to text also need to be applied to tree.children[0].value + tree: {children: [{type: string, value: string}]} // And many more }