From 7f76f80a5a4e3666018766bfa05d912f6b5be79a Mon Sep 17 00:00:00 2001 From: marvinoffers Date: Fri, 14 Mar 2025 12:43:28 +0100 Subject: [PATCH 1/7] base works --- .../highlighter/ClipsViewModal.tsx | 2 +- .../highlighter/ExportModal.m.less | 181 ++++++ .../highlighter/ExportModal.tsx | 558 +++++++++++++++--- .../highlighter/StreamView.tsx | 20 +- .../shared/inputs/FileInput.tsx | 16 +- app/services/highlighter/index.ts | 7 +- .../models/ai-highlighter.models.ts | 6 +- 7 files changed, 677 insertions(+), 113 deletions(-) diff --git a/app/components-react/highlighter/ClipsViewModal.tsx b/app/components-react/highlighter/ClipsViewModal.tsx index 4e73aa085be9..ccd2bf187267 100644 --- a/app/components-react/highlighter/ClipsViewModal.tsx +++ b/app/components-react/highlighter/ClipsViewModal.tsx @@ -48,7 +48,7 @@ export default function ClipsViewModal({ { trim: '60%', preview: '700px', - export: '700px', + export: 'fit-content', remove: '400px', }[modal], ); diff --git a/app/components-react/highlighter/ExportModal.m.less b/app/components-react/highlighter/ExportModal.m.less index 0d3302d9ddd9..05c0ee1c7b34 100644 --- a/app/components-react/highlighter/ExportModal.m.less +++ b/app/components-react/highlighter/ExportModal.m.less @@ -22,3 +22,184 @@ .log-in { text-align: center; } + +.modal-wrapper { + :global { + /* Hide labels */ + .ant-form-item-label, + [class*='ant-col'] .ant-form-item-label { + display: none !important; + } + + /* Hide the button addon */ + .ant-input-group-addon, + .ant-input-wrapper .ant-input-group-addon, + .ant-input-group-wrapper .ant-input-group-addon { + position: absolute; + left: 88%; + bottom: 11px; + background-color: transparent; + } + + /* Style the input */ + .ant-input, + input.ant-input, + .ant-input-disabled, + input.ant-input-disabled { + border: none !important; + background-color: transparent !important; + font-family: monospace !important; + box-shadow: none !important; + padding: 0 !important; + color: inherit !important; + } + + /* Fix overall form item spacing */ + .ant-form-item, + .ant-row.ant-form-item { + margin-bottom: 8px !important; + } + + /* Adjust column widths */ + .ant-col.ant-form-item-control { + flex: 1 1 100% !important; + max-width: 100% !important; + } + } +} + +.settings-and-progress { + width: 422px; + display: flex; + flex-direction: column; + gap: 12px; +} + +.stream-path { + font-family: monospace; + font-size: 10px; + opacity: 0.8; +} + +.thumbnail { + position: relative; + border-radius: 8px; + overflow: hidden; + max-height: 390px; + margin: 0 auto; + + --thumbHeight: 180px; + overflow-x: clip; + + height: calc(var(--thumbHeight) * 1.32); + background: var(--Day-Colors-Dark-4, #4f5e65); +} + +.thumbnail-in-progress img { + position: relative; + filter: blur(10px); +} + +.thumbnail img { + height: 100%; +} + +.thumbnail::before { + content: ''; + border-style: solid; + border-width: 1px; + border-color: #ffffff29; + border-radius: 8px; + position: absolute; + width: 100%; + height: 100%; +} +.progress-item { + position: absolute; + width: 100%; + padding: 24px; + z-index: 10; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + display: flex; + flex-direction: column; + justify-content: center; + text-align: center; +} + +.progress-item h1 { + font-size: 32px; + margin: 0; + margin-bottom: -8px; + font-weight: 600; + color: white; +} + +.progress-item p { + margin: 0; + font-size: 14px; + color: white; +} + +.is-disabled { + pointer-events: none; + opacity: 0.7; +} + +.inner-dropdown-wrapper { + position: relative; + border-radius: 8px; + width: 100%; + height: 40px; + background-color: #232d35; + padding: 4px; + padding-left: 12px; + padding-right: 14px; + display: flex; + justify-content: space-between; + align-items: center; + color: white; + cursor: pointer; +} + +.inner-item-wrapper { + position: absolute; + width: 100%; + background-color: #232d35; + padding: 4px; + border-radius: 8px; +} +.inner-dropdown-item { + color: white; + width: 100%; + height: 32px; + border-radius: 4px; + background-color: #232d35; + display: flex; + align-items: center; + padding-left: 8px; + cursor: pointer; +} + +.inner-dropdown-item.active { + background-color: #e6e8f807; + cursor: default; +} + +.inner-dropdown-item:hover { + background-color: rgba(230, 232, 248, 0.12); +} + +.dropdown-text { + font-size: 16px; + display: flex; + align-items: center; +} +.dropdown-text p { + margin: 0; + font-size: 12px; + margin-left: 8px; + opacity: 0.6; + font-size: 12px; +} diff --git a/app/components-react/highlighter/ExportModal.tsx b/app/components-react/highlighter/ExportModal.tsx index 56e2dee37a7e..63e2a9ff352c 100644 --- a/app/components-react/highlighter/ExportModal.tsx +++ b/app/components-react/highlighter/ExportModal.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect, useMemo } from 'react'; +import React, { useState, useEffect, useMemo, useRef } from 'react'; import { EExportStep, TFPS, @@ -9,7 +9,7 @@ import { Services } from 'components-react/service-provider'; import { FileInput, TextInput, ListInput } from 'components-react/shared/inputs'; import Form from 'components-react/shared/inputs/Form'; import path from 'path'; -import { Button, Progress, Alert } from 'antd'; +import { Button, Progress, Alert, Dropdown } from 'antd'; import YoutubeUpload from './YoutubeUpload'; import { RadioInput } from 'components-react/shared/inputs/RadioInput'; import { confirmAsync } from 'components-react/modals'; @@ -17,9 +17,20 @@ import { $t } from 'services/i18n'; import StorageUpload from './StorageUpload'; import { useVuex } from 'components-react/hooks'; import { initStore, useController } from '../hooks/zustand'; -import { TOrientation } from 'services/highlighter/models/ai-highlighter.models'; +import { EOrientation, TOrientation } from 'services/highlighter/models/ai-highlighter.models'; import { fileExists } from 'services/highlighter/file-utils'; - +import { SCRUB_HEIGHT, SCRUB_WIDTH, SCRUB_FRAMES } from 'services/highlighter/constants'; +import styles from './ExportModal.m.less'; +import { getCombinedClipsDuration } from './utils'; +import { formatSecondsToHMS } from './ClipPreview'; +import { set } from 'lodash'; + +type TSetting = { name: string; fps: TFPS; resolution: TResolution; preset: TPreset }; +const settings: TSetting[] = [ + { name: 'Standard', fps: 30, resolution: 1080, preset: 'fast' }, + { name: 'Best', fps: 60, resolution: 1080, preset: 'slow' }, + { name: 'Custom', fps: 30, resolution: 720, preset: 'ultrafast' }, +]; class ExportController { get service() { return Services.HighlighterService; @@ -37,6 +48,16 @@ class ExportController { ); } + getClips(streamId?: string) { + return this.service.getClips(this.service.views.clips, streamId); + } + getClipThumbnail(streamId?: string) { + return this.getClips(streamId).find(clip => clip.enabled)?.scrubSprite; + } + getDuration(streamId?: string) { + return getCombinedClipsDuration(this.getClips(streamId)); + } + dismissError() { return this.service.actions.dismissError(); } @@ -49,6 +70,9 @@ class ExportController { } setFps(value: string) { + console.log('setFPS'); + console.log(value); + this.service.actions.setFps(parseInt(value, 10) as TFPS); } @@ -60,7 +84,10 @@ class ExportController { this.service.actions.setExportFile(exportFile); } - exportCurrentFile(streamId: string | undefined, orientation: TOrientation = 'horizontal') { + exportCurrentFile( + streamId: string | undefined, + orientation: TOrientation = EOrientation.HORIZONTAL, + ) { this.service.actions.export(false, streamId, orientation); } @@ -108,10 +135,11 @@ function ExportModal({ close, streamId }: { close: () => void; streamId: string // Clear all errors when this component unmounts useEffect(() => unmount, []); - if (exportInfo.exporting) return ; - if (!exportInfo.exported) { + // if (exportInfo.exporting) return ; + if (!exportInfo.exported || exportInfo.exporting) { return (

{$t('Export Progress')}

{!exportInfo.cancelRequested && exportInfo.step === EExportStep.FrameRender && (
@@ -163,11 +193,13 @@ function ExportProgress() { function ExportOptions({ close, + isExporting, streamId, videoName, onVideoNameChange, }: { close: () => void; + isExporting: boolean; streamId: string | undefined; videoName: string; onVideoNameChange: (name: string) => void; @@ -175,6 +207,7 @@ function ExportOptions({ const { UsageStatisticsService } = Services; const { exportInfo, + cancelExport, dismissError, setResolution, setFps, @@ -183,8 +216,39 @@ function ExportOptions({ setExport, exportCurrentFile, getStreamTitle, + getClips, + getDuration, + getClipThumbnail, } = useController(ExportModalCtx); + const [currentFormat, setCurrentFormat] = useState(EOrientation.HORIZONTAL); + + function settingMatcher(initialSetting: TSetting) { + const matchingSetting = settings.find( + setting => + setting.fps === initialSetting.fps && + setting.resolution === initialSetting.resolution && + setting.preset === initialSetting.preset, + ); + if (matchingSetting) { + return matchingSetting; + } + return { + name: 'Custom', + fps: initialSetting.fps, + resolution: initialSetting.resolution, + preset: initialSetting.preset, + }; + } + const [currentSetting, setSetting] = useState( + settingMatcher({ + name: 'from default', + fps: exportInfo.fps, + resolution: exportInfo.resolution, + preset: exportInfo.preset, + }), + ); + // Video name and export file are kept in sync const [exportFile, setExportFile] = useState(getExportFileFromVideoName(videoName)); @@ -220,84 +284,267 @@ function ExportOptions({ } return ( -
-

Export Video

-
- { - onVideoNameChange(name); - setExportFile(getExportFileFromVideoName(name)); - }} - uncontrolled={false} - /> - { - setExportFile(file); - onVideoNameChange(getVideoNameFromExportFile(file)); - }} - /> - - - - {exportInfo.error && ( - - )} -
- - - - + +
+
+ {/* header */}

{$t('Export')}

{' '} +
+ +
- -
+
+
+
+
+ {' '} +

+ { + const name = e.target.value; + onVideoNameChange(name); + setExportFile(getExportFileFromVideoName(name)); + }} + style={{ + width: '100%', + border: 'none', + outline: 'none', + backgroundColor: 'transparent', + padding: 0, + color: 'inherit', + }} + /> +

+ { + setExportFile(file); + onVideoNameChange(getVideoNameFromExportFile(file)); + }} + buttonContent={} + /> +
+
+ +
+ {isExporting && ( +
+

{Math.round((exportInfo.currentFrame / exportInfo.totalFrames) * 100)}%

+

+ {exportInfo.cancelRequested ? ( + {$t('Canceling...')} + ) : ( + 'Exporting video...' + )} +

+ +
+ )} + +
+ +
+
+

+ {formatSecondsToHMS(getDuration(streamId))} | {getClips(streamId).length} clips +

+
+ setCurrentFormat(format)} + /> +
+ +
+ { + setSetting(setting); + if (setting.name !== 'Custom') { + setFps(setting.fps.toString()); + setResolution(setting.resolution.toString()); + setPreset(setting.preset); + } + }} + /> +
+ {currentSetting.name === 'Custom' && ( +
+
+

{$t('Resolution')}

+ +
+ +
+

{$t('Frame rate')}

+ +
+ +
+

{$t('File size')}

+ +
+
+ )} + + {exportInfo.error && ( + + )} +
+ {isExporting ? ( + + ) : ( + + )} +
+
{' '} +
+
+ ); } @@ -347,3 +594,142 @@ function PlatformSelect({ ); } + +function CDropdown({ + initialSetting, + disabled, + emitSettings, +}: { + initialSetting: TSetting; + disabled: boolean; + emitSettings: (settings: TSetting) => void; +}) { + const [isOpen, setIsOpen] = useState(false); + const [currentSetting, setSetting] = useState(initialSetting); + + return ( +
+ + {settings.map(setting => { + return ( +
{ + setSetting(setting); + emitSettings(setting); + setIsOpen(false); + }} + key={setting.name} + > +
+ {setting.name}{' '} + {setting.name !== 'Custom' && ( + <> +

{setting.fps}fps

{setting.resolution}p

+ + )} +
+
+ ); + })} +
+ } + trigger={['click']} + visible={isOpen} + onVisibleChange={setIsOpen} + placement="bottomLeft" + > +
setIsOpen(!isOpen)}> +
+ {currentSetting.name}{' '} + {currentSetting.name !== 'Custom' && ( + <> +

{currentSetting.fps}fps

{currentSetting.resolution}p

+ + )} +
+ +
+ +
+ ); +} + +function Toggle({ + initialState, + disabled, + emitState, +}: { + initialState: TOrientation; + disabled: boolean; + emitState: (state: TOrientation) => void; +}) { + const [currentFormat, setCurrentFormat] = useState(initialState); + + function setFormat(format: TOrientation) { + setCurrentFormat(format); + emitState(format); + } + return ( +
+ {' '} +
setFormat(EOrientation.VERTICAL)} + > +
+
{' '} +
setFormat(EOrientation.HORIZONTAL)} + > +
+
+
+ ); +} diff --git a/app/components-react/highlighter/StreamView.tsx b/app/components-react/highlighter/StreamView.tsx index 149fe4eb73e1..cf17e8c4ecb1 100644 --- a/app/components-react/highlighter/StreamView.tsx +++ b/app/components-react/highlighter/StreamView.tsx @@ -74,28 +74,10 @@ export default function StreamView({ emitSetView }: { emitSetView: (data: IViewS }); const [showModal, rawSetShowModal] = useState(null); - const [modalWidth, setModalWidth] = useState('700px'); const [clipsOfStreamAreLoading, setClipsOfStreamAreLoading] = useState(null); - // This is kind of weird, but ensures that modals stay the right - // size while the closing animation is played. This is why modal - // width has its own state. This makes sure we always set the right - // size whenever displaying a modal. function setShowModal(modal: TModalStreamView | null) { rawSetShowModal(modal); - - if (modal && modal.type) { - setModalWidth( - { - trim: '60%', - preview: '700px', - export: '700px', - remove: '400px', - upload: '400px', - requirements: '400px', - }[modal.type], - ); - } } async function previewVideo(id: string) { @@ -305,7 +287,7 @@ export default function StreamView({ emitSetView }: { emitSetView: (data: IViewS getContainer={`.${styles.streamViewRoot}`} onCancel={closeModal} footer={null} - width={modalWidth} + width={showModal?.type === 'preview' ? 700 : 'fit-content'} closable={false} visible={!!showModal} destroyOnClose={true} diff --git a/app/components-react/shared/inputs/FileInput.tsx b/app/components-react/shared/inputs/FileInput.tsx index c9fb3e4cab46..9423734f2502 100644 --- a/app/components-react/shared/inputs/FileInput.tsx +++ b/app/components-react/shared/inputs/FileInput.tsx @@ -7,7 +7,12 @@ import InputWrapper from './InputWrapper'; import { $t } from '../../../services/i18n'; type TFileInputProps = TSlobsInputProps< - { directory?: boolean; filters?: Electron.FileFilter[]; save?: boolean }, + { + directory?: boolean; + filters?: Electron.FileFilter[]; + save?: boolean; + buttonContent?: React.ReactNode; + }, string, InputProps >; @@ -53,9 +58,14 @@ export const FileInput = InputComponent((p: TFileInputProps) => { inputAttrs?.onChange(val.target.value)} - disabled + onClick={showFileDialog} value={p.value} - addonAfter={} + disabled + addonAfter={ + + } /> ); diff --git a/app/services/highlighter/index.ts b/app/services/highlighter/index.ts index 414d58cd1198..e879c34f77be 100644 --- a/app/services/highlighter/index.ts +++ b/app/services/highlighter/index.ts @@ -64,6 +64,7 @@ import { IHighlight, IHighlighterMilestone, IInput, + EOrientation, } from './models/ai-highlighter.models'; import { HighlighterViews } from './highlighter-views'; import { startRendering } from './rendering/start-rendering'; @@ -110,8 +111,8 @@ export class HighlighterService extends PersistentStatefulService Date: Fri, 14 Mar 2025 14:28:44 +0100 Subject: [PATCH 2/7] css cleanup --- .../highlighter/ExportModal.m.less | 80 +++++- .../highlighter/ExportModal.tsx | 234 ++++-------------- 2 files changed, 128 insertions(+), 186 deletions(-) diff --git a/app/components-react/highlighter/ExportModal.m.less b/app/components-react/highlighter/ExportModal.m.less index 05c0ee1c7b34..513dc63a5cca 100644 --- a/app/components-react/highlighter/ExportModal.m.less +++ b/app/components-react/highlighter/ExportModal.m.less @@ -37,7 +37,7 @@ .ant-input-group-wrapper .ant-input-group-addon { position: absolute; left: 88%; - bottom: 11px; + bottom: 24px; background-color: transparent; } @@ -75,6 +75,23 @@ gap: 12px; } +.path-wrapper { + display: flex; + justify-content: space-between; + flex-direction: column; + margin-top: 12px; + width: 100%; +} + +.custom-input { + width: 100%; + border: none; + outline: none; + background-color: transparent; + padding: 0; + color: inherit; +} + .stream-path { font-family: monospace; font-size: 10px; @@ -114,6 +131,13 @@ width: 100%; height: 100%; } + +.clip-info-wrapper { + display: flex; + justify-content: space-between; + align-items: center; +} + .progress-item { position: absolute; width: 100%; @@ -203,3 +227,57 @@ opacity: 0.6; font-size: 12px; } + +.custom-section { + width: 100%; + display: flex; + flex-direction: column; + gap: 4px; +} + +.custom-item-wrapper { + display: flex; + justify-content: space-between; + width: 100%; + padding-left: 14px; + align-items: center; +} + +.orientation-toggle { + display: flex; + padding: 4px; + gap: 4px; + border-radius: 8px; + background-color: #232d35; + cursor: pointer; + box-shadow: 0px 0px 1px 0px rgba(0, 0, 0, 0.13), 0px 1px 4px 0px rgba(0, 0, 0, 0.13); +} + +.orientation-button { + width: 32px; + height: 32px; + border-radius: 4px; + display: grid; + place-content: center; + opacity: 0.6; + background-color: transparent; + + &.active { + background-color: #2c353d; + opacity: 1; + } +} + +.vertical-icon { + width: 14px; + height: 22px; + border: 2px solid #f9f9f9; + border-radius: 3px; +} + +.horizontal-icon { + width: 22px; + height: 14px; + border: 2px solid #f9f9f9; + border-radius: 3px; +} diff --git a/app/components-react/highlighter/ExportModal.tsx b/app/components-react/highlighter/ExportModal.tsx index 63e2a9ff352c..002901a9eca6 100644 --- a/app/components-react/highlighter/ExportModal.tsx +++ b/app/components-react/highlighter/ExportModal.tsx @@ -138,7 +138,7 @@ function ExportModal({ close, streamId }: { close: () => void; streamId: string // if (exportInfo.exporting) return ; if (!exportInfo.exported || exportInfo.exporting) { return ( - void; streamId: string return ; } -function ExportProgress() { - const { exportInfo, cancelExport } = useController(ExportModalCtx); - - return ( -
-

{$t('Export Progress')}

- - {!exportInfo.cancelRequested && exportInfo.step === EExportStep.FrameRender && ( -
- {$t('Rendering Frames: %{currentFrame}/%{totalFrames}', { - currentFrame: exportInfo.currentFrame, - totalFrames: exportInfo.totalFrames, - })} -
- )} - {!exportInfo.cancelRequested && exportInfo.step === EExportStep.AudioMix && ( -
- {$t('Mixing Audio:')} - -
- )} - {exportInfo.cancelRequested && {$t('Canceling...')}} -
- -
- ); -} - -function ExportOptions({ +function ExportFlow({ close, isExporting, streamId, @@ -287,68 +246,41 @@ function ExportOptions({
- {/* header */}

{$t('Export')}

{' '} +

{$t('Export')}

{' '}
-
-
-
- {' '} -

- { - const name = e.target.value; - onVideoNameChange(name); - setExportFile(getExportFileFromVideoName(name)); - }} - style={{ - width: '100%', - border: 'none', - outline: 'none', - backgroundColor: 'transparent', - padding: 0, - color: 'inherit', - }} - /> -

- { - setExportFile(file); - onVideoNameChange(getVideoNameFromExportFile(file)); +
+

+ { + const name = e.target.value; + onVideoNameChange(name); + setExportFile(getExportFileFromVideoName(name)); }} - buttonContent={} /> -

+ + { + setExportFile(file); + onVideoNameChange(getVideoNameFromExportFile(file)); + }} + buttonContent={} + />
-
+

{formatSecondsToHMS(getDuration(streamId))} | {getClips(streamId).length} clips

- setCurrentFormat(format)} @@ -425,7 +351,7 @@ function ExportOptions({ justifyContent: 'space-between', }} > - { @@ -439,16 +365,8 @@ function ExportOptions({ />
{currentSetting.name === 'Custom' && ( -
-
+
+

{$t('Resolution')}

-
+

{$t('Frame rate')}

-
+

{$t('File size')}

- {' '} +
setFormat(EOrientation.VERTICAL)} > -
-
{' '} +
+
setFormat(EOrientation.HORIZONTAL)} > -
+
); From 0f6369b2002c6856519892851a6b20e898204243 Mon Sep 17 00:00:00 2001 From: marvinoffers Date: Mon, 17 Mar 2025 12:44:25 +0100 Subject: [PATCH 3/7] only use enabled clips --- app/components-react/highlighter/ExportModal.tsx | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/app/components-react/highlighter/ExportModal.tsx b/app/components-react/highlighter/ExportModal.tsx index 002901a9eca6..190bbb04d080 100644 --- a/app/components-react/highlighter/ExportModal.tsx +++ b/app/components-react/highlighter/ExportModal.tsx @@ -49,7 +49,7 @@ class ExportController { } getClips(streamId?: string) { - return this.service.getClips(this.service.views.clips, streamId); + return this.service.getClips(this.service.views.clips, streamId).filter(clip => clip.enabled); } getClipThumbnail(streamId?: string) { return this.getClips(streamId).find(clip => clip.enabled)?.scrubSprite; @@ -182,6 +182,9 @@ function ExportFlow({ const [currentFormat, setCurrentFormat] = useState(EOrientation.HORIZONTAL); + const [clipsLength, setClipsLength] = useState(getClips(streamId).length); + const [clipsDuration, setClipsDuration] = useState(formatSecondsToHMS(getDuration(streamId))); + function settingMatcher(initialSetting: TSetting) { const matchingSetting = settings.find( setting => @@ -293,7 +296,9 @@ function ExportFlow({ > {isExporting && (
-

{Math.round((exportInfo.currentFrame / exportInfo.totalFrames) * 100)}%

+

+ {Math.round((exportInfo.currentFrame / exportInfo.totalFrames) * 100) || 0}% +

{exportInfo.cancelRequested ? ( {$t('Canceling...')} @@ -335,7 +340,7 @@ function ExportFlow({ marginLeft: '8px', }} > - {formatSecondsToHMS(getDuration(streamId))} | {getClips(streamId).length} clips + {clipsDuration} | {clipsLength} clips

Date: Mon, 17 Mar 2025 15:54:10 +0100 Subject: [PATCH 4/7] adjusted colors --- app/components-react/highlighter/ExportModal.m.less | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/components-react/highlighter/ExportModal.m.less b/app/components-react/highlighter/ExportModal.m.less index 513dc63a5cca..eddf45f03f0d 100644 --- a/app/components-react/highlighter/ExportModal.m.less +++ b/app/components-react/highlighter/ExportModal.m.less @@ -176,14 +176,14 @@ border-radius: 8px; width: 100%; height: 40px; - background-color: #232d35; + background-color: var(--dropdown-alt-bg); padding: 4px; padding-left: 12px; padding-right: 14px; display: flex; justify-content: space-between; align-items: center; - color: white; + color: var(--title); cursor: pointer; } @@ -248,7 +248,7 @@ padding: 4px; gap: 4px; border-radius: 8px; - background-color: #232d35; + background-color: var(--dropdown-alt-bg); cursor: pointer; box-shadow: 0px 0px 1px 0px rgba(0, 0, 0, 0.13), 0px 1px 4px 0px rgba(0, 0, 0, 0.13); } @@ -263,7 +263,7 @@ background-color: transparent; &.active { - background-color: #2c353d; + background-color: var(--dropdown-bg); opacity: 1; } } @@ -271,13 +271,13 @@ .vertical-icon { width: 14px; height: 22px; - border: 2px solid #f9f9f9; + border: 2px solid var(--title); border-radius: 3px; } .horizontal-icon { width: 22px; height: 14px; - border: 2px solid #f9f9f9; + border: 2px solid var(--title); border-radius: 3px; } From ba56ccbf995fa5aa03e7d063d2a8e0fa84606a04 Mon Sep 17 00:00:00 2001 From: marvinoffers Date: Mon, 17 Mar 2025 16:20:55 +0100 Subject: [PATCH 5/7] wording fixes --- app/components-react/highlighter/ExportModal.tsx | 16 +++++++--------- app/i18n/en-US/highlighter.json | 4 +++- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/app/components-react/highlighter/ExportModal.tsx b/app/components-react/highlighter/ExportModal.tsx index 190bbb04d080..f16df7c50c07 100644 --- a/app/components-react/highlighter/ExportModal.tsx +++ b/app/components-react/highlighter/ExportModal.tsx @@ -70,9 +70,6 @@ class ExportController { } setFps(value: string) { - console.log('setFPS'); - console.log(value); - this.service.actions.setFps(parseInt(value, 10) as TFPS); } @@ -182,8 +179,8 @@ function ExportFlow({ const [currentFormat, setCurrentFormat] = useState(EOrientation.HORIZONTAL); - const [clipsLength, setClipsLength] = useState(getClips(streamId).length); - const [clipsDuration, setClipsDuration] = useState(formatSecondsToHMS(getDuration(streamId))); + const clipsAmount = getClips(streamId).length; + const clipsDuration = formatSecondsToHMS(getDuration(streamId)); function settingMatcher(initialSetting: TSetting) { const matchingSetting = settings.find( @@ -202,6 +199,7 @@ function ExportFlow({ preset: initialSetting.preset, }; } + const [currentSetting, setSetting] = useState( settingMatcher({ name: 'from default', @@ -303,7 +301,7 @@ function ExportFlow({ {exportInfo.cancelRequested ? ( {$t('Canceling...')} ) : ( - 'Exporting video...' + {$t('Exporting video...')} )}

- {clipsDuration} | {clipsLength} clips + {clipsDuration} | {$t('%{clipsAmount} clips', { clipsAmount })}

-

{$t('Frame rate')}

+

{$t('Frame Rate')}

-

{$t('File size')}

+

{$t('File Size')}

Date: Mon, 17 Mar 2025 16:26:19 +0100 Subject: [PATCH 6/7] removed change --- app/components-react/shared/inputs/FileInput.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/app/components-react/shared/inputs/FileInput.tsx b/app/components-react/shared/inputs/FileInput.tsx index 9423734f2502..6b961966ef16 100644 --- a/app/components-react/shared/inputs/FileInput.tsx +++ b/app/components-react/shared/inputs/FileInput.tsx @@ -58,7 +58,6 @@ export const FileInput = InputComponent((p: TFileInputProps) => { inputAttrs?.onChange(val.target.value)} - onClick={showFileDialog} value={p.value} disabled addonAfter={ From 8d861cd9803556686e0d11ef7c1575e6b2359aeb Mon Sep 17 00:00:00 2001 From: marvinoffers Date: Tue, 25 Mar 2025 17:35:28 +0100 Subject: [PATCH 7/7] review fixes --- .../highlighter/EducationCarousel.tsx | 7 ------- app/components-react/highlighter/ExportModal.tsx | 12 +++++------- app/components-react/highlighter/StreamCard.tsx | 1 - 3 files changed, 5 insertions(+), 15 deletions(-) diff --git a/app/components-react/highlighter/EducationCarousel.tsx b/app/components-react/highlighter/EducationCarousel.tsx index 5fc5773905b1..c2d5636a7f34 100644 --- a/app/components-react/highlighter/EducationCarousel.tsx +++ b/app/components-react/highlighter/EducationCarousel.tsx @@ -119,28 +119,24 @@ const SupportedGameModes = () => (
@@ -163,7 +159,6 @@ const Overlay = () => (
@@ -176,7 +171,6 @@ const Overlay = () => (
{' '} @@ -187,7 +181,6 @@ const Overlay = () => (
diff --git a/app/components-react/highlighter/ExportModal.tsx b/app/components-react/highlighter/ExportModal.tsx index f16df7c50c07..388b4eaaad44 100644 --- a/app/components-react/highlighter/ExportModal.tsx +++ b/app/components-react/highlighter/ExportModal.tsx @@ -23,7 +23,7 @@ import { SCRUB_HEIGHT, SCRUB_WIDTH, SCRUB_FRAMES } from 'services/highlighter/co import styles from './ExportModal.m.less'; import { getCombinedClipsDuration } from './utils'; import { formatSecondsToHMS } from './ClipPreview'; -import { set } from 'lodash'; +import cx from 'classnames'; type TSetting = { name: string; fps: TFPS; resolution: TResolution; preset: TPreset }; const settings: TSetting[] = [ @@ -132,7 +132,6 @@ function ExportModal({ close, streamId }: { close: () => void; streamId: string // Clear all errors when this component unmounts useEffect(() => unmount, []); - // if (exportInfo.exporting) return ; if (!exportInfo.exported || exportInfo.exporting) { return (
-
+

{ @@ -285,7 +284,7 @@ function ExportFlow({

clip?.streamInfo?.[stream.id]?.orderPosition === 0)?.scrubSprite || clips.find(clip => clip.scrubSprite)?.scrubSprite } - alt="" />