From e734110b543b1d4b6c1054ad835b9d60ac99cb1a Mon Sep 17 00:00:00 2001 From: Nigel Breslaw Date: Wed, 14 Feb 2024 19:37:11 +0100 Subject: [PATCH] Possible refresh bug (#370) --- native_gg/App.tsx | 45 +++++---------------- native_gg/src/authentication/AuthService.ts | 15 +++++-- native_gg/src/state/Actions.ts | 37 +++++++++++++++-- 3 files changed, 56 insertions(+), 41 deletions(-) diff --git a/native_gg/App.tsx b/native_gg/App.tsx index 32ceab2c2..fa801ca7f 100644 --- a/native_gg/App.tsx +++ b/native_gg/App.tsx @@ -6,39 +6,25 @@ import { useEffect, useReducer, useRef } from "react"; import AuthUI from "./src/authentication/AuthUI.tsx"; import { clientID } from "./src/constants/env.ts"; import AuthService from "./src/authentication/AuthService.ts"; -import { AppAction, AppState } from "./src/state/Actions.ts"; - -const initialState: AppState = { - authenticated: false, - currentAccount: null, -}; - -const reducer = (state: AppState, action: AppAction) => { - const { authenticated, currentAccount } = state; - switch (action.type) { - case "setAuthenticated": { - return { authenticated: action.payload, currentAccount }; - } - case "setCurrentAccount": { - return { authenticated, currentAccount: action.payload }; - } - default: { - return state; - } - } -}; +import { authReducer, initialAuthState } from "./src/state/Actions.ts"; export default function App() { if (process.env.NODE_ENV === "development" && clientID === undefined) { console.warn("No .ENV file found. Please create one."); } const authServiceRef = useRef(null); - authServiceRef.current = AuthService.getInstance(); - const [state, dispatch] = useReducer(reducer, initialState); - authServiceRef.current.subscribe(dispatch); + const [state, dispatch] = useReducer(authReducer, initialAuthState); + + const accountAvatar = state.initComplete + ? state.currentAccount + ? `https://www.bungie.net${state.currentAccount?.iconPath}` + : "https://d33wubrfki0l68.cloudfront.net/554c3b0e09cf167f0281fda839a5433f2040b349/ecfc9/img/header_logo.svg" + : ""; useEffect(() => { + authServiceRef.current = AuthService.getInstance(); + authServiceRef.current.subscribe(dispatch); // Unsubscribe when the component unmounts return () => { if (authServiceRef.current) { @@ -56,16 +42,7 @@ export default function App() { /> Guardian Ghost - + { diff --git a/native_gg/src/authentication/AuthService.ts b/native_gg/src/authentication/AuthService.ts index e650069b2..fc4d2cd7f 100644 --- a/native_gg/src/authentication/AuthService.ts +++ b/native_gg/src/authentication/AuthService.ts @@ -5,7 +5,6 @@ import * as WebBrowser from "expo-web-browser"; import * as v from "valibot"; import { clientID, redirectURL } from "../constants/env.ts"; import { Store } from "../constants/storage.ts"; -import { AppAction } from "../state/Actions.ts"; import { RefreshToken, refreshTokenSchema } from "./Types.ts"; import { getAccessToken, getRefreshToken } from "./Utilities.ts"; import { @@ -15,11 +14,12 @@ import { getLinkedProfiles, linkedProfilesSchema, } from "../account/Account.ts"; +import { AuthAction } from "../state/Actions.ts"; class AuthService { private static instance: AuthService; private authToken: RefreshToken | null; - private dispatch: React.Dispatch | null; + private dispatch: React.Dispatch | null; private stateID: string; private usedAuthCodes: Array; private currentAccount: BungieUser | null; @@ -40,6 +40,7 @@ class AuthService { console.info("No valid user and auth found"); }) .finally(() => { + this.setInitComplete(); const p2 = performance.now(); console.log("took:", (p2 - p1).toFixed(4), "ms"); }); @@ -101,7 +102,7 @@ class AuthService { } // Method to subscribe to auth changes - subscribe(dispatch: React.Dispatch) { + subscribe(dispatch: React.Dispatch) { this.dispatch = dispatch; } @@ -146,6 +147,14 @@ class AuthService { } } + setInitComplete() { + if (this.dispatch) { + this.dispatch({ type: "setInitComplete", payload: true }); + } else { + console.error("No dispatch"); + } + } + startAuth(): void { this.stateID = randomUUID(); const authURL = `https://www.bungie.net/en/oauth/authorize?client_id=${clientID}&response_type=code&reauth=true&state=${this.stateID}`; diff --git a/native_gg/src/state/Actions.ts b/native_gg/src/state/Actions.ts index 9adb231f6..c95d0e3f9 100644 --- a/native_gg/src/state/Actions.ts +++ b/native_gg/src/state/Actions.ts @@ -1,6 +1,22 @@ import { BungieUser } from "../account/Account"; -export type AppAction = +export type AuthState = { + initComplete: boolean; + authenticated: boolean; + currentAccount: BungieUser | null; +}; + +export const initialAuthState: AuthState = { + initComplete: false, + authenticated: false, + currentAccount: null, +}; + +export type AuthAction = + | { + type: "setInitComplete"; + payload: boolean; + } | { type: "setAuthenticated"; payload: boolean; @@ -10,7 +26,20 @@ export type AppAction = payload: BungieUser | null; }; -export type AppState = { - authenticated: boolean; - currentAccount: BungieUser | null; +export const authReducer = (state: AuthState, action: AuthAction) => { + const { initComplete, authenticated, currentAccount } = state; + switch (action.type) { + case "setInitComplete": { + return { initComplete: action.payload, authenticated, currentAccount }; + } + case "setAuthenticated": { + return { initComplete, authenticated: action.payload, currentAccount }; + } + case "setCurrentAccount": { + return { initComplete, authenticated, currentAccount: action.payload }; + } + default: { + return state; + } + } };