about summary refs log tree commit diff
path: root/src/view/com/modals
diff options
context:
space:
mode:
Diffstat (limited to 'src/view/com/modals')
-rw-r--r--src/view/com/modals/ChangeEmail.tsx25
-rw-r--r--src/view/com/modals/SwitchAccount.tsx147
-rw-r--r--src/view/com/modals/VerifyEmail.tsx20
3 files changed, 108 insertions, 84 deletions
diff --git a/src/view/com/modals/ChangeEmail.tsx b/src/view/com/modals/ChangeEmail.tsx
index 710c0588e..6f7a92102 100644
--- a/src/view/com/modals/ChangeEmail.tsx
+++ b/src/view/com/modals/ChangeEmail.tsx
@@ -6,7 +6,6 @@ import {Text} from '../util/text/Text'
 import {Button} from '../util/forms/Button'
 import {ErrorMessage} from '../util/error/ErrorMessage'
 import * as Toast from '../util/Toast'
-import {useStores} from 'state/index'
 import {s, colors} from 'lib/styles'
 import {usePalette} from 'lib/hooks/usePalette'
 import {isWeb} from 'platform/detection'
@@ -15,6 +14,7 @@ import {cleanError} from 'lib/strings/errors'
 import {Trans, msg} from '@lingui/macro'
 import {useLingui} from '@lingui/react'
 import {useModalControls} from '#/state/modals'
+import {useSession, useSessionApi} from '#/state/session'
 
 enum Stages {
   InputEmail,
@@ -26,12 +26,11 @@ export const snapPoints = ['90%']
 
 export const Component = observer(function Component({}: {}) {
   const pal = usePalette('default')
-  const store = useStores()
+  const {agent, currentAccount} = useSession()
+  const {updateCurrentAccount} = useSessionApi()
   const {_} = useLingui()
   const [stage, setStage] = useState<Stages>(Stages.InputEmail)
-  const [email, setEmail] = useState<string>(
-    store.session.currentSession?.email || '',
-  )
+  const [email, setEmail] = useState<string>(currentAccount?.email || '')
   const [confirmationCode, setConfirmationCode] = useState<string>('')
   const [isProcessing, setIsProcessing] = useState<boolean>(false)
   const [error, setError] = useState<string>('')
@@ -39,19 +38,19 @@ export const Component = observer(function Component({}: {}) {
   const {openModal, closeModal} = useModalControls()
 
   const onRequestChange = async () => {
-    if (email === store.session.currentSession?.email) {
+    if (email === currentAccount?.email) {
       setError('Enter your new email above')
       return
     }
     setError('')
     setIsProcessing(true)
     try {
-      const res = await store.agent.com.atproto.server.requestEmailUpdate()
+      const res = await agent.com.atproto.server.requestEmailUpdate()
       if (res.data.tokenRequired) {
         setStage(Stages.ConfirmCode)
       } else {
-        await store.agent.com.atproto.server.updateEmail({email: email.trim()})
-        store.session.updateLocalAccountData({
+        await agent.com.atproto.server.updateEmail({email: email.trim()})
+        updateCurrentAccount({
           email: email.trim(),
           emailConfirmed: false,
         })
@@ -79,11 +78,11 @@ export const Component = observer(function Component({}: {}) {
     setError('')
     setIsProcessing(true)
     try {
-      await store.agent.com.atproto.server.updateEmail({
+      await agent.com.atproto.server.updateEmail({
         email: email.trim(),
         token: confirmationCode.trim(),
       })
-      store.session.updateLocalAccountData({
+      updateCurrentAccount({
         email: email.trim(),
         emailConfirmed: false,
       })
@@ -120,8 +119,8 @@ export const Component = observer(function Component({}: {}) {
           ) : stage === Stages.ConfirmCode ? (
             <Trans>
               An email has been sent to your previous address,{' '}
-              {store.session.currentSession?.email || ''}. It includes a
-              confirmation code which you can enter below.
+              {currentAccount?.email || ''}. It includes a confirmation code
+              which you can enter below.
             </Trans>
           ) : (
             <Trans>
diff --git a/src/view/com/modals/SwitchAccount.tsx b/src/view/com/modals/SwitchAccount.tsx
index 1d9457995..2ff70eea4 100644
--- a/src/view/com/modals/SwitchAccount.tsx
+++ b/src/view/com/modals/SwitchAccount.tsx
@@ -6,7 +6,6 @@ import {
   View,
 } from 'react-native'
 import {Text} from '../util/text/Text'
-import {useStores} from 'state/index'
 import {s} from 'lib/styles'
 import {usePalette} from 'lib/hooks/usePalette'
 import {useAnalytics} from 'lib/analytics/analytics'
@@ -19,26 +18,94 @@ import {BottomSheetScrollView} from '@gorhom/bottom-sheet'
 import {Haptics} from 'lib/haptics'
 import {Trans, msg} from '@lingui/macro'
 import {useLingui} from '@lingui/react'
+import {useSession, useSessionApi, SessionAccount} from '#/state/session'
+import {useGetProfile} from '#/data/useGetProfile'
 
 export const snapPoints = ['40%', '90%']
 
-export function Component({}: {}) {
+function SwitchAccountCard({account}: {account: SessionAccount}) {
   const pal = usePalette('default')
+  const {_} = useLingui()
   const {track} = useAnalytics()
-  const {_: _lingui} = useLingui()
+  const {isSwitchingAccounts, currentAccount} = useSession()
+  const {logout} = useSessionApi()
+  const {isError, data: profile} = useGetProfile({did: account.did})
+  const isCurrentAccount = account.did === currentAccount?.did
+  const {onPressSwitchAccount} = useAccountSwitcher()
+
+  const onPressSignout = React.useCallback(() => {
+    track('Settings:SignOutButtonClicked')
+    logout()
+  }, [track, logout])
+
+  // TODO
+  if (isError || !currentAccount) return null
+
+  const contents = (
+    <View style={[pal.view, styles.linkCard]}>
+      <View style={styles.avi}>
+        <UserAvatar size={40} avatar={profile?.avatar} />
+      </View>
+      <View style={[s.flex1]}>
+        <Text type="md-bold" style={pal.text} numberOfLines={1}>
+          {profile?.displayName || currentAccount.handle}
+        </Text>
+        <Text type="sm" style={pal.textLight} numberOfLines={1}>
+          {currentAccount.handle}
+        </Text>
+      </View>
+
+      {isCurrentAccount ? (
+        <TouchableOpacity
+          testID="signOutBtn"
+          onPress={isSwitchingAccounts ? undefined : onPressSignout}
+          accessibilityRole="button"
+          accessibilityLabel={_(msg`Sign out`)}
+          accessibilityHint={`Signs ${profile?.displayName} out of Bluesky`}>
+          <Text type="lg" style={pal.link}>
+            <Trans>Sign out</Trans>
+          </Text>
+        </TouchableOpacity>
+      ) : (
+        <AccountDropdownBtn handle={account.handle} />
+      )}
+    </View>
+  )
 
-  const store = useStores()
-  const [isSwitching, _, onPressSwitchAccount] = useAccountSwitcher()
+  return isCurrentAccount ? (
+    <Link
+      href={makeProfileLink({
+        did: currentAccount.did,
+        handle: currentAccount.handle,
+      })}
+      title="Your profile"
+      noFeedback>
+      {contents}
+    </Link>
+  ) : (
+    <TouchableOpacity
+      testID={`switchToAccountBtn-${account.handle}`}
+      key={account.did}
+      style={[isSwitchingAccounts && styles.dimmed]}
+      onPress={
+        isSwitchingAccounts ? undefined : () => onPressSwitchAccount(account)
+      }
+      accessibilityRole="button"
+      accessibilityLabel={`Switch to ${account.handle}`}
+      accessibilityHint="Switches the account you are logged in to">
+      {contents}
+    </TouchableOpacity>
+  )
+}
+
+export function Component({}: {}) {
+  const pal = usePalette('default')
+  const {isSwitchingAccounts, currentAccount, accounts} = useSession()
 
   React.useEffect(() => {
     Haptics.default()
   })
 
-  const onPressSignout = React.useCallback(() => {
-    track('Settings:SignOutButtonClicked')
-    store.session.logout()
-  }, [track, store])
-
   return (
     <BottomSheetScrollView
       style={[styles.container, pal.view]}
@@ -46,62 +113,20 @@ export function Component({}: {}) {
       <Text type="title-xl" style={[styles.title, pal.text]}>
         <Trans>Switch Account</Trans>
       </Text>
-      {isSwitching ? (
+
+      {isSwitchingAccounts || !currentAccount ? (
         <View style={[pal.view, styles.linkCard]}>
           <ActivityIndicator />
         </View>
       ) : (
-        <Link href={makeProfileLink(store.me)} title="Your profile" noFeedback>
-          <View style={[pal.view, styles.linkCard]}>
-            <View style={styles.avi}>
-              <UserAvatar size={40} avatar={store.me.avatar} />
-            </View>
-            <View style={[s.flex1]}>
-              <Text type="md-bold" style={pal.text} numberOfLines={1}>
-                {store.me.displayName || store.me.handle}
-              </Text>
-              <Text type="sm" style={pal.textLight} numberOfLines={1}>
-                {store.me.handle}
-              </Text>
-            </View>
-            <TouchableOpacity
-              testID="signOutBtn"
-              onPress={isSwitching ? undefined : onPressSignout}
-              accessibilityRole="button"
-              accessibilityLabel={_lingui(msg`Sign out`)}
-              accessibilityHint={`Signs ${store.me.displayName} out of Bluesky`}>
-              <Text type="lg" style={pal.link}>
-                <Trans>Sign out</Trans>
-              </Text>
-            </TouchableOpacity>
-          </View>
-        </Link>
+        <SwitchAccountCard account={currentAccount} />
       )}
-      {store.session.switchableAccounts.map(account => (
-        <TouchableOpacity
-          testID={`switchToAccountBtn-${account.handle}`}
-          key={account.did}
-          style={[pal.view, styles.linkCard, isSwitching && styles.dimmed]}
-          onPress={
-            isSwitching ? undefined : () => onPressSwitchAccount(account)
-          }
-          accessibilityRole="button"
-          accessibilityLabel={`Switch to ${account.handle}`}
-          accessibilityHint="Switches the account you are logged in to">
-          <View style={styles.avi}>
-            <UserAvatar size={40} avatar={account.aviUrl} />
-          </View>
-          <View style={[s.flex1]}>
-            <Text type="md-bold" style={pal.text}>
-              {account.displayName || account.handle}
-            </Text>
-            <Text type="sm" style={pal.textLight}>
-              {account.handle}
-            </Text>
-          </View>
-          <AccountDropdownBtn handle={account.handle} />
-        </TouchableOpacity>
-      ))}
+
+      {accounts
+        .filter(a => a.did !== currentAccount?.did)
+        .map(account => (
+          <SwitchAccountCard key={account.did} account={account} />
+        ))}
     </BottomSheetScrollView>
   )
 }
diff --git a/src/view/com/modals/VerifyEmail.tsx b/src/view/com/modals/VerifyEmail.tsx
index e48e0e4a2..106e05b87 100644
--- a/src/view/com/modals/VerifyEmail.tsx
+++ b/src/view/com/modals/VerifyEmail.tsx
@@ -14,7 +14,6 @@ import {Text} from '../util/text/Text'
 import {Button} from '../util/forms/Button'
 import {ErrorMessage} from '../util/error/ErrorMessage'
 import * as Toast from '../util/Toast'
-import {useStores} from 'state/index'
 import {s, colors} from 'lib/styles'
 import {usePalette} from 'lib/hooks/usePalette'
 import {isWeb} from 'platform/detection'
@@ -23,6 +22,7 @@ import {cleanError} from 'lib/strings/errors'
 import {Trans, msg} from '@lingui/macro'
 import {useLingui} from '@lingui/react'
 import {useModalControls} from '#/state/modals'
+import {useSession, useSessionApi} from '#/state/session'
 
 export const snapPoints = ['90%']
 
@@ -38,7 +38,8 @@ export const Component = observer(function Component({
   showReminder?: boolean
 }) {
   const pal = usePalette('default')
-  const store = useStores()
+  const {agent, currentAccount} = useSession()
+  const {updateCurrentAccount} = useSessionApi()
   const {_} = useLingui()
   const [stage, setStage] = useState<Stages>(
     showReminder ? Stages.Reminder : Stages.Email,
@@ -53,7 +54,7 @@ export const Component = observer(function Component({
     setError('')
     setIsProcessing(true)
     try {
-      await store.agent.com.atproto.server.requestEmailConfirmation()
+      await agent.com.atproto.server.requestEmailConfirmation()
       setStage(Stages.ConfirmCode)
     } catch (e) {
       setError(cleanError(String(e)))
@@ -66,11 +67,11 @@ export const Component = observer(function Component({
     setError('')
     setIsProcessing(true)
     try {
-      await store.agent.com.atproto.server.confirmEmail({
-        email: (store.session.currentSession?.email || '').trim(),
+      await agent.com.atproto.server.confirmEmail({
+        email: (currentAccount?.email || '').trim(),
         token: confirmationCode.trim(),
       })
-      store.session.updateLocalAccountData({emailConfirmed: true})
+      updateCurrentAccount({emailConfirmed: true})
       Toast.show('Email verified')
       closeModal()
     } catch (e) {
@@ -112,9 +113,8 @@ export const Component = observer(function Component({
             </Trans>
           ) : stage === Stages.ConfirmCode ? (
             <Trans>
-              An email has been sent to{' '}
-              {store.session.currentSession?.email || ''}. It includes a
-              confirmation code which you can enter below.
+              An email has been sent to {currentAccount?.email || ''}. It
+              includes a confirmation code which you can enter below.
             </Trans>
           ) : (
             ''
@@ -130,7 +130,7 @@ export const Component = observer(function Component({
                 size={16}
               />
               <Text type="xl-medium" style={[pal.text, s.flex1, {minWidth: 0}]}>
-                {store.session.currentSession?.email || ''}
+                {currentAccount?.email || ''}
               </Text>
             </View>
             <Pressable