fix apply state actions
This commit is contained in:
@@ -58,14 +58,6 @@ export function ApplyActions(props: ApplyActionsProps) {
|
||||
);
|
||||
|
||||
switch (props.applyState ? props.applyState.status : null) {
|
||||
case "not-started":
|
||||
return (
|
||||
<div className="flex select-none items-center rounded bg-zinc-700 pl-2 pr-1">
|
||||
<span className="text-lightgray inline-flex w-min items-center gap-2 text-center text-xs">
|
||||
Pending
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
case "streaming":
|
||||
return (
|
||||
<div className="flex select-none items-center rounded bg-zinc-700 pl-2 pr-1">
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
import Spinner from "../../gui/Spinner";
|
||||
|
||||
export interface GeneratingCodeLoaderProps {
|
||||
showLineCount: boolean;
|
||||
codeBlockContent: string;
|
||||
isPending: boolean;
|
||||
}
|
||||
|
||||
export function GeneratingCodeLoader({
|
||||
showLineCount,
|
||||
codeBlockContent,
|
||||
isPending,
|
||||
}: GeneratingCodeLoaderProps) {
|
||||
const numLinesCodeBlock = codeBlockContent.split("\n").length;
|
||||
const linesGeneratedText =
|
||||
numLinesCodeBlock === 1
|
||||
? `1 line generated`
|
||||
: `${numLinesCodeBlock} lines ${isPending ? "pending" : "generated"}`;
|
||||
|
||||
return (
|
||||
<span className="text-lightgray inline-flex items-center gap-2">
|
||||
{showLineCount ? linesGeneratedText : "Generating"}
|
||||
{!isPending && <Spinner />}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
@@ -11,14 +11,15 @@ import { IdeMessengerContext } from "../../../context/IdeMessenger";
|
||||
import { useIdeMessengerRequest } from "../../../hooks";
|
||||
import { useWebviewListener } from "../../../hooks/useWebviewListener";
|
||||
import { useAppSelector } from "../../../redux/hooks";
|
||||
import { selectCurrentToolCallApplyState } from "../../../redux/selectors/selectCurrentToolCall";
|
||||
import { selectApplyStateByStreamId } from "../../../redux/slices/sessionSlice";
|
||||
import { getFontSize } from "../../../util";
|
||||
import Spinner from "../../gui/Spinner";
|
||||
import { isTerminalCodeBlock } from "../utils";
|
||||
import { ApplyActions } from "./ApplyActions";
|
||||
import { CopyButton } from "./CopyButton";
|
||||
import { CreateFileButton } from "./CreateFileButton";
|
||||
import { FileInfo } from "./FileInfo";
|
||||
import { GeneratingCodeLoader } from "./GeneratingCodeLoader";
|
||||
import { InsertButton } from "./InsertButton";
|
||||
import { RunInTerminalButton } from "./RunInTerminalButton";
|
||||
|
||||
@@ -49,8 +50,9 @@ export interface StepContainerPreToolbarProps {
|
||||
codeBlockContent: string;
|
||||
language: string | null;
|
||||
relativeFilepath?: string;
|
||||
isFinalCodeblock: boolean;
|
||||
itemIndex?: number;
|
||||
codeBlockIndex: number; // To track which codeblock we are applying
|
||||
isLastCodeblock: boolean;
|
||||
codeBlockStreamId: string;
|
||||
range?: string;
|
||||
children: any;
|
||||
@@ -62,8 +64,9 @@ export function StepContainerPreToolbar({
|
||||
codeBlockContent,
|
||||
language,
|
||||
relativeFilepath,
|
||||
isFinalCodeblock,
|
||||
itemIndex,
|
||||
codeBlockIndex,
|
||||
isLastCodeblock,
|
||||
codeBlockStreamId,
|
||||
range,
|
||||
children,
|
||||
@@ -71,6 +74,7 @@ export function StepContainerPreToolbar({
|
||||
disableManualApply,
|
||||
}: StepContainerPreToolbarProps) {
|
||||
const ideMessenger = useContext(IdeMessengerContext);
|
||||
const history = useAppSelector((state) => state.session.history);
|
||||
const [isExpanded, setIsExpanded] = useState(expanded ?? true);
|
||||
|
||||
const [relativeFilepathUri, setRelativeFilepathUri] = useState<string | null>(
|
||||
@@ -95,6 +99,9 @@ export function StepContainerPreToolbar({
|
||||
const applyState = useAppSelector((state) =>
|
||||
selectApplyStateByStreamId(state, codeBlockStreamId),
|
||||
);
|
||||
const currentToolCallApplyState = useAppSelector(
|
||||
selectCurrentToolCallApplyState,
|
||||
);
|
||||
|
||||
/**
|
||||
* In the case where `relativeFilepath` is defined, this will just be `relativeFilepathUri`.
|
||||
@@ -110,7 +117,12 @@ export function StepContainerPreToolbar({
|
||||
relativeFilepath && /\.[0-9a-z]+$/i.test(relativeFilepath);
|
||||
|
||||
const isStreaming = useAppSelector((store) => store.session.isStreaming);
|
||||
const isGeneratingCodeBlock = isFinalCodeblock && isStreaming;
|
||||
|
||||
const isLastItem = useMemo(() => {
|
||||
return itemIndex === history.length - 1;
|
||||
}, [history.length, itemIndex]);
|
||||
|
||||
const isGeneratingCodeBlock = isLastItem && isLastCodeblock && isStreaming;
|
||||
|
||||
// If we are creating a file, we already render that in the button
|
||||
// so we don't want to dispaly it twice here
|
||||
@@ -221,6 +233,32 @@ export function StepContainerPreToolbar({
|
||||
}
|
||||
|
||||
const renderActionButtons = () => {
|
||||
const isPendingToolCall =
|
||||
currentToolCallApplyState &&
|
||||
currentToolCallApplyState.streamId === applyState?.streamId &&
|
||||
currentToolCallApplyState.status === "not-started";
|
||||
|
||||
if (isGeneratingCodeBlock || isPendingToolCall) {
|
||||
const numLines = codeBlockContent.split("\n").length;
|
||||
const plural = numLines === 1 ? "" : "s";
|
||||
if (isGeneratingCodeBlock) {
|
||||
return (
|
||||
<span className="text-lightgray inline-flex w-min items-center gap-2">
|
||||
{!isExpanded ? `${numLines} line${plural} generated` : "Generating"}{" "}
|
||||
<div>
|
||||
<Spinner />
|
||||
</div>
|
||||
</span>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<span className="text-lightgray inline-flex w-min items-center gap-2">
|
||||
{`${numLines} line${plural} pending`}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (isTerminalCodeBlock(language, codeBlockContent)) {
|
||||
return <RunInTerminalButton command={codeBlockContent} />;
|
||||
}
|
||||
@@ -281,17 +319,7 @@ export function StepContainerPreToolbar({
|
||||
</div>
|
||||
)}
|
||||
|
||||
{isGeneratingCodeBlock || applyState?.status === "not-started" ? (
|
||||
<GeneratingCodeLoader
|
||||
showLineCount={!isExpanded}
|
||||
codeBlockContent={codeBlockContent}
|
||||
isPending={
|
||||
applyState?.status === "not-started" && !isGeneratingCodeBlock
|
||||
}
|
||||
/>
|
||||
) : (
|
||||
renderActionButtons()
|
||||
)}
|
||||
{renderActionButtons()}
|
||||
</div>
|
||||
</ToolbarDiv>
|
||||
|
||||
|
||||
@@ -193,11 +193,7 @@ const StyledMarkdownPreview = memo(function StyledMarkdownPreview(
|
||||
};
|
||||
}, [props.itemIndex, history, allSymbols]);
|
||||
const pastFileInfoRef = useUpdatingRef(pastFileInfo);
|
||||
|
||||
const isLastItem = useMemo(() => {
|
||||
return props.itemIndex === history.length - 1;
|
||||
}, [history.length, props.itemIndex]);
|
||||
const isLastItemRef = useUpdatingRef(isLastItem);
|
||||
const itemIndexRef = useUpdatingRef(props.itemIndex);
|
||||
|
||||
const codeblockStreamIds = useRef<string[]>([]);
|
||||
useEffect(() => {
|
||||
@@ -296,8 +292,7 @@ const StyledMarkdownPreview = memo(function StyledMarkdownPreview(
|
||||
|
||||
const language = getLanguageFromClassName(className);
|
||||
|
||||
const isFinalCodeblock =
|
||||
preChildProps["data-islastcodeblock"] && isLastItemRef.current;
|
||||
const isLastCodeblock = preChildProps["data-islastcodeblock"];
|
||||
|
||||
if (codeblockStreamIds.current[codeBlockIndex] === undefined) {
|
||||
codeblockStreamIds.current[codeBlockIndex] =
|
||||
@@ -307,10 +302,11 @@ const StyledMarkdownPreview = memo(function StyledMarkdownPreview(
|
||||
return (
|
||||
<StepContainerPreToolbar
|
||||
codeBlockContent={codeBlockContent}
|
||||
itemIndex={itemIndexRef.current}
|
||||
codeBlockIndex={codeBlockIndex}
|
||||
language={language}
|
||||
relativeFilepath={relativeFilePath}
|
||||
isFinalCodeblock={isFinalCodeblock}
|
||||
isLastCodeblock={isLastCodeblock}
|
||||
range={range}
|
||||
codeBlockStreamId={codeblockStreamIds.current[codeBlockIndex]}
|
||||
expanded={props.expandCodeblocks}
|
||||
|
||||
@@ -57,11 +57,11 @@ export function LumpToolbar() {
|
||||
if (metaKey && event.key === "Enter") {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
dispatch(callCurrentTool());
|
||||
void dispatch(callCurrentTool());
|
||||
} else if ((jetbrains ? altKey : metaKey) && event.key === "Backspace") {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
dispatch(cancelCurrentToolCall());
|
||||
void dispatch(cancelCurrentToolCall());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -19,7 +19,7 @@ export function EditFile(props: EditToolCallProps) {
|
||||
const src = `\`\`\`${getMarkdownLanguageTagForFile(props.relativeFilePath ?? "test.txt")} ${props.relativeFilePath}\n${props.changes ?? ""}\n\`\`\``;
|
||||
|
||||
const dispatch = useAppDispatch();
|
||||
const isStreaming = useAppSelector((state) => state.session.isStreaming);
|
||||
|
||||
const applyState = useAppSelector((state) =>
|
||||
selectApplyStateByToolCallId(state, props.toolCallId),
|
||||
);
|
||||
|
||||
@@ -27,8 +27,8 @@ function FunctionSpecificToolCallDiv({
|
||||
case BuiltInToolNames.EditExistingFile:
|
||||
return (
|
||||
<EditFile
|
||||
relativeFilePath={args.filepath}
|
||||
changes={args.changes}
|
||||
relativeFilePath={args.filepath ?? ""}
|
||||
changes={args.changes ?? ""}
|
||||
toolCallId={toolCall.id}
|
||||
historyIndex={historyIndex}
|
||||
/>
|
||||
|
||||
@@ -63,7 +63,6 @@ export const streamNormalInput = createAsyncThunk<
|
||||
dispatch(abortStream());
|
||||
break;
|
||||
}
|
||||
|
||||
dispatch(streamUpdate(next.value));
|
||||
next = await gen.next();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user