@@ -244,6 +244,41 @@ <h2>How to</h2>
244244 fileName : null ,
245245 lastFileName : null ,
246246 onDisconnect : null ,
247+ autoUpload : false ,
248+ autoUploadTriggered : false ,
249+ } ;
250+
251+ const applyQueryParams = ( ) => {
252+ const params = new URLSearchParams ( window . location . search ) ;
253+ const branch = params . get ( "branch" ) ;
254+ if ( branch ) {
255+ const normalized = branch . trim ( ) . toLowerCase ( ) ;
256+ if ( normalized === "dev" ) {
257+ ui . branchSelect . value = "development" ;
258+ } else if ( normalized === "main" ) {
259+ ui . branchSelect . value = "main" ;
260+ } else if ( normalized === "development" ) {
261+ ui . branchSelect . value = "development" ;
262+ }
263+ }
264+
265+ const fapParam = params . get ( "FapOS" ) || params . get ( "fapos" ) || params . get ( "track" ) ;
266+ if ( fapParam ) {
267+ const normalized = fapParam . trim ( ) . toLowerCase ( ) ;
268+ if ( normalized === "momentum" ) {
269+ ui . trackSelect . value = "momentum" ;
270+ } else if ( normalized === "momentumdev" || normalized === "momentum dev" || normalized === "momentum-dev" ) {
271+ ui . trackSelect . value = "momentum dev" ;
272+ } else if ( normalized === "unleashed" ) {
273+ ui . trackSelect . value = "unleashed" ;
274+ }
275+ }
276+
277+ const auto = params . get ( "auto" ) || params . get ( "autoupload" ) ;
278+ if ( auto ) {
279+ const normalized = auto . trim ( ) . toLowerCase ( ) ;
280+ state . autoUpload = normalized === "1" || normalized === "true" || normalized === "yes" ;
281+ }
247282 } ;
248283
249284 const encoder = new TextEncoder ( ) ;
@@ -380,6 +415,9 @@ <h2>How to</h2>
380415
381416 if ( ! state . fileData ) {
382417 fetchLatest ( ) . catch ( ( err ) => log ( `Fetch after connect failed: ${ err . message || err } ` ) ) ;
418+ } else if ( state . autoUpload && ! state . autoUploadTriggered ) {
419+ state . autoUploadTriggered = true ;
420+ upload ( ) . catch ( ( err ) => log ( `Auto upload failed: ${ err . message || err } ` ) ) ;
383421 }
384422 } catch ( err ) {
385423 await disconnect ( ) ;
@@ -402,6 +440,10 @@ <h2>How to</h2>
402440 if ( ! current || current === "/ext/apps/lab_c5.fap" || ( prevPath && current === prevPath ) ) {
403441 ui . destPath . value = `/ext/apps/${ name } ` ;
404442 }
443+ if ( state . autoUpload && state . connected && ! state . autoUploadTriggered ) {
444+ state . autoUploadTriggered = true ;
445+ upload ( ) . catch ( ( err ) => log ( `Auto upload failed: ${ err . message || err } ` ) ) ;
446+ }
405447 } ;
406448
407449 const fetchFirstAvailable = async ( urls ) => {
@@ -422,8 +464,19 @@ <h2>How to</h2>
422464
423465 const getBranch = ( ) => ui . branchSelect . value || "main" ;
424466
467+ const trackMatchesName = ( name , track ) => {
468+ const lower = name . toLowerCase ( ) ;
469+ if ( track === "momentum dev" ) {
470+ return / m o m e n t u m [ - _ ] d e v / . test ( lower ) ;
471+ }
472+ if ( track === "momentum" ) {
473+ return lower . includes ( "momentum" ) && ! / m o m e n t u m [ - _ ] d e v / . test ( lower ) ;
474+ }
475+ return lower . includes ( track ) ;
476+ } ;
477+
425478 const pickLatestFromList = ( files , track ) => {
426- const candidates = files . filter ( ( f ) => f . name && f . name . toLowerCase ( ) . includes ( track ) && f . name . toLowerCase ( ) . endsWith ( ".fap" ) ) ;
479+ const candidates = files . filter ( ( f ) => f . name && trackMatchesName ( f . name , track ) && f . name . toLowerCase ( ) . endsWith ( ".fap" ) ) ;
427480 if ( ! candidates . length ) return null ;
428481 const sorted = candidates . sort ( ( a , b ) => {
429482 const av = parseVersion ( a . name ) . version || [ ] ;
@@ -438,7 +491,7 @@ <h2>How to</h2>
438491 const res = await fetch ( apiUrl , { cache : "no-store" , headers : { Accept : "application/vnd.github+json" } } ) ;
439492 if ( ! res . ok ) throw new Error ( `GitHub API failed: ${ res . status } ${ res . statusText } ` ) ;
440493 const release = await res . json ( ) ;
441- const asset = ( release . assets || [ ] ) . find ( ( a ) => a . name && a . name . toLowerCase ( ) . includes ( track ) && a . name . endsWith ( ".fap" ) ) ;
494+ const asset = ( release . assets || [ ] ) . find ( ( a ) => a . name && trackMatchesName ( a . name , track ) && a . name . endsWith ( ".fap" ) ) ;
442495 if ( ! asset ) throw new Error ( `No .fap asset for ${ track } found in latest release` ) ;
443496 const browserUrl = asset . browser_download_url || asset . url ;
444497 const rawFallback = `https://raw.githubusercontent.com/C5Lab/projectZero/main/FLIPPER/dist/${ asset . name } ` ;
@@ -555,6 +608,7 @@ <h2>How to</h2>
555608 setStatus ( "Connect first." , true ) ;
556609 return ;
557610 }
611+ state . autoUploadTriggered = true ;
558612 const dest = ui . destPath . value . trim ( ) . replace ( / \\ \\ / g, "/" ) . replace ( / \\ / g, "/" ) || `/ext/apps/${ state . fileName } ` ;
559613 const data = state . fileData ;
560614 const chunkSize = 8192 ;
@@ -611,6 +665,7 @@ <h2>How to</h2>
611665 } catch ( err ) {
612666 setStatus ( err . message || "Upload failed" , true ) ;
613667 log ( `Error: ${ err . message || err } ` ) ;
668+ state . autoUploadTriggered = false ;
614669 } finally {
615670 ui . uploadBtn . disabled = false ;
616671 }
@@ -633,6 +688,7 @@ <h2>How to</h2>
633688 fetchLatest ( ) . catch ( ( ) => { } ) ;
634689 } ) ;
635690 // auto-fetch latest on load to reduce clicks
691+ applyQueryParams ( ) ;
636692 fetchLatest ( ) . catch ( ( ) => { } ) ;
637693 </ script >
638694</ body >
0 commit comments