Skip to content

Commit 232aaa6

Browse files
committed
fix: small cleanup
1 parent 93cb970 commit 232aaa6

3 files changed

Lines changed: 48 additions & 45 deletions

File tree

packages/shared/src/contexts/AuthContext.tsx

Lines changed: 9 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import React, {
88
} from 'react';
99
import type { QueryObserverResult } from '@tanstack/react-query';
1010
import { useRouter } from 'next/router';
11+
import type { GrowthBookContextValue } from '@growthbook/growthbook-react';
1112
import { GrowthBookContext } from '@growthbook/growthbook-react';
1213
import type { AnonymousUser, LoggedUser } from '../lib/user';
1314
import { deleteAccount, logout as dispatchLogout } from '../lib/user';
@@ -49,12 +50,6 @@ type ShowLoginParams = {
4950
options?: LoginOptions;
5051
};
5152

52-
type GrowthBookContextData = {
53-
growthbook?: {
54-
getFeatureValue: <T>(id: string, defaultValue: T) => T | undefined;
55-
};
56-
};
57-
5853
export interface AuthContextData {
5954
user?: LoggedUser;
6055
isLoggedIn: boolean;
@@ -85,7 +80,6 @@ export interface AuthContextData {
8580
isGdprCovered?: boolean;
8681
isValidRegion?: boolean;
8782
isFunnel?: boolean;
88-
inlineLoginEnabled?: boolean;
8983
}
9084

9185
const isExtension = checkIsExtension();
@@ -168,37 +162,19 @@ export const AuthContextProvider = ({
168162
isAndroidApp,
169163
}: AuthContextProviderProps): ReactElement => {
170164
const [loginState, setLoginState] = useState<LoginState | null>(null);
171-
const [inlineLoginEnabled, setInlineLoginEnabled] = useState<boolean>();
172-
const inlineLoginEnabledRef = useRef<boolean>();
173165
const endUser = user && 'providers' in user ? user : null;
174166
const referral = user?.referralId || user?.referrer;
175167
const referralOrigin = user?.referralOrigin;
176168
const router = useRouter();
177169
const isFunnelRef = useRef(!!router?.pathname?.startsWith(webFunnelPrefix));
178170
const growthbookContext = useContext(
179171
GrowthBookContext,
180-
) as unknown as GrowthBookContextData;
172+
) as unknown as GrowthBookContextValue;
181173
const growthbook = growthbookContext?.growthbook;
182174
const isValidRegion = useMemo(
183175
() => !invalidPlusRegions.includes(geo?.region),
184176
[geo?.region],
185177
);
186-
const evaluateInlineLogin = useCallback((): boolean => {
187-
if (!isNullOrUndefined(inlineLoginEnabledRef.current)) {
188-
return inlineLoginEnabledRef.current;
189-
}
190-
191-
const isEnabled =
192-
growthbook?.getFeatureValue<boolean>(
193-
inlineLoginFeatureId,
194-
inlineLoginDefaultValue,
195-
) === true;
196-
197-
inlineLoginEnabledRef.current = isEnabled;
198-
setInlineLoginEnabled(isEnabled);
199-
200-
return isEnabled;
201-
}, [growthbook]);
202178

203179
return (
204180
<AuthContext.Provider
@@ -212,7 +188,6 @@ export const AuthContextProvider = ({
212188
firstVisit: user?.firstVisit,
213189
trackingId: user?.id,
214190
shouldShowLogin: loginState !== null,
215-
inlineLoginEnabled,
216191
showLogin: useCallback(
217192
({ trigger, options = {} }) => {
218193
const hasCompanion = !!isCompanionActivated();
@@ -223,7 +198,12 @@ export const AuthContextProvider = ({
223198
}
224199

225200
const params = new URLSearchParams(globalThis?.location.search);
226-
const shouldUseInlineLogin = !isExtension && evaluateInlineLogin();
201+
const shouldUseInlineLogin =
202+
!isExtension &&
203+
growthbook?.getFeatureValue(
204+
inlineLoginFeatureId,
205+
inlineLoginDefaultValue,
206+
) === true;
227207

228208
setLoginState({ ...options, trigger });
229209
if (isExtension) {
@@ -247,7 +227,7 @@ export const AuthContextProvider = ({
247227

248228
router.push(onboardingPath);
249229
},
250-
[evaluateInlineLogin, router],
230+
[growthbook, router],
251231
),
252232
closeLogin: useCallback(() => setLoginState(null), []),
253233
loginState,

packages/shared/src/contexts/BootProvider.spec.tsx

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import type { ReactNode } from 'react';
22
import React, { useContext } from 'react';
3+
import type { NextRouter } from 'next/router';
4+
import { useRouter } from 'next/router';
35
import nock from 'nock';
46
import type { RenderResult } from '@testing-library/react';
57
import { fireEvent, render, screen } from '@testing-library/react';
@@ -47,9 +49,19 @@ jest.mock('../lib/user', () => {
4749

4850
const getRedirectUriMock = jest.fn();
4951

52+
const mockUseRouter = (router: Partial<NextRouter> = {}) => {
53+
jest.mocked(useRouter).mockReturnValue({
54+
query: {},
55+
push: jest.fn(),
56+
pathname: '/',
57+
...router,
58+
} as unknown as NextRouter);
59+
};
60+
5061
beforeEach(() => {
5162
nock.cleanAll();
5263
localStorage.clear();
64+
mockUseRouter();
5365
});
5466

5567
const defaultAlerts: Alerts = { filter: true, rankLastSeen: undefined };
@@ -417,7 +429,6 @@ const AuthMock = ({ updatedUser, loginTrigger }: AuthMockProps) => {
417429
getRedirectUri,
418430
trackingId,
419431
anonymous,
420-
inlineLoginEnabled,
421432
} = useContext(AuthContext);
422433

423434
return (
@@ -462,9 +473,6 @@ const AuthMock = ({ updatedUser, loginTrigger }: AuthMockProps) => {
462473
</button>
463474
<span data-test-value={trackingId}>Tracking ID</span>
464475
<span data-test-value={JSON.stringify(anonymous)}>Anonymous User</span>
465-
<span data-test-value={`${inlineLoginEnabled}`}>
466-
Inline Login Enabled
467-
</span>
468476
</>
469477
);
470478
};
@@ -505,7 +513,13 @@ it('should trigger show login callback', async () => {
505513
await expectToHaveTestValue(login, JSON.stringify({ trigger: expected }));
506514
});
507515

508-
it('should evaluate inline login only after auth intent', async () => {
516+
it('should keep inline login on page when enabled after auth intent', async () => {
517+
const push = jest.fn();
518+
mockUseRouter({
519+
push,
520+
pathname: '/posts/shared',
521+
});
522+
509523
renderComponent(<AuthMock loginTrigger={AuthTriggers.Comment} />, {
510524
...defaultBootData,
511525
user: defaultAnonymousUser,
@@ -522,12 +536,16 @@ it('should evaluate inline login only after auth intent', async () => {
522536
});
523537

524538
const login = await screen.findByText('Log in');
525-
const inlineLogin = await screen.findByText('Inline Login Enabled');
526-
await expectToHaveTestValue(inlineLogin, 'undefined');
539+
await expectToHaveTestValue(login, 'null');
540+
expect(push).not.toHaveBeenCalled();
527541

528542
fireEvent.click(login);
529543

530-
await expectToHaveTestValue(inlineLogin, 'true');
544+
await expectToHaveTestValue(
545+
login,
546+
JSON.stringify({ trigger: AuthTriggers.Comment }),
547+
);
548+
expect(push).not.toHaveBeenCalled();
531549
});
532550

533551
it('should trigger close login callback', async () => {

packages/webapp/pages/_app.tsx

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { ProgressiveEnhancementContextProvider } from '@dailydotdev/shared/src/c
2121
import { SubscriptionContextProvider } from '@dailydotdev/shared/src/contexts/SubscriptionContext';
2222
import { ShortcutsProvider } from '@dailydotdev/shared/src/features/shortcuts/contexts/ShortcutsProvider';
2323
import { canonicalFromRouter } from '@dailydotdev/shared/src/lib/canonical';
24+
import { featureInlineLogin } from '@dailydotdev/shared/src/lib/featureManagement';
2425
import '@dailydotdev/shared/src/styles/globals.css';
2526
import useLogPageView from '@dailydotdev/shared/src/hooks/log/useLogPageView';
2627
import { BootDataProvider } from '@dailydotdev/shared/src/contexts/BootProvider';
@@ -36,7 +37,10 @@ import { LazyModal } from '@dailydotdev/shared/src/components/modals/common/type
3637
import { defaultQueryClientConfig } from '@dailydotdev/shared/src/lib/query';
3738
import { useWebVitals } from '@dailydotdev/shared/src/hooks/useWebVitals';
3839
import { LazyModalElement } from '@dailydotdev/shared/src/components/modals/LazyModalElement';
39-
import { useManualScrollRestoration } from '@dailydotdev/shared/src/hooks';
40+
import {
41+
useConditionalFeature,
42+
useManualScrollRestoration,
43+
} from '@dailydotdev/shared/src/hooks';
4044
import { useScrollbarWidth } from '@dailydotdev/shared/src/hooks/useScrollbarWidth';
4145
import { PushNotificationContextProvider } from '@dailydotdev/shared/src/contexts/PushNotificationContext';
4246
import { SerwistProvider } from '@serwist/turbopack/react';
@@ -102,9 +106,8 @@ const onboardingExcludedPaths = [
102106
'/jobs',
103107
'/settings',
104108
];
105-
// Once auth intent assigns the user to inline_login, only force the rest of
106-
// onboarding when they land on the main feed. Everywhere else they can keep
107-
// browsing after the inline first step.
109+
// While inline_login is active for an auth intent, only force the rest of
110+
// onboarding when the user lands on the main feed.
108111
const mainFeedPathnames = new Set([
109112
'/',
110113
'/popular',
@@ -175,8 +178,11 @@ function InternalApp({ Component, pageProps, router }: AppProps): ReactElement {
175178
shouldShowLogin,
176179
closeLogin,
177180
loginState,
178-
inlineLoginEnabled,
179181
} = useAuthContext();
182+
const { value: inlineLoginEnabled } = useConditionalFeature({
183+
feature: featureInlineLogin,
184+
shouldEvaluate: shouldShowLogin,
185+
});
180186
const { showBanner, onAcceptCookies, onOpenBanner, onHideBanner } =
181187
useCookieBanner();
182188
useWebVitals();
@@ -238,9 +244,8 @@ function InternalApp({ Component, pageProps, router }: AppProps): ReactElement {
238244
return;
239245
}
240246

241-
// Inline login experiment: after auth intent enrolls the user, defer the
242-
// rest of onboarding until they navigate to the main feed; otherwise let
243-
// them keep browsing.
247+
// Inline login experiment: while the auth intent is active, defer the rest
248+
// of onboarding until they navigate to the main feed.
244249
if (inlineLoginEnabled && !mainFeedPathnames.has(router.pathname)) {
245250
return;
246251
}

0 commit comments

Comments
 (0)