some cleanup

This commit is contained in:
hzrd149
2023-02-24 08:38:53 -06:00
parent be77fad706
commit 759edb33ad
11 changed files with 76 additions and 68 deletions

View File

@@ -1,13 +1,13 @@
import { Menu, MenuButton, MenuList, IconButton, MenuListProps, MenuButtonProps } from "@chakra-ui/react"; import { Menu, MenuButton, MenuList, IconButton, MenuListProps, IconButtonProps } from "@chakra-ui/react";
import { MoreIcon } from "./icons"; import { MoreIcon } from "./icons";
export type MenuIconButtonProps = MenuButtonProps & { export type MenuIconButtonProps = IconButtonProps & {
children: MenuListProps["children"]; children: MenuListProps["children"];
}; };
export const MenuIconButton = ({ children, ...props }: MenuIconButtonProps) => ( export const MenuIconButton = ({ children, ...props }: MenuIconButtonProps) => (
<Menu isLazy> <Menu isLazy>
<MenuButton as={IconButton} icon={<MoreIcon />} aria-label="view raw" title="view raw" size="xs" {...props} /> <MenuButton as={IconButton} icon={<MoreIcon />} {...props} />
<MenuList>{children}</MenuList> <MenuList>{children}</MenuList>
</Menu> </Menu>
); );

View File

@@ -69,28 +69,30 @@ export const Note = React.memo(({ event, maxHeight }: NoteProps) => {
</CardBody> </CardBody>
<CardFooter padding="2" display="flex" gap="2"> <CardFooter padding="2" display="flex" gap="2">
<IconButton <IconButton
variant="link"
icon={<ReplyIcon />} icon={<ReplyIcon />}
title="Reply" title="Reply"
aria-label="Reply" aria-label="Reply"
onClick={reply} onClick={reply}
size="xs" size="sm"
isDisabled={account.readonly} isDisabled={account.readonly}
/> />
<IconButton <IconButton
variant="link"
icon={<ShareIcon />} icon={<ShareIcon />}
onClick={share} onClick={share}
aria-label="Share Note" aria-label="Share Note"
title="Share Note" title="Share Note"
size="xs" size="sm"
isDisabled={account.readonly} isDisabled={account.readonly}
/> />
<ButtonGroup size="xs" isAttached> <ButtonGroup size="sm" variant="link">
<NoteZapButton note={event} size="xs" /> <NoteZapButton note={event} size="sm" />
<NoteLikeButton note={event} size="xs" /> <NoteLikeButton note={event} size="sm" />
</ButtonGroup> </ButtonGroup>
<Box flexGrow={1} /> <Box flexGrow={1} />
<NoteRelays event={event} size="xs" /> <NoteRelays event={event} size="sm" variant="link" />
<NoteMenu event={event} /> <NoteMenu event={event} size="sm" variant="link" aria-label="More Options" />
</CardFooter> </CardFooter>
</Card> </Card>
); );

View File

@@ -12,13 +12,13 @@ import { useCopyToClipboard } from "react-use";
import { Bech32Prefix, normalizeToBech32 } from "../../helpers/nip-19"; import { Bech32Prefix, normalizeToBech32 } from "../../helpers/nip-19";
import { NostrEvent } from "../../types/nostr-event"; import { NostrEvent } from "../../types/nostr-event";
import { MenuIconButton } from "../menu-icon-button"; import { MenuIconButton, MenuIconButtonProps } from "../menu-icon-button";
import { ClipboardIcon, CodeIcon, LikeIcon } from "../icons"; import { ClipboardIcon, CodeIcon, LikeIcon } from "../icons";
import { getReferences } from "../../helpers/nostr-event"; import { getReferences } from "../../helpers/nostr-event";
import NoteReactionsModal from "./note-reactions-modal"; import NoteReactionsModal from "./note-reactions-modal";
export const NoteMenu = ({ event }: { event: NostrEvent }) => { export const NoteMenu = ({ event, ...props }: { event: NostrEvent } & Omit<MenuIconButtonProps, "children">) => {
const infoModal = useDisclosure(); const infoModal = useDisclosure();
const reactionsModal = useDisclosure(); const reactionsModal = useDisclosure();
const [_clipboardState, copyToClipboard] = useCopyToClipboard(); const [_clipboardState, copyToClipboard] = useCopyToClipboard();
@@ -26,7 +26,7 @@ export const NoteMenu = ({ event }: { event: NostrEvent }) => {
return ( return (
<> <>
<MenuIconButton> <MenuIconButton {...props}>
<MenuItem onClick={reactionsModal.onOpen} icon={<LikeIcon />}> <MenuItem onClick={reactionsModal.onOpen} icon={<LikeIcon />}>
Reactions Reactions
</MenuItem> </MenuItem>

View File

@@ -51,7 +51,7 @@ export const NoteRelays = memo(({ event, ...props }: NoteRelaysProps) => {
return ( return (
<Popover isLazy> <Popover isLazy>
<PopoverTrigger> <PopoverTrigger>
<IconButton title="Note Relays" icon={<RelayIcon />} size={props.size ?? "sm"} aria-label="Note Relays" /> <IconButton title="Note Relays" icon={<RelayIcon />} aria-label="Note Relays" {...props} />
</PopoverTrigger> </PopoverTrigger>
<PopoverContent> <PopoverContent>
<PopoverArrow /> <PopoverArrow />

View File

@@ -1,7 +0,0 @@
import { useCurrentAccount } from "./use-current-account";
/** @deprecated */
export function useReadonlyMode() {
const account = useCurrentAccount();
return account.readonly;
}

View File

@@ -85,7 +85,7 @@ class ClientRelayService {
await results.onComplete; await results.onComplete;
// pass new event to the user relay service // pass new event to the user relay service
userRelaysService.handleEvent(event); userRelaysService.receiveEvent(event);
} }
getWriteUrls() { getWriteUrls() {

View File

@@ -35,7 +35,6 @@ async function fetchIdentity(address: string) {
const { name, domain } = parseAddress(address); const { name, domain } = parseAddress(address);
if (!name || !domain) throw new Error("invalid address"); if (!name || !domain) throw new Error("invalid address");
try {
const json = await fetch(`https://${domain}/.well-known/nostr.json?name=${name}`) const json = await fetch(`https://${domain}/.well-known/nostr.json?name=${name}`)
.then((res) => res.json() as Promise<IdentityJson>) .then((res) => res.json() as Promise<IdentityJson>)
.then((json) => { .then((json) => {
@@ -58,7 +57,6 @@ async function fetchIdentity(address: string) {
await addToCache(domain, json); await addToCache(domain, json);
return getIdentityFromJson(name, domain, json); return getIdentityFromJson(name, domain, json);
} catch (e) {}
} }
async function addToCache(domain: string, json: IdentityJson) { async function addToCache(domain: string, json: IdentityJson) {

View File

@@ -5,9 +5,12 @@ import { Kind0ParsedContent, parseKind0Event } from "../helpers/user-metadata";
import { SuperMap } from "../classes/super-map"; import { SuperMap } from "../classes/super-map";
import Subject from "../classes/subject"; import Subject from "../classes/subject";
class UserMetadataService extends CachedPubkeyEventRequester { class UserMetadataService {
requester: CachedPubkeyEventRequester;
constructor() { constructor() {
super(0, "user-metadata"); this.requester = new CachedPubkeyEventRequester(0, "user-metadata");
this.requester.readCache = this.readCache;
this.requester.writeCache = this.writeCache;
} }
readCache(pubkey: string) { readCache(pubkey: string) {
@@ -20,13 +23,18 @@ class UserMetadataService extends CachedPubkeyEventRequester {
private parsedSubjects = new SuperMap<string, Subject<Kind0ParsedContent>>(() => new Subject<Kind0ParsedContent>()); private parsedSubjects = new SuperMap<string, Subject<Kind0ParsedContent>>(() => new Subject<Kind0ParsedContent>());
requestMetadata(pubkey: string, relays: string[], alwaysRequest = false) { requestMetadata(pubkey: string, relays: string[], alwaysRequest = false) {
const sub = this.parsedSubjects.get(pubkey); const sub = this.parsedSubjects.get(pubkey);
const requestSub = this.requester.requestEvent(pubkey, relays, alwaysRequest);
const requestSub = this.requestEvent(pubkey, relays, alwaysRequest);
sub.connectWithHandler(requestSub, (event, next) => next(parseKind0Event(event))); sub.connectWithHandler(requestSub, (event, next) => next(parseKind0Event(event)));
return sub; return sub;
} }
receiveEvent(event: NostrEvent) {
this.requester.handleEvent(event);
}
update() {
this.requester.update();
}
} }
const userMetadataService = new UserMetadataService(); const userMetadataService = new UserMetadataService();
@@ -35,9 +43,4 @@ setInterval(() => {
userMetadataService.update(); userMetadataService.update();
}, 1000 * 2); }, 1000 * 2);
if (import.meta.env.DEV) {
// @ts-ignore
window.userMetadataService = userMetadataService;
}
export default userMetadataService; export default userMetadataService;

View File

@@ -20,9 +20,12 @@ function parseRelaysEvent(event: NostrEvent): UserRelays {
}; };
} }
class UserRelaysService extends CachedPubkeyEventRequester { class UserRelaysService {
requester: CachedPubkeyEventRequester;
constructor() { constructor() {
super(10002, "user-relays"); this.requester = new CachedPubkeyEventRequester(10002, "user-relays");
this.requester.readCache = this.readCache;
this.requester.writeCache = this.writeCache;
} }
readCache(pubkey: string) { readCache(pubkey: string) {
@@ -32,16 +35,21 @@ class UserRelaysService extends CachedPubkeyEventRequester {
return db.put("userRelays", event); return db.put("userRelays", event);
} }
private parsedSubjects = new SuperMap<string, Subject<UserRelays>>(() => new Subject<UserRelays>()); private subjects = new SuperMap<string, Subject<UserRelays>>(() => new Subject<UserRelays>());
requestRelays(pubkey: string, relays: string[], alwaysRequest = false) { requestRelays(pubkey: string, relays: string[], alwaysRequest = false) {
const sub = this.parsedSubjects.get(pubkey); const sub = this.subjects.get(pubkey);
const requestSub = this.requester.requestEvent(pubkey, relays, alwaysRequest);
const requestSub = this.requestEvent(pubkey, relays, alwaysRequest);
sub.connectWithHandler(requestSub, (event, next) => next(parseRelaysEvent(event))); sub.connectWithHandler(requestSub, (event, next) => next(parseRelaysEvent(event)));
return sub; return sub;
} }
receiveEvent(event: NostrEvent) {
this.requester.handleEvent(event);
}
update() {
this.requester.update();
}
} }
const userRelaysService = new UserRelaysService(); const userRelaysService = new UserRelaysService();

View File

@@ -118,10 +118,14 @@ const MetadataForm = ({ defaultValues, onSubmit }: MetadataFormProps) => {
minLength: 5, minLength: 5,
validate: async (address) => { validate: async (address) => {
if (!address) return true; if (!address) return true;
if (!address.includes("@")) return "invalid address"; if (!address.includes("@")) return "Invalid address";
try {
const id = await dnsIdentityService.getIdentity(address); const id = await dnsIdentityService.getIdentity(address);
if (!id) return "cant find NIP-05 ID"; if (!id) return "Cant find NIP-05 ID";
if (id.pubkey !== account.pubkey) return "Pubkey dose not match"; if (id.pubkey !== account.pubkey) return "Pubkey dose not match";
} catch (e) {
return "Failed to fetch ID";
}
return true; return true;
}, },
})} })}
@@ -224,7 +228,7 @@ export const ProfileEditView = () => {
const event = await signingService.requestSignature(draft, account); const event = await signingService.requestSignature(draft, account);
const results = nostrPostAction(writeRelays, event); const results = nostrPostAction(writeRelays, event);
userMetadataService.handleEvent(event); userMetadataService.receiveEvent(event);
await results.onComplete; await results.onComplete;
} catch (e) { } catch (e) {

View File

@@ -35,8 +35,8 @@ export default function Header({ pubkey }: { pubkey: string }) {
<UserDnsIdentityIcon pubkey={pubkey} /> <UserDnsIdentityIcon pubkey={pubkey} />
</Flex> </Flex>
<Flex gap="2"> <Flex gap="2">
<UserTipButton pubkey={pubkey} size="xs" /> <UserTipButton pubkey={pubkey} size="sm" variant="link" />
<UserProfileMenu pubkey={pubkey} /> <UserProfileMenu pubkey={pubkey} aria-label="More Options" size="sm" variant="link" />
</Flex> </Flex>
</Flex> </Flex>
{!metadata ? <SkeletonText /> : <Text>{metadata?.about}</Text>} {!metadata ? <SkeletonText /> : <Text>{metadata?.about}</Text>}