@@ -30,6 +30,7 @@ import { blockActionName } from "../lib/undo-names";
3030import { launchesForRate , resolveLogistics } from "../lib/logistics" ;
3131import { recordRecent } from "../lib/recents" ;
3232import { createCoalescedRunner } from "../lib/coalesced-runner" ;
33+ import { bestUnlockedNonBarrelingRecipe } from "../lib/recipe-shortcuts" ;
3334import { IconProvider , useSpoilables } from "../lib/icons" ;
3435import { ModulesModal } from "../lib/modules-modal" ;
3536import { Callout } from "#/components/ui/callout.tsx" ;
@@ -156,9 +157,11 @@ function Block({ blockId }: { blockId: number }) {
156157 toast ( { message : `Extracted "${ out . name } " into a new block.` } ) ;
157158 void navigate ( { to : "/block/$id" , params : { id : String ( out . id ) } } ) ;
158159 } ;
159- const [ pickFor , setPickFor ] = useState < { name : string ; mode : "produce" | "consume" } | null > (
160- null ,
161- ) ;
160+ const [ pickFor , setPickFor ] = useState < {
161+ name : string ;
162+ mode : "produce" | "consume" ;
163+ quick ?: boolean ;
164+ } | null > ( null ) ;
162165 const [ pickMachineFor , setPickMachineFor ] = useState < string | null > ( null ) ; // recipe whose machine we're choosing
163166 const [ pickFuelFor , setPickFuelFor ] = useState < string | null > ( null ) ; // recipe whose fuel we're choosing
164167 const [ pickModulesFor , setPickModulesFor ] = useState < string | null > ( null ) ; // recipe whose modules we're editing
@@ -579,12 +582,33 @@ function Block({ blockId }: { blockId: number }) {
579582 } ) ;
580583 } ;
581584
585+ const quickRecipe = pickFor ?. quick
586+ ? bestUnlockedNonBarrelingRecipe ( picker . data ?? [ ] )
587+ : undefined ;
588+ useEffect ( ( ) => {
589+ if ( ! pickFor ?. quick || ( ! picker . isSuccess && ! picker . isError ) ) return ;
590+ if ( picker . isError ) {
591+ toast ( { message : "Could not load recipe choices." , tone : "destructive" } ) ;
592+ setPickFor ( null ) ;
593+ } else if ( quickRecipe ) add ( quickRecipe . name ) ;
594+ else {
595+ toast ( {
596+ message : `No unlocked non-barreling recipe is available for ${ res ?. display ?. [ pickFor . name ] ?? pickFor . name } .` ,
597+ } ) ;
598+ setPickFor ( null ) ;
599+ }
600+ // `add` intentionally consumes the current picker state and closes it.
601+ // eslint-disable-next-line react-hooks/exhaustive-deps
602+ } , [ pickFor ?. quick , picker . isSuccess , picker . isError , quickRecipe ?. name ] ) ;
603+
582604 // When a flow has exactly one craftable recipe, skip the picker dialog and add
583605 // it directly. A superseded recipe (its base no longer exists in-game) or one
584606 // that's already in the block still opens the dialog, so the explanation/state
585607 // stays visible rather than the click silently doing nothing.
586608 const loneRecipe =
587- pickFor && picker . data ?. length === 1 && ! picker . data [ 0 ] . superseded ? picker . data [ 0 ] : null ;
609+ pickFor && ! pickFor . quick && picker . data ?. length === 1 && ! picker . data [ 0 ] . superseded
610+ ? picker . data [ 0 ]
611+ : null ;
588612 const autoAddRecipe = loneRecipe && ! recipes . includes ( loneRecipe . name ) ? loneRecipe . name : null ;
589613 useEffect ( ( ) => {
590614 if ( autoAddRecipe ) add ( autoAddRecipe ) ;
@@ -718,6 +742,8 @@ function Block({ blockId }: { blockId: number }) {
718742 : "linked" ;
719743 const makeFor = ( name : string ) => setPickFor ( { name, mode : "produce" } ) ;
720744 const useFor = ( name : string ) => setPickFor ( { name, mode : "consume" } ) ;
745+ const quickRecipeFor = ( name : string , mode : "produce" | "consume" ) =>
746+ setPickFor ( { name, mode, quick : true } ) ;
721747 const openCtxMenu = (
722748 e : { clientX : number ; clientY : number } ,
723749 d : { name : string ; kind : string ; link : ItemLink } ,
@@ -808,6 +834,7 @@ function Block({ blockId }: { blockId: number }) {
808834 onGoalMenu = { ( e , name ) => setGoalMenu ( { x : e . clientX , y : e . clientY , name } ) }
809835 onMakeFor = { makeFor }
810836 onUseFor = { useFor }
837+ onQuickRecipeFor = { quickRecipeFor }
811838 onOpenGoalPicker = { ( ) => setGoalPicker ( { } ) }
812839 />
813840 < BalanceCard
@@ -953,7 +980,7 @@ function Block({ blockId }: { blockId: number }) {
953980 ) }
954981
955982 { /* Recipe picker — floats over everything, dismissable */ }
956- { pickFor && ! picker . isLoading && ! autoAddRecipe && (
983+ { pickFor && ! pickFor . quick && ! picker . isLoading && ! autoAddRecipe && (
957984 < RecipePickerDialog
958985 mode = { pickFor . mode }
959986 goodDisplay = { res ?. display ?. [ pickFor . name ] ?? pickFor . name }
0 commit comments