diff --git a/services/user/Chainmail/ui/src/components/account-switcher.tsx b/services/user/Chainmail/ui/src/components/account-switcher.tsx index 1e460dc4c..8c2b371bb 100644 --- a/services/user/Chainmail/ui/src/components/account-switcher.tsx +++ b/services/user/Chainmail/ui/src/components/account-switcher.tsx @@ -1,52 +1,180 @@ -import { useIncomingMessages, useUser } from "@hooks"; +import { + useCreateConnectionToken, + useCurrentAccounts, + useLoggedInUser, + useLogout, + useSelectAccount, +} from "@hooks"; import { cn } from "@lib/utils"; +import { Avatar, AvatarFallback } from "@shadcn/avatar"; +import { Button } from "@shadcn/button"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuGroup, + DropdownMenuItem, + DropdownMenuLabel, + DropdownMenuPortal, + DropdownMenuSeparator, + DropdownMenuSub, + DropdownMenuSubContent, + DropdownMenuSubTrigger, + DropdownMenuTrigger, +} from "@shadcn/dropdown-menu"; import { - Select, - SelectContent, - SelectItem, - SelectTrigger, - SelectValue, -} from "@shadcn/select"; + ChevronsUpDown, + LogIn, + LogOut, + PlusCircle, + User, + UserPlus, +} from "lucide-react"; interface AccountSwitcherProps { isCollapsed: boolean; } export function AccountSwitcher({ isCollapsed }: AccountSwitcherProps) { - const { setSelectedMessageId } = useIncomingMessages(); - const { availableAccounts, user, setUser } = useUser(); + const { mutateAsync: onLogin } = useCreateConnectionToken(); + + const { data: loggedInUser } = useLoggedInUser(); + const isLoggedIn = !!loggedInUser; + + const { data: currentAccounts, isPending: isLoadingAccounts } = + useCurrentAccounts(); + + const isNoOptions = !isLoggedIn && currentAccounts.length == 0; + + const { mutateAsync: onLogout } = useLogout(); + const { mutateAsync: selectAccount } = useSelectAccount(); + + const otherConnectedAccounts = currentAccounts.filter( + (account) => account !== loggedInUser, + ); return ( - + {loggedInUser ? ( + <> + +
+ + + {loggedInUser[0]} + + +
+ + {loggedInUser} + +
+
+
+ + + ) : null} + {isNoOptions && ( + { + onLogin(); + }} + > + + + {isLoadingAccounts ? "Loading..." : "Log in"} + + + )} + {!isNoOptions && !otherConnectedAccounts.length ? ( + { + onLogin(); + }} + > + + Switch account + + ) : null} + {!isNoOptions && otherConnectedAccounts.length ? ( + + + + + + {loggedInUser + ? "Switch account" + : "Select an account"} + + + + + {otherConnectedAccounts.map((account) => ( + { + selectAccount(account); + }} + > + + {account} + + ))} + {otherConnectedAccounts.length ? ( + + ) : null} + { + onLogin(); + }} + > + + More... + + + + + + ) : null} + { + onLogout(); + }} + > + + Log out + + + ); } diff --git a/services/user/Chainmail/ui/src/components/compose-dialog.tsx b/services/user/Chainmail/ui/src/components/compose-dialog.tsx index aea7bbf15..352f122af 100644 --- a/services/user/Chainmail/ui/src/components/compose-dialog.tsx +++ b/services/user/Chainmail/ui/src/components/compose-dialog.tsx @@ -10,8 +10,6 @@ import { toast } from "sonner"; import { type PluginId } from "@psibase/common-lib"; -import { getSupervisor } from "@lib/supervisor"; - import { Button } from "@shadcn/button"; import { Dialog, @@ -27,7 +25,7 @@ import { Separator } from "@shadcn/separator"; import { MarkdownEditor } from "@components"; import { ControlBar } from "@components/editor"; -import { type Message, useDraftMessages, useUser } from "@hooks"; +import { type Message, useDraftMessages, useLoggedInUser } from "@hooks"; import { Form, @@ -38,6 +36,8 @@ import { } from "@shadcn/form"; import { Input } from "@shadcn/input"; +import { supervisor } from "src/main"; + interface SupervisorError { code: number; producer: PluginId; @@ -58,7 +58,7 @@ export const ComposeDialog = ({ }) => { const [open, setOpen] = useState(false); const isSent = useRef(false); - const { user } = useUser(); + const { data: user } = useLoggedInUser(); const { drafts, setDrafts, getDrafts, deleteDraftById } = useDraftMessages(); @@ -122,7 +122,6 @@ export const ComposeDialog = ({ } try { - const supervisor = await getSupervisor(); // TODO: Improve error detection. This promise resolves with success before the transaction is pushed. await supervisor.functionCall({ service: "chainmail", diff --git a/services/user/Chainmail/ui/src/components/mail-display.tsx b/services/user/Chainmail/ui/src/components/mail-display.tsx index 14f7f5a34..8c9c5d3e7 100644 --- a/services/user/Chainmail/ui/src/components/mail-display.tsx +++ b/services/user/Chainmail/ui/src/components/mail-display.tsx @@ -24,9 +24,10 @@ import { ReplyDialogTriggerIconWithTooltip, } from "@components"; import { Message, useDraftMessages, useIncomingMessages } from "@hooks"; -import { getSupervisor } from "@lib/supervisor"; import { wait } from "@lib/utils"; +import { supervisor } from "src/main"; + export function MailDisplay({ message, mailbox, @@ -97,7 +98,6 @@ const ActionBar = ({ const onArchive = async (itemId: string) => { let id = parseInt(itemId); - const supervisor = await getSupervisor(); // TODO: Improve error detection. This promise resolves with success before the transaction is pushed. await supervisor.functionCall({ service: "chainmail", @@ -119,7 +119,6 @@ const ActionBar = ({ const onSave = async (itemId: string) => { let id = parseInt(itemId); - const supervisor = await getSupervisor(); await supervisor.functionCall({ service: "chainmail", intf: "api", diff --git a/services/user/Chainmail/ui/src/components/mode-toggle.tsx b/services/user/Chainmail/ui/src/components/mode-toggle.tsx index 7127b113e..9d2e8ae3f 100644 --- a/services/user/Chainmail/ui/src/components/mode-toggle.tsx +++ b/services/user/Chainmail/ui/src/components/mode-toggle.tsx @@ -15,7 +15,7 @@ export function ModeToggle() { return ( -