Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions packages/types/src/global-settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export const globalSettingsSchema = z.object({
lastShownAnnouncementId: z.string().optional(),
customInstructions: z.string().optional(),
taskHistory: z.array(historyItemSchema).optional(),
showCloudPromotion: z.boolean().optional(),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding a more descriptive comment here explaining the purpose of this setting, e.g.:

Suggested change
showCloudPromotion: z.boolean().optional(),
showCloudPromotion: z.boolean().optional(), // Controls visibility of cloud promotion CTAs in the UI


// Image generation settings (experimental) - flattened for simplicity
openRouterImageApiKey: z.string().optional(),
Expand Down Expand Up @@ -321,6 +322,8 @@ export const EVALS_SETTINGS: RooCodeSettings = {
mode: "code", // "architect",

customModes: [],

showCloudPromotion: true, // Default to true to maintain current behavior
}

export const EVALS_TIMEOUT = 5 * 60 * 1_000
1 change: 1 addition & 0 deletions src/shared/ExtensionMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ export type ExtensionState = Pick<
// | "lastShownAnnouncementId"
| "customInstructions"
// | "taskHistory" // Optional in GlobalSettings, required here.
| "showCloudPromotion"
| "autoApprovalEnabled"
| "alwaysAllowReadOnly"
| "alwaysAllowReadOnlyOutsideWorkspace"
Expand Down
7 changes: 6 additions & 1 deletion webview-ui/src/components/chat/ChatView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
soundEnabled,
soundVolume,
cloudIsAuthenticated,
showCloudPromotion,
messageQueue = [],
} = useExtensionState()

Expand Down Expand Up @@ -1831,7 +1832,11 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
{telemetrySetting === "unset" && <TelemetryBanner />}

<div className="mb-2.5">
{cloudIsAuthenticated || taskHistory.length < 4 ? <RooTips /> : <RooCloudCTA />}
{cloudIsAuthenticated || taskHistory.length < 4 || !showCloudPromotion ? (
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The implementation looks correct. The conditional logic properly checks all three conditions: authentication status, task count, and the new showCloudPromotion setting. Good work maintaining backward compatibility by defaulting to true.

<RooTips />
) : (
<RooCloudCTA />
)}
</div>
{/* Show the task history preview if expanded and tasks exist */}
{taskHistory.length > 0 && isExpanded && <HistoryPreview />}
Expand Down
38 changes: 38 additions & 0 deletions webview-ui/src/components/chat/__tests__/ChatView.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1428,6 +1428,44 @@ describe("ChatView - RooCloudCTA Display Tests", () => {
expect(queryByTestId("roo-cloud-cta")).not.toBeInTheDocument()
expect(getByTestId("roo-tips")).toBeInTheDocument()
})

it("does not show RooCloudCTA when showCloudPromotion is false", () => {
const { queryByTestId, getByTestId } = renderChatView()

// Set showCloudPromotion to false
act(() => {
mockPostMessage({
showCloudPromotion: false,
cloudIsAuthenticated: false,
taskHistory: Array(5).fill({ id: "task", ts: Date.now() }),
clineMessages: [], // No active task
})
})

// Should not show RooCloudCTA when showCloudPromotion is false
expect(queryByTestId("roo-cloud-cta")).not.toBeInTheDocument()
// Should show RooTips instead
expect(getByTestId("roo-tips")).toBeInTheDocument()
})

it("shows RooCloudCTA when showCloudPromotion is true and conditions are met", async () => {
const { getByTestId } = renderChatView()

// Set showCloudPromotion to true with conditions met
act(() => {
mockPostMessage({
showCloudPromotion: true,
cloudIsAuthenticated: false,
taskHistory: Array(5).fill({ id: "task", ts: Date.now() }),
clineMessages: [], // No active task
})
})

// Should show RooCloudCTA when showCloudPromotion is true and conditions are met
await waitFor(() => {
expect(getByTestId("roo-cloud-cta")).toBeInTheDocument()
})
})
})

describe("ChatView - Message Queueing Tests", () => {
Expand Down
13 changes: 13 additions & 0 deletions webview-ui/src/context/ExtensionStateContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ export interface ExtensionStateContextType extends ExtensionState {
mdmCompliant?: boolean
hasOpenedModeSelector: boolean // New property to track if user has opened mode selector
setHasOpenedModeSelector: (value: boolean) => void // Setter for the new property
showCloudPromotion: boolean // New property for cloud promotion visibility
setShowCloudPromotion: (value: boolean) => void // Setter for cloud promotion
alwaysAllowFollowupQuestions: boolean // New property for follow-up questions auto-approve
setAlwaysAllowFollowupQuestions: (value: boolean) => void // Setter for the new property
followupAutoApproveTimeoutMs: number | undefined // Timeout in ms for auto-approving follow-up questions
Expand Down Expand Up @@ -255,6 +257,7 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode
maxDiagnosticMessages: 50,
openRouterImageApiKey: "",
openRouterImageGenerationSelectedModel: "",
showCloudPromotion: true, // Default to true to maintain current behavior
})

const [didHydrateState, setDidHydrateState] = useState(false)
Expand All @@ -274,6 +277,7 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode
global: {},
})
const [includeTaskHistoryInEnhance, setIncludeTaskHistoryInEnhance] = useState(true)
const [showCloudPromotion, setShowCloudPromotion] = useState(true) // Default to true
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good state management implementation. The setting is properly initialized, updated from backend messages, and exposed through the context. However, this won't work without the corresponding backend implementation in ClineProvider.ts.


const setListApiConfigMeta = useCallback(
(value: ProviderSettingsEntry[]) => setState((prevState) => ({ ...prevState, listApiConfigMeta: value })),
Expand Down Expand Up @@ -311,6 +315,10 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode
if ((newState as any).includeTaskHistoryInEnhance !== undefined) {
setIncludeTaskHistoryInEnhance((newState as any).includeTaskHistoryInEnhance)
}
// Update showCloudPromotion if present in state message
if ((newState as any).showCloudPromotion !== undefined) {
setShowCloudPromotion((newState as any).showCloudPromotion)
}
// Handle marketplace data if present in state message
if (newState.marketplaceItems !== undefined) {
setMarketplaceItems(newState.marketplaceItems)
Expand Down Expand Up @@ -527,6 +535,11 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode
},
includeTaskHistoryInEnhance,
setIncludeTaskHistoryInEnhance,
showCloudPromotion,
setShowCloudPromotion: (value) => {
setShowCloudPromotion(value)
setState((prevState) => ({ ...prevState, showCloudPromotion: value }))
},
}

return <ExtensionStateContext.Provider value={contextValue}>{children}</ExtensionStateContext.Provider>
Expand Down
Loading