Skip to content

Commit 9f2350c

Browse files
authored
Merge pull request #8636 from continuedev/continue/con-4856
feat: restore feedback modal for user interest collection
2 parents 521480e + da7baa5 commit 9f2350c

File tree

4 files changed

+89
-2
lines changed

4 files changed

+89
-2
lines changed
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import { usePostHog } from "posthog-js/react";
2+
import { Button, Input, SecondaryButton } from "..";
3+
import { useAppDispatch } from "../../redux/hooks";
4+
import { setDialogMessage, setShowDialog } from "../../redux/slices/uiSlice";
5+
6+
export default function FeedbackDialog() {
7+
const posthog = usePostHog();
8+
const dispatch = useAppDispatch();
9+
10+
return (
11+
<div className="mx-auto flex max-w-md flex-col p-6 pt-8">
12+
<div className="flex items-center gap-2 text-lg font-medium">
13+
<span>👋</span>
14+
<span>Help us improve Continue</span>
15+
</div>
16+
17+
<p className="text-foreground text-sm leading-relaxed">
18+
We're always working to make Continue better and would love to hear from
19+
you. If you're interested in sharing your experience, please enter your
20+
details below.
21+
</p>
22+
23+
<form
24+
onSubmit={(e: any) => {
25+
e.preventDefault();
26+
posthog?.capture("user_interest_form", {
27+
name: e.target.elements[0].value,
28+
email: e.target.elements[1].value,
29+
});
30+
dispatch(
31+
setDialogMessage(
32+
<div className="p-6 text-center">
33+
<div className="mb-2 text-lg">✓ Thank you!</div>
34+
<p className="text-foreground text-sm">
35+
We'll be in touch soon.
36+
</p>
37+
</div>,
38+
),
39+
);
40+
41+
// Auto-close after 2 seconds
42+
setTimeout(() => {
43+
dispatch(setShowDialog(false));
44+
dispatch(setDialogMessage(undefined));
45+
}, 2000);
46+
}}
47+
className="flex flex-col gap-3"
48+
>
49+
<Input type="text" name="name" placeholder="Name" required />
50+
<Input type="email" name="email" placeholder="Email" required />
51+
<div className="mt-2 flex justify-between gap-2">
52+
<SecondaryButton
53+
className="flex-1"
54+
type="button"
55+
onClick={() => {
56+
dispatch(setShowDialog(false));
57+
dispatch(setDialogMessage(undefined));
58+
}}
59+
>
60+
Not now
61+
</SecondaryButton>
62+
<Button className="flex-1" type="submit">
63+
Submit
64+
</Button>
65+
</div>
66+
</form>
67+
68+
<p className="text-description-muted text-xs">
69+
We'll only use this information to reach out for feedback.
70+
</p>
71+
</div>
72+
);
73+
}

gui/src/pages/gui/Chat.tsx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,15 @@ import { ToolCallDiv } from "./ToolCallDiv";
4747
import { useStore } from "react-redux";
4848
import { BackgroundModeView } from "../../components/BackgroundMode/BackgroundModeView";
4949
import { CliInstallBanner } from "../../components/CliInstallBanner";
50+
import FeedbackDialog from "../../components/dialogs/FeedbackDialog";
5051

5152
import { FatalErrorIndicator } from "../../components/config/FatalErrorNotice";
5253
import InlineErrorMessage from "../../components/mainInput/InlineErrorMessage";
5354
import { resolveEditorContent } from "../../components/mainInput/TipTapEditor/utils/resolveEditorContent";
55+
import { setDialogMessage, setShowDialog } from "../../redux/slices/uiSlice";
5456
import { RootState } from "../../redux/store";
5557
import { cancelStream } from "../../redux/thunks/cancelStream";
58+
import { getLocalStorage, setLocalStorage } from "../../util/localStorage";
5659
import { EmptyChatBody } from "./EmptyChatBody";
5760
import { ExploreDialogWatcher } from "./ExploreDialogWatcher";
5861
import { useAutoScroll } from "./useAutoScroll";
@@ -269,6 +272,18 @@ export function Chat() {
269272
editorToClearOnSend.commands.clearContent();
270273
}
271274
}
275+
276+
// Increment localstorage counter for popup
277+
const currentCount = getLocalStorage("mainTextEntryCounter");
278+
if (currentCount) {
279+
setLocalStorage("mainTextEntryCounter", currentCount + 1);
280+
if (currentCount === 300) {
281+
dispatch(setDialogMessage(<FeedbackDialog />));
282+
dispatch(setShowDialog(true));
283+
}
284+
} else {
285+
setLocalStorage("mainTextEntryCounter", 1);
286+
}
272287
},
273288
[dispatch, ideMessenger, reduxStore, setIsCreatingAgent],
274289
);

gui/src/redux/slices/uiSlice.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ export type ToolGroupPolicies = { [toolGroupName: string]: ToolGroupPolicy };
1919
type UIState = {
2020
showDialog: boolean;
2121
dialogMessage: JSX.Element | undefined;
22-
dialogEntryOn: boolean;
2322
onboardingCard: OnboardingCardState;
2423
isExploreDialogOpen: boolean;
2524
hasDismissedExploreDialog: boolean;
@@ -35,7 +34,6 @@ export const DEFAULT_RULE_SETTING: RulePolicy = "on";
3534
export const DEFAULT_UI_SLICE: UIState = {
3635
showDialog: false,
3736
dialogMessage: undefined,
38-
dialogEntryOn: false,
3937
onboardingCard: defaultOnboardingCardState,
4038
isExploreDialogOpen:
4139
getLocalStorage(LocalStorageKey.IsExploreDialogOpen) ?? false,

gui/src/util/localStorage.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ type LocalStorageTypes = {
66
hasDismissedExploreDialog: boolean;
77
onboardingStatus?: OnboardingStatus;
88
hasDismissedOnboardingCard: boolean;
9+
mainTextEntryCounter: number;
910
ide: "vscode" | "jetbrains";
1011
vsCodeUriScheme: string;
1112
fontSize: number;

0 commit comments

Comments
 (0)