Bluesky app fork with some witchin' additions 💫
0
fork

Configure Feed

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

Replace updateCurrentAccount() with refreshSession() (#3910)

Replace updateCurrentAccount() with resumeSession()

authored by

dan and committed by
GitHub
0c6bf276 f62b0458

+15 -257
-171
src/state/session/__tests__/session-test.ts
··· 1302 1302 `) 1303 1303 }) 1304 1304 1305 - it('updates current account', () => { 1306 - let state = getInitialState([]) 1307 - 1308 - const agent1 = new BskyAgent({service: 'https://alice.com'}) 1309 - agent1.session = { 1310 - did: 'alice-did', 1311 - handle: 'alice.test', 1312 - accessJwt: 'alice-access-jwt-1', 1313 - refreshJwt: 'alice-refresh-jwt-1', 1314 - } 1315 - state = run(state, [ 1316 - { 1317 - type: 'switched-to-account', 1318 - newAgent: agent1, 1319 - newAccount: agentToSessionAccountOrThrow(agent1), 1320 - }, 1321 - ]) 1322 - expect(state.accounts.length).toBe(1) 1323 - expect(state.accounts[0].accessJwt).toBe('alice-access-jwt-1') 1324 - expect(state.currentAgentState.did).toBe('alice-did') 1325 - 1326 - state = run(state, [ 1327 - { 1328 - type: 'updated-current-account', 1329 - updatedFields: { 1330 - email: 'alice@foo.bar', 1331 - emailConfirmed: false, 1332 - }, 1333 - }, 1334 - ]) 1335 - expect(state.accounts.length).toBe(1) 1336 - expect(state.accounts[0].email).toBe('alice@foo.bar') 1337 - expect(state.accounts[0].emailConfirmed).toBe(false) 1338 - expect(state.currentAgentState.did).toBe('alice-did') 1339 - expect(printState(state)).toMatchInlineSnapshot(` 1340 - { 1341 - "accounts": [ 1342 - { 1343 - "accessJwt": "alice-access-jwt-1", 1344 - "deactivated": false, 1345 - "did": "alice-did", 1346 - "email": "alice@foo.bar", 1347 - "emailAuthFactor": false, 1348 - "emailConfirmed": false, 1349 - "handle": "alice.test", 1350 - "pdsUrl": undefined, 1351 - "refreshJwt": "alice-refresh-jwt-1", 1352 - "service": "https://alice.com/", 1353 - }, 1354 - ], 1355 - "currentAgentState": { 1356 - "agent": { 1357 - "service": "https://alice.com/", 1358 - }, 1359 - "did": "alice-did", 1360 - }, 1361 - "needsPersist": true, 1362 - } 1363 - `) 1364 - 1365 - state = run(state, [ 1366 - { 1367 - type: 'updated-current-account', 1368 - updatedFields: { 1369 - handle: 'alice-updated.test', 1370 - }, 1371 - }, 1372 - ]) 1373 - expect(state.accounts.length).toBe(1) 1374 - expect(state.accounts[0].handle).toBe('alice-updated.test') 1375 - expect(state.currentAgentState.did).toBe('alice-did') 1376 - expect(printState(state)).toMatchInlineSnapshot(` 1377 - { 1378 - "accounts": [ 1379 - { 1380 - "accessJwt": "alice-access-jwt-1", 1381 - "deactivated": false, 1382 - "did": "alice-did", 1383 - "email": "alice@foo.bar", 1384 - "emailAuthFactor": false, 1385 - "emailConfirmed": false, 1386 - "handle": "alice-updated.test", 1387 - "pdsUrl": undefined, 1388 - "refreshJwt": "alice-refresh-jwt-1", 1389 - "service": "https://alice.com/", 1390 - }, 1391 - ], 1392 - "currentAgentState": { 1393 - "agent": { 1394 - "service": "https://alice.com/", 1395 - }, 1396 - "did": "alice-did", 1397 - }, 1398 - "needsPersist": true, 1399 - } 1400 - `) 1401 - 1402 - const agent2 = new BskyAgent({service: 'https://bob.com'}) 1403 - agent2.session = { 1404 - did: 'bob-did', 1405 - handle: 'bob.test', 1406 - accessJwt: 'bob-access-jwt-1', 1407 - refreshJwt: 'bob-refresh-jwt-1', 1408 - } 1409 - state = run(state, [ 1410 - { 1411 - // Switch to Bob. 1412 - type: 'switched-to-account', 1413 - newAgent: agent2, 1414 - newAccount: agentToSessionAccountOrThrow(agent2), 1415 - }, 1416 - { 1417 - // Update Bob. 1418 - type: 'updated-current-account', 1419 - updatedFields: { 1420 - handle: 'bob-updated.test', 1421 - }, 1422 - }, 1423 - { 1424 - // Switch back to Alice. 1425 - type: 'switched-to-account', 1426 - newAgent: agent1, 1427 - newAccount: agentToSessionAccountOrThrow(agent1), 1428 - }, 1429 - { 1430 - // Update Alice. 1431 - type: 'updated-current-account', 1432 - updatedFields: { 1433 - handle: 'alice-updated-2.test', 1434 - }, 1435 - }, 1436 - ]) 1437 - expect(printState(state)).toMatchInlineSnapshot(` 1438 - { 1439 - "accounts": [ 1440 - { 1441 - "accessJwt": "alice-access-jwt-1", 1442 - "deactivated": false, 1443 - "did": "alice-did", 1444 - "email": undefined, 1445 - "emailAuthFactor": false, 1446 - "emailConfirmed": false, 1447 - "handle": "alice-updated-2.test", 1448 - "pdsUrl": undefined, 1449 - "refreshJwt": "alice-refresh-jwt-1", 1450 - "service": "https://alice.com/", 1451 - }, 1452 - { 1453 - "accessJwt": "bob-access-jwt-1", 1454 - "deactivated": false, 1455 - "did": "bob-did", 1456 - "email": undefined, 1457 - "emailAuthFactor": false, 1458 - "emailConfirmed": false, 1459 - "handle": "bob-updated.test", 1460 - "pdsUrl": undefined, 1461 - "refreshJwt": "bob-refresh-jwt-1", 1462 - "service": "https://bob.com/", 1463 - }, 1464 - ], 1465 - "currentAgentState": { 1466 - "agent": { 1467 - "service": "https://alice.com/", 1468 - }, 1469 - "did": "alice-did", 1470 - }, 1471 - "needsPersist": true, 1472 - } 1473 - `) 1474 - }) 1475 - 1476 1305 it('replaces local accounts with synced accounts', () => { 1477 1306 let state = getInitialState([]) 1478 1307
+1 -19
src/state/session/index.tsx
··· 35 35 logout: async () => {}, 36 36 resumeSession: async () => {}, 37 37 removeAccount: () => {}, 38 - updateCurrentAccount: () => {}, 39 38 }) 40 39 41 40 export function Provider({children}: React.PropsWithChildren<{}>) { ··· 149 148 [cancelPendingTask], 150 149 ) 151 150 152 - const updateCurrentAccount = React.useCallback< 153 - SessionApiContext['updateCurrentAccount'] 154 - >(account => { 155 - dispatch({ 156 - type: 'updated-current-account', 157 - updatedFields: account, 158 - }) 159 - }, []) 160 - 161 151 React.useEffect(() => { 162 152 if (state.needsPersist) { 163 153 state.needsPersist = false ··· 210 200 logout, 211 201 resumeSession, 212 202 removeAccount, 213 - updateCurrentAccount, 214 203 }), 215 - [ 216 - createAccount, 217 - login, 218 - logout, 219 - resumeSession, 220 - removeAccount, 221 - updateCurrentAccount, 222 - ], 204 + [createAccount, login, logout, resumeSession, removeAccount], 223 205 ) 224 206 225 207 // @ts-ignore
-26
src/state/session/reducer.ts
··· 37 37 newAccount: SessionAccount 38 38 } 39 39 | { 40 - type: 'updated-current-account' 41 - updatedFields: Partial< 42 - Pick< 43 - SessionAccount, 44 - 'handle' | 'email' | 'emailConfirmed' | 'emailAuthFactor' 45 - > 46 - > 47 - } 48 - | { 49 40 type: 'removed-account' 50 41 accountDid: string 51 42 } ··· 131 122 did: newAccount.did, 132 123 agent: newAgent, 133 124 }, 134 - needsPersist: true, 135 - } 136 - } 137 - case 'updated-current-account': { 138 - const {updatedFields} = action 139 - return { 140 - accounts: state.accounts.map(a => { 141 - if (a.did === state.currentAgentState.did) { 142 - return { 143 - ...a, 144 - ...updatedFields, 145 - } 146 - } else { 147 - return a 148 - } 149 - }), 150 - currentAgentState: state.currentAgentState, 151 125 needsPersist: true, 152 126 } 153 127 }
-8
src/state/session/types.ts
··· 37 37 logout: (logContext: LogEvents['account:loggedOut']['logContext']) => void 38 38 resumeSession: (account: SessionAccount) => Promise<void> 39 39 removeAccount: (account: SessionAccount) => void 40 - updateCurrentAccount: ( 41 - account: Partial< 42 - Pick< 43 - SessionAccount, 44 - 'handle' | 'email' | 'emailConfirmed' | 'emailAuthFactor' 45 - > 46 - >, 47 - ) => void 48 40 }
+3 -10
src/view/com/modals/ChangeEmail.tsx
··· 4 4 import {useLingui} from '@lingui/react' 5 5 6 6 import {useModalControls} from '#/state/modals' 7 - import {useAgent, useSession, useSessionApi} from '#/state/session' 7 + import {useAgent, useSession} from '#/state/session' 8 8 import {usePalette} from 'lib/hooks/usePalette' 9 9 import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' 10 10 import {cleanError} from 'lib/strings/errors' ··· 28 28 const pal = usePalette('default') 29 29 const {currentAccount} = useSession() 30 30 const {getAgent} = useAgent() 31 - const {updateCurrentAccount} = useSessionApi() 32 31 const {_} = useLingui() 33 32 const [stage, setStage] = useState<Stages>(Stages.InputEmail) 34 33 const [email, setEmail] = useState<string>(currentAccount?.email || '') ··· 51 50 setStage(Stages.ConfirmCode) 52 51 } else { 53 52 await getAgent().com.atproto.server.updateEmail({email: email.trim()}) 54 - updateCurrentAccount({ 55 - email: email.trim(), 56 - emailConfirmed: false, 57 - }) 53 + await getAgent().resumeSession(getAgent().session!) 58 54 Toast.show(_(msg`Email updated`)) 59 55 setStage(Stages.Done) 60 56 } ··· 83 79 email: email.trim(), 84 80 token: confirmationCode.trim(), 85 81 }) 86 - updateCurrentAccount({ 87 - email: email.trim(), 88 - emailConfirmed: false, 89 - }) 82 + await getAgent().resumeSession(getAgent().session!) 90 83 Toast.show(_(msg`Email updated`)) 91 84 setStage(Stages.Done) 92 85 } catch (e) {
+4 -11
src/view/com/modals/ChangeHandle.tsx
··· 15 15 import {useModalControls} from '#/state/modals' 16 16 import {useFetchDid, useUpdateHandleMutation} from '#/state/queries/handle' 17 17 import {useServiceQuery} from '#/state/queries/service' 18 - import { 19 - SessionAccount, 20 - useAgent, 21 - useSession, 22 - useSessionApi, 23 - } from '#/state/session' 18 + import {SessionAccount, useAgent, useSession} from '#/state/session' 24 19 import {useAnalytics} from 'lib/analytics/analytics' 25 20 import {usePalette} from 'lib/hooks/usePalette' 26 21 import {cleanError} from 'lib/strings/errors' ··· 73 68 const {_} = useLingui() 74 69 const pal = usePalette('default') 75 70 const {track} = useAnalytics() 76 - const {updateCurrentAccount} = useSessionApi() 77 71 const {closeModal} = useModalControls() 78 72 const {mutateAsync: updateHandle, isPending: isUpdateHandlePending} = 79 73 useUpdateHandleMutation() 74 + const {getAgent} = useAgent() 80 75 81 76 const [error, setError] = useState<string>('') 82 77 ··· 116 111 await updateHandle({ 117 112 handle: newHandle, 118 113 }) 119 - updateCurrentAccount({ 120 - handle: newHandle, 121 - }) 114 + await getAgent().resumeSession(getAgent().session!) 122 115 closeModal() 123 116 onChanged() 124 117 } catch (err: any) { ··· 134 127 onChanged, 135 128 track, 136 129 closeModal, 137 - updateCurrentAccount, 138 130 updateHandle, 139 131 serviceInfo, 132 + getAgent, 140 133 ]) 141 134 142 135 // rendering
+2 -3
src/view/com/modals/VerifyEmail.tsx
··· 13 13 14 14 import {logger} from '#/logger' 15 15 import {useModalControls} from '#/state/modals' 16 - import {useAgent, useSession, useSessionApi} from '#/state/session' 16 + import {useAgent, useSession} from '#/state/session' 17 17 import {usePalette} from 'lib/hooks/usePalette' 18 18 import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' 19 19 import {cleanError} from 'lib/strings/errors' ··· 43 43 const pal = usePalette('default') 44 44 const {getAgent} = useAgent() 45 45 const {currentAccount} = useSession() 46 - const {updateCurrentAccount} = useSessionApi() 47 46 const {_} = useLingui() 48 47 const [stage, setStage] = useState<Stages>( 49 48 showReminder ? Stages.Reminder : Stages.Email, ··· 82 81 email: (currentAccount?.email || '').trim(), 83 82 token: confirmationCode.trim(), 84 83 }) 85 - updateCurrentAccount({emailConfirmed: true}) 84 + await getAgent().resumeSession(getAgent().session!) 86 85 Toast.show(_(msg`Email verified`)) 87 86 closeModal() 88 87 onSuccess?.()
+2 -3
src/view/screens/Settings/DisableEmail2FADialog.tsx
··· 5 5 6 6 import {cleanError} from '#/lib/strings/errors' 7 7 import {isNative} from '#/platform/detection' 8 - import {useAgent, useSession, useSessionApi} from '#/state/session' 8 + import {useAgent, useSession} from '#/state/session' 9 9 import {ErrorMessage} from '#/view/com/util/error/ErrorMessage' 10 10 import * as Toast from '#/view/com/util/Toast' 11 11 import {atoms as a, useBreakpoints, useTheme} from '#/alf' ··· 30 30 const t = useTheme() 31 31 const {gtMobile} = useBreakpoints() 32 32 const {currentAccount} = useSession() 33 - const {updateCurrentAccount} = useSessionApi() 34 33 const {getAgent} = useAgent() 35 34 36 35 const [stage, setStage] = useState<Stages>(Stages.Email) ··· 61 60 token: confirmationCode.trim(), 62 61 emailAuthFactor: false, 63 62 }) 64 - updateCurrentAccount({emailAuthFactor: false}) 63 + await getAgent().resumeSession(getAgent().session!) 65 64 Toast.show(_(msg`Email 2FA disabled`)) 66 65 } 67 66 control.close()
+3 -6
src/view/screens/Settings/Email2FAToggle.tsx
··· 3 3 import {useLingui} from '@lingui/react' 4 4 5 5 import {useModalControls} from '#/state/modals' 6 - import {useAgent, useSession, useSessionApi} from '#/state/session' 6 + import {useAgent, useSession} from '#/state/session' 7 7 import {ToggleButton} from 'view/com/util/forms/ToggleButton' 8 8 import {useDialogControl} from '#/components/Dialog' 9 9 import {DisableEmail2FADialog} from './DisableEmail2FADialog' ··· 11 11 export function Email2FAToggle() { 12 12 const {_} = useLingui() 13 13 const {currentAccount} = useSession() 14 - const {updateCurrentAccount} = useSessionApi() 15 14 const {openModal} = useModalControls() 16 15 const disableDialogCtrl = useDialogControl() 17 16 const {getAgent} = useAgent() ··· 22 21 email: currentAccount.email, 23 22 emailAuthFactor: true, 24 23 }) 25 - updateCurrentAccount({ 26 - emailAuthFactor: true, 27 - }) 24 + await getAgent().resumeSession(getAgent().session!) 28 25 } 29 - }, [currentAccount, updateCurrentAccount, getAgent]) 26 + }, [currentAccount, getAgent]) 30 27 31 28 const onToggle = React.useCallback(() => { 32 29 if (!currentAccount) {