Compare commits
	
		
			1 Commits
		
	
	
		
			pierremtb/
			...
			extrude-ma
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 2d350a93ed | 
| @ -72,55 +72,78 @@ function CommandBarHeader({ children }: React.PropsWithChildren<{}>) { | ||||
|                 )} | ||||
|               {selectedCommand?.name} | ||||
|             </p> | ||||
|             {Object.entries(selectedCommand?.args || {}).map( | ||||
|               ([argName, arg], i) => ( | ||||
|                 <button | ||||
|                   disabled={!isReviewing && currentArgument?.name === argName} | ||||
|                   onClick={() => { | ||||
|                     commandBarSend({ | ||||
|                       type: isReviewing | ||||
|                         ? 'Edit argument' | ||||
|                         : 'Change current argument', | ||||
|                       data: { arg: { ...arg, name: argName } }, | ||||
|                     }) | ||||
|                   }} | ||||
|                   key={argName} | ||||
|                   className={`relative w-fit px-2 py-1 rounded-sm flex gap-2 items-center border ${ | ||||
|                     argName === currentArgument?.name | ||||
|                       ? 'disabled:bg-energy-10/50 dark:disabled:bg-energy-10/20 disabled:border-energy-10 dark:disabled:border-energy-10 disabled:text-chalkboard-100 dark:disabled:text-chalkboard-10' | ||||
|                       : 'bg-chalkboard-20/50 dark:bg-chalkboard-80/50 border-chalkboard-20 dark:border-chalkboard-80' | ||||
|                   }`} | ||||
|                 > | ||||
|                   {argumentsToSubmit[argName] ? ( | ||||
|                     arg.inputType === 'selection' ? ( | ||||
|                       getSelectionTypeDisplayText( | ||||
|                         argumentsToSubmit[argName] as Selections | ||||
|                       ) | ||||
|                     ) : typeof argumentsToSubmit[argName] === 'object' ? ( | ||||
|                       JSON.stringify(argumentsToSubmit[argName]) | ||||
|                     ) : ( | ||||
|                       argumentsToSubmit[argName] | ||||
|                     ) | ||||
|                   ) : arg.payload ? ( | ||||
|                     arg.inputType === 'selection' ? ( | ||||
|                       getSelectionTypeDisplayText(arg.payload as Selections) | ||||
|                     ) : typeof arg.payload === 'object' ? ( | ||||
|                       JSON.stringify(arg.payload) | ||||
|                     ) : ( | ||||
|                       arg.payload | ||||
|                     ) | ||||
|                   ) : ( | ||||
|                     <em>{argName}</em> | ||||
|                   )} | ||||
|                   {showShortcuts && ( | ||||
|                     <small className="absolute -top-[1px] right-full translate-x-1/2 px-0.5 rounded-sm bg-chalkboard-80 text-chalkboard-10 dark:bg-energy-10 dark:text-chalkboard-100"> | ||||
|                       <span className="sr-only">Hotkey: </span> | ||||
|                       {i + 1} | ||||
|                     </small> | ||||
|                   )} | ||||
|                 </button> | ||||
|             {Object.entries(selectedCommand?.args || {}) | ||||
|               .filter(([argName, _]) => | ||||
|                 selectedCommand?.args | ||||
|                   ? selectedCommand?.args[argName]?.required || | ||||
|                     (argName in argumentsToSubmit && argumentsToSubmit[argName]) | ||||
|                   : false | ||||
|               ) | ||||
|             )} | ||||
|               .map(([argName, arg], i) => ( | ||||
|                 <div className="relative group" key={argName}> | ||||
|                   <button | ||||
|                     disabled={!isReviewing && currentArgument?.name === argName} | ||||
|                     onClick={() => { | ||||
|                       commandBarSend({ | ||||
|                         type: isReviewing | ||||
|                           ? 'Edit argument' | ||||
|                           : 'Change current argument', | ||||
|                         data: { arg: { ...arg, name: argName } }, | ||||
|                       }) | ||||
|                     }} | ||||
|                     className={`relative w-fit px-2 py-1 rounded-sm flex gap-2 items-center border ${ | ||||
|                       argName === currentArgument?.name | ||||
|                         ? 'disabled:bg-energy-10/50 dark:disabled:bg-energy-10/20 disabled:border-energy-10 dark:disabled:border-energy-10 disabled:text-chalkboard-100 dark:disabled:text-chalkboard-10' | ||||
|                         : 'bg-chalkboard-20/50 dark:bg-chalkboard-80/50 border-chalkboard-20 dark:border-chalkboard-80' | ||||
|                     }`} | ||||
|                   > | ||||
|                     {argumentsToSubmit[argName] ? ( | ||||
|                       arg.inputType === 'selection' ? ( | ||||
|                         getSelectionTypeDisplayText( | ||||
|                           argumentsToSubmit[argName] as Selections | ||||
|                         ) | ||||
|                       ) : typeof argumentsToSubmit[argName] === 'object' ? ( | ||||
|                         JSON.stringify(argumentsToSubmit[argName]) | ||||
|                       ) : ( | ||||
|                         argumentsToSubmit[argName] | ||||
|                       ) | ||||
|                     ) : arg.payload ? ( | ||||
|                       arg.inputType === 'selection' ? ( | ||||
|                         getSelectionTypeDisplayText(arg.payload as Selections) | ||||
|                       ) : typeof arg.payload === 'object' ? ( | ||||
|                         JSON.stringify(arg.payload) | ||||
|                       ) : ( | ||||
|                         arg.payload | ||||
|                       ) | ||||
|                     ) : ( | ||||
|                       <em>{argName}</em> | ||||
|                     )} | ||||
|                     {showShortcuts && ( | ||||
|                       <small className="absolute -top-[1px] right-full translate-x-1/2 px-0.5 rounded-sm bg-chalkboard-80 text-chalkboard-10 dark:bg-energy-10 dark:text-chalkboard-100"> | ||||
|                         <span className="sr-only">Hotkey: </span> | ||||
|                         {i + 1} | ||||
|                       </small> | ||||
|                     )} | ||||
|                   </button> | ||||
|                   {!arg.required && ( | ||||
|                     <button | ||||
|                       onClick={() => { | ||||
|                         commandBarSend({ | ||||
|                           type: 'Remove argument', | ||||
|                           data: { [argName]: { ...arg, name: argName } }, | ||||
|                         }) | ||||
|                       }} | ||||
|                       className="invisible group-hover:visible absolute top-0 right-0 -translate-y-1/2 !p-0 flex items-center justify-center rounded-sm border-none bg-none" | ||||
|                     > | ||||
|                       <CustomIcon | ||||
|                         name="close" | ||||
|                         className="w-4 h-4 bg-destroy-80 dark:bg-destroy-30 hover:bg-destroy-70 dark:hover:bg-destroy-0 text-destroy-10 dark:text-destroy-80" | ||||
|                       /> | ||||
|                       <span className="sr-only">Remove argument</span> | ||||
|                     </button> | ||||
|                   )} | ||||
|                 </div> | ||||
|               ))} | ||||
|           </div> | ||||
|           {isReviewing ? <ReviewingButton /> : <GatheringArgsButton />} | ||||
|         </div> | ||||
|  | ||||
| @ -1,12 +1,21 @@ | ||||
| import { useCommandsContext } from 'hooks/useCommandsContext' | ||||
| import CommandBarHeader from './CommandBarHeader' | ||||
| import { useHotkeys } from 'react-hotkeys-hook' | ||||
| import { ActionButton } from 'components/ActionButton' | ||||
|  | ||||
| function CommandBarReview({ stepBack }: { stepBack: () => void }) { | ||||
|   const { commandBarState, commandBarSend } = useCommandsContext() | ||||
|   const { | ||||
|     context: { argumentsToSubmit, selectedCommand }, | ||||
|   } = commandBarState | ||||
|   const optionalArgsNotAdded = Object.entries( | ||||
|     selectedCommand?.args || {} | ||||
|   ).filter( | ||||
|     ([key, val]) => | ||||
|       selectedCommand?.args && | ||||
|       !selectedCommand.args[key].required && | ||||
|       !argumentsToSubmit[key] | ||||
|   ) | ||||
|  | ||||
|   useHotkeys('backspace', stepBack, { | ||||
|     enableOnFormTags: true, | ||||
| @ -46,7 +55,7 @@ function CommandBarReview({ stepBack }: { stepBack: () => void }) { | ||||
|  | ||||
|   return ( | ||||
|     <CommandBarHeader> | ||||
|       <p className="px-4">Confirm {selectedCommand?.name}</p> | ||||
|       <p className="px-4 py-1">Confirm {selectedCommand?.name}</p> | ||||
|       <form | ||||
|         id="review-form" | ||||
|         className="absolute opacity-0 inset-0 pointer-events-none" | ||||
| @ -74,6 +83,41 @@ function CommandBarReview({ stepBack }: { stepBack: () => void }) { | ||||
|           ) | ||||
|         })} | ||||
|       </form> | ||||
|       {optionalArgsNotAdded.length > 0 && ( | ||||
|         <> | ||||
|           <div className="block w-full my-2 h-[1px] bg-chalkboard-20 dark:bg-chalkboard-80" /> | ||||
|           <div className="flex flex-wrap px-4 gap-2 items-center"> | ||||
|             {optionalArgsNotAdded.map(([key, _]) => { | ||||
|               const arg = selectedCommand?.args | ||||
|                 ? selectedCommand?.args[key] | ||||
|                 : undefined | ||||
|               if (!arg) return null | ||||
|  | ||||
|               return ( | ||||
|                 <ActionButton | ||||
|                   Element="button" | ||||
|                   key={key} | ||||
|                   className="text-xs [&:not(:hover)]:border-transparent gap-0.5" | ||||
|                   onClick={() => { | ||||
|                     commandBarSend({ | ||||
|                       type: 'Edit argument', | ||||
|                       data: { arg: { ...arg, name: key } }, | ||||
|                     }) | ||||
|                   }} | ||||
|                   icon={{ | ||||
|                     icon: 'plus', | ||||
|                     bgClassName: '!bg-transparent', | ||||
|                     iconClassName: | ||||
|                       'text-chalkboard-10 dark:text-chalkboard-100', | ||||
|                   }} | ||||
|                 > | ||||
|                   {key} | ||||
|                 </ActionButton> | ||||
|               ) | ||||
|             })} | ||||
|           </div> | ||||
|         </> | ||||
|       )} | ||||
|     </CommandBarHeader> | ||||
|   ) | ||||
| } | ||||
|  | ||||
| @ -16,6 +16,7 @@ export type CustomIconName = | ||||
|   | 'line' | ||||
|   | 'move' | ||||
|   | 'parallel' | ||||
|   | 'plus' | ||||
|   | 'search' | ||||
|   | 'sketch' | ||||
|   | 'vertical' | ||||
| @ -297,6 +298,22 @@ export const CustomIcon = ({ | ||||
|           /> | ||||
|         </svg> | ||||
|       ) | ||||
|     case 'plus': | ||||
|       return ( | ||||
|         <svg | ||||
|           {...props} | ||||
|           viewBox="0 0 20 20" | ||||
|           fill="none" | ||||
|           xmlns="http://www.w3.org/2000/svg" | ||||
|         > | ||||
|           <path | ||||
|             fillRule="evenodd" | ||||
|             clipRule="evenodd" | ||||
|             d="M9.5 9.5V5.5H10.5V9.5H14.5V10.5H10.5V14.5H9.5V10.5H5.5V9.5H9.5Z" | ||||
|             fill="currentColor" | ||||
|           /> | ||||
|         </svg> | ||||
|       ) | ||||
|     case 'search': | ||||
|       return ( | ||||
|         <svg | ||||
|  | ||||
| @ -15,6 +15,7 @@ export type ModelingCommandSchema = { | ||||
|     selection: Selections // & { type: 'face' } would be cool to lock that down | ||||
|     // result: (typeof EXTRUSION_RESULTS)[number] | ||||
|     distance: number | ||||
|     makeVariable?: string | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -52,6 +53,10 @@ export const modelingMachineConfig: CommandSetConfig< | ||||
|         defaultValue: 5, | ||||
|         required: true, | ||||
|       }, | ||||
|       makeVariable: { | ||||
|         inputType: 'string', | ||||
|         required: false, | ||||
|       }, | ||||
|     }, | ||||
|   }, | ||||
| } | ||||
|  | ||||
| @ -8,7 +8,7 @@ import { Selections } from 'lib/selections' | ||||
|  | ||||
| export const commandBarMachine = createMachine( | ||||
|   { | ||||
|     /** @xstate-layout N4IgpgJg5mDOIC5QGED2BbdBDAdhABAEJYBOAxMgDaqxgDaADALqKgAONAlgC6eo6sQAD0QBaAJwA6AGwAmAKwBmBoukAWafIAcDcSoA0IAJ6JZDaZIDs8hgzV6AjA61a1DWQF8PhtJlwFiciowUkYWJBAOWB4+AQiRBFF5CwdpcVkHS1lpVyU5QxNEh1lFGTUsrUUtOQd5SwZLLx8MbDwiUkkqGkgyAHk2MBwwwSiY-kEEswdJNWcNbPFLNMr5AsRFWUtJcVSdRR2VVMUmkF9WgI6u2ggyADFONv98WkowAGNufDeW-2GI0d443iiHESkktUUG1klTsSi0awQDgYWhmqkWjnUslBWhOZyegU61GuZAAghACN8-HhYH92FxAXFQAlRA5FpJ5FjFPYtNDpIpLOkEW4GNs4eJxJoGvJxOVcT82gSrj0AEpgdCoABuYC+8ogNOYI3psQmYlkGUkU2slhc6mkmUUCIyKLc4i0lkU8iUyjUHLlVIuJEkAGUwK8Pg8oDr-WQQ2HPpTzrTIkagUzEDkLHZkQK1CUtKCHAiNlsdjkVAdFEc-ed2oGAOJYbgACzAJAj+FIUAAruhBtxYGQACJwUPveO6pMA43AhA5UqWXOzBjS-nOR3LySqXNODTyZwONTV-GXXXPUcfHqTlOM4TrSublb5-lLewlIVySRaOrmGw-jLSI8FRPf0zzjS8HHCOlogZE1ERUEUSgPa05yQ1ZjEQeZP2-VwDzUN1zEabxTlPAkG2bVt207Hs+wHZAm1wGAvi7EgSD7DsSG7XscG4K9oOnNNEVUeQZGSOxc0qaQ7HhdDBJFeRc35extGkNI+UAgNJDIls2xwSMqK4-tJBJAB3LAYl0-AHjYLtuBjLsACN0B4djOL7XixhvBIDxUT8qj5VIkTwtQHRk8oUQcD15LMXQclcdTa00xttMojjqO42BJAANSwShOAgRsIzICB+DASQHg1VAAGtSo1HK8sbMASVSgz3JgmdMnKGYzRlbIdGXA8EX8zd3RsTY9yyY4iLxID6ySiiLP0misrq-LeF0shWxIVBAzYShGwAM229BJFq3LVsa5q3INf5r1gg9JIfXqqh0TQsiFTYrCyJZRpsXJ4oJVUNU4MBjLsxznITX5rqgjzYMsaZtGXaVNhcZFKgRd0RXUdJ6mUXQXX+jpAeB0GyQIRbuNa-jbwQcVSmhAUeTkWQ3HyGSBVKDQMyRAKAsJwNiZBshVXVLUXLSnjoeTPjUxpnmpFtcVs1cPNBq5T8fR5DrKwaHEppIomwCBoWAFEIGcinJcg6XYZnTRhJsbQJU9VlQTVtQNbqcVZhsSFxH5zoWzeSr2ya1z0qKkqypwCrqpOlaGrDiX9WtqdZYSeSEeXEplCceo1xkvQLGCmUIp0Mwck8fWQMVIOQ4spODIHYqcFK8qqpqhPuAu8P+zoCDDRlzzTCkCVWWlSxrBceTygRFxZHZNJbE2VQ5AFAO6PeevI0bmiNpY7bJF2g6jvjs7E8u9KqfTxAkK2fZYuRvdYUGjQZnqYVxRKdx-ZOHBUAgHAQQ00AyD1tgJUQCwLQMEyHUG0Gh7SOmmDuGB6gOTyVBMkDeRJIBgLahA4oFo8zWlSPUT00o0KFA9NMYKrhKwbH2GaQ81cawEljGOdskM8B4OpgkWY9MV5ZjqLUN6MlqGojoRFEo6QWYb1PC8McuCbpD1gosLYrhkTZCxNIawhYxEfW0HhCKKgzT8lBAHLS809KX37Dwm+iIWZSEinjTRy51BFnvNofM7hGZfgXBYuaOlrG9wyiZMya1IxWRsnY4eDi2TONsK45IaghQbEkO4VIKlsaVE2AE8iQTxZN2WufCJMS7o6JSBKNQLp7CT35EKZw2wnDVDyCvBczDmg10NsbYyZS7aZHBNU58q8sTQgxnud+kVsjyQzHrTprDLh11DjY+AyjwFy00DQ2EaQBSLAPLIDGWRNw2BUiXHkwVCJeCAA */ | ||||
|     /** @xstate-layout N4IgpgJg5mDOIC5QGED2BbdBDAdhABAEJYBOAxMgDaqxgDaADALqKgAONAlgC6eo6sQAD0QBaAJwA6AGwAmAKwBmBoukAWafIAcDcSoA0IAJ6JZDaZIDs8hgzV6AjA61a1DWQF8PhtJlwFiciowUkYWJBAOWB4+AQiRBFF5CwdpcVkHS1lpVyU5QxNEh1lFGTUsrUUtOQd5SwZLLx8MbDwiUkkqGkgyAHk2MBwwwSiY-kEEswdJNWcNbPFLNMr5AsRFWUtJcVSdRR2VVMUmkF9WgI6u2ggyADFONv98WkowAGNufDeW-2GI0d443iiHESkktUUG1klTsSi0awQDgYWhmqkWjnUslBWhOZyegU61GuZAAghACN8-HhYH92FxAXFQAlRA5FpJ5FjFPYtNDpIpLOkEW4GNs4eJxJoGvJxOVcT82gSrj0AEpgdCoABuYC+8ogNOYI3psQmYlkGUkU2slhc6mkmUUCIyKLc4i0lkU8iUyjUHLlVIuJEkAGUwK8Pg8oDr-WQQ2HPpTzrTIkagUzEDkLHZkQK1CUtKCHAiNlsdjkVAdFEc-ed2oG8W0Xu9uD0kwDjcCEJDplUPfn+Ut7CUhXJJFo6uYbBOMtJq-jLrrnqGmy2HOE6dEGSbESoRSUHOVqpV99Zh7JR+PXPu1G7zI1vKcFwSAOJYbgACzAJAj+FIUAAruggzcLAFBvrgMBfH+JAkEBP4kP+gE4NwrYpoywiIA4qjyDIyR2LmlTSHY8LGBhyjsrm-L2No0hpHys4Kh0L7vp+36-gBQEgQAInAS4fFGiYGv8qFbjkpSWLmswMNK-LOI6UmSKouZOBo8jOPu9EBpITEfl+OCRmxiHAZIJIAO5YDEen4A8bB-twMZ-gARugPBwQhQEoRu7ZpoibilJU1SVnaRFqA6JEIAe4IevIua2BKLhqBptZaa+OmsfB7FIbAkgAGpYJQnAQK+EZkBA-BgJIDwaqgADW5UanlBWvmAJLpYZHljGhCSZOUMxmjK2Q6FJ+4Iny3bujYmyqVkxz3vWmnaSxlkGRxOUNYVvB6WQn4kKggZsJQr4AGa7egkj1fl63Na17mCeuHVbvuhEKTyokuBOWRCpsVhZEsE02LkiUEqqGqcGAJn2U5LkJr8t3Jp5qboQgljTNoUnSpsb0uKFhTuiK6jpPUyi6C6gMdMDoPg2SBDLUh7Wbh24qlNCAovWabj5GFAqlBoGZIqkTh2qTgbk2DZCquqWquRlyGw22CNdQwrJlGkehuq4eYjVyo4+jy3WVg0OKzY+ZNgCDosAKIQC5NMy2ucP3R2mjYTY2gSp6rKgpraja3U4qzDYkLiELnQfm81Xfi1bmZSVZUVTgVW1Wda1NZH0v6nbcudYg0Uo1JJTKE49SyWFegWCFMqYToZg5J4Rv+klyCh+Hlmp4ZIGlTg5WVTVdXJ82rccXQq6GvDWcIFi2x2qCizWC40XlAiLhnskejuO6NGbEHdc1oqTcR9d0fbbtkj7UdJ1JxdKcH8BdNeYjx5bPsORjukqmwiNGgzPUwriiU7hb80euz4UqLX0tfEC4tNTahtrfeWpg7DTAlMeQ8XIOSrDCrsdk4gqjImRD6TCIVg4LV0mAqOwExZqigVLNqw8hKjwepoUo7g4SzE0EFQsGDpTbFcG6AhgUlheHvDgVAEA4CCDmrWEeDtvKiAWBaRWVobQaHtI6aYylzDFGUIpSsCVt5zjrESSAUj6YyOKBaPM1pUj1E9NKdBhQPTTBCq4SsGx9hs2DrGJs35oZ4GMXfBIswmabG9FJZGdRZBFlUqiZxmESjpFkLowBO95z10bB8IxdDpGIxntrZE2QsTSGsBw+xX1tDXkwioM0-JQREJASQ6hHE-FwMRAkqQUUiZ5KkuoIslZ2QuBlFaGiWQEm1OYvUm2WVTLmQ2pGaytkmlj2KGydpthOnJDUEKDYkh3CpBovjSomxRmpSWuA1al8ZkLIYUscEEo1AunsJYd0lghTOG2E4aoeRgniUSQ+IBJszYmUuY7TI4I7n9lUHIdIxEcZRPKFFbI0UMyGySfokO7xm6RgHplIF3laivMZgRNm7NsaIACgpV2SxajYMhDNLwQA */ | ||||
|     context: { | ||||
|       commands: [] as Command[], | ||||
|       selectedCommand: undefined as Command | undefined, | ||||
| @ -167,6 +167,19 @@ export const commandBarMachine = createMachine( | ||||
|               }), | ||||
|             ], | ||||
|           }, | ||||
|  | ||||
|           'Remove argument': [ | ||||
|             { | ||||
|               target: 'Review', | ||||
|               cond: 'Is current argument', | ||||
|               actions: 'Remove argument', | ||||
|             }, | ||||
|             { | ||||
|               target: 'Gathering arguments', | ||||
|               internal: true, | ||||
|               actions: 'Remove argument', | ||||
|             }, | ||||
|           ], | ||||
|         }, | ||||
|       }, | ||||
|  | ||||
| @ -185,17 +198,7 @@ export const commandBarMachine = createMachine( | ||||
|  | ||||
|           'Remove argument': { | ||||
|             target: 'Review', | ||||
|             actions: [ | ||||
|               assign({ | ||||
|                 argumentsToSubmit: (context, event) => { | ||||
|                   const argName = Object.keys(event.data)[0] | ||||
|                   const { argumentsToSubmit } = context | ||||
|                   const newArgumentsToSubmit = { ...argumentsToSubmit } | ||||
|                   newArgumentsToSubmit[argName] = undefined | ||||
|                   return newArgumentsToSubmit | ||||
|                 }, | ||||
|               }), | ||||
|             ], | ||||
|             actions: ['Remove argument'], | ||||
|           }, | ||||
|  | ||||
|           'Edit argument': { | ||||
| @ -362,10 +365,25 @@ export const commandBarMachine = createMachine( | ||||
|           return args | ||||
|         }, | ||||
|       }), | ||||
|       'Remove argument': assign({ | ||||
|         argumentsToSubmit: (context, event) => { | ||||
|           if (event.type !== 'Remove argument') return context.argumentsToSubmit | ||||
|           const argName = Object.keys(event.data)[0] | ||||
|           const { argumentsToSubmit } = context | ||||
|           const newArgumentsToSubmit = { ...argumentsToSubmit } | ||||
|           delete newArgumentsToSubmit[argName] | ||||
|           return newArgumentsToSubmit | ||||
|         }, | ||||
|       }), | ||||
|     }, | ||||
|     guards: { | ||||
|       'Command needs review': (context, _) => | ||||
|         context.selectedCommand?.needsReview || false, | ||||
|       'Is current argument': (context, event) => { | ||||
|         if (event.type !== 'Remove argument') return false | ||||
|         const argName = Object.keys(event.data)[0] | ||||
|         return argName === context.currentArgument?.name | ||||
|       }, | ||||
|     }, | ||||
|     services: { | ||||
|       'Validate argument': (context, event) => { | ||||
| @ -381,6 +399,10 @@ export const commandBarMachine = createMachine( | ||||
|         return new Promise((resolve, reject) => { | ||||
|           for (const [argName, arg] of Object.entries( | ||||
|             context.argumentsToSubmit | ||||
|           ).filter(([argName, _]) => | ||||
|             context.selectedCommand?.args | ||||
|               ? context.selectedCommand?.args[argName]?.required | ||||
|               : false | ||||
|           )) { | ||||
|             let argConfig = context.selectedCommand!.args![argName] | ||||
|  | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	