show type of account on account picker

This commit is contained in:
hzrd149 2023-06-30 14:52:26 -05:00
parent 7a339ae03d
commit 593ad6bdb2
7 changed files with 70 additions and 19 deletions

View File

@ -0,0 +1,5 @@
---
"nostrudel": patch
---
show type of account on account picker

View File

@ -0,0 +1,27 @@
import { Badge, BadgeProps } from "@chakra-ui/react";
import { Account } from "../services/account";
export default function AccountInfoBadge({ account, ...props }: BadgeProps & { account: Account }) {
if (account.useExtension) {
return (
<Badge {...props} variant="solid" colorScheme="green">
extension
</Badge>
);
}
if (account.secKey) {
return (
<Badge {...props} variant="solid" colorScheme="red">
nsec
</Badge>
);
}
if (account.readonly) {
return (
<Badge {...props} variant="solid" colorScheme="blue">
read-only
</Badge>
);
}
return null;
}

View File

@ -15,12 +15,14 @@ import {
import { getUserDisplayName } from "../../helpers/user-metadata";
import useSubject from "../../hooks/use-subject";
import { useUserMetadata } from "../../hooks/use-user-metadata";
import accountService from "../../services/account";
import accountService, { Account } from "../../services/account";
import { AddIcon } from "../icons";
import { UserAvatar } from "../user-avatar";
import { useLocation, useNavigate } from "react-router-dom";
import AccountInfoBadge from "../account-info-badge";
function AccountItem({ pubkey }: { pubkey: string }) {
function AccountItem({ account }: { account: Account }) {
const pubkey = account.pubkey;
const metadata = useUserMetadata(pubkey, []);
const accord = useAccordionContext();
@ -32,9 +34,10 @@ function AccountItem({ pubkey }: { pubkey: string }) {
return (
<Box display="flex" gap="4" alignItems="center" cursor="pointer" onClick={handleClick}>
<UserAvatar pubkey={pubkey} size="sm" />
<Text flex={1} mr="4" overflow="hidden">
{getUserDisplayName(metadata, pubkey)}
</Text>
<Box flex={1}>
<Text isTruncated>{getUserDisplayName(metadata, pubkey)}</Text>
<AccountInfoBadge fontSize="0.7em" account={account} />
</Box>
<IconButton
icon={<CloseIcon />}
aria-label="Remove Account"
@ -60,7 +63,7 @@ export function AccountSwitcherList() {
return (
<Flex gap="2" direction="column" padding="2">
{otherAccounts.map((account) => (
<AccountItem key={account.pubkey} pubkey={account.pubkey} />
<AccountItem key={account.pubkey} account={account} />
))}
<Button
size="sm"

View File

@ -4,13 +4,13 @@ import { RelayMode } from "../classes/relay";
import { nip19 } from "nostr-tools";
import { useUserRelays } from "./use-user-relays";
export function useSharableProfileId(pubkey: string) {
export function useSharableProfileId(pubkey: string, relayCount = 2) {
const userRelays = useUserRelays(pubkey);
return useMemo(() => {
const writeUrls = userRelays.filter((r) => r.mode & RelayMode.WRITE).map((r) => r.url);
const ranked = relayScoreboardService.getRankedRelays(writeUrls);
const onlyTwo = ranked.slice(0, 2);
const onlyTwo = ranked.slice(0, relayCount);
return onlyTwo.length > 0 ? nip19.nprofileEncode({ pubkey, relays: onlyTwo }) : nip19.npubEncode(pubkey);
}, [userRelays]);

View File

@ -2,10 +2,12 @@ import { CloseIcon } from "@chakra-ui/icons";
import { Box, IconButton, Text } from "@chakra-ui/react";
import { getUserDisplayName } from "../../../helpers/user-metadata";
import { useUserMetadata } from "../../../hooks/use-user-metadata";
import accountService from "../../../services/account";
import accountService, { Account } from "../../../services/account";
import { UserAvatar } from "../../../components/user-avatar";
import AccountInfoBadge from "../../../components/account-info-badge";
export default function AccountCard({ pubkey }: { pubkey: string }) {
export default function AccountCard({ account }: { account: Account }) {
const pubkey = account.pubkey;
// this wont load unless the data is cached since there are no relay connections yet
const metadata = useUserMetadata(pubkey, []);
@ -21,10 +23,13 @@ export default function AccountCard({ pubkey }: { pubkey: string }) {
cursor="pointer"
onClick={() => accountService.switchAccount(pubkey)}
>
<UserAvatar pubkey={pubkey} size="sm" noProxy />
<Text flex={1} mr="4" overflow="hidden">
{getUserDisplayName(metadata, pubkey)}
</Text>
<UserAvatar pubkey={pubkey} size="md" noProxy />
<Box flex={1}>
<Text isTruncated fontWeight="bold">
{getUserDisplayName(metadata, pubkey)}
</Text>
<AccountInfoBadge account={account} />
</Box>
<IconButton
icon={<CloseIcon />}
aria-label="Remove Account"
@ -32,7 +37,7 @@ export default function AccountCard({ pubkey }: { pubkey: string }) {
e.stopPropagation();
accountService.removeAccount(pubkey);
}}
size="sm"
size="md"
variant="ghost"
/>
</Box>

View File

@ -86,7 +86,7 @@ export default function LoginStartView() {
</Heading>
<Flex gap="2" direction="column" minW={300}>
{accounts.map((account) => (
<AccountCard key={account.pubkey} pubkey={account.pubkey} />
<AccountCard key={account.pubkey} account={account} />
))}
</Flex>
</>

View File

@ -8,6 +8,7 @@ import {
AccordionItem,
AccordionPanel,
Box,
Button,
Flex,
Heading,
IconButton,
@ -40,6 +41,7 @@ import { readablizeSats } from "../../helpers/bolt11";
import { UserAvatar } from "../../components/user-avatar";
import { useIsMobile } from "../../hooks/use-is-mobile";
import { getUserDisplayName } from "../../helpers/user-metadata";
import { useSharableProfileId } from "../../hooks/use-shareable-profile-id";
function buildDescriptionContent(description: string) {
let content: EmbedableContent = [description.trim()];
@ -59,12 +61,10 @@ export default function UserAboutTab() {
const metadata = useUserMetadata(pubkey, contextRelays);
const contacts = useUserContacts(pubkey, contextRelays);
const npub = normalizeToBech32(pubkey, Bech32Prefix.Pubkey);
const nprofile = useSharableProfileId(pubkey);
const { value: stats } = useAsync(() => userTrustedStatsService.getUserStats(pubkey), [pubkey]);
const account = useCurrentAccount();
const isSelf = pubkey === account?.pubkey;
const aboutContent = metadata?.about && buildDescriptionContent(metadata?.about);
return (
@ -259,6 +259,17 @@ export default function UserAboutTab() {
</AccordionItem>
)}
</Accordion>
<Flex gap="2">
<Button
as={Link}
href={`https://nosta.me/${nprofile}`}
leftIcon={<Image src="https://nosta.me/images/favicon-32x32.png" w="1.2em" />}
rightIcon={<ExternalLinkIcon />}
isExternal
>
Nosta.me page
</Button>
</Flex>
</Flex>
);
}