···23232424let __globalAgent: BskyAgent = PUBLIC_BSKY_AGENT
25252626-/**
2727- * NOTE
2828- * Never hold on to the object returned by this function.
2929- * Call `getAgent()` at the time of invocation to ensure
3030- * that you never have a stale agent.
3131- */
3232-export function getAgent() {
2626+function __getAgent() {
3327 return __globalAgent
2828+}
2929+3030+export function useAgent() {
3131+ return React.useMemo(() => ({getAgent: __getAgent}), [])
3432}
35333634export type SessionAccount = persisted.PersistedAccount
+2-1
src/view/com/composer/Composer.tsx
···3232import {useProfileQuery} from '#/state/queries/profile'
3333import {Gif} from '#/state/queries/tenor'
3434import {ThreadgateSetting} from '#/state/queries/threadgate'
3535-import {getAgent, useSession} from '#/state/session'
3535+import {useAgent, useSession} from '#/state/session'
3636import {useComposerControls} from '#/state/shell/composer'
3737import {useAnalytics} from 'lib/analytics/analytics'
3838import * as apilib from 'lib/api/index'
···8383 imageUris: initImageUris,
8484}: Props) {
8585 const {currentAccount} = useSession()
8686+ const {getAgent} = useAgent()
8687 const {data: currentProfile} = useProfileQuery({did: currentAccount!.did})
8788 const {isModalActive} = useModals()
8889 const {closeComposer} = useComposerControls()
+5-3
src/view/com/composer/useExternalLinkFetch.e2e.ts
···11-import {useState, useEffect} from 'react'
11+import {useEffect, useState} from 'react'
22+33+import {useAgent} from '#/state/session'
24import * as apilib from 'lib/api/index'
35import {getLinkMeta} from 'lib/link-meta/link-meta'
46import {ComposerOpts} from 'state/shell/composer'
55-import {getAgent} from '#/state/session'
6778export function useExternalLinkFetch({}: {
89 setQuote: (opts: ComposerOpts['quote']) => void
910}) {
1111+ const {getAgent} = useAgent()
1012 const [extLink, setExtLink] = useState<apilib.ExternalEmbedDraft | undefined>(
1113 undefined,
1214 )
···3941 })
4042 }
4143 return cleanup
4242- }, [extLink])
4444+ }, [extLink, getAgent])
43454446 return {extLink, setExtLink}
4547}
+13-11
src/view/com/composer/useExternalLinkFetch.ts
···11-import {useState, useEffect} from 'react'
22-import {ImageModel} from 'state/models/media/image'
11+import {useEffect, useState} from 'react'
22+33+import {logger} from '#/logger'
44+import {useFetchDid} from '#/state/queries/handle'
55+import {useGetPost} from '#/state/queries/post'
66+import {useAgent} from '#/state/session'
37import * as apilib from 'lib/api/index'
44-import {getLinkMeta} from 'lib/link-meta/link-meta'
88+import {POST_IMG_MAX} from 'lib/constants'
59import {
66- getPostAsQuote,
710 getFeedAsEmbed,
811 getListAsEmbed,
1212+ getPostAsQuote,
913} from 'lib/link-meta/bsky'
1414+import {getLinkMeta} from 'lib/link-meta/link-meta'
1015import {downloadAndResize} from 'lib/media/manip'
1116import {
1212- isBskyPostUrl,
1317 isBskyCustomFeedUrl,
1418 isBskyListUrl,
1919+ isBskyPostUrl,
1520} from 'lib/strings/url-helpers'
2121+import {ImageModel} from 'state/models/media/image'
1622import {ComposerOpts} from 'state/shell/composer'
1717-import {POST_IMG_MAX} from 'lib/constants'
1818-import {logger} from '#/logger'
1919-import {getAgent} from '#/state/session'
2020-import {useGetPost} from '#/state/queries/post'
2121-import {useFetchDid} from '#/state/queries/handle'
22232324export function useExternalLinkFetch({
2425 setQuote,
···3031 )
3132 const getPost = useGetPost()
3233 const fetchDid = useFetchDid()
3434+ const {getAgent} = useAgent()
33353436 useEffect(() => {
3537 let aborted = false
···135137 })
136138 }
137139 return cleanup
138138- }, [extLink, setQuote, getPost, fetchDid])
140140+ }, [extLink, setQuote, getPost, fetchDid, getAgent])
139141140142 return {extLink, setExtLink}
141143}
+13-11
src/view/com/modals/ChangeEmail.tsx
···11import React, {useState} from 'react'
22import {ActivityIndicator, SafeAreaView, StyleSheet, View} from 'react-native'
33-import {ScrollView, TextInput} from './util'
44-import {Text} from '../util/text/Text'
55-import {Button} from '../util/forms/Button'
66-import {ErrorMessage} from '../util/error/ErrorMessage'
77-import * as Toast from '../util/Toast'
88-import {s, colors} from 'lib/styles'
33+import {msg, Trans} from '@lingui/macro'
44+import {useLingui} from '@lingui/react'
55+66+import {useModalControls} from '#/state/modals'
77+import {useAgent, useSession, useSessionApi} from '#/state/session'
98import {usePalette} from 'lib/hooks/usePalette'
1010-import {isWeb} from 'platform/detection'
119import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
1210import {cleanError} from 'lib/strings/errors'
1313-import {Trans, msg} from '@lingui/macro'
1414-import {useLingui} from '@lingui/react'
1515-import {useModalControls} from '#/state/modals'
1616-import {useSession, useSessionApi, getAgent} from '#/state/session'
1111+import {colors, s} from 'lib/styles'
1212+import {isWeb} from 'platform/detection'
1313+import {ErrorMessage} from '../util/error/ErrorMessage'
1414+import {Button} from '../util/forms/Button'
1515+import {Text} from '../util/text/Text'
1616+import * as Toast from '../util/Toast'
1717+import {ScrollView, TextInput} from './util'
17181819enum Stages {
1920 InputEmail,
···2627export function Component() {
2728 const pal = usePalette('default')
2829 const {currentAccount} = useSession()
3030+ const {getAgent} = useAgent()
2931 const {updateCurrentAccount} = useSessionApi()
3032 const {_} = useLingui()
3133 const [stage, setStage] = useState<Stages>(Stages.InputEmail)