diff --git a/app.json b/app.json index a369176..e8b2faf 100644 --- a/app.json +++ b/app.json @@ -10,7 +10,7 @@ "ios": { "supportsTablet": true, "bundleIdentifier": "com.beenvoice.app", - "buildNumber": "18", + "buildNumber": "20", "icon": "./assets/beenvoice.icon", "infoPlist": { "ITSAppUsesNonExemptEncryption": false, diff --git a/app/(auth)/index.tsx b/app/(auth)/index.tsx index 395cf3e..fe31b03 100644 --- a/app/(auth)/index.tsx +++ b/app/(auth)/index.tsx @@ -1,5 +1,12 @@ import { Redirect } from "expo-router"; +import { useAccounts } from "@/contexts/AccountsContext"; export default function AuthIndex() { + const { accounts, activeAccountId } = useAccounts(); + + if (!activeAccountId && accounts.length > 0) { + return ; + } + return ; } diff --git a/app/(auth)/select-account.tsx b/app/(auth)/select-account.tsx new file mode 100644 index 0000000..9cf8e51 --- /dev/null +++ b/app/(auth)/select-account.tsx @@ -0,0 +1,159 @@ +import { Ionicons } from "@expo/vector-icons"; +import { Redirect, router } from "expo-router"; +import { useState } from "react"; +import { ActivityIndicator, Pressable, StyleSheet, Text, View } from "react-native"; + +import { AuthCard } from "@/components/auth/AuthCard"; +import { AuthCardHeader } from "@/components/auth/AuthCardHeader"; +import { AuthScreenLayout } from "@/components/auth/AuthScreenLayout"; +import { Button } from "@/components/ui/Button"; +import { fonts, radii, spacing } from "@/constants/theme"; +import { useAccounts } from "@/contexts/AccountsContext"; +import { useAppTheme } from "@/contexts/ThemeContext"; +import { startAdditionalAccountSignIn } from "@/lib/add-account"; +import { formatServerHost } from "@/lib/server-mode"; + +function initials(name: string, email: string) { + const source = name.trim() || email.trim(); + const parts = source.split(/\s+/).filter(Boolean); + if (parts.length >= 2) { + return `${parts[0]![0] ?? ""}${parts[1]![0] ?? ""}`.toUpperCase(); + } + return (source[0] ?? "?").toUpperCase(); +} + +export default function SelectAccountScreen() { + const { colors } = useAppTheme(); + const { accounts, activeAccountId, switchAccount, clearActiveAccount } = useAccounts(); + const [selectingId, setSelectingId] = useState(null); + const [adding, setAdding] = useState(false); + + async function handleSelect(accountId: string) { + if (selectingId) return; + setSelectingId(accountId); + try { + await switchAccount(accountId); + router.replace("/(auth)/sign-in"); + } finally { + setSelectingId(null); + } + } + + async function handleAddAccount() { + if (adding) return; + setAdding(true); + try { + await startAdditionalAccountSignIn(clearActiveAccount); + } finally { + setAdding(false); + } + } + + if (activeAccountId || accounts.length === 0) { + return ; + } + + return ( + + + + + + {accounts.map((account) => { + const isSelecting = selectingId === account.id; + + return ( + void handleSelect(account.id)} + style={({ pressed }) => [ + styles.accountRow, + { backgroundColor: colors.muted, borderColor: colors.border }, + pressed && styles.pressed, + ]} + > + + + {initials(account.name, account.email)} + + + + + {account.name || account.email} + + + {account.email} + + + {formatServerHost(account.instanceUrl)} + + + {isSelecting ? ( + + ) : ( + + )} + + ); + })} + + +