frontend client for gemstone. decentralised workplace app
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

refactor!: rework oauth provider to be less unstable

serenity b49583fd 0e14e2f5

+64 -59
+9 -8
src/components/Auth/Login.web.tsx
··· 1 1 import { oAuthClient } from "@/lib/utils/atproto/oauth"; 2 - import { useOAuth } from "@/providers/OAuthProvider"; 2 + import { useOAuthSetter, useOAuthValue } from "@/providers/OAuthProvider"; 3 3 import { Agent } from "@atproto/api"; 4 4 import { useState } from "react"; 5 5 import { Button, StyleSheet, TextInput, View } from "react-native"; 6 6 7 7 export const Login = () => { 8 8 const [atprotoHandle, setAtprotoHandle] = useState(""); 9 - const [oAuth, setOAuth] = useOAuth(); 9 + const oAuth = useOAuthValue(); 10 + const setOAuth = useOAuthSetter(); 10 11 const providedOAuthClient = oAuth.client ?? oAuthClient; 11 12 const handlePress = async () => { 12 13 const session = await providedOAuthClient.signIn(atprotoHandle); 13 14 14 15 const agent = new Agent(session); 15 - if (setOAuth) 16 - setOAuth({ 17 - session, 18 - agent, 19 - isLoading: false, 20 - }); 16 + 17 + setOAuth({ 18 + session, 19 + agent, 20 + isLoading: false, 21 + }); 21 22 }; 22 23 23 24 const handleSubmit = () => {
+53 -49
src/providers/OAuthProvider.tsx
··· 5 5 import { isDevMode } from "@/lib/utils/env"; 6 6 import { Agent } from "@atproto/api"; 7 7 import type { OAuthSession } from "@atproto/oauth-client"; 8 - import type { ReactNode, Dispatch } from "react"; 8 + import type { Dispatch, ReactNode, SetStateAction } from "react"; 9 9 import { createContext, useContext, useEffect, useState } from "react"; 10 10 11 - export interface OAuth { 11 + export interface OAuthContextValue { 12 12 session?: OAuthSession; 13 13 agent?: Agent; 14 14 client?: TypedExpoOAuthClientInstance; 15 15 isLoading: boolean; 16 16 } 17 17 18 - const OAuthContext = createContext<[OAuth, Dispatch<OAuth> | undefined]>([ 19 - { isLoading: true }, 20 - undefined, 21 - ]); 18 + const OAuthContext = createContext< 19 + [OAuthContextValue, Dispatch<SetStateAction<OAuthContextValue>>] | null 20 + >(null); 21 + 22 + export const useOAuthValue = () => { 23 + const value = useContext(OAuthContext); 24 + if (!value) 25 + throw new Error( 26 + "OAuth provider failed to initialise. Did you access this out of tree somehow? Tried to access OAuth value before it was initialised.", 27 + ); 28 + return value[0]; 29 + }; 30 + 31 + export const useOAuthSetter = () => { 32 + const value = useContext(OAuthContext); 33 + if (!value) 34 + throw new Error( 35 + "OAuth provider failed to initialise. Did you access this out of tree somehow? Tried to access OAuth value before it was initialised.", 36 + ); 37 + return value[1]; 38 + }; 39 + 40 + export const useOAuthSession = () => { 41 + const { session } = useOAuthValue(); 42 + return session; 43 + }; 44 + 45 + export const useOAuthAgent = () => { 46 + const { agent } = useOAuthValue(); 47 + return agent; 48 + }; 49 + 50 + export const useOAuthClient = () => { 51 + const { client } = useOAuthValue(); 52 + return client; 53 + }; 22 54 23 55 export const OAuthProvider = ({ children }: { children: ReactNode }) => { 24 56 const providedOAuthClient = oAuthClient; 25 - const [oAuth, setOAuth] = useState<OAuth>({ 26 - session: undefined, 27 - agent: undefined, 57 + const [oAuth, setOAuth] = useState<OAuthContextValue>({ 28 58 client: providedOAuthClient, 29 - isLoading: true, 59 + isLoading: false, 30 60 }); 31 61 32 62 useEffect(() => { 33 63 const initOAuth = async () => { 34 64 try { 35 65 const result = await providedOAuthClient.init(); 36 - if (result && isDevMode) { 66 + if (result) { 37 67 const { session, state } = result; 38 - console.log("session state:", state); 39 - if (state != null) { 40 - console.log( 41 - `${session.sub} was successfully authenticated (state: ${state})`, 42 - ); 43 - } else { 44 - console.log( 45 - `${session.sub} was restored (last active session), token_endpoint: ${session.serverMetadata.token_endpoint}`, 46 - ); 68 + 69 + if (isDevMode) { 70 + console.log("session state:", state); 71 + if (state != null) { 72 + console.log( 73 + `${session.sub} was successfully authenticated (state: ${state})`, 74 + ); 75 + } else { 76 + console.log( 77 + `${session.sub} was restored (last active session), token_endpoint: ${session.serverMetadata.token_endpoint}`, 78 + ); 79 + } 47 80 } 48 81 const agent = new Agent(session); 49 82 setOAuth({ ··· 87 120 88 121 return <OAuthContext value={[oAuth, setOAuth]}>{children}</OAuthContext>; 89 122 }; 90 - 91 - export const useOAuth = () => { 92 - return useContext(OAuthContext); 93 - }; 94 - 95 - export const useOAuthValue = () => { 96 - const [oAuth] = useContext(OAuthContext); 97 - return oAuth; 98 - }; 99 - 100 - export const useSetOAuthValue = () => { 101 - const [, setOAuth] = useContext(OAuthContext); 102 - return setOAuth; 103 - }; 104 - 105 - export const useOAuthSession = () => { 106 - const [oAuth] = useContext(OAuthContext); 107 - return oAuth.session; 108 - }; 109 - 110 - export const useOAuthAgent = () => { 111 - const [oAuth] = useContext(OAuthContext); 112 - return oAuth.agent; 113 - }; 114 - 115 - export const useOAuthClient = () => { 116 - const [oAuth] = useContext(OAuthContext); 117 - return oAuth.client; 118 - };
+2 -2
src/providers/authed/HandshakesProvider.tsx
··· 12 12 MembershipsProvider, 13 13 useMemberships, 14 14 } from "@/providers/authed/MembershipsProvider"; 15 - import type { OAuth } from "@/providers/OAuthProvider"; 15 + import type { OAuthContextValue} from "@/providers/OAuthProvider"; 16 16 import { useOAuthValue } from "@/providers/OAuthProvider"; 17 17 import { initiateHandshakeTo } from "@/queries/initiate-handshake-to"; 18 18 import { useQueries } from "@tanstack/react-query"; ··· 123 123 }: { 124 124 channel: SystemsGmstnDevelopmentChannel; 125 125 memberships: Array<SystemsGmstnDevelopmentChannelMembership>; 126 - oauth: OAuth; 126 + oauth: OAuthContextValue; 127 127 }) => { 128 128 const { routeThrough } = channel; 129 129 const latticeAtUri = stringToAtUri(routeThrough.uri);