summaryrefslogtreecommitdiff
path: root/extension/react-app/src/pages/gui.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'extension/react-app/src/pages/gui.tsx')
-rw-r--r--extension/react-app/src/pages/gui.tsx107
1 files changed, 65 insertions, 42 deletions
diff --git a/extension/react-app/src/pages/gui.tsx b/extension/react-app/src/pages/gui.tsx
index 70031d40..9bb558c7 100644
--- a/extension/react-app/src/pages/gui.tsx
+++ b/extension/react-app/src/pages/gui.tsx
@@ -6,7 +6,7 @@ import {
} from "../components";
import Loader from "../components/Loader";
import ContinueButton from "../components/ContinueButton";
-import { FullState, HighlightedRangeContext } from "../../../schema/FullState";
+import { ContextItem, FullState } from "../../../schema/FullState";
import { useCallback, useEffect, useRef, useState, useContext } from "react";
import { History } from "../../../schema/History";
import { HistoryNode } from "../../../schema/HistoryNode";
@@ -22,12 +22,16 @@ import TextDialog from "../components/TextDialog";
import HeaderButtonWithText from "../components/HeaderButtonWithText";
import ReactSwitch from "react-switch";
import { usePostHog } from "posthog-js/react";
-import { useSelector } from "react-redux";
+import { useDispatch, useSelector } from "react-redux";
import { RootStore } from "../redux/store";
import { postVscMessage } from "../vscode";
import UserInputContainer from "../components/UserInputContainer";
import Onboarding from "../components/Onboarding";
import { isMetaEquivalentKeyPressed } from "../util";
+import {
+ setBottomMessage,
+ setBottomMessageCloseTimeout,
+} from "../redux/slices/uiStateSlice";
const TopGUIDiv = styled.div`
overflow: hidden;
@@ -64,9 +68,6 @@ function GUI(props: GUIProps) {
const vscMachineId = useSelector(
(state: RootStore) => state.config.vscMachineId
);
- const vscMediaUrl = useSelector(
- (state: RootStore) => state.config.vscMediaUrl
- );
const [dataSwitchChecked, setDataSwitchChecked] = useState(false);
const dataSwitchOn = useSelector(
(state: RootStore) => state.config.dataSwitchOn
@@ -80,15 +81,13 @@ function GUI(props: GUIProps) {
const [waitingForSteps, setWaitingForSteps] = useState(false);
const [userInputQueue, setUserInputQueue] = useState<string[]>([]);
- const [highlightedRanges, setHighlightedRanges] = useState<
- HighlightedRangeContext[]
- >([]);
const [addingHighlightedCode, setAddingHighlightedCode] = useState(false);
+ const [selectedContextItems, setSelectedContextItems] = useState<
+ ContextItem[]
+ >([]);
const [availableSlashCommands, setAvailableSlashCommands] = useState<
{ name: string; description: string }[]
>([]);
- const [pinned, setPinned] = useState(false);
- const [showDataSharingInfo, setShowDataSharingInfo] = useState(false);
const [stepsOpen, setStepsOpen] = useState<boolean[]>([
true,
true,
@@ -117,10 +116,36 @@ function GUI(props: GUIProps) {
current_index: 3,
} as any);
+ const vscMediaUrl = useSelector(
+ (state: RootStore) => state.config.vscMediaUrl
+ );
const [showFeedbackDialog, setShowFeedbackDialog] = useState(false);
const [feedbackDialogMessage, setFeedbackDialogMessage] = useState("");
const [feedbackEntryOn, setFeedbackEntryOn] = useState(true);
+ const dispatch = useDispatch();
+ const bottomMessage = useSelector(
+ (state: RootStore) => state.uiState.bottomMessage
+ );
+
+ const [displayBottomMessageOnBottom, setDisplayBottomMessageOnBottom] =
+ useState<boolean>(true);
+ const mainTextInputRef = useRef<HTMLInputElement>(null);
+
+ const aboveComboBoxDivRef = useRef<HTMLDivElement>(null);
+
+ useEffect(() => {
+ if (!aboveComboBoxDivRef.current) return;
+ if (
+ aboveComboBoxDivRef.current.getBoundingClientRect().top >
+ window.innerHeight / 2
+ ) {
+ setDisplayBottomMessageOnBottom(false);
+ } else {
+ setDisplayBottomMessageOnBottom(true);
+ }
+ }, [bottomMessage, aboveComboBoxDivRef.current]);
+
const topGuiDivRef = useRef<HTMLDivElement>(null);
const [scrollTimeout, setScrollTimeout] = useState<NodeJS.Timeout | null>(
@@ -152,6 +177,8 @@ function GUI(props: GUIProps) {
history.timeline[history.current_index]?.active
) {
client?.deleteAtIndex(history.current_index);
+ } else if (e.key === "Escape") {
+ dispatch(setBottomMessage(undefined));
}
};
window.addEventListener("keydown", listener);
@@ -178,7 +205,7 @@ function GUI(props: GUIProps) {
setWaitingForSteps(waitingForSteps);
setHistory(state.history);
- setHighlightedRanges(state.highlighted_ranges);
+ setSelectedContextItems(state.selected_context_items || []);
setUserInputQueue(state.user_input_queue);
setAddingHighlightedCode(state.adding_highlighted_code);
setAvailableSlashCommands(
@@ -211,15 +238,6 @@ function GUI(props: GUIProps) {
scrollToBottom();
}, [waitingForSteps]);
- const mainTextInputRef = useRef<HTMLInputElement>(null);
-
- const deleteContextItems = useCallback(
- (indices: number[]) => {
- client?.deleteContextAtIndices(indices);
- },
- [client]
- );
-
const onMainTextInput = (event?: any) => {
if (mainTextInputRef.current) {
let input = (mainTextInputRef.current as any).inputValue;
@@ -351,6 +369,7 @@ function GUI(props: GUIProps) {
})}
</div>
+ <div ref={aboveComboBoxDivRef} />
<ComboBox
ref={mainTextInputRef}
onEnter={(e) => {
@@ -360,11 +379,7 @@ function GUI(props: GUIProps) {
}}
onInputValueChange={() => {}}
items={availableSlashCommands}
- highlightedCodeSections={highlightedRanges}
- deleteContextItems={deleteContextItems}
- onTogglePin={() => {
- setPinned((prev: boolean) => !prev);
- }}
+ selectedContextItems={selectedContextItems}
onToggleAddContext={() => {
client?.toggleAddingHighlightedCode();
}}
@@ -373,29 +388,34 @@ function GUI(props: GUIProps) {
<ContinueButton onClick={onMainTextInput} />
</TopGUIDiv>
<div
+ onMouseEnter={() => {
+ dispatch(setBottomMessageCloseTimeout(undefined));
+ }}
+ onMouseLeave={(e) => {
+ if (!e.buttons) {
+ dispatch(setBottomMessage(undefined));
+ }
+ }}
style={{
position: "fixed",
- bottom: "50px",
+ bottom: displayBottomMessageOnBottom ? "50px" : undefined,
+ top: displayBottomMessageOnBottom ? undefined : "50px",
+ left: "0",
+ right: "0",
+ margin: "8px",
+ marginTop: "0px",
backgroundColor: vscBackground,
color: vscForeground,
borderRadius: defaultBorderRadius,
- padding: "16px",
- margin: "16px",
+ padding: "12px",
zIndex: 100,
- boxShadow: `0px 0px 10px 0px ${vscForeground}`,
+ boxShadow: `0px 0px 4px 0px ${vscForeground}`,
+ maxHeight: "50vh",
+ overflow: "scroll",
}}
- hidden={!showDataSharingInfo}
+ hidden={!bottomMessage}
>
- By turning on this switch, you will begin collecting accepted and
- rejected suggestions in .continue/suggestions.json. This data is stored
- locally on your machine and not sent anywhere.
- <br />
- <br />
- <b>
- {dataSwitchChecked
- ? "👍 Data is being collected"
- : "👎 No data is being collected"}
- </b>
+ {bottomMessage}
</div>
<Footer dataSwitchChecked={dataSwitchChecked}>
{vscMediaUrl && (
@@ -403,10 +423,13 @@ function GUI(props: GUIProps) {
href="https://github.com/continuedev/continue"
style={{ marginRight: "auto" }}
>
- <img src={`${vscMediaUrl}/continue-dev-square.png`} width="22px" />
+ <img
+ src={`${vscMediaUrl}/continue-dev-square.png`}
+ width="22px"
+ style={{ backgroundColor: "black", color: "red" }}
+ />
</a>
)}
- {/* <p style={{ margin: "0", marginRight: "auto" }}>Continue</p> */}
<HeaderButtonWithText
onClick={() => {
// Show the dialog