Improve Kodu promo behavior

This commit is contained in:
Saoud Rizwan
2024-08-25 17:38:48 -04:00
parent d2be6b7030
commit 79250e9b57
9 changed files with 101 additions and 48 deletions

View File

@@ -2,14 +2,14 @@ import React, { useCallback, useEffect, useMemo, useState } from "react"
import { useEvent } from "react-use"
import { ApiConfiguration } from "../../src/shared/api"
import { ClaudeMessage, ExtensionMessage } from "../../src/shared/ExtensionMessage"
import { HistoryItem } from "../../src/shared/HistoryItem"
import "./App.css"
import { normalizeApiConfiguration } from "./components/ApiOptions"
import ChatView from "./components/ChatView"
import HistoryView from "./components/HistoryView"
import SettingsView from "./components/SettingsView"
import WelcomeView from "./components/WelcomeView"
import { vscode } from "./utils/vscode"
import HistoryView from "./components/HistoryView"
import { HistoryItem } from "../../src/shared/HistoryItem"
/*
The contents of webviews however are created when the webview becomes visible and destroyed when the webview is moved into the background. Any state inside the webview will be lost when the webview is moved to a background tab.
@@ -34,7 +34,7 @@ const App: React.FC = () => {
const [showAnnouncement, setShowAnnouncement] = useState(false)
const [koduCredits, setKoduCredits] = useState<number | undefined>(undefined)
const [isNewUser, setIsNewUser] = useState(false)
const [shouldShowKoduPromo, setShouldShowKoduPromo] = useState(true)
useEffect(() => {
vscode.postMessage({ type: "webviewDidLaunch" })
}, [])
@@ -71,6 +71,7 @@ const App: React.FC = () => {
if (message.state!.shouldShowAnnouncement) {
setShowAnnouncement(true)
}
setShouldShowKoduPromo(message.state!.shouldShowKoduPromo)
setDidHydrateState(true)
break
case "action":
@@ -167,6 +168,7 @@ const App: React.FC = () => {
}}
apiConfiguration={apiConfiguration}
vscodeUriScheme={vscodeUriScheme}
shouldShowKoduPromo={shouldShowKoduPromo}
/>
</>
)}

View File

@@ -1,6 +1,6 @@
import { VSCodeButton, VSCodeLink } from "@vscode/webview-ui-toolkit/react"
import { ApiConfiguration } from "../../../src/shared/api"
import { getKoduHomepageUrl, getKoduSignInUrl } from "../../../src/shared/kodu"
import { getKoduSignInUrl } from "../../../src/shared/kodu"
import VSCodeButtonLink from "./VSCodeButtonLink"
interface AnnouncementProps {
@@ -34,25 +34,19 @@ const Announcement = ({ version, hideAnnouncement, apiConfiguration, vscodeUriSc
<ul style={{ margin: "0 0 8px", paddingLeft: "20px" }}>
<li>
Excited to announce that{" "}
<VSCodeLink
href={apiConfiguration?.koduApiKey ? getKoduHomepageUrl() : getKoduSignInUrl(vscodeUriScheme)}
style={{ display: "inline" }}>
Kodu
</VSCodeLink>{" "}
is offering $10 free credits to help new users get the most out of Claude Dev with high rate limits
and prompt caching! Stay tuned for some exciting updates like easier billing and deploying live
websites.
Excited to announce that we've partnered with Anthropic and are offering $20 free credits to help
users get the most out of Claude Dev with high rate limits and prompt caching! Stay tuned for some
exciting updates like easier billing, voice mode and one click deployment.
{apiConfiguration?.koduApiKey === undefined && (
<VSCodeButtonLink
appearance="secondary"
href={getKoduSignInUrl(vscodeUriScheme)}
style={{
transform: "scale(0.8)",
transform: "scale(0.85)",
transformOrigin: "left center",
margin: "4px 0 2px 0",
}}>
Claim $10 Free Credits
Claim $20 Free Credits with Kodu
</VSCodeButtonLink>
)}
</li>

View File

@@ -17,6 +17,7 @@ import TaskHeader from "./TaskHeader"
import Thumbnails from "./Thumbnails"
import { HistoryItem } from "../../../src/shared/HistoryItem"
import { ApiConfiguration } from "../../../src/shared/api"
import KoduPromo from "./KoduPromo"
interface ChatViewProps {
version: string
@@ -31,6 +32,7 @@ interface ChatViewProps {
showHistoryView: () => void
apiConfiguration?: ApiConfiguration
vscodeUriScheme?: string
shouldShowKoduPromo: boolean
}
const MAX_IMAGES_PER_MESSAGE = 20 // Anthropic limits to 20 images
@@ -48,6 +50,7 @@ const ChatView = ({
showHistoryView,
apiConfiguration,
vscodeUriScheme,
shouldShowKoduPromo,
}: ChatViewProps) => {
//const task = messages.length > 0 ? (messages[0].say === "task" ? messages[0] : undefined) : undefined) : undefined
const task = messages.length > 0 ? messages[0] : undefined // leaving this less safe version here since if the first message is not a task, then the extension is in a bad state and needs to be debugged (see ClaudeDev.abort)
@@ -495,6 +498,9 @@ const ChatView = ({
vscodeUriScheme={vscodeUriScheme}
/>
)}
{apiConfiguration?.koduApiKey === undefined && !showAnnouncement && shouldShowKoduPromo && (
<KoduPromo vscodeUriScheme={vscodeUriScheme} style={{ margin: "10px 15px -10px 15px" }} />
)}
<div style={{ padding: "0 20px", flexGrow: taskHistory.length > 0 ? undefined : 1 }}>
<h2>What can I do for you?</h2>
<p>

View File

@@ -0,0 +1,69 @@
import React from "react"
import { getKoduSignInUrl } from "../../../src/shared/kodu"
import { vscode } from "../utils/vscode"
interface KoduPromoProps {
vscodeUriScheme?: string
style?: React.CSSProperties
}
const KoduPromo: React.FC<KoduPromoProps> = ({ vscodeUriScheme, style }) => {
function onClose() {
vscode.postMessage({ type: "didDismissKoduPromo" })
}
return (
<div style={{ ...style }}>
<div
style={{
display: "flex",
alignItems: "center",
justifyContent: "space-between",
backgroundColor: "var(--vscode-editor-inactiveSelectionBackground)",
color: "var(--vscode-textLink-foreground)",
padding: "6px 8px",
borderRadius: "3px",
margin: "0 0 8px 0px",
fontSize: "12px",
cursor: "pointer",
}}>
<a
href={getKoduSignInUrl(vscodeUriScheme)}
style={{
textDecoration: "none",
color: "inherit",
outline: "none",
display: "flex",
alignItems: "center",
}}>
<i
className="codicon codicon-info"
style={{
marginRight: 6,
fontSize: 16,
}}></i>
<span>Claim $20 free credits from Kodu</span>
</a>
<button
onClick={onClose}
style={{
background: "none",
border: "none",
color: "var(--vscode-textLink-foreground)",
cursor: "pointer",
fontSize: "12px",
opacity: 0.7,
padding: 0,
marginLeft: 4,
marginTop: 2,
}}
onMouseEnter={(e) => (e.currentTarget.style.opacity = "1")}
onMouseLeave={(e) => (e.currentTarget.style.opacity = "0.7")}>
<i className="codicon codicon-close"></i>
</button>
</div>
</div>
)
}
export default KoduPromo

View File

@@ -1,16 +1,15 @@
import {
VSCodeButton,
VSCodeCheckbox,
VSCodeLink,
VSCodeTextArea,
VSCodeTextField,
VSCodeCheckbox,
} from "@vscode/webview-ui-toolkit/react"
import React, { useEffect, useState } from "react"
import { ApiConfiguration } from "../../../src/shared/api"
import { validateApiConfiguration, validateMaxRequestsPerTask } from "../utils/validate"
import { vscode } from "../utils/vscode"
import ApiOptions from "./ApiOptions"
import { getKoduSignInUrl } from "../../../src/shared/kodu"
type SettingsViewProps = {
version: string
@@ -106,36 +105,6 @@ const SettingsView = ({
</div>
<div
style={{ flexGrow: 1, overflowY: "scroll", paddingRight: 8, display: "flex", flexDirection: "column" }}>
{apiConfiguration?.koduApiKey === undefined && (
<a
href={getKoduSignInUrl(vscodeUriScheme)}
style={{
textDecoration: "none",
color: "inherit",
outline: "none",
}}>
<div
style={{
display: "flex",
alignItems: "center",
backgroundColor: "var(--vscode-editor-inactiveSelectionBackground)",
color: "var(--vscode-textLink-foreground)",
padding: "6px 8px",
borderRadius: "3px",
margin: "0 0 8px 0px",
fontSize: "12px",
cursor: "pointer",
}}>
<i
className="codicon codicon-info"
style={{
marginRight: 6,
fontSize: 16,
}}></i>
<span>Claim $10 free credits from Kodu</span>
</div>
</a>
)}
<div style={{ marginBottom: 5 }}>
<ApiOptions
apiConfiguration={apiConfiguration}

View File

@@ -60,7 +60,7 @@ const WelcomeView: React.FC<WelcomeViewProps> = ({ apiConfiguration, setApiConfi
color: "var(--vscode-infoIcon-foreground)",
}}></i>
<span>
Explore Claude's capabilities with $10 free credits from{" "}
Explore Claude's capabilities with $20 free credits from{" "}
<VSCodeLink href={getKoduSignInUrl(vscodeUriScheme)} style={{ display: "inline" }}>
Kodu
</VSCodeLink>