Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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
1 change: 0 additions & 1 deletion .github/workflows/vercel-prod-on-release.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
name: Deploy to Vercel Production on Release

on:
workflow_dispatch:
release:
Comment on lines 3 to 4
types: [published]

Expand Down
24 changes: 3 additions & 21 deletions src/app/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@
import './App.css';
import AppRouter from './router/Router';
import { MemoryRouter } from 'react-router-dom';
import { useDispatch } from 'react-redux';
import { anonymousLogin } from './store/profile-reducer';
import { app } from '../firebase';
import { Suspense, useEffect, useState } from 'react';
import { Suspense } from 'react';
import { useAuthReady } from './components/AuthSessionProvider';
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
import AppContainer from './AppContainer';
Expand All @@ -32,29 +30,13 @@ function buildPathFromNextRouter(
}

function App({ locale }: AppProps): React.ReactElement {
const dispatch = useDispatch();
const [isAppReady, setIsAppReady] = useState(false);
const isAppReady = useAuthReady();

const pathname = usePathname();
const searchParams = useSearchParams();

const initialPath = buildPathFromNextRouter(pathname, searchParams, locale);

useEffect(() => {
const unsubscribe = app.auth().onAuthStateChanged((user) => {
if (user != null) {
setIsAppReady(true);
} else {
setIsAppReady(false);
dispatch(anonymousLogin());
}
});
dispatch(anonymousLogin());
return () => {
unsubscribe();
};
}, [dispatch]);

return (
<Suspense>
<LocalizationProvider dateAdapter={AdapterDayjs}>
Expand Down
6 changes: 3 additions & 3 deletions src/app/[locale]/components/HomePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,23 +91,23 @@ export default async function HomePage(): Promise<ReactElement> {
mt: 4,
}}
>
{t('servingOver')}
{t('servingOver') + ' '}
<Box
component='span'
sx={{ fontSize: 30, color: 'primary.main', mx: 1 }}
itemProp='numberOfItems'
>
6000
</Box>
{t('feeds')}
{' ' + t('feeds') + ' '}
<Box
component='span'
sx={{ fontSize: 30, color: 'primary.main', mx: 1 }}
itemProp='spatialCoverage'
>
99
</Box>
{t('countries')}
{' ' + t('countries')}
</Typography>
<SearchBox />
<Box
Expand Down
38 changes: 2 additions & 36 deletions src/app/[locale]/feeds/lib/useFeedsSearch.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
'use client';
import { useEffect, useState } from 'react';
import useSWR, { useSWRConfig } from 'swr';
import { searchFeeds } from '../../../services/feeds';
import {
type AllFeedsType,
type AllFeedsParams,
} from '../../../services/feeds/utils';
import { getUserAccessToken } from '../../../services/profile-service';
import { app } from '../../../../firebase';
import { useAuthReady } from '../../../components/AuthSessionProvider';
import {
getDataTypeParamFromSelectedFeedTypes,
getInitialSelectedFeedTypes,
Expand All @@ -18,39 +17,6 @@ const SEARCH_LIMIT = 20;
// This is for client-side caching
const CACHE_TTL_MS = 60 * 30 * 1000; // 30 minutes - controls how long search results are cached in SWR

/**
* Ensures a Firebase user exists (anonymous or authenticated) before
* SWR attempts to fetch. If no user is signed in, triggers anonymous
* sign-in — the same thing App.tsx does for legacy React Router pages.
* This is needed for the access token
*
* TODO: Revisit this logic to be used at a more global level without slowing down the initial load of all pages that don't require auth (e.g. about, contact). For example, we could move this logic to a context provider that's used only on the feeds page and its children.
*/
function useFirebaseAuthReady(): boolean {
const [isReady, setIsReady] = useState(() => app.auth().currentUser !== null);

useEffect(() => {
const unsubscribe = app.auth().onAuthStateChanged((user) => {
if (user !== null) {
setIsReady(true);
} else {
// No user — trigger anonymous sign-in (mirrors App.tsx behavior)
setIsReady(false);
app
.auth()
.signInAnonymously()
.catch(() => {
// Auth listener will handle the state update on success;
// if sign-in fails, isReady stays false and SWR won't fetch.
});
}
});
return unsubscribe;
}, []);

return isReady;
}

/**
* Derives all API query params from the URL search params.
* This is the single source of truth — no duplicated React state.
Expand Down Expand Up @@ -192,7 +158,7 @@ export function useFeedsSearch(searchParams: URLSearchParams): {
isError: boolean;
searchLimit: number;
} {
const authReady = useFirebaseAuthReady();
const authReady = useAuthReady();
const { cache } = useSWRConfig();
const derivedSearchParams = deriveSearchParams(searchParams);
const key = authReady ? buildSwrKey(derivedSearchParams) : null;
Expand Down
Loading
Loading