mirror of
https://github.com/PeWu/topola-viewer.git
synced 2026-07-17 17:21:48 +00:00
Extract useGoogleAuth from app.tsx
This commit is contained in:
@@ -100,7 +100,7 @@ We will gradually eliminate React state variables in `src/app.tsx` and derive th
|
|||||||
* [x] **Step 3.4:** Extract `config` state. Parse display settings on render using `argsToConfig` helper. Remove state. In `ViewPage`, run `updateChartWithConfig(config, data)` synchronously during the render pass (e.g. in the `useMemo` that derives query parameters/config) to update the in-memory chart data before it is rendered by the `<Chart>` child component. Run E2E and visual tests to verify no rendering regressions occurred.
|
* [x] **Step 3.4:** Extract `config` state. Parse display settings on render using `argsToConfig` helper. Remove state. In `ViewPage`, run `updateChartWithConfig(config, data)` synchronously during the render pass (e.g. in the `useMemo` that derives query parameters/config) to update the in-memory chart data before it is rendered by the `<Chart>` child component. Run E2E and visual tests to verify no rendering regressions occurred.
|
||||||
|
|
||||||
#### Phase 4: Structural Page Nesting
|
#### Phase 4: Structural Page Nesting
|
||||||
* [ ] **Step 4.1:** Create `src/hooks/use_google_auth.ts` to manage Google Drive authentication token updates. Remove `hasGoogleToken` state from `src/app.tsx`.
|
* [x] **Step 4.1:** Create `src/hooks/use_google_auth.ts` to manage Google Drive authentication token updates. Remove `hasGoogleToken` state from `src/app.tsx`.
|
||||||
* [ ] **Step 4.2:** Create `src/pages/view_page.tsx` containing layout rendering (`renderMainArea`), asynchronous data loaders, view state management, `revokeObjectUrls` cleanups, and `<GoogleAuthModal>` error fallback state and rendering.
|
* [ ] **Step 4.2:** Create `src/pages/view_page.tsx` containing layout rendering (`renderMainArea`), asynchronous data loaders, view state management, `revokeObjectUrls` cleanups, and `<GoogleAuthModal>` error fallback state and rendering.
|
||||||
* [ ] **Step 4.3:** Create `src/pages/intro_page.tsx` rendering the landing screen and its own local header.
|
* [ ] **Step 4.3:** Create `src/pages/intro_page.tsx` rendering the landing screen and its own local header.
|
||||||
* [ ] **Step 4.4:** Refactor `src/app.tsx` to serve as a pure routing switch routing to `<IntroPage />` or `<ViewPage />`. In `App`, handle Google Drive redirection synchronously during the render pass by returning a `<Navigate replace />` element (preventing render flashing), and ensure the redirection parser checks both the router `location.search` and the external `window.location.search` to handle HashRouter query structure robustly. Once external parameters (like `state` or `authcode`) are detected, they must be stripped from `window.location.search` using `window.history.replaceState` to prevent redirection loops on page refresh. Remove all layout state logic from the root file, including moving the `useWebMcpBridge` hook invocation into `<ViewPage />`. Run final verification scripts (`npm run check:all`).
|
* [ ] **Step 4.4:** Refactor `src/app.tsx` to serve as a pure routing switch routing to `<IntroPage />` or `<ViewPage />`. In `App`, handle Google Drive redirection synchronously during the render pass by returning a `<Navigate replace />` element (preventing render flashing), and ensure the redirection parser checks both the router `location.search` and the external `window.location.search` to handle HashRouter query structure robustly. Once external parameters (like `state` or `authcode`) are detected, they must be stripped from `window.location.search` using `window.history.replaceState` to prevent redirection loops on page refresh. Remove all layout state logic from the root file, including moving the `useWebMcpBridge` hook invocation into `<ViewPage />`. Run final verification scripts (`npm run check:all`).
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ import {
|
|||||||
WikiTreeSourceSpec,
|
WikiTreeSourceSpec,
|
||||||
} from './datasource/wikitree';
|
} from './datasource/wikitree';
|
||||||
import {DonatsoChart} from './donatso-chart';
|
import {DonatsoChart} from './donatso-chart';
|
||||||
|
import {useGoogleAuth} from './hooks/use_google_auth';
|
||||||
import {useWebMcpBridge} from './hooks/use_webmcp_bridge';
|
import {useWebMcpBridge} from './hooks/use_webmcp_bridge';
|
||||||
import {Intro} from './intro';
|
import {Intro} from './intro';
|
||||||
import {GoogleAuthModal} from './menu/google_auth_modal';
|
import {GoogleAuthModal} from './menu/google_auth_modal';
|
||||||
@@ -90,10 +91,8 @@ export function App() {
|
|||||||
const [showAuthModal, setShowAuthModal] = useState(false);
|
const [showAuthModal, setShowAuthModal] = useState(false);
|
||||||
/** Stores the file ID that failed to load from Google Drive due to authorization errors. */
|
/** Stores the file ID that failed to load from Google Drive due to authorization errors. */
|
||||||
const [failedFileId, setFailedFileId] = useState<string>();
|
const [failedFileId, setFailedFileId] = useState<string>();
|
||||||
/** Tracks whether the user has a valid cached Google Drive OAuth access token. */
|
/** Tracks whether the user has a valid cached Google Drive OAuth access token and provides a state setter. */
|
||||||
const [hasGoogleToken, setHasGoogleToken] = useState(
|
const {hasGoogleToken, setHasGoogleToken} = useGoogleAuth();
|
||||||
() => !!googleDriveService.getAccessToken(),
|
|
||||||
);
|
|
||||||
|
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|||||||
19
src/hooks/use_google_auth.ts
Normal file
19
src/hooks/use_google_auth.ts
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import {useState} from 'react';
|
||||||
|
import {googleDriveService} from '../datasource/google_drive_service';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom React hook to manage and track the state of Google Drive OAuth2 credentials.
|
||||||
|
*/
|
||||||
|
export function useGoogleAuth() {
|
||||||
|
/** Tracks whether the user has a valid cached Google Drive OAuth access token. */
|
||||||
|
const [hasGoogleToken, setHasGoogleToken] = useState(
|
||||||
|
() => !!googleDriveService.getAccessToken(),
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
/** Tracks whether the user has a valid cached Google Drive OAuth access token. */
|
||||||
|
hasGoogleToken,
|
||||||
|
/** Function to update the token presence state in React. */
|
||||||
|
setHasGoogleToken,
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user