Merge 7ffab280c383f80172845d8e2f18eb50e8af2582 into 8a05c05596ca9ba0735dafd8e359885de4c2c969
This commit is contained in:
commit
87b0b37ed1
@ -363,11 +363,17 @@
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.agent-chat__input-wrap {
|
||||
position: relative;
|
||||
margin: 0 18px 14px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.agent-chat__input {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: 0 18px 14px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: var(--card);
|
||||
border: 1px solid var(--border);
|
||||
|
||||
@ -513,7 +513,7 @@
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.agent-chat__input {
|
||||
.agent-chat__input-wrap {
|
||||
margin: 0 8px 10px;
|
||||
}
|
||||
|
||||
|
||||
@ -952,6 +952,16 @@ export function renderChat(props: ChatProps) {
|
||||
</div>
|
||||
`;
|
||||
|
||||
/** After arrow-key navigation, scroll the active slash-menu item into view. */
|
||||
const scrollSlashMenuActiveIntoView = () => {
|
||||
requestAnimationFrame(() => {
|
||||
const active = document.querySelector(".agent-chat__input-wrap .slash-menu-item--active");
|
||||
if (active) {
|
||||
active.scrollIntoView({ block: "nearest" });
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const handleKeyDown = (e: KeyboardEvent) => {
|
||||
// Slash menu navigation — arg mode
|
||||
if (vs.slashMenuOpen && vs.slashMenuMode === "args" && vs.slashMenuArgItems.length > 0) {
|
||||
@ -961,11 +971,13 @@ export function renderChat(props: ChatProps) {
|
||||
e.preventDefault();
|
||||
vs.slashMenuIndex = (vs.slashMenuIndex + 1) % len;
|
||||
requestUpdate();
|
||||
scrollSlashMenuActiveIntoView();
|
||||
return;
|
||||
case "ArrowUp":
|
||||
e.preventDefault();
|
||||
vs.slashMenuIndex = (vs.slashMenuIndex - 1 + len) % len;
|
||||
requestUpdate();
|
||||
scrollSlashMenuActiveIntoView();
|
||||
return;
|
||||
case "Tab":
|
||||
e.preventDefault();
|
||||
@ -992,11 +1004,13 @@ export function renderChat(props: ChatProps) {
|
||||
e.preventDefault();
|
||||
vs.slashMenuIndex = (vs.slashMenuIndex + 1) % len;
|
||||
requestUpdate();
|
||||
scrollSlashMenuActiveIntoView();
|
||||
return;
|
||||
case "ArrowUp":
|
||||
e.preventDefault();
|
||||
vs.slashMenuIndex = (vs.slashMenuIndex - 1 + len) % len;
|
||||
requestUpdate();
|
||||
scrollSlashMenuActiveIntoView();
|
||||
return;
|
||||
case "Tab":
|
||||
e.preventDefault();
|
||||
@ -1182,34 +1196,35 @@ export function renderChat(props: ChatProps) {
|
||||
}
|
||||
|
||||
<!-- Input bar -->
|
||||
<div class="agent-chat__input">
|
||||
<div class="agent-chat__input-wrap">
|
||||
${renderSlashMenu(requestUpdate, props)}
|
||||
${renderAttachmentPreview(props)}
|
||||
<div class="agent-chat__input">
|
||||
${renderAttachmentPreview(props)}
|
||||
|
||||
<input
|
||||
type="file"
|
||||
accept=${CHAT_ATTACHMENT_ACCEPT}
|
||||
multiple
|
||||
class="agent-chat__file-input"
|
||||
@change=${(e: Event) => handleFileSelect(e, props)}
|
||||
/>
|
||||
<input
|
||||
type="file"
|
||||
accept=${CHAT_ATTACHMENT_ACCEPT}
|
||||
multiple
|
||||
class="agent-chat__file-input"
|
||||
@change=${(e: Event) => handleFileSelect(e, props)}
|
||||
/>
|
||||
|
||||
${vs.sttRecording && vs.sttInterimText ? html`<div class="agent-chat__stt-interim">${vs.sttInterimText}</div>` : nothing}
|
||||
${vs.sttRecording && vs.sttInterimText ? html`<div class="agent-chat__stt-interim">${vs.sttInterimText}</div>` : nothing}
|
||||
|
||||
<textarea
|
||||
${ref((el) => el && adjustTextareaHeight(el as HTMLTextAreaElement))}
|
||||
.value=${props.draft}
|
||||
dir=${detectTextDirection(props.draft)}
|
||||
?disabled=${!props.connected}
|
||||
@keydown=${handleKeyDown}
|
||||
@input=${handleInput}
|
||||
@paste=${(e: ClipboardEvent) => handlePaste(e, props)}
|
||||
placeholder=${vs.sttRecording ? "Listening..." : placeholder}
|
||||
rows="1"
|
||||
></textarea>
|
||||
<textarea
|
||||
${ref((el) => el && adjustTextareaHeight(el as HTMLTextAreaElement))}
|
||||
.value=${props.draft}
|
||||
dir=${detectTextDirection(props.draft)}
|
||||
?disabled=${!props.connected}
|
||||
@keydown=${handleKeyDown}
|
||||
@input=${handleInput}
|
||||
@paste=${(e: ClipboardEvent) => handlePaste(e, props)}
|
||||
placeholder=${vs.sttRecording ? "Listening..." : placeholder}
|
||||
rows="1"
|
||||
></textarea>
|
||||
|
||||
<div class="agent-chat__toolbar">
|
||||
<div class="agent-chat__toolbar-left">
|
||||
<div class="agent-chat__toolbar">
|
||||
<div class="agent-chat__toolbar-left">
|
||||
<button
|
||||
class="agent-chat__input-btn"
|
||||
@click=${() => {
|
||||
@ -1324,7 +1339,8 @@ export function renderChat(props: ChatProps) {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</section>
|
||||
`;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user