mirror of
				https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web.git
				synced 2025-10-31 06:13:43 +08:00 
			
		
		
		
	feat: close #782 select prompt with arrow down / up
This commit is contained in:
		| @@ -224,18 +224,63 @@ export function PromptHints(props: { | |||||||
|   prompts: Prompt[]; |   prompts: Prompt[]; | ||||||
|   onPromptSelect: (prompt: Prompt) => void; |   onPromptSelect: (prompt: Prompt) => void; | ||||||
| }) { | }) { | ||||||
|   if (props.prompts.length === 0) return null; |   const noPrompts = props.prompts.length === 0; | ||||||
|  |   const [selectIndex, setSelectIndex] = useState(0); | ||||||
|  |   const selectedRef = useRef<HTMLDivElement>(null); | ||||||
|  |  | ||||||
|  |   useEffect(() => { | ||||||
|  |     setSelectIndex(0); | ||||||
|  |   }, [props.prompts.length]); | ||||||
|  |  | ||||||
|  |   useEffect(() => { | ||||||
|  |     const onKeyDown = (e: KeyboardEvent) => { | ||||||
|  |       if (noPrompts) return; | ||||||
|  |  | ||||||
|  |       // arrow up / down to select prompt | ||||||
|  |       const changeIndex = (delta: number) => { | ||||||
|  |         e.stopPropagation(); | ||||||
|  |         e.preventDefault(); | ||||||
|  |         const nextIndex = Math.max( | ||||||
|  |           0, | ||||||
|  |           Math.min(props.prompts.length - 1, selectIndex + delta), | ||||||
|  |         ); | ||||||
|  |         setSelectIndex(nextIndex); | ||||||
|  |         selectedRef.current?.scrollIntoView({ | ||||||
|  |           block: "center", | ||||||
|  |         }); | ||||||
|  |       }; | ||||||
|  |  | ||||||
|  |       if (e.key === "ArrowUp") { | ||||||
|  |         changeIndex(1); | ||||||
|  |       } else if (e.key === "ArrowDown") { | ||||||
|  |         changeIndex(-1); | ||||||
|  |       } else if (e.key === "Enter") { | ||||||
|  |         const selectedPrompt = props.prompts.at(selectIndex); | ||||||
|  |         if (selectedPrompt) { | ||||||
|  |           props.onPromptSelect(selectedPrompt); | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     window.addEventListener("keydown", onKeyDown); | ||||||
|  |  | ||||||
|  |     return () => window.removeEventListener("keydown", onKeyDown); | ||||||
|  |     // eslint-disable-next-line react-hooks/exhaustive-deps | ||||||
|  |   }, [noPrompts, selectIndex]); | ||||||
|  |  | ||||||
|  |   if (noPrompts) return null; | ||||||
|   return ( |   return ( | ||||||
|     <div className={styles["prompt-hints"]}> |     <div className={styles["prompt-hints"]}> | ||||||
|       {props.prompts.map((prompt, i) => ( |       {props.prompts.map((prompt, i) => ( | ||||||
|         <div |         <div | ||||||
|           className={styles["prompt-hint"]} |           ref={i === selectIndex ? selectedRef : null} | ||||||
|  |           className={ | ||||||
|  |             styles["prompt-hint"] + | ||||||
|  |             ` ${i === selectIndex ? styles["prompt-hint-selected"] : ""}` | ||||||
|  |           } | ||||||
|           key={prompt.title + i.toString()} |           key={prompt.title + i.toString()} | ||||||
|           onClick={() => { |           onClick={() => props.onPromptSelect(prompt)} | ||||||
|             console.log("click hint"); |           onMouseEnter={() => setSelectIndex(i)} | ||||||
|             props.onPromptSelect(prompt); |  | ||||||
|           }} |  | ||||||
|         > |         > | ||||||
|           <div className={styles["hint-title"]}>{prompt.title}</div> |           <div className={styles["hint-title"]}>{prompt.title}</div> | ||||||
|           <div className={styles["hint-content"]}>{prompt.content}</div> |           <div className={styles["hint-content"]}>{prompt.content}</div> | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user