Refactor useLoggedInAccounts into a separate hook

This commit is contained in:
Alex Gleason 2025-04-18 15:30:11 -05:00
parent 884b85ce25
commit d88285480c
No known key found for this signature in database
GPG Key ID: 7211D1F99744FBB7
2 changed files with 64 additions and 49 deletions

View File

@ -9,68 +9,21 @@ import {
} from '@/components/ui/dropdown-menu.tsx';
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar.tsx';
import { Button } from '@/components/ui/button.tsx';
import { useNostrLogin } from '@nostrify/react/login';
import { useQuery } from '@tanstack/react-query';
import { useNostr } from '@nostrify/react';
import { NSchema as n, NostrEvent, NostrMetadata } from '@nostrify/nostrify';
import LoginDialog from './LoginDialog';
import SignupDialog from './SignupDialog';
interface Account {
id: string;
pubkey: string;
event?: NostrEvent;
metadata: NostrMetadata;
}
import { useLoggedInAccounts } from '@/hooks/useLoggedInAccounts';
export function AccountSwitcher() {
const { nostr } = useNostr();
const { logins, setLogin, removeLogin } = useNostrLogin();
const { currentUser, otherUsers, setLogin, removeLogin } = useLoggedInAccounts();
const [loginDialogOpen, setLoginDialogOpen] = useState(false);
const [signupDialogOpen, setSignupDialogOpen] = useState(false);
const { data: authors = [] } = useQuery({
queryKey: ['logins', logins.map((l) => l.id).join(';')],
queryFn: async ({ signal }) => {
let events: NostrEvent[] = [];
try {
events = await nostr.query(
[{ kinds: [0], authors: logins.map((l) => l.pubkey) }],
{ signal: AbortSignal.any([signal, AbortSignal.timeout(500)]) },
);
} catch (error) {
console.error('Error fetching accounts:', error);
return [];
}
return logins.map(({ id, pubkey }): Account => {
const event = events.find((e) => e.pubkey === pubkey);
try {
const metadata = n.json().pipe(n.metadata()).parse(event?.content);
return { id, pubkey, metadata, event };
} catch {
return { id, pubkey, metadata: {}, event };
}
});
}
});
const [_, ...otherUsers] = (authors || []) as [Account | undefined, ...Account[]];
const handleLogin = () => {
setLoginDialogOpen(false);
setSignupDialogOpen(false);
};
const currentUser: Account | undefined = (() => {
const login = logins[0];
if (!login) return undefined;
const author = authors.find((a) => a.id === login.id);
return { metadata: {}, ...author, id: login.id, pubkey: login.pubkey };
})();
if (!currentUser) {
return (
<>

View File

@ -0,0 +1,62 @@
import { useNostr } from '@nostrify/react';
import { useNostrLogin } from '@nostrify/react/login';
import { useQuery } from '@tanstack/react-query';
import { NSchema as n, NostrEvent, NostrMetadata } from '@nostrify/nostrify';
export interface Account {
id: string;
pubkey: string;
event?: NostrEvent;
metadata: NostrMetadata;
}
export function useLoggedInAccounts() {
const { nostr } = useNostr();
const { logins, setLogin, removeLogin } = useNostrLogin();
const { data: authors = [] } = useQuery({
queryKey: ['logins', logins.map((l) => l.id).join(';')],
queryFn: async ({ signal }) => {
let events: NostrEvent[] = [];
try {
events = await nostr.query(
[{ kinds: [0], authors: logins.map((l) => l.pubkey) }],
{ signal: AbortSignal.any([signal, AbortSignal.timeout(500)]) },
);
} catch (error) {
console.error('Error fetching accounts:', error);
return [];
}
return logins.map(({ id, pubkey }): Account => {
const event = events.find((e) => e.pubkey === pubkey);
try {
const metadata = n.json().pipe(n.metadata()).parse(event?.content);
return { id, pubkey, metadata, event };
} catch {
return { id, pubkey, metadata: {}, event };
}
});
}
});
// Current user is the first login
const currentUser: Account | undefined = (() => {
const login = logins[0];
if (!login) return undefined;
const author = authors.find((a) => a.id === login.id);
return { metadata: {}, ...author, id: login.id, pubkey: login.pubkey };
})();
// Other users are all logins except the current one
const otherUsers = (authors || []).slice(1) as Account[];
return {
authors,
currentUser,
otherUsers,
setLogin,
removeLogin,
};
}