1- import { memo , useState , useRef , useEffect } from "react" ;
1+ import { memo , useState , useRef , useEffect , useCallback } from "react" ;
22import { RenderQueueItem } from "./RenderQueueItem" ;
33import type { RenderJob , ResolutionPreset } from "./useRenderQueue" ;
44
5+ const RENDER_SETTINGS_KEY = "hf-studio-render-settings" ;
6+
7+ interface PersistedRenderSettings {
8+ format : "mp4" | "webm" | "mov" ;
9+ quality : "draft" | "standard" | "high" ;
10+ fps : 24 | 30 | 60 ;
11+ }
12+
13+ export function getPersistedRenderSettings ( ) : PersistedRenderSettings {
14+ try {
15+ const raw = localStorage . getItem ( RENDER_SETTINGS_KEY ) ;
16+ if ( raw ) {
17+ const parsed = JSON . parse ( raw ) ;
18+ return {
19+ format : [ "mp4" , "webm" , "mov" ] . includes ( parsed . format ) ? parsed . format : "mp4" ,
20+ quality : [ "draft" , "standard" , "high" ] . includes ( parsed . quality )
21+ ? parsed . quality
22+ : "standard" ,
23+ fps : [ 24 , 30 , 60 ] . includes ( parsed . fps ) ? parsed . fps : 30 ,
24+ } ;
25+ }
26+ } catch {
27+ /* ignore */
28+ }
29+ return { format : "mp4" , quality : "standard" , fps : 30 } ;
30+ }
31+
532export interface CompositionDimensions {
633 width : number ;
734 height : number ;
@@ -198,10 +225,19 @@ function FormatExportButton({
198225 isRendering : boolean ;
199226 compositionDimensions ?: CompositionDimensions | null ;
200227} ) {
201- const [ format , setFormat ] = useState < "mp4" | "webm" | "mov" > ( "mp4" ) ;
202- const [ quality , setQuality ] = useState < "draft" | "standard" | "high" > ( "standard" ) ;
228+ const persisted = getPersistedRenderSettings ( ) ;
229+ const [ format , setFormat ] = useState < "mp4" | "webm" | "mov" > ( persisted . format ) ;
230+ const [ quality , setQuality ] = useState < "draft" | "standard" | "high" > ( persisted . quality ) ;
203231 const [ resolution , setResolution ] = useState < ResolutionPreset | "auto" > ( "auto" ) ;
204- const [ fps , setFps ] = useState < 24 | 30 | 60 > ( 30 ) ;
232+ const [ fps , setFps ] = useState < 24 | 30 | 60 > ( persisted . fps ) ;
233+
234+ const persistSettings = useCallback ( ( f : typeof format , q : typeof quality , fp : typeof fps ) => {
235+ try {
236+ localStorage . setItem ( RENDER_SETTINGS_KEY , JSON . stringify ( { format : f , quality : q , fps : fp } ) ) ;
237+ } catch {
238+ /* ignore */
239+ }
240+ } , [ ] ) ;
205241
206242 // MOV (ProRes) is a fixed-quality codec — quality selector has no effect.
207243 const showQuality = format !== "mov" ;
@@ -228,7 +264,11 @@ function FormatExportButton({
228264 { showQuality && (
229265 < select
230266 value = { quality }
231- onChange = { ( e ) => setQuality ( e . target . value as "draft" | "standard" | "high" ) }
267+ onChange = { ( e ) => {
268+ const v = e . target . value as "draft" | "standard" | "high" ;
269+ setQuality ( v ) ;
270+ persistSettings ( format , v , fps ) ;
271+ } }
232272 disabled = { isRendering }
233273 title = { QUALITY_OPTIONS . find ( ( q ) => q . value === quality ) ?. title }
234274 className = "h-5 px-1 text-[10px] bg-neutral-800 border border-neutral-700 text-neutral-300 outline-none disabled:opacity-50"
@@ -242,7 +282,11 @@ function FormatExportButton({
242282 ) }
243283 < select
244284 value = { fps }
245- onChange = { ( e ) => setFps ( Number ( e . target . value ) as 24 | 30 | 60 ) }
285+ onChange = { ( e ) => {
286+ const v = Number ( e . target . value ) as 24 | 30 | 60 ;
287+ setFps ( v ) ;
288+ persistSettings ( format , quality , v ) ;
289+ } }
246290 disabled = { isRendering }
247291 title = "Frames per second"
248292 className = "h-5 px-1 text-[10px] bg-neutral-800 border border-neutral-700 text-neutral-300 outline-none disabled:opacity-50"
@@ -253,7 +297,11 @@ function FormatExportButton({
253297 </ select >
254298 < select
255299 value = { format }
256- onChange = { ( e ) => setFormat ( e . target . value as "mp4" | "webm" | "mov" ) }
300+ onChange = { ( e ) => {
301+ const v = e . target . value as "mp4" | "webm" | "mov" ;
302+ setFormat ( v ) ;
303+ persistSettings ( v , quality , fps ) ;
304+ } }
257305 disabled = { isRendering }
258306 className = "h-5 px-1 text-[10px] bg-neutral-800 border border-neutral-700 text-neutral-300 outline-none disabled:opacity-50"
259307 >
0 commit comments