Skip to content

Commit 825781f

Browse files
msukkariclaude
andcommitted
chore: add CHANGELOG entry for #939
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 28c6076 commit 825781f

File tree

5 files changed

+32
-35
lines changed

5 files changed

+32
-35
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1414
- Added `wa_user_created` PostHog event fired on successful user sign-up. [#933](https://github.com/sourcebot-dev/sourcebot/pull/933)
1515
- Added `wa_askgh_login_wall_prompted` PostHog event fired when an unauthenticated user attempts to ask a question on Ask GitHub. [#933](https://github.com/sourcebot-dev/sourcebot/pull/933)
1616
- Added Bitbucket Server (Data Center) OAuth 2.0 SSO identity provider support (`provider: "bitbucket-server"`). [#934](https://github.com/sourcebot-dev/sourcebot/pull/934)
17+
- Added login wall when anonymous users try to send messages on duplicated chats (askgh experiment). [#939](https://github.com/sourcebot-dev/sourcebot/pull/939)
1718

1819
### Changed
1920
- Hide version upgrade toast for askgithub deployment (`EXPERIMENT_ASK_GH_ENABLED`). [#931](https://github.com/sourcebot-dev/sourcebot/pull/931)

packages/web/src/app/[domain]/chat/[id]/components/chatThreadPanel.tsx

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { ResizablePanel } from '@/components/ui/resizable';
44
import { ChatThread } from '@/features/chat/components/chatThread';
55
import { LanguageModelInfo, SBChatMessage, SearchScope, SET_CHAT_STATE_SESSION_STORAGE_KEY, SetChatStatePayload } from '@/features/chat/types';
66
import { RepositoryQuery, SearchContextQuery } from '@/lib/types';
7-
import type { IdentityProviderMetadata } from '@/lib/identityProviders';
87
import { CreateUIMessage } from 'ai';
98
import { useEffect, useState } from 'react';
109
import { useChatId } from '../../useChatId';
@@ -19,8 +18,6 @@ interface ChatThreadPanelProps {
1918
isOwner: boolean;
2019
isAuthenticated: boolean;
2120
chatName?: string;
22-
providers: IdentityProviderMetadata[];
23-
isAskGhEnabled: boolean;
2421
}
2522

2623
export const ChatThreadPanel = ({
@@ -32,8 +29,6 @@ export const ChatThreadPanel = ({
3229
isOwner,
3330
isAuthenticated,
3431
chatName,
35-
providers,
36-
isAskGhEnabled,
3732
}: ChatThreadPanelProps) => {
3833
// @note: we are guaranteed to have a chatId because this component will only be
3934
// mounted when on a /chat/[id] route.
@@ -81,8 +76,6 @@ export const ChatThreadPanel = ({
8176
isOwner={isOwner}
8277
isAuthenticated={isAuthenticated}
8378
chatName={chatName}
84-
providers={providers}
85-
isAskGhEnabled={isAskGhEnabled}
8679
/>
8780
</div>
8881
</ResizablePanel>

packages/web/src/app/[domain]/chat/[id]/page.tsx

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@ import { ChatVisibility } from '@sourcebot/db';
1818
import { Metadata } from 'next';
1919
import { SBChatMessage } from '@/features/chat/types';
2020
import { env, hasEntitlement } from '@sourcebot/shared';
21-
import { getIdentityProviderMetadata } from '@/lib/identityProviders';
22-
2321
import { captureEvent } from '@/lib/posthog';
2422

2523
interface PageProps {
@@ -152,9 +150,6 @@ export default async function Page(props: PageProps) {
152150

153151
const hasChatSharingEntitlement = hasEntitlement('chat-sharing');
154152

155-
const isAskGhEnabled = env.EXPERIMENT_ASK_GH_ENABLED === 'true';
156-
const providers = isAskGhEnabled ? getIdentityProviderMetadata() : [];
157-
158153
return (
159154
<div className="flex flex-col h-screen w-screen">
160155
<TopBar
@@ -201,8 +196,6 @@ export default async function Page(props: PageProps) {
201196
isOwner={isOwner}
202197
isAuthenticated={!!session}
203198
chatName={name ?? undefined}
204-
providers={providers}
205-
isAskGhEnabled={isAskGhEnabled}
206199
/>
207200
</ResizablePanelGroup>
208201
</div>

packages/web/src/features/chat/actions.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -981,6 +981,16 @@ export const _getAISDKLanguageModelAndOptions = async (config: LanguageModel): P
981981

982982
}
983983

984+
export const getAskGhLoginWallData = async () => sew(async () => {
985+
const isEnabled = env.EXPERIMENT_ASK_GH_ENABLED === 'true';
986+
if (!isEnabled) {
987+
return { isEnabled: false as const, providers: [] };
988+
}
989+
990+
const { getIdentityProviderMetadata } = await import('@/lib/identityProviders');
991+
return { isEnabled: true as const, providers: getIdentityProviderMetadata() };
992+
});
993+
984994
const extractLanguageModelKeyValuePairs = async (
985995
pairs: {
986996
[k: string]: string | Token;

packages/web/src/features/chat/components/chatThread/chatThread.tsx

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import { SignInPromptBanner } from './signInPromptBanner';
3030
import { DuplicateChatDialog } from '@/app/[domain]/chat/components/duplicateChatDialog';
3131
import { LoginModal } from '@/app/components/loginModal';
3232
import type { IdentityProviderMetadata } from '@/lib/identityProviders';
33+
import { getAskGhLoginWallData } from '../../actions';
3334
import { useParams } from 'next/navigation';
3435

3536
type ChatHistoryState = {
@@ -50,8 +51,6 @@ interface ChatThreadProps {
5051
isOwner?: boolean;
5152
isAuthenticated?: boolean;
5253
chatName?: string;
53-
providers?: IdentityProviderMetadata[];
54-
isAskGhEnabled?: boolean;
5554
}
5655

5756
export const ChatThread = ({
@@ -66,8 +65,6 @@ export const ChatThread = ({
6665
isOwner = true,
6766
isAuthenticated = false,
6867
chatName,
69-
providers = [],
70-
isAskGhEnabled = false,
7168
}: ChatThreadProps) => {
7269
const [isErrorBannerVisible, setIsErrorBannerVisible] = useState(false);
7370
const scrollAreaRef = useRef<HTMLDivElement>(null);
@@ -80,6 +77,7 @@ export const ChatThread = ({
8077
const [isContextSelectorOpen, setIsContextSelectorOpen] = useState(false);
8178
const [isDuplicateDialogOpen, setIsDuplicateDialogOpen] = useState(false);
8279
const [isLoginModalOpen, setIsLoginModalOpen] = useState(false);
80+
const [loginWallProviders, setLoginWallProviders] = useState<IdentityProviderMetadata[]>([]);
8381
const hasRestoredPendingMessage = useRef(false);
8482
const captureEvent = useCaptureEvent();
8583

@@ -212,7 +210,7 @@ export const ChatThread = ({
212210

213211
// Restore pending message after OAuth redirect (askgh login wall)
214212
useEffect(() => {
215-
if (!isAskGhEnabled || !isAuthenticated || !isOwner || hasRestoredPendingMessage.current) {
213+
if (!isAuthenticated || !isOwner || hasRestoredPendingMessage.current) {
216214
return;
217215
}
218216

@@ -240,7 +238,7 @@ export const ChatThread = ({
240238
} catch (error) {
241239
console.error('Failed to restore pending message:', error);
242240
}
243-
}, [isAskGhEnabled, isAuthenticated, isOwner, chatId, sendMessage, selectedSearchScopes]);
241+
}, [isAuthenticated, isOwner, chatId, sendMessage, selectedSearchScopes]);
244242

245243
// Track scroll position changes.
246244
useEffect(() => {
@@ -329,12 +327,16 @@ export const ChatThread = ({
329327
}
330328
}, [error]);
331329

332-
const onSubmit = useCallback((children: Descendant[], editor: CustomEditor) => {
333-
if (isAskGhEnabled && !isAuthenticated) {
334-
captureEvent('wa_askgh_login_wall_prompted', {});
335-
sessionStorage.setItem(PENDING_MESSAGE_STORAGE_KEY, JSON.stringify({ chatId, children }));
336-
setIsLoginModalOpen(true);
337-
return;
330+
const onSubmit = useCallback(async (children: Descendant[], editor: CustomEditor) => {
331+
if (!isAuthenticated) {
332+
const result = await getAskGhLoginWallData();
333+
if (!isServiceError(result) && result.isEnabled) {
334+
captureEvent('wa_askgh_login_wall_prompted', {});
335+
sessionStorage.setItem(PENDING_MESSAGE_STORAGE_KEY, JSON.stringify({ chatId, children }));
336+
setLoginWallProviders(result.providers);
337+
setIsLoginModalOpen(true);
338+
return;
339+
}
338340
}
339341

340342
const text = slateContentToString(children);
@@ -346,7 +348,7 @@ export const ChatThread = ({
346348
setIsAutoScrollEnabled(true);
347349

348350
resetEditor(editor);
349-
}, [sendMessage, selectedSearchScopes, isAskGhEnabled, isAuthenticated, captureEvent, chatId]);
351+
}, [sendMessage, selectedSearchScopes, isAuthenticated, captureEvent, chatId]);
350352

351353
const onDuplicate = useCallback(async (newName: string): Promise<string | null> => {
352354
if (!defaultChatId) {
@@ -499,14 +501,12 @@ export const ChatThread = ({
499501
)}
500502
</div>
501503

502-
{isAskGhEnabled && (
503-
<LoginModal
504-
isOpen={isLoginModalOpen}
505-
onOpenChange={setIsLoginModalOpen}
506-
providers={providers}
507-
callbackUrl={typeof window !== 'undefined' ? window.location.href : ''}
508-
/>
509-
)}
504+
<LoginModal
505+
isOpen={isLoginModalOpen}
506+
onOpenChange={setIsLoginModalOpen}
507+
providers={loginWallProviders}
508+
callbackUrl={typeof window !== 'undefined' ? window.location.href : ''}
509+
/>
510510
</>
511511
);
512512
}

0 commit comments

Comments
 (0)