Skip to content
Merged
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
22 changes: 18 additions & 4 deletions webview-ui/src/components/chat/ShareButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,20 +35,32 @@ export const ShareButton = ({ item, disabled = false }: ShareButtonProps) => {
const { t } = useTranslation()
const { sharingEnabled, cloudIsAuthenticated, cloudUserInfo } = useExtensionState()
const wasUnauthenticatedRef = useRef(false)
const initiatedAuthFromThisButtonRef = useRef(false)

// Track authentication state changes to auto-open popover after login
useEffect(() => {
if (!cloudIsAuthenticated || !sharingEnabled) {
wasUnauthenticatedRef.current = true
} else if (wasUnauthenticatedRef.current && cloudIsAuthenticated && sharingEnabled) {
// User just authenticated, send telemetry, close modal, and open the popover
telemetryClient.capture(TelemetryEventName.ACCOUNT_CONNECT_SUCCESS)
setConnectModalOpen(false)
setShareDropdownOpen(true)
// Only open dropdown if auth was initiated from this button
if (initiatedAuthFromThisButtonRef.current) {
// User just authenticated from this share button, send telemetry, close modal, and open the popover
telemetryClient.capture(TelemetryEventName.ACCOUNT_CONNECT_SUCCESS)
setConnectModalOpen(false)
setShareDropdownOpen(true)
initiatedAuthFromThisButtonRef.current = false // Reset the flag
}
wasUnauthenticatedRef.current = false
}
}, [cloudIsAuthenticated, sharingEnabled])

// Cleanup effect to reset flag on unmount
useEffect(() => {
return () => {
initiatedAuthFromThisButtonRef.current = false
}
}, [])

// Listen for share success messages from the extension
useEffect(() => {
const handleMessage = (event: MessageEvent) => {
Expand Down Expand Up @@ -92,6 +104,8 @@ export const ShareButton = ({ item, disabled = false }: ShareButtonProps) => {
// Send telemetry for connect to cloud action
telemetryClient.capture(TelemetryEventName.SHARE_CONNECT_TO_CLOUD_CLICKED)

// Mark that authentication was initiated from this button
initiatedAuthFromThisButtonRef.current = true
vscode.postMessage({ type: "rooCloudSignIn" })
setShareDropdownOpen(false)
setConnectModalOpen(false)
Expand Down
46 changes: 43 additions & 3 deletions webview-ui/src/components/chat/__tests__/TaskActions.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ describe("TaskActions", () => {
expect(screen.queryByText("Connect to Cloud")).not.toBeInTheDocument()
})

it("automatically opens popover when user becomes authenticated", () => {
it("does not automatically open popover when user becomes authenticated from elsewhere", () => {
// Start with unauthenticated state
mockUseExtensionState.mockReturnValue({
sharingEnabled: false,
Expand All @@ -277,7 +277,7 @@ describe("TaskActions", () => {
// Verify popover is not open initially
expect(screen.queryByText("Share with Organization")).not.toBeInTheDocument()

// Simulate user becoming authenticated
// Simulate user becoming authenticated (e.g., from AccountView)
mockUseExtensionState.mockReturnValue({
sharingEnabled: true,
cloudIsAuthenticated: true,
Expand All @@ -288,7 +288,47 @@ describe("TaskActions", () => {

rerender(<TaskActions item={mockItem} buttonsDisabled={false} />)

// Verify popover automatically opens and shows sharing options
// Verify popover does NOT automatically open when auth happens from elsewhere
expect(screen.queryByText("Share with Organization")).not.toBeInTheDocument()
expect(screen.queryByText("Share Publicly")).not.toBeInTheDocument()
})

it("automatically opens popover when user authenticates from share button", () => {
// Start with unauthenticated state
mockUseExtensionState.mockReturnValue({
sharingEnabled: false,
cloudIsAuthenticated: false,
} as any)

const { rerender } = render(<TaskActions item={mockItem} buttonsDisabled={false} />)

// Click share button to open connect modal
const buttons = screen.getAllByRole("button")
const shareButton = buttons.find((btn) => btn.querySelector(".codicon-link"))
expect(shareButton).toBeDefined()
fireEvent.click(shareButton!)

// Click connect button to initiate authentication
const connectButton = screen.getByText("Connect")
fireEvent.click(connectButton)

// Verify rooCloudSignIn message was sent
expect(mockPostMessage).toHaveBeenCalledWith({
type: "rooCloudSignIn",
})

// Simulate user becoming authenticated after clicking connect from share button
mockUseExtensionState.mockReturnValue({
sharingEnabled: true,
cloudIsAuthenticated: true,
cloudUserInfo: {
organizationName: "Test Organization",
},
} as any)

rerender(<TaskActions item={mockItem} buttonsDisabled={false} />)

// Verify popover automatically opens when auth was initiated from share button
expect(screen.getByText("Share with Organization")).toBeInTheDocument()
expect(screen.getByText("Share Publicly")).toBeInTheDocument()
})
Expand Down
Loading