diff --git a/package.json b/package.json index 965db511..a9800080 100644 --- a/package.json +++ b/package.json @@ -74,8 +74,8 @@ "@types/mime-types": "^3.0.1", "@types/morgan": "^1.9.10", "@types/node": "22.19.19", - "@types/react": "^18.3.29", - "@types/react-dom": "^18.3.7", + "@types/react": "^19.2.15", + "@types/react-dom": "^19.2.3", "@types/react-syntax-highlighter": "^15.5.13", "@types/semver": "^7.7.1", "@types/smpte-timecode": "^1.2.5", @@ -114,11 +114,11 @@ "p-map": "^7.0.4", "p-retry": "^8.0.0", "pretty-bytes": "^7.1.0", - "react": "^18.3.1", - "react-dom": "^18.3.1", + "react": "^19.2.6", + "react-dom": "^19.2.6", "react-i18next": "^17.0.8", "react-icons": "^5.6.0", - "react-leaflet": "^4.2.1", + "react-leaflet": "^5.0.0", "react-lottie-player": "^2.1.0", "react-markdown": "^10.1.0", "react-syntax-highlighter": "^16.1.1", diff --git a/src/renderer/src/App.tsx b/src/renderer/src/App.tsx index 8c532c69..b77637b3 100644 --- a/src/renderer/src/App.tsx +++ b/src/renderer/src/App.tsx @@ -167,7 +167,7 @@ function App() { // State per application launch const [ffmpegInfo, setFfmpegInfo] = useState>>(); - const lastOpenedPathRef = useRef(); + const lastOpenedPathRef = useRef(undefined); const [showRightBar, setShowRightBar] = useState(true); const [lastCommandsVisible, setLastCommandsVisible] = useState(false); const [settingsVisible, setSettingsVisible] = useState(false); @@ -372,7 +372,7 @@ function App() { const segmentsAtCursor = useMemo(() => findSegmentsAtCursor(commandedTime).map((index) => cutSegments[index]), [commandedTime, cutSegments, findSegmentsAtCursor]); const firstSegmentAtCursor = useMemo(() => segmentsAtCursor[0], [segmentsAtCursor]); - const segmentAtCursorRef = useRef(); + const segmentAtCursorRef = useRef(undefined); useEffect(() => { segmentAtCursorRef.current = firstSegmentAtCursor; }, [firstSegmentAtCursor]); diff --git a/src/renderer/src/MediaSourcePlayer.tsx b/src/renderer/src/MediaSourcePlayer.tsx index 9f7fb5a2..af57036a 100644 --- a/src/renderer/src/MediaSourcePlayer.tsx +++ b/src/renderer/src/MediaSourcePlayer.tsx @@ -312,7 +312,7 @@ function MediaSourcePlayer({ rotate, filePath, videoStream, audioStreams, master filePath: string, videoStream: FFprobeStream | undefined, audioStreams: FFprobeStream[], - masterVideoRef: RefObject, + masterVideoRef: RefObject, mediaSourceQuality: number, ffmpegHwaccel: FfmpegHwAccel, }) { diff --git a/src/renderer/src/Timeline.tsx b/src/renderer/src/Timeline.tsx index e4e2a8da..1983569f 100644 --- a/src/renderer/src/Timeline.tsx +++ b/src/renderer/src/Timeline.tsx @@ -158,7 +158,7 @@ function Timeline({ const timelineScrollerRef = useRef(null); const timelineScrollerSkipEventRef = useRef(false); - const timelineScrollerSkipEventDebounce = useRef<() => void>(); + const timelineScrollerSkipEventDebounce = useRef<() => void>(undefined); const timelineWrapperRef = useRef(null); const isZoomed = zoom > 1; @@ -278,7 +278,7 @@ function Timeline({ return (relX / target.offsetWidth) * fileDurationNonZero; }, [fileDurationNonZero]); - const mouseDownRef = useRef(); + const mouseDownRef = useRef(undefined); useEffect(() => { setHoveringTime(undefined); @@ -290,7 +290,7 @@ function Timeline({ currentCutSegRef.current = currentCutSeg; }, [currentCutSeg]); - const resizingSegmentRef = useRef<{ operation: 'start' | 'end' | 'move', offset?: number } | undefined>(); + const resizingSegmentRef = useRef<{ operation: 'start' | 'end' | 'move', offset?: number } | undefined>(undefined); const onMouseDown = useCallback>((e) => { if (e.nativeEvent.buttons !== 1) return; // not primary button diff --git a/src/renderer/src/components/BigWaveform.tsx b/src/renderer/src/components/BigWaveform.tsx index 3a7e1c14..fd71de64 100644 --- a/src/renderer/src/components/BigWaveform.tsx +++ b/src/renderer/src/components/BigWaveform.tsx @@ -28,7 +28,7 @@ function BigWaveform({ waveforms, relevantTime, playing, fileDurationNonZero, zo const smoothTime = smoothTimeRaw ?? relevantTime; - const mouseDownRef = useRef<{ relevantTime: number, x: number }>(); + const mouseDownRef = useRef<{ relevantTime: number, x: number }>(undefined); const containerRef = useRef(null); const getRect = useCallback(() => containerRef.current!.getBoundingClientRect(), []); diff --git a/src/renderer/src/components/ExportConfirm.tsx b/src/renderer/src/components/ExportConfirm.tsx index 68c019d7..62446eb2 100644 --- a/src/renderer/src/components/ExportConfirm.tsx +++ b/src/renderer/src/components/ExportConfirm.tsx @@ -149,7 +149,7 @@ function ExportConfirm({ onClosePress: () => void, onExportConfirm: () => void, outFormat: string | undefined, - renderOutFmt: (style: CSSProperties) => JSX.Element, + renderOutFmt: (style: CSSProperties) => ReactNode, outputDir: string | undefined, numStreamsTotal: number, numStreamsToCopy: number, diff --git a/src/renderer/src/components/PlaybackStreamSelector.tsx b/src/renderer/src/components/PlaybackStreamSelector.tsx index d6b3dcf3..ccb842e2 100644 --- a/src/renderer/src/components/PlaybackStreamSelector.tsx +++ b/src/renderer/src/components/PlaybackStreamSelector.tsx @@ -32,7 +32,7 @@ function PlaybackStreamSelector({ onActiveAudioStreamsChange: (a: Set) => void, }) { const [controlVisible, setControlVisible] = useState(false); - const timeoutRef = useRef(); + const timeoutRef = useRef(undefined); const { t } = useTranslation(); diff --git a/src/renderer/src/components/TextInput.tsx b/src/renderer/src/components/TextInput.tsx index 48de0d3e..6c081a3d 100644 --- a/src/renderer/src/components/TextInput.tsx +++ b/src/renderer/src/components/TextInput.tsx @@ -1,11 +1,12 @@ -import type { CSSProperties } from 'react'; -import { forwardRef } from 'react'; +import { forwardRef, type CSSProperties, type InputHTMLAttributes } from 'react'; +type Props = InputHTMLAttributes & { style?: CSSProperties }; + const inputStyle: CSSProperties = { borderRadius: '.4em', flexGrow: 1, fontFamily: 'inherit', fontSize: '.8em', backgroundColor: 'var(--gray-3)', color: 'var(--gray-12)', border: '1px solid var(--gray-7)', appearance: 'none' }; // eslint-disable-next-line react/display-name -const TextInput = forwardRef(({ style, ...props }, forwardedRef) => ( +const TextInput = forwardRef(({ style, ...props }, forwardedRef) => ( // eslint-disable-next-line react/jsx-props-no-spreading )); diff --git a/src/renderer/src/components/VolumeControl.tsx b/src/renderer/src/components/VolumeControl.tsx index 33d50ddc..b3f76190 100644 --- a/src/renderer/src/components/VolumeControl.tsx +++ b/src/renderer/src/components/VolumeControl.tsx @@ -12,7 +12,7 @@ function VolumeControl({ playbackVolume, setPlaybackVolume, onToggleMutedClick } onToggleMutedClick: () => void, }) { const [volumeControlVisible, setVolumeControlVisible] = useState(false); - const timeoutRef = useRef(); + const timeoutRef = useRef(undefined); const { t } = useTranslation(); const actionTitle = useActionTitle(); diff --git a/src/renderer/src/hooks/useContextMenu.ts b/src/renderer/src/hooks/useContextMenu.ts index 86c13a15..d286f547 100644 --- a/src/renderer/src/hooks/useContextMenu.ts +++ b/src/renderer/src/hooks/useContextMenu.ts @@ -7,7 +7,7 @@ import type { ContextMenuTemplate } from '../types'; // https://github.com/transflow/use-electron-context-menu export default function useContextMenu( - ref: RefObject, + ref: RefObject, template: ContextMenuTemplate, ) { const { openMenu, closeMenu } = useNativeMenu(template); diff --git a/src/renderer/src/hooks/useKeyboard.ts b/src/renderer/src/hooks/useKeyboard.ts index a1598dff..7192f584 100644 --- a/src/renderer/src/hooks/useKeyboard.ts +++ b/src/renderer/src/hooks/useKeyboard.ts @@ -88,12 +88,12 @@ export default ({ keyBindings, keyUpActions, getKeyboardAction, closeExportConfi // optimization to prevent re-binding all the time: - const onKeyDownRef = useRef<(a: KeyEventParams) => void>(); + const onKeyDownRef = useRef<(a: KeyEventParams) => void>(undefined); useEffect(() => { onKeyDownRef.current = onKeyDown2; }, [onKeyDown2]); - const onKeyUpRef = useRef<(a: KeyEventParams) => void>(); + const onKeyUpRef = useRef<(a: KeyEventParams) => void>(undefined); useEffect(() => { onKeyUpRef.current = onKeyUp2; }, [onKeyUp2]); diff --git a/src/renderer/src/hooks/useKeyframes.ts b/src/renderer/src/hooks/useKeyframes.ts index 8758a874..97d39aa9 100644 --- a/src/renderer/src/hooks/useKeyframes.ts +++ b/src/renderer/src/hooks/useKeyframes.ts @@ -27,7 +27,7 @@ function useKeyframes({ keyframesEnabled, filePath, commandedTime, videoStream, }) { const { t } = useTranslation(); - const readingKeyframesPromise = useRef>(); + const readingKeyframesPromise = useRef>(undefined); const [neighbouringKeyFramesMap, setNeighbouringKeyFrames] = useState>({}); const neighbouringKeyFrames = useMemo(() => Object.values(neighbouringKeyFramesMap), [neighbouringKeyFramesMap]); diff --git a/src/renderer/src/hooks/useSegmentsAutoSave.ts b/src/renderer/src/hooks/useSegmentsAutoSave.ts index e5cc4a2b..bb139ab5 100644 --- a/src/renderer/src/hooks/useSegmentsAutoSave.ts +++ b/src/renderer/src/hooks/useSegmentsAutoSave.ts @@ -32,7 +32,7 @@ export default ({ autoSaveProjectFile, storeProjectInWorkingDir, filePath, custo // NOTE: Could lose a save if user closes too fast, but not a big issue I think const [debouncedSaveOperation] = useDebounce(currentSaveOperation, isDev ? 2000 : 500); - const lastSaveOperation = useRef(); + const lastSaveOperation = useRef(undefined); useEffect(() => { async function save() { diff --git a/src/renderer/src/hooks/useVideo.ts b/src/renderer/src/hooks/useVideo.ts index 6a964af5..457ea09c 100644 --- a/src/renderer/src/hooks/useVideo.ts +++ b/src/renderer/src/hooks/useVideo.ts @@ -9,7 +9,7 @@ export default ({ filePath }: { filePath: string | undefined }) => { const [outputPlaybackRate, setOutputPlaybackRateState] = useState(1); const [playerTime, setPlayerTime] = useState(); const [playbackMode, setPlaybackModeState] = useState(); - const playbackModeRef = useRef(); + const playbackModeRef = useRef(undefined); const setPlaybackMode = useCallback((mode: PlaybackMode | undefined) => { playbackModeRef.current = mode; @@ -34,7 +34,7 @@ export default ({ filePath }: { filePath: string | undefined }) => { // https://kitchen.vibbio.com/blog/optimizing-html5-video-scrubbing/ const seekingRef = useRef(undefined); - const seekToRef = useRef(); + const seekToRef = useRef(undefined); const smoothSeek = useCallback((seekTo: number) => { if (seekingRef.current) { diff --git a/src/renderer/src/hooks/useWaveform.ts b/src/renderer/src/hooks/useWaveform.ts index 3433507e..aa60cec5 100644 --- a/src/renderer/src/hooks/useWaveform.ts +++ b/src/renderer/src/hooks/useWaveform.ts @@ -22,7 +22,7 @@ export default ({ filePath, relevantTime, fileDuration, waveformEnabled, audioSt }) => { const [waveforms, setWaveforms] = useState([]); const [overviewWaveform, setOverviewWaveform] = useState(); - const waveformsRef = useRef(); + const waveformsRef = useRef(undefined); useEffect(() => { waveformsRef.current = waveforms; diff --git a/yarn.lock b/yarn.lock index 693ae0ed..cd947150 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3628,14 +3628,14 @@ __metadata: languageName: node linkType: hard -"@react-leaflet/core@npm:^2.1.0": - version: 2.1.0 - resolution: "@react-leaflet/core@npm:2.1.0" +"@react-leaflet/core@npm:^3.0.0": + version: 3.0.0 + resolution: "@react-leaflet/core@npm:3.0.0" peerDependencies: leaflet: ^1.9.0 - react: ^18.0.0 - react-dom: ^18.0.0 - checksum: 10/12ce28b85cf6712a1a7b7c49466b941fc619bc7b1535308bc5711a35f7e89eb16298babfd62f6b3a92e64abf94dcf517b2bc460f59fcf20599821bc6ab3b3048 + react: ^19.0.0 + react-dom: ^19.0.0 + checksum: 10/193f4928ff609a922493f05e2f301f53a3d9b8387e90fc6ab4bc4f78f97272cad000fbdf0f1d23069f67cb35d3d855734ce5a5feab98619aebfc3334be2967c7 languageName: node linkType: hard @@ -4595,13 +4595,6 @@ __metadata: languageName: node linkType: hard -"@types/prop-types@npm:*": - version: 15.7.4 - resolution: "@types/prop-types@npm:15.7.4" - checksum: 10/ef6e1899e59b876c273811b1bd845022fc66d5a3d11cb38a25b6c566b30514ae38fe20a40f67622f362a4f4f7f9224e22d8da101cff3d6e97e11d7b4c307cfc1 - languageName: node - linkType: hard - "@types/qs@npm:*": version: 6.9.14 resolution: "@types/qs@npm:6.9.14" @@ -4616,12 +4609,12 @@ __metadata: languageName: node linkType: hard -"@types/react-dom@npm:^18.3.7": - version: 18.3.7 - resolution: "@types/react-dom@npm:18.3.7" +"@types/react-dom@npm:^19.2.3": + version: 19.2.3 + resolution: "@types/react-dom@npm:19.2.3" peerDependencies: - "@types/react": ^18.0.0 - checksum: 10/317569219366d487a3103ba1e5e47154e95a002915fdcf73a44162c48fe49c3a57fcf7f57fc6979e70d447112681e6b13c6c3c1df289db8b544df4aab2d318f3 + "@types/react": ^19.2.0 + checksum: 10/616c4a8aee250ea05fb1e7b98e7e00475dd3a6c1c30d7be18b4b93caba832f4203106b3a496a6b147e5acc2da14575eca47bce234c633bca1f8430ef8ffb234a languageName: node linkType: hard @@ -4634,13 +4627,12 @@ __metadata: languageName: node linkType: hard -"@types/react@npm:*, @types/react@npm:^18.3.29": - version: 18.3.29 - resolution: "@types/react@npm:18.3.29" +"@types/react@npm:*, @types/react@npm:^19.2.15": + version: 19.2.15 + resolution: "@types/react@npm:19.2.15" dependencies: - "@types/prop-types": "npm:*" csstype: "npm:^3.2.2" - checksum: 10/1630416dbca8097bc56bb2f7e51208a7d696ed704c58bb3f0470eb982852f1af6d95d5c658eec51d7a5adae6587679d7d81b531b676dfcb405164e32feee6b4b + checksum: 10/f77447366a94804feea450568f7ebdadc00155457b4c74240972a73601294b09f45cac4e1a28aa97bc01da9ed130bb5fe9a687835d4da6307d457f92530acc3a languageName: node linkType: hard @@ -10063,7 +10055,7 @@ __metadata: languageName: node linkType: hard -"loose-envify@npm:^1.1.0, loose-envify@npm:^1.4.0": +"loose-envify@npm:^1.4.0": version: 1.4.0 resolution: "loose-envify@npm:1.4.0" dependencies: @@ -10109,8 +10101,8 @@ __metadata: "@types/mime-types": "npm:^3.0.1" "@types/morgan": "npm:^1.9.10" "@types/node": "npm:22.19.19" - "@types/react": "npm:^18.3.29" - "@types/react-dom": "npm:^18.3.7" + "@types/react": "npm:^19.2.15" + "@types/react-dom": "npm:^19.2.3" "@types/react-syntax-highlighter": "npm:^15.5.13" "@types/semver": "npm:^7.7.1" "@types/smpte-timecode": "npm:^1.2.5" @@ -10164,11 +10156,11 @@ __metadata: p-map: "npm:^7.0.4" p-retry: "npm:^8.0.0" pretty-bytes: "npm:^7.1.0" - react: "npm:^18.3.1" - react-dom: "npm:^18.3.1" + react: "npm:^19.2.6" + react-dom: "npm:^19.2.6" react-i18next: "npm:^17.0.8" react-icons: "npm:^5.6.0" - react-leaflet: "npm:^4.2.1" + react-leaflet: "npm:^5.0.0" react-lottie-player: "npm:^2.1.0" react-markdown: "npm:^10.1.0" react-syntax-highlighter: "npm:^16.1.1" @@ -12108,15 +12100,14 @@ __metadata: languageName: node linkType: hard -"react-dom@npm:^18.3.1": - version: 18.3.1 - resolution: "react-dom@npm:18.3.1" +"react-dom@npm:^19.2.6": + version: 19.2.6 + resolution: "react-dom@npm:19.2.6" dependencies: - loose-envify: "npm:^1.1.0" - scheduler: "npm:^0.23.2" + scheduler: "npm:^0.27.0" peerDependencies: - react: ^18.3.1 - checksum: 10/3f4b73a3aa083091173b29812b10394dd06f4ac06aff410b74702cfb3aa29d7b0ced208aab92d5272919b612e5cda21aeb1d54191848cf6e46e9e354f3541f81 + react: ^19.2.6 + checksum: 10/695122e37dec3460311231ff1f9a96368d74457d4ccf60010eaebc08c3e1c47b054c9267b40d98c689ae99d0c29a340acacfd405016a954a4f11613146191e68 languageName: node linkType: hard @@ -12165,16 +12156,16 @@ __metadata: languageName: node linkType: hard -"react-leaflet@npm:^4.2.1": - version: 4.2.1 - resolution: "react-leaflet@npm:4.2.1" +"react-leaflet@npm:^5.0.0": + version: 5.0.0 + resolution: "react-leaflet@npm:5.0.0" dependencies: - "@react-leaflet/core": "npm:^2.1.0" + "@react-leaflet/core": "npm:^3.0.0" peerDependencies: leaflet: ^1.9.0 - react: ^18.0.0 - react-dom: ^18.0.0 - checksum: 10/01cee12dc32e86d0153c989894fdba1c5c50fa41ad8d712352fa616f7b0dd32844aa17bb06c66f7569133675e2946c669090b4c496610cce3fa37c22254ca89f + react: ^19.0.0 + react-dom: ^19.0.0 + checksum: 10/170bf8d83141c8406fddc8cab41608ec6938efaafa5ae08c2060f9c0739370b84ed61d809c092d9f9ea79461399519f18f1cdf06dcb0e26d61d89eda46fb30be languageName: node linkType: hard @@ -12332,16 +12323,7 @@ __metadata: languageName: node linkType: hard -"react@npm:^18.3.1": - version: 18.3.1 - resolution: "react@npm:18.3.1" - dependencies: - loose-envify: "npm:^1.1.0" - checksum: 10/261137d3f3993eaa2368a83110466fc0e558bc2c7f7ae7ca52d94f03aac945f45146bd85e5f481044db1758a1dbb57879e2fcdd33924e2dde1bdc550ce73f7bf - languageName: node - linkType: hard - -"react@npm:^19.2.5": +"react@npm:^19.2.5, react@npm:^19.2.6": version: 19.2.6 resolution: "react@npm:19.2.6" checksum: 10/205f0db93bd6c6485f94471d1c3437ae1d410f322297c76186fe4f658f88a6786bb0805e3cf8f330f24d1daa923b6b610ec63960d2461e9201bca64ca8361db9 @@ -12978,12 +12960,10 @@ __metadata: languageName: node linkType: hard -"scheduler@npm:^0.23.2": - version: 0.23.2 - resolution: "scheduler@npm:0.23.2" - dependencies: - loose-envify: "npm:^1.1.0" - checksum: 10/e8d68b89d18d5b028223edf090092846868a765a591944760942b77ea1f69b17235f7e956696efbb62c8130ab90af7e0949bfb8eba7896335507317236966bc9 +"scheduler@npm:^0.27.0": + version: 0.27.0 + resolution: "scheduler@npm:0.27.0" + checksum: 10/eab3c3a8373195173e59c147224fc30dabe6dd453f248f5e610e8458512a5a2ee3a06465dc400ebfe6d35c9f5b7f3bb6b2e41c88c86fd177c25a73e7286a1e06 languageName: node linkType: hard