mirror of
https://github.com/wavetermdev/waveterm.git
synced 2024-12-22 16:48:23 +01:00
save work
This commit is contained in:
parent
918ff98ea1
commit
34837aabae
@ -11,6 +11,7 @@ import { Markdown } from "@/elements";
|
|||||||
import type { OverlayScrollbars } from "overlayscrollbars";
|
import type { OverlayScrollbars } from "overlayscrollbars";
|
||||||
import { OverlayScrollbarsComponent, OverlayScrollbarsComponentRef } from "overlayscrollbars-react";
|
import { OverlayScrollbarsComponent, OverlayScrollbarsComponentRef } from "overlayscrollbars-react";
|
||||||
import tinycolor from "tinycolor2";
|
import tinycolor from "tinycolor2";
|
||||||
|
import * as appconst from "@/app/appconst";
|
||||||
|
|
||||||
import "./aichat.less";
|
import "./aichat.less";
|
||||||
|
|
||||||
@ -54,10 +55,9 @@ class AIChatKeybindings extends React.Component<{ AIChatObject: AIChat }, {}> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@mobxReact.observer
|
@mobxReact.observer
|
||||||
class ChatContent extends React.Component<{}, {}> {
|
class ChatContent extends React.Component<{ chatWindowRef }, {}> {
|
||||||
chatListKeyCount: number = 0;
|
chatListKeyCount: number = 0;
|
||||||
containerRef: React.RefObject<OverlayScrollbarsComponentRef> = React.createRef();
|
containerRef: React.RefObject<OverlayScrollbarsComponentRef> = React.createRef();
|
||||||
chatWindowRef: React.RefObject<HTMLDivElement> = React.createRef();
|
|
||||||
osInstance: OverlayScrollbars = null;
|
osInstance: OverlayScrollbars = null;
|
||||||
|
|
||||||
componentDidUpdate() {
|
componentDidUpdate() {
|
||||||
@ -66,7 +66,7 @@ class ChatContent extends React.Component<{}, {}> {
|
|||||||
const { viewport } = this.osInstance.elements();
|
const { viewport } = this.osInstance.elements();
|
||||||
viewport.scrollTo({
|
viewport.scrollTo({
|
||||||
behavior: "auto",
|
behavior: "auto",
|
||||||
top: this.chatWindowRef.current.scrollHeight,
|
top: this.props.chatWindowRef.current.scrollHeight,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -84,7 +84,7 @@ class ChatContent extends React.Component<{}, {}> {
|
|||||||
const { viewport } = instance.elements();
|
const { viewport } = instance.elements();
|
||||||
viewport.scrollTo({
|
viewport.scrollTo({
|
||||||
behavior: "auto",
|
behavior: "auto",
|
||||||
top: this.chatWindowRef.current.scrollHeight,
|
top: this.props.chatWindowRef.current.scrollHeight,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,7 +116,7 @@ class ChatContent extends React.Component<{}, {}> {
|
|||||||
<i className="fa-sharp fa-solid fa-sparkles"></i>
|
<i className="fa-sharp fa-solid fa-sparkles"></i>
|
||||||
</div>
|
</div>
|
||||||
<Markdown
|
<Markdown
|
||||||
inputModel={GlobalModel.aichatModel}
|
inputModel={GlobalModel.inputModel}
|
||||||
text={chatItem.assistantresponse.message}
|
text={chatItem.assistantresponse.message}
|
||||||
codeSelect
|
codeSelect
|
||||||
/>
|
/>
|
||||||
@ -148,7 +148,7 @@ class ChatContent extends React.Component<{}, {}> {
|
|||||||
options={{ scrollbars: { autoHide: "leave" } }}
|
options={{ scrollbars: { autoHide: "leave" } }}
|
||||||
events={{ initialized: this.onScrollbarInitialized }}
|
events={{ initialized: this.onScrollbarInitialized }}
|
||||||
>
|
>
|
||||||
<div ref={this.chatWindowRef} className="chat-window">
|
<div ref={this.props.chatWindowRef} className="chat-window">
|
||||||
<div className="filler"></div>
|
<div className="filler"></div>
|
||||||
<For each="chitem" index="idx" of={chatMessageItems}>
|
<For each="chitem" index="idx" of={chatMessageItems}>
|
||||||
{this.renderChatMessage(chitem)}
|
{this.renderChatMessage(chitem)}
|
||||||
@ -162,13 +162,39 @@ class ChatContent extends React.Component<{}, {}> {
|
|||||||
@mobxReact.observer
|
@mobxReact.observer
|
||||||
class AIChat extends React.Component<{}, {}> {
|
class AIChat extends React.Component<{}, {}> {
|
||||||
textAreaRef: React.RefObject<HTMLTextAreaElement> = React.createRef();
|
textAreaRef: React.RefObject<HTMLTextAreaElement> = React.createRef();
|
||||||
|
chatWindowRef: React.RefObject<HTMLDivElement> = React.createRef();
|
||||||
termFontSize: number = 14;
|
termFontSize: number = 14;
|
||||||
|
|
||||||
|
// Adjust the height of the textarea to fit the text
|
||||||
|
@boundMethod
|
||||||
|
onTextAreaChange(e: any) {
|
||||||
|
if (this.textAreaRef.current == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Calculate the bounding height of the text area
|
||||||
|
const textAreaMaxLines = 4;
|
||||||
|
const textAreaLineHeight = this.termFontSize * 1.5;
|
||||||
|
const textAreaMinHeight = textAreaLineHeight;
|
||||||
|
const textAreaMaxHeight = textAreaLineHeight * textAreaMaxLines;
|
||||||
|
|
||||||
|
// Get the height of the wrapped text area content. Courtesy of https://stackoverflow.com/questions/995168/textarea-to-resize-based-on-content-length
|
||||||
|
this.textAreaRef.current.style.height = "1px";
|
||||||
|
const scrollHeight: number = this.textAreaRef.current.scrollHeight;
|
||||||
|
|
||||||
|
// Set the new height of the text area, bounded by the min and max height.
|
||||||
|
const newHeight = Math.min(Math.max(scrollHeight, textAreaMinHeight), textAreaMaxHeight);
|
||||||
|
this.textAreaRef.current.style.height = newHeight + "px";
|
||||||
|
GlobalModel.inputModel.codeSelectDeselectAll();
|
||||||
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
const inputModel = GlobalModel.inputModel;
|
const inputModel = GlobalModel.inputModel;
|
||||||
|
|
||||||
|
inputModel.openAIAssistantChat();
|
||||||
|
|
||||||
if (this.textAreaRef.current != null) {
|
if (this.textAreaRef.current != null) {
|
||||||
this.textAreaRef.current.focus();
|
this.textAreaRef.current.focus();
|
||||||
// inputModel.setCmdInfoChatRefs(this.textAreaRef, this.chatWindowScrollRef);
|
inputModel.setCmdInfoChatRefs(this.textAreaRef, this.chatWindowRef);
|
||||||
}
|
}
|
||||||
this.requestChatUpdate();
|
this.requestChatUpdate();
|
||||||
this.onTextAreaChange(null);
|
this.onTextAreaChange(null);
|
||||||
@ -183,7 +209,6 @@ class AIChat extends React.Component<{}, {}> {
|
|||||||
|
|
||||||
submitChatMessage(messageStr: string) {
|
submitChatMessage(messageStr: string) {
|
||||||
const curLine = GlobalModel.inputModel.curLine;
|
const curLine = GlobalModel.inputModel.curLine;
|
||||||
console.log("enter key pressed", messageStr, "curLine: ", curLine);
|
|
||||||
const prtn = GlobalModel.submitChatInfoCommand(messageStr, curLine, false);
|
const prtn = GlobalModel.submitChatInfoCommand(messageStr, curLine, false);
|
||||||
prtn.then((rtn) => {
|
prtn.then((rtn) => {
|
||||||
if (!rtn.success) {
|
if (!rtn.success) {
|
||||||
@ -198,9 +223,13 @@ class AIChat extends React.Component<{}, {}> {
|
|||||||
return { numLines, linePos };
|
return { numLines, linePos };
|
||||||
}
|
}
|
||||||
|
|
||||||
@mobx.action.bound
|
@mobx.action
|
||||||
|
@boundMethod
|
||||||
onTextAreaFocused(e: any) {
|
onTextAreaFocused(e: any) {
|
||||||
|
console.log("focused");
|
||||||
GlobalModel.inputModel.setAuxViewFocus(true);
|
GlobalModel.inputModel.setAuxViewFocus(true);
|
||||||
|
GlobalModel.inputModel.setActiveAuxView(appconst.InputAuxView_AIChat);
|
||||||
|
|
||||||
this.onTextAreaChange(e);
|
this.onTextAreaChange(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,22 +240,8 @@ class AIChat extends React.Component<{}, {}> {
|
|||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust the height of the textarea to fit the text
|
|
||||||
@boundMethod
|
@boundMethod
|
||||||
onTextAreaChange(e: any) {
|
onTextAreaInput(e: any) {
|
||||||
// Calculate the bounding height of the text area
|
|
||||||
const textAreaMaxLines = 4;
|
|
||||||
const textAreaLineHeight = this.termFontSize * 1.5;
|
|
||||||
const textAreaMinHeight = textAreaLineHeight;
|
|
||||||
const textAreaMaxHeight = textAreaLineHeight * textAreaMaxLines;
|
|
||||||
|
|
||||||
// Get the height of the wrapped text area content. Courtesy of https://stackoverflow.com/questions/995168/textarea-to-resize-based-on-content-length
|
|
||||||
this.textAreaRef.current.style.height = "1px";
|
|
||||||
const scrollHeight: number = this.textAreaRef.current.scrollHeight;
|
|
||||||
|
|
||||||
// Set the new height of the text area, bounded by the min and max height.
|
|
||||||
const newHeight = Math.min(Math.max(scrollHeight, textAreaMinHeight), textAreaMaxHeight);
|
|
||||||
this.textAreaRef.current.style.height = newHeight + "px";
|
|
||||||
GlobalModel.inputModel.codeSelectDeselectAll();
|
GlobalModel.inputModel.codeSelectDeselectAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -272,6 +287,7 @@ class AIChat extends React.Component<{}, {}> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onArrowDownPressed(): boolean {
|
onArrowDownPressed(): boolean {
|
||||||
|
console.log("got here");
|
||||||
const currentRef = this.textAreaRef.current;
|
const currentRef = this.textAreaRef.current;
|
||||||
const inputModel = GlobalModel.inputModel;
|
const inputModel = GlobalModel.inputModel;
|
||||||
if (currentRef == null) {
|
if (currentRef == null) {
|
||||||
@ -294,15 +310,22 @@ class AIChat extends React.Component<{}, {}> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const chatMessageItems = GlobalModel.aichatModel.aiCmdInfoChatItems.slice();
|
const chatMessageItems = GlobalModel.inputModel.AICmdInfoChatItems.slice();
|
||||||
|
const renderAIChatKeybindings = GlobalModel.inputModel.shouldRenderAuxViewKeybindings(
|
||||||
|
appconst.InputAuxView_AIChat,
|
||||||
|
"sidebar"
|
||||||
|
);
|
||||||
|
console.log("renderAIChatKeybindings=====", renderAIChatKeybindings);
|
||||||
return (
|
return (
|
||||||
<div className="sidebar-aichat">
|
<div className="sidebar-aichat">
|
||||||
<AIChatKeybindings AIChatObject={this}></AIChatKeybindings>
|
<If condition={renderAIChatKeybindings}>
|
||||||
|
<AIChatKeybindings AIChatObject={this}></AIChatKeybindings>
|
||||||
|
</If>
|
||||||
<div className="titlebar">
|
<div className="titlebar">
|
||||||
<div className="title-string">Wave AI</div>
|
<div className="title-string">Wave AI</div>
|
||||||
</div>
|
</div>
|
||||||
<If condition={chatMessageItems.length > 0}>
|
<If condition={chatMessageItems.length > 0}>
|
||||||
<ChatContent />
|
<ChatContent chatWindowRef={this.chatWindowRef} />
|
||||||
</If>
|
</If>
|
||||||
<div className="chat-input">
|
<div className="chat-input">
|
||||||
<textarea
|
<textarea
|
||||||
@ -311,11 +334,13 @@ class AIChat extends React.Component<{}, {}> {
|
|||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
autoCorrect="off"
|
autoCorrect="off"
|
||||||
autoFocus={true}
|
autoFocus={true}
|
||||||
id="chat-cmd-input"
|
className="chat-cmd-input chat-textarea"
|
||||||
|
onFocus={this.onTextAreaFocused}
|
||||||
|
onBlur={this.onTextAreaBlur}
|
||||||
onChange={this.onTextAreaChange}
|
onChange={this.onTextAreaChange}
|
||||||
|
onInput={this.onTextAreaInput}
|
||||||
onKeyDown={this.onKeyDown}
|
onKeyDown={this.onKeyDown}
|
||||||
style={{ fontSize: this.termFontSize }}
|
style={{ fontSize: this.termFontSize }}
|
||||||
className="chat-textarea"
|
|
||||||
placeholder="Send a Message..."
|
placeholder="Send a Message..."
|
||||||
></textarea>
|
></textarea>
|
||||||
</div>
|
</div>
|
||||||
|
@ -245,6 +245,7 @@ class AIChat extends React.Component<{}, {}> {
|
|||||||
const chatMessageItems = GlobalModel.inputModel.AICmdInfoChatItems.slice();
|
const chatMessageItems = GlobalModel.inputModel.AICmdInfoChatItems.slice();
|
||||||
const chitem: OpenAICmdInfoChatMessageType = null;
|
const chitem: OpenAICmdInfoChatMessageType = null;
|
||||||
const renderKeybindings = GlobalModel.inputModel.shouldRenderAuxViewKeybindings(appconst.InputAuxView_AIChat);
|
const renderKeybindings = GlobalModel.inputModel.shouldRenderAuxViewKeybindings(appconst.InputAuxView_AIChat);
|
||||||
|
console.log("renderKeybindings", renderKeybindings);
|
||||||
return (
|
return (
|
||||||
<AuxiliaryCmdView
|
<AuxiliaryCmdView
|
||||||
title="Wave AI"
|
title="Wave AI"
|
||||||
@ -267,14 +268,13 @@ class AIChat extends React.Component<{}, {}> {
|
|||||||
ref={this.textAreaRef}
|
ref={this.textAreaRef}
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
autoCorrect="off"
|
autoCorrect="off"
|
||||||
id="chat-cmd-input"
|
className="chat-cmd-input chat-textarea"
|
||||||
onFocus={this.onTextAreaFocused}
|
onFocus={this.onTextAreaFocused}
|
||||||
onBlur={this.onTextAreaBlur}
|
onBlur={this.onTextAreaBlur}
|
||||||
onChange={this.onTextAreaChange}
|
onChange={this.onTextAreaChange}
|
||||||
onInput={this.onTextAreaInput}
|
onInput={this.onTextAreaInput}
|
||||||
onKeyDown={this.onKeyDown}
|
onKeyDown={this.onKeyDown}
|
||||||
style={{ fontSize: this.termFontSize }}
|
style={{ fontSize: this.termFontSize }}
|
||||||
className="chat-textarea"
|
|
||||||
placeholder="Send a Message..."
|
placeholder="Send a Message..."
|
||||||
></textarea>
|
></textarea>
|
||||||
</div>
|
</div>
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
// Apply a border between the base cmdinput and any views shown above it
|
// Apply a border between the base cmdinput and any views shown above it
|
||||||
// TODO: use a generic selector for this
|
// TODO: use a generic selector for this
|
||||||
&.has-aichat,
|
// &.has-aichat,
|
||||||
&.has-history,
|
&.has-history,
|
||||||
&.has-info,
|
&.has-info,
|
||||||
&.has-suggestions {
|
&.has-suggestions {
|
||||||
@ -21,8 +21,8 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.has-history,
|
// &.has-aichat,
|
||||||
&.has-aichat {
|
&.has-history {
|
||||||
height: max(300px, 70%);
|
height: max(300px, 70%);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,9 +86,9 @@ class CmdInput extends React.Component<{}, {}> {
|
|||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
const inputModel = GlobalModel.inputModel;
|
const inputModel = GlobalModel.inputModel;
|
||||||
if (inputModel.getActiveAuxView() === appconst.InputAuxView_AIChat) {
|
if (inputModel.getActiveAuxView() === appconst.InputAuxView_AIChat) {
|
||||||
inputModel.closeAuxView();
|
// inputModel.closeAuxView();
|
||||||
} else {
|
} else {
|
||||||
inputModel.openAIAssistantChat();
|
// inputModel.openAIAssistantChat();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,10 +191,10 @@ class CmdInput extends React.Component<{}, {}> {
|
|||||||
<div className="cmd-input-grow-spacer"></div>
|
<div className="cmd-input-grow-spacer"></div>
|
||||||
<HistoryInfo />
|
<HistoryInfo />
|
||||||
</When>
|
</When>
|
||||||
<When condition={openView === appconst.InputAuxView_AIChat}>
|
{/* <When condition={openView === appconst.InputAuxView_AIChat}>
|
||||||
<div className="cmd-input-grow-spacer"></div>
|
<div className="cmd-input-grow-spacer"></div>
|
||||||
<AIChat />
|
<AIChat />
|
||||||
</When>
|
</When> */}
|
||||||
<When condition={openView === appconst.InputAuxView_Info}>
|
<When condition={openView === appconst.InputAuxView_Info}>
|
||||||
<InfoMsg key="infomsg" />
|
<InfoMsg key="infomsg" />
|
||||||
</When>
|
</When>
|
||||||
|
@ -620,6 +620,8 @@ class TextAreaInput extends React.Component<{ screen: Screen; onHeightChange: ()
|
|||||||
|
|
||||||
const renderCmdInputKeybindings = inputModel.shouldRenderAuxViewKeybindings(null);
|
const renderCmdInputKeybindings = inputModel.shouldRenderAuxViewKeybindings(null);
|
||||||
const renderHistoryKeybindings = inputModel.shouldRenderAuxViewKeybindings(appconst.InputAuxView_History);
|
const renderHistoryKeybindings = inputModel.shouldRenderAuxViewKeybindings(appconst.InputAuxView_History);
|
||||||
|
console.log("renderCmdInputKeybindings", renderCmdInputKeybindings);
|
||||||
|
console.log("renderHistoryKeybindings", renderHistoryKeybindings);
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="textareainput-div control is-expanded"
|
className="textareainput-div control is-expanded"
|
||||||
|
@ -3,26 +3,25 @@
|
|||||||
|
|
||||||
import type React from "react";
|
import type React from "react";
|
||||||
import * as mobx from "mobx";
|
import * as mobx from "mobx";
|
||||||
import type { Model } from "./model";
|
import { Model } from "./model";
|
||||||
import { GlobalCommandRunner } from "./global";
|
import { GlobalCommandRunner } from "./global";
|
||||||
|
|
||||||
class AIChatModel {
|
class AIChatModel {
|
||||||
globalModel: Model;
|
globalModel: Model;
|
||||||
aiChatTextAreaRef: React.RefObject<HTMLTextAreaElement>;
|
chatTextAreaRef: React.RefObject<HTMLTextAreaElement>;
|
||||||
aiChatWindowRef: React.RefObject<HTMLDivElement>;
|
chatWindowRef: React.RefObject<HTMLDivElement>;
|
||||||
codeSelectBlockRefArray: Array<React.RefObject<HTMLElement>>;
|
codeSelectBlockRefArray: Array<React.RefObject<HTMLElement>>;
|
||||||
codeSelectSelectedIndex: OV<number> = mobx.observable.box(-1);
|
codeSelectSelectedIndex: OV<number> = mobx.observable.box(-1);
|
||||||
codeSelectUuid: string;
|
codeSelectUuid: string;
|
||||||
|
|
||||||
aiCmdInfoChatItems: mobx.IObservableArray<OpenAICmdInfoChatMessageType> = mobx.observable.array([], {
|
aiCmdInfoChatItems: mobx.IObservableArray<OpenAICmdInfoChatMessageType> = mobx.observable.array([], {
|
||||||
name: "aicmdinfo-chat",
|
name: "aicmdinfo-chat",
|
||||||
});
|
});
|
||||||
|
isFocused: OV<boolean> = mobx.observable.box(false, {
|
||||||
|
name: "isFocused",
|
||||||
|
});
|
||||||
readonly codeSelectTop: number = -2;
|
readonly codeSelectTop: number = -2;
|
||||||
readonly codeSelectBottom: number = -1;
|
readonly codeSelectBottom: number = -1;
|
||||||
|
|
||||||
// focus
|
|
||||||
physicalInputFocused: OV<boolean> = mobx.observable.box(false);
|
|
||||||
|
|
||||||
constructor(globalModel: Model) {
|
constructor(globalModel: Model) {
|
||||||
this.globalModel = globalModel;
|
this.globalModel = globalModel;
|
||||||
mobx.makeObservable(this);
|
mobx.makeObservable(this);
|
||||||
@ -33,39 +32,20 @@ class AIChatModel {
|
|||||||
this.codeSelectUuid = "";
|
this.codeSelectUuid = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Focuses the main input or the auxiliary view, depending on the active auxiliary view
|
|
||||||
@mobx.action
|
@mobx.action
|
||||||
giveFocus(): void {
|
focus(): void {
|
||||||
// focus aichat sidebar input
|
if (this.chatTextAreaRef?.current != null) {
|
||||||
|
this.chatTextAreaRef.current.focus();
|
||||||
|
}
|
||||||
|
this.isFocused.set(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@mobx.action
|
@mobx.action
|
||||||
setPhysicalInputFocused(isFocused: boolean): void {
|
unFocus() {
|
||||||
this.physicalInputFocused.set(isFocused);
|
if (this.chatTextAreaRef?.current != null) {
|
||||||
if (isFocused) {
|
this.chatTextAreaRef.current.blur();
|
||||||
const screen = this.globalModel.getActiveScreen();
|
|
||||||
if (screen != null) {
|
|
||||||
if (screen.focusType.get() != "input") {
|
|
||||||
GlobalCommandRunner.screenSetFocus("input");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
this.isFocused.set(false);
|
||||||
|
|
||||||
hasFocus(): boolean {
|
|
||||||
const mainInputElem = document.getElementById("main-cmd-input");
|
|
||||||
if (document.activeElement == mainInputElem) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
const historyInputElem = document.querySelector(".cmd-input input.history-input");
|
|
||||||
if (document.activeElement == historyInputElem) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
let aiChatInputElem = document.querySelector(".cmd-input chat-cmd-input");
|
|
||||||
if (document.activeElement == aiChatInputElem) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@mobx.action
|
@mobx.action
|
||||||
@ -74,27 +54,23 @@ class AIChatModel {
|
|||||||
this.codeSelectBlockRefArray = [];
|
this.codeSelectBlockRefArray = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
closeAuxView(): void {
|
close(): void {
|
||||||
// close and give focus back to main input
|
// close and give focus back to main input
|
||||||
}
|
}
|
||||||
|
|
||||||
shouldRenderAuxViewKeybindings(view: InputAuxViewType): boolean {
|
shouldRenderKeybindings(view: InputAuxViewType): boolean {
|
||||||
// when aichat sidebar is mounted, it will render the keybindings
|
// when aichat sidebar is mounted, it will render the keybindings
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
setCmdInfoChatRefs(
|
setRefs(textAreaRef: React.RefObject<HTMLTextAreaElement>, chatWindowRef: React.RefObject<HTMLDivElement>) {
|
||||||
textAreaRef: React.RefObject<HTMLTextAreaElement>,
|
this.chatTextAreaRef = textAreaRef;
|
||||||
chatWindowRef: React.RefObject<HTMLDivElement>
|
this.chatWindowRef = chatWindowRef;
|
||||||
) {
|
|
||||||
this.aiChatTextAreaRef = textAreaRef;
|
|
||||||
this.aiChatWindowRef = chatWindowRef;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setAIChatFocus() {
|
unsetRefs() {
|
||||||
if (this.aiChatTextAreaRef?.current != null) {
|
this.chatTextAreaRef = null;
|
||||||
this.aiChatTextAreaRef.current.focus();
|
this.chatWindowRef = null;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
addCodeBlockToCodeSelect(blockRef: React.RefObject<HTMLElement>, uuid: string): number {
|
addCodeBlockToCodeSelect(blockRef: React.RefObject<HTMLElement>, uuid: string): number {
|
||||||
@ -113,14 +89,14 @@ class AIChatModel {
|
|||||||
if (blockIndex >= 0 && blockIndex < this.codeSelectBlockRefArray.length) {
|
if (blockIndex >= 0 && blockIndex < this.codeSelectBlockRefArray.length) {
|
||||||
this.codeSelectSelectedIndex.set(blockIndex);
|
this.codeSelectSelectedIndex.set(blockIndex);
|
||||||
const currentRef = this.codeSelectBlockRefArray[blockIndex].current;
|
const currentRef = this.codeSelectBlockRefArray[blockIndex].current;
|
||||||
if (currentRef != null && this.aiChatWindowRef?.current != null) {
|
if (currentRef != null && this.chatWindowRef?.current != null) {
|
||||||
const chatWindowTop = this.aiChatWindowRef.current.scrollTop;
|
const chatWindowTop = this.chatWindowRef.current.scrollTop;
|
||||||
const chatWindowBottom = chatWindowTop + this.aiChatWindowRef.current.clientHeight - 100;
|
const chatWindowBottom = chatWindowTop + this.chatWindowRef.current.clientHeight - 100;
|
||||||
const elemTop = currentRef.offsetTop;
|
const elemTop = currentRef.offsetTop;
|
||||||
let elemBottom = elemTop - currentRef.offsetHeight;
|
let elemBottom = elemTop - currentRef.offsetHeight;
|
||||||
const elementIsInView = elemBottom < chatWindowBottom && elemTop > chatWindowTop;
|
const elementIsInView = elemBottom < chatWindowBottom && elemTop > chatWindowTop;
|
||||||
if (!elementIsInView) {
|
if (!elementIsInView) {
|
||||||
this.aiChatWindowRef.current.scrollTop = elemBottom - this.aiChatWindowRef.current.clientHeight / 3;
|
this.chatWindowRef.current.scrollTop = elemBottom - this.chatWindowRef.current.clientHeight / 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -139,8 +115,8 @@ class AIChatModel {
|
|||||||
const incBlockIndex = this.codeSelectSelectedIndex.get() + 1;
|
const incBlockIndex = this.codeSelectSelectedIndex.get() + 1;
|
||||||
if (this.codeSelectSelectedIndex.get() == this.codeSelectBlockRefArray.length - 1) {
|
if (this.codeSelectSelectedIndex.get() == this.codeSelectBlockRefArray.length - 1) {
|
||||||
this.codeSelectDeselectAll();
|
this.codeSelectDeselectAll();
|
||||||
if (this.aiChatWindowRef?.current != null) {
|
if (this.chatWindowRef?.current != null) {
|
||||||
this.aiChatWindowRef.current.scrollTop = this.aiChatWindowRef.current.scrollHeight;
|
this.chatWindowRef.current.scrollTop = this.chatWindowRef.current.scrollHeight;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (incBlockIndex >= 0 && incBlockIndex < this.codeSelectBlockRefArray.length) {
|
if (incBlockIndex >= 0 && incBlockIndex < this.codeSelectBlockRefArray.length) {
|
||||||
@ -162,8 +138,8 @@ class AIChatModel {
|
|||||||
const decBlockIndex = this.codeSelectSelectedIndex.get() - 1;
|
const decBlockIndex = this.codeSelectSelectedIndex.get() - 1;
|
||||||
if (decBlockIndex < 0) {
|
if (decBlockIndex < 0) {
|
||||||
this.codeSelectDeselectAll(this.codeSelectTop);
|
this.codeSelectDeselectAll(this.codeSelectTop);
|
||||||
if (this.aiChatWindowRef?.current != null) {
|
if (this.chatWindowRef?.current != null) {
|
||||||
this.aiChatWindowRef.current.scrollTop = 0;
|
this.chatWindowRef.current.scrollTop = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (decBlockIndex >= 0 && decBlockIndex < this.codeSelectBlockRefArray.length) {
|
if (decBlockIndex >= 0 && decBlockIndex < this.codeSelectBlockRefArray.length) {
|
||||||
|
@ -139,6 +139,7 @@ class InputModel {
|
|||||||
giveFocus(): void {
|
giveFocus(): void {
|
||||||
// Override active view to the main input if aux view does not have focus
|
// Override active view to the main input if aux view does not have focus
|
||||||
const activeAuxView = this.getAuxViewFocus() ? this.getActiveAuxView() : null;
|
const activeAuxView = this.getAuxViewFocus() ? this.getActiveAuxView() : null;
|
||||||
|
console.log("activeAuxView", activeAuxView);
|
||||||
switch (activeAuxView) {
|
switch (activeAuxView) {
|
||||||
case appconst.InputAuxView_History: {
|
case appconst.InputAuxView_History: {
|
||||||
const elem: HTMLElement = document.querySelector(".cmd-input input.history-input");
|
const elem: HTMLElement = document.querySelector(".cmd-input input.history-input");
|
||||||
@ -190,7 +191,7 @@ class InputModel {
|
|||||||
if (document.activeElement == historyInputElem) {
|
if (document.activeElement == historyInputElem) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
let aiChatInputElem = document.querySelector(".cmd-input chat-cmd-input");
|
let aiChatInputElem = document.querySelector(".cmd-input .chat-cmd-input");
|
||||||
if (document.activeElement == aiChatInputElem) {
|
if (document.activeElement == aiChatInputElem) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -459,17 +460,22 @@ class InputModel {
|
|||||||
this.giveFocus();
|
this.giveFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
shouldRenderAuxViewKeybindings(view: InputAuxViewType): boolean {
|
shouldRenderAuxViewKeybindings(view: InputAuxViewType, test?: string): boolean {
|
||||||
|
console.log("view", view, this.getAuxViewFocus(), this.getActiveAuxView());
|
||||||
if (GlobalModel.activeMainView.get() != "session") {
|
if (GlobalModel.activeMainView.get() != "session") {
|
||||||
|
console.log("1");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (GlobalModel.getActiveScreen()?.getFocusType() != "input") {
|
if (GlobalModel.getActiveScreen()?.getFocusType() != "input") {
|
||||||
|
console.log("2");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// (view == null) means standard cmdinput keybindings
|
// (view == null) means standard cmdinput keybindings
|
||||||
if (view == null) {
|
if (view == null) {
|
||||||
|
console.log("3");
|
||||||
return !this.getAuxViewFocus();
|
return !this.getAuxViewFocus();
|
||||||
} else {
|
} else {
|
||||||
|
console.log("4");
|
||||||
return this.getAuxViewFocus() && view == this.getActiveAuxView();
|
return this.getAuxViewFocus() && view == this.getActiveAuxView();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -659,6 +665,7 @@ class InputModel {
|
|||||||
|
|
||||||
@mobx.action
|
@mobx.action
|
||||||
openAIAssistantChat(): void {
|
openAIAssistantChat(): void {
|
||||||
|
console.log("openAIAssistantChat");
|
||||||
this.setActiveAuxView(appconst.InputAuxView_AIChat);
|
this.setActiveAuxView(appconst.InputAuxView_AIChat);
|
||||||
this.setAuxViewFocus(true);
|
this.setAuxViewFocus(true);
|
||||||
this.globalModel.sendActivity("aichat-open");
|
this.globalModel.sendActivity("aichat-open");
|
||||||
@ -759,23 +766,18 @@ class InputModel {
|
|||||||
|
|
||||||
@mobx.computed
|
@mobx.computed
|
||||||
get curLine(): string {
|
get curLine(): string {
|
||||||
console.log("triggered get curLine");
|
|
||||||
const hidx = this.historyIndex.get();
|
const hidx = this.historyIndex.get();
|
||||||
if (hidx < this.modHistory.length && this.modHistory[hidx] != null) {
|
if (hidx < this.modHistory.length && this.modHistory[hidx] != null) {
|
||||||
console.log("this.modHistory[hidx]", this.modHistory[hidx]);
|
|
||||||
return this.modHistory[hidx];
|
return this.modHistory[hidx];
|
||||||
}
|
}
|
||||||
const hitems = this.filteredHistoryItems;
|
const hitems = this.filteredHistoryItems;
|
||||||
if (hidx == 0 || hitems == null || hidx > hitems.length) {
|
if (hidx == 0 || hitems == null || hidx > hitems.length) {
|
||||||
console.log("returning empty string 1");
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
const hitem = hitems[hidx - 1];
|
const hitem = hitems[hidx - 1];
|
||||||
if (hitem == null) {
|
if (hitem == null) {
|
||||||
console.log("returning empty string 2");
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
console.log("returning hitem.cmdstr", hitem.cmdstr);
|
|
||||||
return hitem.cmdstr;
|
return hitem.cmdstr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1345,7 +1345,6 @@ class Model {
|
|||||||
interactive: boolean,
|
interactive: boolean,
|
||||||
runUpdate: boolean = true
|
runUpdate: boolean = true
|
||||||
): Promise<CommandRtnType> {
|
): Promise<CommandRtnType> {
|
||||||
console.log("cmdPk", cmdPk);
|
|
||||||
if (this.debugCmds > 0) {
|
if (this.debugCmds > 0) {
|
||||||
console.log("[cmd]", cmdPacketString(cmdPk));
|
console.log("[cmd]", cmdPacketString(cmdPk));
|
||||||
if (this.debugCmds > 1) {
|
if (this.debugCmds > 1) {
|
||||||
|
@ -461,7 +461,11 @@ class SourceCodeRenderer extends React.Component<
|
|||||||
ref={this.markdownRef}
|
ref={this.markdownRef}
|
||||||
onScroll={() => this.handleDivScroll()}
|
onScroll={() => this.handleDivScroll()}
|
||||||
>
|
>
|
||||||
<Markdown text={this.state.code} style={{ width: "100%", padding: "1rem" }} />
|
<Markdown
|
||||||
|
inputModel={GlobalModel.inputModel}
|
||||||
|
text={this.state.code}
|
||||||
|
style={{ width: "100%", padding: "1rem" }}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user