diff --git a/src/components/app-handler-modal/index.tsx b/src/components/app-handler-modal/index.tsx index 8e07e2c03..57dc33051 100644 --- a/src/components/app-handler-modal/index.tsx +++ b/src/components/app-handler-modal/index.tsx @@ -19,14 +19,14 @@ import { Text, } from "@chakra-ui/react"; import { NostrEvent, kinds, nip19 } from "nostr-tools"; -import { encodeDecodeResult } from "applesauce-core/helpers"; +import { encodeDecodeResult, getProfileContent, ProfileContent } from "applesauce-core/helpers"; import { ExternalLinkIcon } from "../icons"; import useTimelineLoader from "../../hooks/use-timeline-loader"; import useSingleEvent from "../../hooks/use-single-event"; import useReplaceableEvent from "../../hooks/use-replaceable-event"; import { useReadRelays } from "../../hooks/use-client-relays"; -import { Kind0ParsedContent, getDisplayName, parseMetadataContent } from "../../helpers/nostr/user-metadata"; +import { getDisplayName } from "../../helpers/nostr/profile"; import { MetadataAvatar } from "../user/user-avatar"; import HoverLinkOverlay from "../hover-link-overlay"; import ArrowRight from "../icons/arrow-right"; @@ -62,7 +62,7 @@ function getKindFromDecoded(decoded: nip19.DecodeResult) { } function AppHandler({ app, decoded }: { app: NostrEvent; decoded: nip19.DecodeResult }) { - const metadata = useMemo(() => parseMetadataContent(app), [app]); + const metadata = useMemo(() => getProfileContent(app), [app]); const link = useMemo(() => { const tag = app.tags.find((t) => t[0] === "web" && t[2] === decoded.type) || app.tags.find((t) => t[0] === "web"); return tag ? tag[1].replace("", encodeDecodeResult(decoded)) : undefined; @@ -111,7 +111,7 @@ export default function AppHandlerModal({ const filteredApps = apps.filter((app) => { if (search.length > 1) { try { - const parsed = JSON.parse(app.content) as Kind0ParsedContent; + const parsed = JSON.parse(app.content) as ProfileContent; if (getDisplayName(parsed, app.pubkey).toLowerCase().includes(search.toLowerCase())) { return true; } diff --git a/src/components/common-menu-items/share-link.tsx b/src/components/common-menu-items/share-link.tsx index eb65d95ea..4530d78c4 100644 --- a/src/components/common-menu-items/share-link.tsx +++ b/src/components/common-menu-items/share-link.tsx @@ -4,7 +4,7 @@ import { MenuItem, useToast } from "@chakra-ui/react"; import { NostrEvent } from "../../types/nostr-event"; import { ShareIcon } from "../icons"; import useUserProfile from "../../hooks/use-user-profile"; -import { getDisplayName } from "../../helpers/nostr/user-metadata"; +import { getDisplayName } from "../../helpers/nostr/profile"; import useShareableEventAddress from "../../hooks/use-shareable-event-address"; export default function ShareLinkMenuItem({ event }: { event: NostrEvent }) { diff --git a/src/components/compact-user-stack.tsx b/src/components/compact-user-stack.tsx index 3b4659dfb..af6830630 100644 --- a/src/components/compact-user-stack.tsx +++ b/src/components/compact-user-stack.tsx @@ -16,7 +16,7 @@ import { Link as RouterLink } from "react-router-dom"; import { nip19 } from "nostr-tools"; import UserAvatar from "./user/user-avatar"; -import { getDisplayName } from "../helpers/nostr/user-metadata"; +import { getDisplayName } from "../helpers/nostr/profile"; import useUserProfile from "../hooks/use-user-profile"; function UserTag({ pubkey, ...props }: { pubkey: string } & Omit) { diff --git a/src/components/event-zap-modal/index.tsx b/src/components/event-zap-modal/index.tsx index 60095620e..ce098fbc6 100644 --- a/src/components/event-zap-modal/index.tsx +++ b/src/components/event-zap-modal/index.tsx @@ -11,10 +11,9 @@ import { import dayjs from "dayjs"; import { kinds } from "nostr-tools"; import { getValue } from "applesauce-core/observable"; -import { getInboxes, getOutboxes } from "applesauce-core/helpers"; +import { getInboxes, getOutboxes, safeRelayUrls } from "applesauce-core/helpers"; import { DraftNostrEvent, NostrEvent, isDTag } from "../../types/nostr-event"; -import clientRelaysService from "../../services/client-relays"; import { getZapSplits } from "../../helpers/nostr/zaps"; import { unique } from "../../helpers/array"; import relayScoreboardService from "../../services/relay-scoreboard"; @@ -81,7 +80,7 @@ async function getPayRequestForPubkey( content: comment ?? "", tags: [ ["p", pubkey], - ["relays", ...unique([...userInbox, ...eventRelays, ...outbox, ...additional])], + ["relays", ...unique(safeRelayUrls([...userInbox, ...eventRelays, ...outbox, ...additional]))], ["amount", String(amount)], ], }; diff --git a/src/components/layout/account-switcher.tsx b/src/components/layout/account-switcher.tsx index a3f237b3f..6138dd3e0 100644 --- a/src/components/layout/account-switcher.tsx +++ b/src/components/layout/account-switcher.tsx @@ -2,7 +2,7 @@ import { CloseIcon } from "@chakra-ui/icons"; import { useNavigate, Link as RouterLink } from "react-router-dom"; import { Box, Button, ButtonGroup, Flex, IconButton, Text, useDisclosure } from "@chakra-ui/react"; -import { getDisplayName } from "../../helpers/nostr/user-metadata"; +import { getDisplayName } from "../../helpers/nostr/profile"; import useUserProfile from "../../hooks/use-user-profile"; import accountService from "../../services/account"; import { AddIcon, ChevronDownIcon, ChevronUpIcon } from "../icons"; diff --git a/src/components/search-modal/index.tsx b/src/components/search-modal/index.tsx index c23eb8577..59feccd56 100644 --- a/src/components/search-modal/index.tsx +++ b/src/components/search-modal/index.tsx @@ -8,7 +8,7 @@ import { nip19 } from "nostr-tools"; import UserAvatar from "../user/user-avatar"; import useUserProfile from "../../hooks/use-user-profile"; -import { getDisplayName } from "../../helpers/nostr/user-metadata"; +import { getDisplayName } from "../../helpers/nostr/profile"; import { userSearchDirectory } from "../../services/username-search"; function UserOption({ pubkey }: { pubkey: string }) { diff --git a/src/components/user/user-avatar.tsx b/src/components/user/user-avatar.tsx index 1aadde5d7..45b2df52a 100644 --- a/src/components/user/user-avatar.tsx +++ b/src/components/user/user-avatar.tsx @@ -2,10 +2,11 @@ import { forwardRef, memo, useMemo } from "react"; import { Avatar, AvatarProps } from "@chakra-ui/react"; import { useAsync } from "react-use"; import styled from "@emotion/styled"; +import { ProfileContent } from "applesauce-core/helpers"; import { getIdenticon } from "../../helpers/identicon"; import { safeUrl } from "../../helpers/parse"; -import { Kind0ParsedContent, getDisplayName } from "../../helpers/nostr/user-metadata"; +import { getDisplayName } from "../../helpers/nostr/profile"; import useAppSettings from "../../hooks/use-app-settings"; import useCurrentAccount from "../../hooks/use-current-account"; import { buildImageProxyURL } from "../../helpers/image"; @@ -79,7 +80,7 @@ const SquareAvatarWithBorder = styled(SquareAvatar)` `; export type MetadataAvatarProps = Omit & { - metadata?: Kind0ParsedContent; + metadata?: ProfileContent; pubkey?: string; noProxy?: boolean; square?: boolean; diff --git a/src/components/user/user-link.tsx b/src/components/user/user-link.tsx index 39193d0e5..b9347d35a 100644 --- a/src/components/user/user-link.tsx +++ b/src/components/user/user-link.tsx @@ -2,7 +2,7 @@ import { Link, LinkProps } from "@chakra-ui/react"; import { Link as RouterLink } from "react-router-dom"; import { nip19 } from "nostr-tools"; -import { getDisplayName } from "../../helpers/nostr/user-metadata"; +import { getDisplayName } from "../../helpers/nostr/profile"; import useUserProfile from "../../hooks/use-user-profile"; import useAppSettings from "../../hooks/use-app-settings"; import useCurrentAccount from "../../hooks/use-current-account"; diff --git a/src/components/user/user-name.tsx b/src/components/user/user-name.tsx index 896557f1e..0f9f216ae 100644 --- a/src/components/user/user-name.tsx +++ b/src/components/user/user-name.tsx @@ -1,7 +1,7 @@ import { memo } from "react"; import { Text, TextProps } from "@chakra-ui/react"; -import { getDisplayName } from "../../helpers/nostr/user-metadata"; +import { getDisplayName } from "../../helpers/nostr/profile"; import useUserProfile from "../../hooks/use-user-profile"; import useAppSettings from "../../hooks/use-app-settings"; diff --git a/src/const.ts b/src/const.ts index 8525c29f1..a2da22af1 100644 --- a/src/const.ts +++ b/src/const.ts @@ -1,5 +1,5 @@ +import { safeRelayUrls } from "applesauce-core/helpers"; import { kinds } from "nostr-tools"; -import { safeRelayUrl, safeRelayUrls } from "./helpers/relay"; export const DEFAULT_SEARCH_RELAYS = safeRelayUrls([ "wss://relay.nostr.band", @@ -8,11 +8,10 @@ export const DEFAULT_SEARCH_RELAYS = safeRelayUrls([ "wss://filter.nostr.wine", ]); export const WIKI_RELAYS = safeRelayUrls(["wss://relay.wikifreedia.xyz/"]); -export const COMMON_CONTACT_RELAY = safeRelayUrl("wss://purplepag.es") as string; -export const COMMON_CONTACT_RELAYS = [COMMON_CONTACT_RELAY]; +export const COMMON_CONTACT_RELAYS = safeRelayUrls(["wss://purplepag.es/"]); export const DEFAULT_SIGNAL_RELAYS = safeRelayUrls(["wss://nostrue.com/", "wss://relay.damus.io"]); -export const DEFAULT_NOSTR_CONNECT_RELAYS = safeRelayUrls(["wss://relay.nsec.app"]); +export const DEFAULT_NOSTR_CONNECT_RELAYS = safeRelayUrls(["wss://relay.nsec.app/"]); export const DEFAULT_ICE_SERVERS: RTCIceServer[] = [ { diff --git a/src/helpers/nostr/profile.ts b/src/helpers/nostr/profile.ts new file mode 100644 index 000000000..8eb21e3e9 --- /dev/null +++ b/src/helpers/nostr/profile.ts @@ -0,0 +1,22 @@ +import { nip19 } from "nostr-tools"; +import emojiRegex from "emoji-regex"; +import { truncatedId } from "./event"; +import { ProfileContent } from "applesauce-core/helpers"; + +export function getSearchNames(profile: ProfileContent) { + if (!profile) return []; + + return [profile.displayName, profile.display_name, profile.name].filter(Boolean) as string[]; +} + +const matchEmoji = emojiRegex(); +export function getDisplayName(metadata: ProfileContent | undefined, pubkey: string, removeEmojis = false) { + let displayName = metadata?.displayName || metadata?.display_name || metadata?.name; + + if (displayName) { + if (removeEmojis) displayName = displayName.replaceAll(matchEmoji, ""); + return displayName; + } + + return truncatedId(nip19.npubEncode(pubkey)); +} diff --git a/src/helpers/nostr/user-metadata.ts b/src/helpers/nostr/user-metadata.ts deleted file mode 100644 index 21403100d..000000000 --- a/src/helpers/nostr/user-metadata.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { NostrEvent, nip19 } from "nostr-tools"; -import emojiRegex from "emoji-regex"; -import { truncatedId } from "./event"; -import { ProfileContent } from "applesauce-core/helpers"; - -/** @deprecated use ProfileContent instead */ -export type Kind0ParsedContent = { - pubkey?: string; - name?: string; - display_name?: string; - displayName?: string; - about?: string; - /** @deprecated */ - image?: string; - picture?: string; - banner?: string; - website?: string; - lud16?: string; - lud06?: string; - nip05?: string; -}; - -/** @deprecated use getProfileContent instead */ -export function parseMetadataContent(event: NostrEvent): Kind0ParsedContent { - try { - const metadata = JSON.parse(event.content) as Kind0ParsedContent; - metadata.pubkey = event.pubkey; - - // ensure nip05 is a string - if (metadata.nip05 && typeof metadata.nip05 !== "string") metadata.nip05 = String(metadata.nip05); - - // fix user website - if (metadata.website) metadata.website = fixWebsiteUrl(metadata.website); - - return metadata; - } catch (e) {} - return {}; -} - -export function getSearchNames(profile: ProfileContent) { - if (!profile) return []; - - return [profile.displayName, profile.display_name, profile.name].filter(Boolean) as string[]; -} - -const matchEmoji = emojiRegex(); -export function getDisplayName(metadata: Kind0ParsedContent | undefined, pubkey: string, removeEmojis = false) { - let displayName = metadata?.displayName || metadata?.display_name || metadata?.name; - - if (displayName) { - if (removeEmojis) displayName = displayName.replaceAll(matchEmoji, ""); - return displayName; - } - - return truncatedId(nip19.npubEncode(pubkey)); -} - -export function fixWebsiteUrl(website: string) { - if (website.match(/^http?s:\/\//)) { - return website; - } - return "https://" + website; -} diff --git a/src/helpers/nostr/video.ts b/src/helpers/nostr/video.ts index 5f013700f..4b929bdfe 100644 --- a/src/helpers/nostr/video.ts +++ b/src/helpers/nostr/video.ts @@ -4,12 +4,12 @@ export const FLARE_VIDEO_KIND = 34235; export function getVideoTitle(video: NostrEvent) { const title = video.tags.find((t) => t[0] === "title")?.[1]; - if (!title) throw new Error("missing title"); + if (!title) throw new Error("Missing title"); return title; } export function getVideoUrl(video: NostrEvent) { const url = video.tags.find((t) => t[0] === "url")?.[1]; - if (!url) throw new Error("missing url"); + if (!url) throw new Error("Missing url"); return url; } export function getVideoSummary(video: NostrEvent) { diff --git a/src/helpers/nostr/zaps.ts b/src/helpers/nostr/zaps.ts index 2005018ad..bca7090e8 100644 --- a/src/helpers/nostr/zaps.ts +++ b/src/helpers/nostr/zaps.ts @@ -1,8 +1,6 @@ import { bech32 } from "@scure/base"; -import {} from "nostr-tools/nip57"; -import { isETag, isPTag, NostrEvent } from "../../types/nostr-event"; -import { utils } from "nostr-tools"; -import { getZapPayment, ProfileContent } from "applesauce-core/helpers"; +import { NostrEvent, utils } from "nostr-tools"; +import { getZapPayment, isETag, isPTag, ProfileContent } from "applesauce-core/helpers"; // based on https://github.com/nbd-wtf/nostr-tools/blob/master/nip57.ts export async function getZapEndpoint(metadata: ProfileContent): Promise { diff --git a/src/providers/global/web-of-trust-provider.tsx b/src/providers/global/web-of-trust-provider.tsx index 81fd9a11a..65b7018c3 100644 --- a/src/providers/global/web-of-trust-provider.tsx +++ b/src/providers/global/web-of-trust-provider.tsx @@ -6,7 +6,7 @@ import { getPubkeysFromList } from "../../helpers/nostr/lists"; import useCurrentAccount from "../../hooks/use-current-account"; import { PubkeyGraph } from "../../classes/pubkey-graph"; import replaceableEventsService from "../../services/replaceable-events"; -import { COMMON_CONTACT_RELAY } from "../../const"; +import { COMMON_CONTACT_RELAYS } from "../../const"; import { eventStore } from "../../services/event-store"; export function loadSocialGraph( @@ -40,7 +40,11 @@ export function loadSocialGraph( if (contacts) { handleEvent(contacts); } else { - replaceableEventsService.requestEvent(relay ? [relay, COMMON_CONTACT_RELAY] : [COMMON_CONTACT_RELAY], kind, pubkey); + replaceableEventsService.requestEvent( + relay ? [relay, ...COMMON_CONTACT_RELAYS] : COMMON_CONTACT_RELAYS, + kind, + pubkey, + ); // wait for event to load const sub = eventStore.replaceable(kind, pubkey).subscribe((e) => { diff --git a/src/providers/route/mute-modal-provider.tsx b/src/providers/route/mute-modal-provider.tsx index 2db30fc73..1079743d5 100644 --- a/src/providers/route/mute-modal-provider.tsx +++ b/src/providers/route/mute-modal-provider.tsx @@ -20,7 +20,7 @@ import { PropsWithChildren, createContext, useCallback, useContext, useEffect, u import dayjs from "dayjs"; import { useInterval } from "react-use"; -import { getDisplayName } from "../../helpers/nostr/user-metadata"; +import { getDisplayName } from "../../helpers/nostr/profile"; import useUserProfile from "../../hooks/use-user-profile"; import useCurrentAccount from "../../hooks/use-current-account"; import { diff --git a/src/services/user-event-sync.ts b/src/services/user-event-sync.ts index 991990e5a..5e9050f2f 100644 --- a/src/services/user-event-sync.ts +++ b/src/services/user-event-sync.ts @@ -3,7 +3,7 @@ import _throttle from "lodash.throttle"; import { combineLatest, distinct, filter } from "rxjs"; import { USER_BLOSSOM_SERVER_LIST_KIND } from "blossom-client-sdk"; -import { COMMON_CONTACT_RELAY } from "../const"; +import { COMMON_CONTACT_RELAYS } from "../const"; import { logger } from "../helpers/debug"; import accountService from "./account"; import clientRelaysService from "./client-relays"; @@ -24,7 +24,7 @@ function downloadEvents(account: Account) { }; log("Loading outboxes"); - requestReplaceable([...relays, COMMON_CONTACT_RELAY], kinds.RelayList); + requestReplaceable([...relays, ...COMMON_CONTACT_RELAYS], kinds.RelayList); const mailboxesSub = queryStore.mailboxes(account.pubkey).subscribe((mailboxes) => { log("Loading user information"); @@ -35,7 +35,7 @@ function downloadEvents(account: Account) { log("Loading contacts list"); replaceableEventsService.requestEvent( - [...clientRelaysService.readRelays.value, COMMON_CONTACT_RELAY], + [...clientRelaysService.readRelays.value, ...COMMON_CONTACT_RELAYS], kinds.Contacts, account.pubkey, undefined, diff --git a/src/services/username-search.ts b/src/services/username-search.ts index 0f6460c64..b8fbd7b3b 100644 --- a/src/services/username-search.ts +++ b/src/services/username-search.ts @@ -4,7 +4,7 @@ import { from } from "rxjs"; import { filter, bufferTime, concatMap, mergeWith, shareReplay, map, scan } from "rxjs/operators"; import { getProfileContent, isFromCache } from "applesauce-core/helpers"; -import { getSearchNames } from "../helpers/nostr/user-metadata"; +import { getSearchNames } from "../helpers/nostr/profile"; import db from "./db"; import { eventStore } from "./event-store"; import { logger } from "../helpers/debug"; diff --git a/src/views/discovery/dvm-feed/components/dvm-name.tsx b/src/views/discovery/dvm-feed/components/dvm-name.tsx index 3c6bc3c45..f77e443f7 100644 --- a/src/views/discovery/dvm-feed/components/dvm-name.tsx +++ b/src/views/discovery/dvm-feed/components/dvm-name.tsx @@ -3,7 +3,7 @@ import { Link as RouterLink } from "react-router-dom"; import { nip19 } from "nostr-tools"; import useUserProfile from "../../../../hooks/use-user-profile"; -import { getDisplayName } from "../../../../helpers/nostr/user-metadata"; +import { getDisplayName } from "../../../../helpers/nostr/profile"; import { AddressPointer } from "nostr-tools/nip19"; import useDVMMetadata from "../../../../hooks/use-dvm-metadata"; diff --git a/src/views/profile/edit.tsx b/src/views/profile/edit.tsx index f85ae7d1c..30d5324dd 100644 --- a/src/views/profile/edit.tsx +++ b/src/views/profile/edit.tsx @@ -10,12 +10,11 @@ import { Link, Textarea, } from "@chakra-ui/react"; -import dayjs from "dayjs"; import { useForm } from "react-hook-form"; +import { ProfileContent, unixNow } from "applesauce-core/helpers"; import { ExternalLinkIcon } from "../../components/icons"; import { isLNURL } from "../../helpers/lnurl"; -import { Kind0ParsedContent } from "../../helpers/nostr/user-metadata"; import { useReadRelays } from "../../hooks/use-client-relays"; import useCurrentAccount from "../../hooks/use-current-account"; import useUserProfile from "../../hooks/use-user-profile"; @@ -23,7 +22,7 @@ import dnsIdentityService from "../../services/dns-identity"; import { DraftNostrEvent } from "../../types/nostr-event"; import lnurlMetadataService from "../../services/lnurl-metadata"; import VerticalPageLayout from "../../components/vertical-page-layout"; -import { COMMON_CONTACT_RELAY } from "../../const"; +import { COMMON_CONTACT_RELAYS } from "../../const"; import { usePublishEvent } from "../../providers/global/publish-provider"; const isEmail = @@ -234,7 +233,7 @@ export const ProfileEditView = () => { ); const handleSubmit = async (data: FormData) => { - const newMetadata: Kind0ParsedContent = { + const newMetadata: ProfileContent = { name: data.username, picture: data.picture, banner: data.banner, @@ -253,13 +252,13 @@ export const ProfileEditView = () => { } const draft: DraftNostrEvent = { - created_at: dayjs().unix(), + created_at: unixNow(), kind: 0, content: JSON.stringify({ ...metadata, ...newMetadata }), tags: [], }; - await publish("Update Profile", draft, [COMMON_CONTACT_RELAY]); + await publish("Update Profile", draft, COMMON_CONTACT_RELAYS); }; return ; diff --git a/src/views/relays/mailboxes/index.tsx b/src/views/relays/mailboxes/index.tsx index ec85b0b5e..f123d445e 100644 --- a/src/views/relays/mailboxes/index.tsx +++ b/src/views/relays/mailboxes/index.tsx @@ -2,6 +2,7 @@ import { useCallback } from "react"; import { Flex, Heading, IconButton, Link, Text } from "@chakra-ui/react"; import { CloseIcon } from "@chakra-ui/icons"; import { Link as RouterLink } from "react-router-dom"; +import { kinds } from "nostr-tools"; import RequireCurrentAccount from "../../../providers/route/require-current-account"; import useUserMailboxes from "../../../hooks/use-user-mailboxes"; @@ -12,19 +13,18 @@ import { RelayMode } from "../../../classes/relay"; import { NostrEvent } from "../../../types/nostr-event"; import useAsyncErrorHandler from "../../../hooks/use-async-error-handler"; import { usePublishEvent } from "../../../providers/global/publish-provider"; -import { COMMON_CONTACT_RELAY } from "../../../const"; import BackButton from "../../../components/router/back-button"; import { addRelayModeToMailbox, removeRelayModeFromMailbox } from "../../../helpers/nostr/mailbox"; import AddRelayForm from "../app/add-relay-form"; import DebugEventButton from "../../../components/debug-modal/debug-event-button"; import useReplaceableEvent from "../../../hooks/use-replaceable-event"; -import { kinds } from "nostr-tools"; +import { COMMON_CONTACT_RELAYS } from "../../../const"; function RelayLine({ relay, mode, list }: { relay: string; mode: RelayMode; list?: NostrEvent }) { const publish = usePublishEvent(); const remove = useAsyncErrorHandler(async () => { const draft = removeRelayModeFromMailbox(list, relay, mode); - await publish("Remove relay", draft, [COMMON_CONTACT_RELAY]); + await publish("Remove relay", draft, COMMON_CONTACT_RELAYS); }, [relay, mode, list, publish]); return ( @@ -55,7 +55,7 @@ function MailboxesPage() { const addRelay = useCallback( async (relay: string, mode: RelayMode) => { const draft = addRelayModeToMailbox(event ?? undefined, relay, mode); - await publish("Add Relay", draft, [COMMON_CONTACT_RELAY]); + await publish("Add Relay", draft, COMMON_CONTACT_RELAYS); }, [event], ); diff --git a/src/views/signin/components/account-card.tsx b/src/views/signin/components/account-card.tsx index 16bb6680f..0797c7b73 100644 --- a/src/views/signin/components/account-card.tsx +++ b/src/views/signin/components/account-card.tsx @@ -1,7 +1,7 @@ import { CloseIcon } from "@chakra-ui/icons"; import { Box, IconButton, Text } from "@chakra-ui/react"; -import { getDisplayName } from "../../../helpers/nostr/user-metadata"; +import { getDisplayName } from "../../../helpers/nostr/profile"; import useUserProfile from "../../../hooks/use-user-profile"; import accountService from "../../../services/account"; import UserAvatar from "../../../components/user/user-avatar"; diff --git a/src/views/signup/create-step.tsx b/src/views/signup/create-step.tsx index 72da62f46..f812a155d 100644 --- a/src/views/signup/create-step.tsx +++ b/src/views/signup/create-step.tsx @@ -2,13 +2,12 @@ import { useEffect, useState } from "react"; import { generateSecretKey, finalizeEvent, kinds } from "nostr-tools"; import { Avatar, Button, Flex, Heading, Text, useToast } from "@chakra-ui/react"; import { bytesToHex } from "@noble/hashes/utils"; -import dayjs from "dayjs"; +import { ProfileContent, unixNow } from "applesauce-core/helpers"; -import { Kind0ParsedContent } from "../../helpers/nostr/user-metadata"; import { containerProps } from "./common"; import { nostrBuildUploadImage } from "../../helpers/media-upload/nostr-build"; import accountService from "../../services/account"; -import { COMMON_CONTACT_RELAY } from "../../const"; +import { COMMON_CONTACT_RELAYS } from "../../const"; import { DraftNostrEvent } from "../../types/nostr-event"; import { usePublishEvent } from "../../providers/global/publish-provider"; import NsecAccount from "../../classes/accounts/nsec-account"; @@ -20,7 +19,7 @@ export default function CreateStep({ onBack, onSubmit, }: { - metadata: Kind0ParsedContent; + metadata: ProfileContent; relays: string[]; profileImage?: File; onBack: () => void; @@ -52,14 +51,14 @@ export default function CreateStep({ const kind0 = finalizeEvent( { content: JSON.stringify({ ...metadata, picture: uploaded?.url }), - created_at: dayjs().unix(), + created_at: unixNow(), kind: kinds.Metadata, tags: [], }, hex, ); - await publish("Create Profile", kind0, [...relays, COMMON_CONTACT_RELAY]); + await publish("Create Profile", kind0, [...relays, ...COMMON_CONTACT_RELAYS]); // login const account = NsecAccount.newKey(); @@ -71,7 +70,7 @@ export default function CreateStep({ kind: kinds.RelayList, content: "", tags: relays.map((url) => ["r", url]), - created_at: dayjs().unix(), + created_at: unixNow(), }; const signed = finalizeEvent(draft, hex); await publish("Set Mailbox Relays", signed, relays); diff --git a/src/views/signup/finished-step.tsx b/src/views/signup/finished-step.tsx index 0ec47f1b0..f2537a0ca 100644 --- a/src/views/signup/finished-step.tsx +++ b/src/views/signup/finished-step.tsx @@ -1,12 +1,12 @@ -import { Box, Button, Card, Flex, Heading, Text } from "@chakra-ui/react"; +import { Button, Card, Flex, Heading, Text } from "@chakra-ui/react"; import { Link as RouterLink } from "react-router-dom"; +import { ProfileContent } from "applesauce-core/helpers"; import { useAsync } from "react-use"; import UserAvatarLink from "../../components/user/user-avatar-link"; import UserLink from "../../components/user/user-link"; import { containerProps } from "./common"; import { UserFollowButton } from "../../components/user/user-follow-button"; -import { Kind0ParsedContent } from "../../helpers/nostr/user-metadata"; import UserDnsIdentity from "../../components/user/user-dns-identity"; type TrendingApi = { @@ -24,7 +24,7 @@ type TrendingApi = { function About({ profile }: { profile: { content: string } }) { const { value: metadata, error } = useAsync( - async () => JSON.parse(profile.content) as Kind0ParsedContent, + async () => JSON.parse(profile.content) as ProfileContent, [profile.content], ); return metadata ? {metadata.about} : null; diff --git a/src/views/signup/index.tsx b/src/views/signup/index.tsx index 30b5daeba..85c32b13a 100644 --- a/src/views/signup/index.tsx +++ b/src/views/signup/index.tsx @@ -1,8 +1,8 @@ import { useState } from "react"; import { Flex } from "@chakra-ui/react"; import { useNavigate, useParams } from "react-router-dom"; +import { ProfileContent } from "applesauce-core/helpers"; -import { Kind0ParsedContent } from "../../helpers/nostr/user-metadata"; import NameStep from "./name-step"; import ProfileImageStep from "./profile-image-step"; import RelayStep from "./relay-step"; @@ -14,7 +14,7 @@ export default function SignupView() { const step = useParams().step || "name"; const navigate = useNavigate(); - const [metadata, setMetadata] = useState({}); + const [metadata, setMetadata] = useState({}); const [profileImage, setProfileImage] = useState(); const [relays, setRelays] = useState([]); const [secretKey, setSecretKey] = useState(""); diff --git a/src/views/signup/name-step.tsx b/src/views/signup/name-step.tsx index 1212bb78c..3e8afb415 100644 --- a/src/views/signup/name-step.tsx +++ b/src/views/signup/name-step.tsx @@ -1,11 +1,11 @@ import { Button, Flex, Heading, Input, Text, Textarea } from "@chakra-ui/react"; import { useForm } from "react-hook-form"; +import { ProfileContent } from "applesauce-core/helpers"; import { Link as RouterLink, useLocation } from "react-router-dom"; -import { Kind0ParsedContent } from "../../helpers/nostr/user-metadata"; import { AppIcon, containerProps } from "./common"; -export default function NameStep({ onSubmit }: { onSubmit: (metadata: Kind0ParsedContent) => void }) { +export default function NameStep({ onSubmit }: { onSubmit: (metadata: ProfileContent) => void }) { const location = useLocation(); const { register, handleSubmit, formState } = useForm({ defaultValues: { diff --git a/src/views/user/index.tsx b/src/views/user/index.tsx index b3c3f68f9..e8063e2f1 100644 --- a/src/views/user/index.tsx +++ b/src/views/user/index.tsx @@ -28,7 +28,7 @@ import { import { Outlet, useMatches, useNavigate } from "react-router-dom"; import useUserProfile from "../../hooks/use-user-profile"; -import { getDisplayName } from "../../helpers/nostr/user-metadata"; +import { getDisplayName } from "../../helpers/nostr/profile"; import { useAppTitle } from "../../hooks/use-app-title"; import { useReadRelays } from "../../hooks/use-client-relays"; import relayScoreboardService from "../../services/relay-scoreboard";