mirror of
https://github.com/webadderallorg/Recordly.git
synced 2026-09-27 16:25:35 +00:00
fix: address startup review regressions
This commit is contained in:
@@ -1,11 +1,12 @@
|
||||
import { Toaster as Sonner } from "sonner";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
type ToasterProps = React.ComponentProps<typeof Sonner>;
|
||||
|
||||
const Toaster = ({ ...props }: ToasterProps) => {
|
||||
const Toaster = ({ className, ...props }: ToasterProps) => {
|
||||
return (
|
||||
<Sonner
|
||||
className="toaster group"
|
||||
className={cn("toaster group", className)}
|
||||
duration={3000}
|
||||
toastOptions={{
|
||||
classNames: {
|
||||
|
||||
@@ -1168,7 +1168,14 @@ export function SettingsPanel({
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (!isBackgroundPanel && activeEffectSection !== "scene") return;
|
||||
if (
|
||||
!isBackgroundPanel &&
|
||||
activeEffectSection !== "scene" &&
|
||||
activeEffectSection !== "frame" &&
|
||||
activeEffectSection !== "crop"
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
let mounted = true;
|
||||
(async () => {
|
||||
|
||||
@@ -103,7 +103,7 @@ export default function VideoEditor() {
|
||||
setExportPipelineModel,
|
||||
} = exportSettings;
|
||||
const exportSession = useExportSession();
|
||||
const { exporterRef, pendingExportSaveRef } = exportSession;
|
||||
const { exporterRef, exportRunIdRef, pendingExportSaveRef } = exportSession;
|
||||
const enableModernExportPipeline = useCallback(() => {
|
||||
setExportPipelineModel("modern");
|
||||
}, []);
|
||||
@@ -165,6 +165,7 @@ export default function VideoEditor() {
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
exportRunIdRef.current += 1;
|
||||
exporterRef.current?.cancel();
|
||||
exporterRef.current = null;
|
||||
const pending = pendingExportSaveRef.current;
|
||||
|
||||
@@ -83,8 +83,10 @@ export function useExportDialogActions({
|
||||
}, [videoPath, videoPlaybackRef, hasCaptionsForSidecar, settings, session, handleExport]);
|
||||
|
||||
const handleCancelExport = useCallback(() => {
|
||||
if (!session.exporterRef.current) return;
|
||||
session.exporterRef.current.cancel();
|
||||
if (!session.isExporting) return;
|
||||
session.exportRunIdRef.current += 1;
|
||||
session.exporterRef.current?.cancel();
|
||||
session.exporterRef.current = null;
|
||||
toast.info("Export canceled");
|
||||
session.clearPendingExportSave();
|
||||
session.setShowExportDropdown(false);
|
||||
|
||||
@@ -66,6 +66,7 @@ export function useExportRunner(input: ExportRunnerInput) {
|
||||
pendingExportSaveRef,
|
||||
clearPendingExportSave,
|
||||
markExportAsSaving,
|
||||
exportRunIdRef,
|
||||
} = exportSession;
|
||||
if (!videoPath) {
|
||||
toast.error("No video loaded");
|
||||
@@ -78,6 +79,10 @@ export function useExportRunner(input: ExportRunnerInput) {
|
||||
return;
|
||||
}
|
||||
|
||||
const exportRunId = exportRunIdRef.current + 1;
|
||||
exportRunIdRef.current = exportRunId;
|
||||
const exportWasCancelled = () => exportRunIdRef.current !== exportRunId;
|
||||
|
||||
setIsExporting(true);
|
||||
setExportProgress(null);
|
||||
setExportError(null);
|
||||
@@ -112,6 +117,7 @@ export function useExportRunner(input: ExportRunnerInput) {
|
||||
if (settings.format === "gif" && settings.gifConfig) {
|
||||
// GIF Export
|
||||
const { GifExporter } = await import("@/lib/exporter/gifExporter");
|
||||
if (exportWasCancelled()) return;
|
||||
const gifExporter = new GifExporter({
|
||||
videoUrl: videoPath,
|
||||
width: settings.gifConfig.width,
|
||||
@@ -141,6 +147,7 @@ export function useExportRunner(input: ExportRunnerInput) {
|
||||
|
||||
exporterRef.current = gifExporter;
|
||||
const result = await gifExporter.export();
|
||||
if (exportWasCancelled()) return;
|
||||
|
||||
if (result.success && result.blob) {
|
||||
const timestamp = Date.now();
|
||||
@@ -224,6 +231,7 @@ export function useExportRunner(input: ExportRunnerInput) {
|
||||
});
|
||||
const supportedSourceDimensions =
|
||||
await ensureSupportedMp4SourceDimensions(selectedMp4FrameRate);
|
||||
if (exportWasCancelled()) return;
|
||||
const { width: exportWidth, height: exportHeight } =
|
||||
calculateMp4ExportDimensions(
|
||||
supportedSourceDimensions.width,
|
||||
@@ -281,20 +289,20 @@ export function useExportRunner(input: ExportRunnerInput) {
|
||||
sourceAudioTrackSettings: sourceAudioTrackSettingsForExport,
|
||||
};
|
||||
|
||||
const Exporter =
|
||||
pipelineModel === "modern"
|
||||
? (await import("@/lib/exporter/modernVideoExporter"))
|
||||
.ModernVideoExporter
|
||||
: (await import("@/lib/exporter/videoExporter")).VideoExporter;
|
||||
if (exportWasCancelled()) return;
|
||||
const exporter =
|
||||
pipelineModel === "modern"
|
||||
? new (
|
||||
await import("@/lib/exporter/modernVideoExporter")
|
||||
).ModernVideoExporter({
|
||||
...exporterConfig,
|
||||
backendPreference,
|
||||
})
|
||||
: new (await import("@/lib/exporter/videoExporter")).VideoExporter(
|
||||
exporterConfig,
|
||||
);
|
||||
? new Exporter({ ...exporterConfig, backendPreference })
|
||||
: new Exporter(exporterConfig);
|
||||
|
||||
exporterRef.current = exporter;
|
||||
const result = await exporter.export();
|
||||
if (exportWasCancelled()) return;
|
||||
const smokeExportElapsedMs =
|
||||
smokeExportStartedAt !== null
|
||||
? Math.round(performance.now() - smokeExportStartedAt)
|
||||
@@ -466,6 +474,7 @@ export function useExportRunner(input: ExportRunnerInput) {
|
||||
video.currentTime = restoreTime;
|
||||
}
|
||||
} catch (error) {
|
||||
if (exportWasCancelled()) return;
|
||||
console.error("Export error:", error);
|
||||
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
||||
if (smokeExportConfig.enabled) {
|
||||
@@ -487,10 +496,12 @@ export function useExportRunner(input: ExportRunnerInput) {
|
||||
window.close();
|
||||
}
|
||||
} finally {
|
||||
setIsExporting(false);
|
||||
exporterRef.current = null;
|
||||
setShowExportDropdown(keepExportDialogOpen);
|
||||
remountPreview();
|
||||
if (!exportWasCancelled()) {
|
||||
setIsExporting(false);
|
||||
exporterRef.current = null;
|
||||
setShowExportDropdown(keepExportDialogOpen);
|
||||
remountPreview();
|
||||
}
|
||||
}
|
||||
},
|
||||
[showExportSuccessToast],
|
||||
|
||||
@@ -13,6 +13,7 @@ export function useExportSession() {
|
||||
const [exportedFilePath, setExportedFilePath] = useState<string>();
|
||||
const [hasPendingExportSave, setHasPendingExportSave] = useState(false);
|
||||
const exporterRef = useRef<CancelableExporter | null>(null);
|
||||
const exportRunIdRef = useRef(0);
|
||||
const pendingExportSaveRef = useRef<PendingExportSave | null>(null);
|
||||
|
||||
const clearPendingExportSave = useCallback(() => {
|
||||
@@ -42,6 +43,7 @@ export function useExportSession() {
|
||||
hasPendingExportSave,
|
||||
setHasPendingExportSave,
|
||||
exporterRef,
|
||||
exportRunIdRef,
|
||||
pendingExportSaveRef,
|
||||
clearPendingExportSave,
|
||||
markExportAsSaving,
|
||||
|
||||
Reference in New Issue
Block a user