✨ feat(vscode): 文件和文件夹在预览顶部问
侧栏「问 AI」打开代码阅读预览。文件夹是没有代码块的一页,源码文件在整页顶部聊,代码块下面的问答不动。历史按工作区文件夹和相对路径记在窗口状态里,不写进按块存的记录。
This commit is contained in:
1 parent
2be635d1e5
commit
2c10acf9c4
19 files changed
+610
-459
No files matched your search
@@ -138,22 +138,38 @@ function CurrentItem({ ask, onOpenImage, onStop }: { ask: Ask, onOpenImage: (url
|
||||
}
|
||||
|
||||
/** 底下的输入框:Enter 发送、Shift+Enter 换行、Esc 收起;正在答时发送换成停止。能贴图、拖图,贴的图在输入框上面一排,随下一个问题发 */
|
||||
function AskInput({ running, first, profiles, onSelectProfile, onAsk, onStop, onClose, onOpenImage }: {
|
||||
function AskInput({ running, first, hint, profiles, onSelectProfile, onAsk, onStop, onClose, closable, onOpenImage, autoFocus, focusToken }: {
|
||||
running: Ask | undefined
|
||||
/** 这块还没问过:提示「问这块代码…」,问过了是「继续问…」 */
|
||||
/** 还没问过:提示「问…」,问过了是「继续问…」 */
|
||||
first: boolean
|
||||
/** 「问」后面的对象:块下面是「这块代码」,顶部是「这个文件」或「这个文件夹」 */
|
||||
hint: string
|
||||
profiles: ProfileChoice
|
||||
onSelectProfile: (id: string) => void
|
||||
onAsk: (question: string, images: PendingImage[]) => void
|
||||
onStop: (askId: string) => void
|
||||
onClose: () => void
|
||||
/** Esc 收起。顶部那条一直摊开,不收 */
|
||||
closable: boolean
|
||||
onOpenImage: (url: string) => void
|
||||
/** 展开时把光标放进输入框。顶部那条一直摊开,不要抢阅读时光标 */
|
||||
autoFocus: boolean
|
||||
/** 大于 0 时再放一次光标;侧栏「问 AI」打开已经在的预览时用 */
|
||||
focusToken: number
|
||||
}): ReactElement {
|
||||
const [value, setValue] = useState('')
|
||||
const [images, setImages] = useState<PendingImage[]>([])
|
||||
/** 贴的、拖的有没加上的:给人看的原因,下次贴图或发送时清掉 */
|
||||
const [notice, setNotice] = useState<string>()
|
||||
const textarea = useRef<HTMLTextAreaElement>(null)
|
||||
useEffect(() => {
|
||||
if (autoFocus)
|
||||
textarea.current?.focus()
|
||||
}, [autoFocus])
|
||||
useEffect(() => {
|
||||
if (focusToken > 0)
|
||||
textarea.current?.focus()
|
||||
}, [focusToken])
|
||||
const attach = (files: File[]): void => {
|
||||
if (files.length === 0)
|
||||
return
|
||||
@@ -179,7 +195,7 @@ function AskInput({ running, first, profiles, onSelectProfile, onAsk, onStop, on
|
||||
event.preventDefault()
|
||||
send()
|
||||
}
|
||||
else if (event.key === 'Escape') {
|
||||
else if (closable && event.key === 'Escape') {
|
||||
event.preventDefault()
|
||||
onClose()
|
||||
}
|
||||
@@ -211,9 +227,8 @@ function AskInput({ running, first, profiles, onSelectProfile, onAsk, onStop, on
|
||||
<textarea
|
||||
ref={textarea}
|
||||
rows={1}
|
||||
autoFocus
|
||||
value={value}
|
||||
placeholder={`${first ? '问这块代码…' : '继续问…'} Enter 发送,Esc 收起`}
|
||||
placeholder={`${first ? `问${hint}…` : '继续问…'} Enter 发送${closable ? ',Esc 收起' : ''}`}
|
||||
aria-label="问 AI 的问题"
|
||||
onChange={event => setValue(event.target.value)}
|
||||
onKeyDown={onKeyDown}
|
||||
@@ -251,6 +266,14 @@ export interface AskThreadProps {
|
||||
open: boolean
|
||||
/** 输入框旁边的 profile 下拉 */
|
||||
profiles: ProfileChoice
|
||||
/** 「问」后面的对象,默认「这块代码」 */
|
||||
hint?: string
|
||||
/** 展开时聚焦输入框,默认聚焦。一直摊开的顶部聊天不聚焦 */
|
||||
autoFocus?: boolean
|
||||
/** 变大时把光标放进输入框 */
|
||||
focusToken?: number
|
||||
/** Esc 能不能收起,默认能。顶部聊天不收 */
|
||||
closable?: boolean
|
||||
now?: number
|
||||
onSelectProfile: (id: string) => void
|
||||
/** images 是贴进输入框的图片,随问题一起发 */
|
||||
@@ -264,7 +287,7 @@ export interface AskThreadProps {
|
||||
* 块下面的问答区(左边一条竖线):展开时是灰字的历史、当前这一轮、输入框;
|
||||
* 没展开但问过的块是一行「问过 N 次」、下面默认摊开灰字历史,点这一行收起 / 再摊开,读代码时一眼看到这里问过什么。
|
||||
*/
|
||||
export function AskThread({ history, asks, open, profiles, now = Date.now(), onSelectProfile, onAsk, onStop, onDelete, onClose }: AskThreadProps): ReactElement | null {
|
||||
export function AskThread({ history, asks, open, profiles, hint = '这块代码', autoFocus = true, focusToken = 0, closable = true, now = Date.now(), onSelectProfile, onAsk, onStop, onDelete, onClose }: AskThreadProps): ReactElement | null {
|
||||
const [showHistory, setShowHistory] = useState(true)
|
||||
/** 正在看大图的那张 */
|
||||
const [preview, setPreview] = useState<string>()
|
||||
@@ -295,10 +318,14 @@ export function AskThread({ history, asks, open, profiles, now = Date.now(), onS
|
||||
first={history.length === 0 && asks.length === 0}
|
||||
profiles={profiles}
|
||||
onSelectProfile={onSelectProfile}
|
||||
hint={hint}
|
||||
onAsk={onAsk}
|
||||
onStop={onStop}
|
||||
onClose={onClose}
|
||||
closable={closable}
|
||||
onOpenImage={setPreview}
|
||||
autoFocus={autoFocus}
|
||||
focusToken={focusToken}
|
||||
/>
|
||||
{lightbox}
|
||||
</section>
|
||||
|
||||
Reference in new issue
Block a user