reorg components

This commit is contained in:
hzrd149 2024-02-16 11:18:37 +00:00
parent ef9de96f3f
commit 8bf1db3d26
288 changed files with 707 additions and 1126 deletions

View File

@ -5,7 +5,7 @@ import debug, { Debugger } from "debug";
import NostrSubscription from "./nostr-subscription";
import EventStore from "./event-store";
import { getEventCoordinate } from "../helpers/nostr/events";
import { getEventCoordinate } from "../helpers/nostr/event";
export function createCoordinate(kind: number, pubkey: string, d?: string) {
return `${kind}:${pubkey}${d ? ":" + d : ""}`;

View File

@ -1,7 +1,7 @@
import { NostrEvent } from "nostr-tools";
import { nanoid } from "nanoid";
import { getEventUID, sortByDate } from "../helpers/nostr/events";
import { getEventUID, sortByDate } from "../helpers/nostr/event";
import ControlledObservable from "./controlled-observable";
import SuperMap from "./super-map";
import deleteEventService from "../services/delete-events";

View File

@ -1,8 +1,8 @@
import { NostrEvent } from "nostr-tools";
import { relaysFromContactsEvent } from "../helpers/nostr/contacts";
import { getRelaysFromMailbox } from "../helpers/nostr/mailbox";
import { safeRelayUrl } from "../helpers/relay";
import relayPoolService from "../services/relay-pool";
import { NostrEvent } from "../types/nostr-event";
import { RelayMode } from "./relay";
export default class RelaySet extends Set<string> {

View File

@ -10,7 +10,7 @@ import NostrMultiSubscription from "./nostr-multi-subscription";
import Subject, { PersistentSubject } from "./subject";
import { logger } from "../helpers/debug";
import EventStore from "./event-store";
import { isReplaceable } from "../helpers/nostr/events";
import { isReplaceable } from "../helpers/nostr/event";
import replaceableEventsService from "../services/replaceable-events";
import deleteEventService from "../services/delete-events";
import {

View File

@ -3,11 +3,11 @@ import { useEffect, useState } from "react";
import { Box, Button, ButtonGroup, Card, CardProps, Heading, IconButton, Link } from "@chakra-ui/react";
import { getDecodedToken, Token, CashuMint } from "@cashu/cashu-ts";
import { CopyIconButton } from "./copy-icon-button";
import { useUserMetadata } from "../hooks/use-user-metadata";
import useCurrentAccount from "../hooks/use-current-account";
import { ECashIcon, WalletIcon } from "./icons";
import { getMint } from "../services/cashu-mints";
import { CopyIconButton } from "../copy-icon-button";
import { useUserMetadata } from "../../hooks/use-user-metadata";
import useCurrentAccount from "../../hooks/use-current-account";
import { ECashIcon, WalletIcon } from "../icons";
import { getMint } from "../../services/cashu-mints";
function RedeemButton({ token }: { token: string }) {
const account = useCurrentAccount()!;

View File

@ -1,9 +1,9 @@
import { memo } from "react";
import { verifyEvent } from "nostr-tools";
import { NostrEvent } from "../types/nostr-event";
import { CheckIcon, VerificationFailed } from "./icons";
import useAppSettings from "../hooks/use-app-settings";
import { NostrEvent } from "../../types/nostr-event";
import { CheckIcon, VerificationFailed } from "../icons";
import useAppSettings from "../../hooks/use-app-settings";
function EventVerificationIcon({ event }: { event: NostrEvent }) {
const { showSignatureVerification } = useAppSettings();

View File

@ -15,8 +15,8 @@ import {
import { Link as RouterLink } from "react-router-dom";
import { nip19 } from "nostr-tools";
import UserAvatar from "./user-avatar";
import { getUserDisplayName } from "../helpers/user-metadata";
import UserAvatar from "./user/user-avatar";
import { getUserDisplayName } from "../helpers/nostr/user-metadata";
import { useUserMetadata } from "../hooks/use-user-metadata";
function UserTag({ pubkey, ...props }: { pubkey: string } & Omit<TagProps, "children">) {

View File

@ -1,90 +0,0 @@
import { useMemo, useState } from "react";
import {
Text,
useDisclosure,
Modal,
ModalOverlay,
ModalContent,
ModalHeader,
ModalBody,
ModalCloseButton,
Button,
TableContainer,
Table,
Thead,
Tbody,
Td,
Tr,
Th,
Flex,
ButtonProps,
} from "@chakra-ui/react";
import relayPoolService from "../services/relay-pool";
import { useInterval } from "react-use";
import { RelayStatus } from "./relay-status";
import { RelayIcon } from "./icons";
import Relay from "../classes/relay";
import { RelayFavicon } from "./relay-favicon";
import relayScoreboardService from "../services/relay-scoreboard";
import { RelayScoreBreakdown } from "./relay-score-breakdown";
export const ConnectedRelays = ({ ...props }: Omit<ButtonProps, "children">) => {
const { isOpen, onOpen, onClose } = useDisclosure();
const [relays, setRelays] = useState<Relay[]>(relayPoolService.getRelays());
const sortedRelays = useMemo(() => relayScoreboardService.getRankedRelays(relays.map((r) => r.url)), [relays]);
useInterval(() => {
setRelays(relayPoolService.getRelays());
}, 1000);
const connected = relays.filter((relay) => relay.okay);
return (
<>
<Button onClick={onOpen} leftIcon={<RelayIcon />} {...props}>
connected to {connected.length} relays
</Button>
<Modal isOpen={isOpen} onClose={onClose} size="5xl">
<ModalOverlay />
<ModalContent>
<ModalHeader pb="0">Connected Relays</ModalHeader>
<ModalCloseButton />
<ModalBody p="2">
<TableContainer>
<Table size="sm">
<Thead>
<Tr>
<Th>Relay</Th>
<Th>Claims</Th>
<Th>Score</Th>
<Th>Status</Th>
</Tr>
</Thead>
<Tbody>
{sortedRelays.map((url) => (
<Tr key={url}>
<Td>
<Flex alignItems="center" maxW="sm" overflow="hidden">
<RelayFavicon size="xs" relay={url} mr="2" />
<Text>{url}</Text>
</Flex>
</Td>
<Td>{relayPoolService.getRelayClaims(url).size}</Td>
<Td>
<RelayScoreBreakdown relay={url} />
</Td>
<Td>
<RelayStatus url={url} />
</Td>
</Tr>
))}
</Tbody>
</Table>
</TableContainer>
</ModalBody>
</ModalContent>
</Modal>
</>
);
};

View File

@ -23,7 +23,7 @@ import {
import { ModalProps } from "@chakra-ui/react";
import { nip19 } from "nostr-tools";
import { getContentTagRefs, getEventUID, getThreadReferences } from "../../helpers/nostr/events";
import { getContentTagRefs, getEventUID, getThreadReferences } from "../../helpers/nostr/event";
import { NostrEvent } from "../../types/nostr-event";
import RawValue from "./raw-value";
import { getSharableEventAddress } from "../../helpers/nip19";

View File

@ -4,11 +4,11 @@ import { NostrEvent, nip19 } from "nostr-tools";
import { Link as RouterLink } from "react-router-dom";
import { Tag, isATag, isETag, isPTag } from "../../types/nostr-event";
import { aTagToAddressPointer, eTagToEventPointer } from "../../helpers/nostr/events";
import { aTagToAddressPointer, eTagToEventPointer } from "../../helpers/nostr/event";
import { EmbedEventPointer } from "../embed-event";
import UserAvatarLink from "../user-avatar-link";
import UserLink from "../user-link";
import { UserDnsIdentityIcon } from "../user-dns-identity-icon";
import UserAvatarLink from "../user/user-avatar-link";
import UserLink from "../user/user-link";
import { UserDnsIdentityIcon } from "../user/user-dns-identity-icon";
function EventTag({ tag }: { tag: Tag }) {
const expand = useDisclosure();

View File

@ -5,7 +5,7 @@ export type MenuIconButtonProps = IconButtonProps & {
children: MenuListProps["children"];
};
export function CustomMenuIconButton({ children, icon, ...props }: MenuIconButtonProps) {
export function DotsMenuButton({ children, icon, ...props }: MenuIconButtonProps) {
return (
<Menu isLazy>
<MenuButton as={IconButton} icon={icon || <MoreIcon />} {...props} />

View File

@ -9,8 +9,8 @@ import {
import { NostrEvent } from "../../../types/nostr-event";
import { buildAppSelectUrl } from "../../../helpers/nostr/apps";
import { getSharableEventAddress } from "../../../helpers/nip19";
import UserAvatarLink from "../../user-avatar-link";
import UserLink from "../../user-link";
import UserAvatarLink from "../../user/user-avatar-link";
import UserLink from "../../user/user-link";
import Timestamp from "../../timestamp";
export default function EmbeddedArticle({ article, ...props }: Omit<CardProps, "children"> & { article: NostrEvent }) {

View File

@ -12,8 +12,8 @@ import {
Text,
} from "@chakra-ui/react";
import UserAvatarLink from "../../../components/user-avatar-link";
import UserLink from "../../../components/user-link";
import UserAvatarLink from "../../user/user-avatar-link";
import UserLink from "../../user/user-link";
import { getSharableEventAddress } from "../../../helpers/nip19";
import { NostrEvent } from "../../../types/nostr-event";
import { getBadgeDescription, getBadgeImage, getBadgeName } from "../../../helpers/nostr/badges";

View File

@ -2,8 +2,8 @@ import { Link as RouterLink } from "react-router-dom";
import { Box, Card, CardBody, CardFooter, CardHeader, CardProps, Flex, Heading, LinkBox, Text } from "@chakra-ui/react";
import { nip19 } from "nostr-tools";
import UserAvatarLink from "../../user-avatar-link";
import UserLink from "../../user-link";
import UserAvatarLink from "../../user/user-avatar-link";
import UserLink from "../../user/user-link";
import { NostrEvent } from "../../../types/nostr-event";
import useChannelMetadata from "../../../hooks/use-channel-metadata";
import HoverLinkOverlay from "../../hover-link-overlay";

View File

@ -2,8 +2,8 @@ import { Link as RouterLink } from "react-router-dom";
import { Card, CardFooter, CardHeader, CardProps, Heading, LinkBox, LinkOverlay, Text } from "@chakra-ui/react";
import { nip19 } from "nostr-tools";
import UserAvatarLink from "../../../components/user-avatar-link";
import UserLink from "../../../components/user-link";
import UserAvatarLink from "../../user/user-avatar-link";
import UserLink from "../../user/user-link";
import { NostrEvent } from "../../../types/nostr-event";
import { getCommunityImage, getCommunityName } from "../../../helpers/nostr/communities";

View File

@ -2,8 +2,8 @@ import { Card, CardBody, CardHeader, CardProps, IconButton, LinkBox, Text, useDi
import { NostrEvent } from "../../../types/nostr-event";
import { TrustProvider } from "../../../providers/local/trust";
import UserAvatarLink from "../../user-avatar-link";
import UserLink from "../../user-link";
import UserAvatarLink from "../../user/user-avatar-link";
import UserLink from "../../user/user-link";
import Timestamp from "../../timestamp";
import DecryptPlaceholder from "../../../views/dms/components/decrypt-placeholder";
import useCurrentAccount from "../../../hooks/use-current-account";

View File

@ -15,8 +15,8 @@ import { Link as RouterLink } from "react-router-dom";
import { getSharableEventAddress } from "../../../helpers/nip19";
import { getEmojisFromPack, getPackName } from "../../../helpers/nostr/emoji-packs";
import UserAvatarLink from "../../user-avatar-link";
import UserLink from "../../user-link";
import UserAvatarLink from "../../user/user-avatar-link";
import UserLink from "../../user/user-link";
import EmojiPackFavoriteButton from "../../../views/emoji-packs/components/emoji-pack-favorite-button";
import EmojiPackMenu from "../../../views/emoji-packs/components/emoji-pack-menu";
import { NostrEvent } from "../../../types/nostr-event";

View File

@ -2,8 +2,8 @@ import { Card, CardBody, CardProps, Flex, Heading, Image, Link, Text } from "@ch
import { Link as RouterLink, useNavigate } from "react-router-dom";
import { NostrEvent } from "../../../types/nostr-event";
import UserLink from "../../user-link";
import UserAvatar from "../../user-avatar";
import UserLink from "../../user/user-link";
import UserAvatar from "../../user/user-avatar";
import { useBreakpointValue } from "../../../providers/global/breakpoint-provider";
import { getVideoDuration, getVideoImages, getVideoSummary, getVideoTitle } from "../../../helpers/nostr/flare";
import { getSharableEventAddress } from "../../../helpers/nip19";

View File

@ -4,8 +4,8 @@ import { Link as RouterLink } from "react-router-dom";
import { getSharableEventAddress } from "../../../helpers/nip19";
import { NostrEvent } from "../../../types/nostr-event";
import { getGoalName } from "../../../helpers/nostr/goal";
import UserAvatarLink from "../../user-avatar-link";
import UserLink from "../../user-link";
import UserAvatarLink from "../../user/user-avatar-link";
import UserLink from "../../user/user-link";
import GoalProgress from "../../../views/goals/components/goal-progress";
import GoalZapButton from "../../../views/goals/components/goal-zap-button";
import GoalTopZappers from "../../../views/goals/components/goal-top-zappers";

View File

@ -3,12 +3,12 @@ import { Link as RouterLink } from "react-router-dom";
import { NostrEvent } from "../../../types/nostr-event";
import { getListDescription, getListName, isSpecialListKind } from "../../../helpers/nostr/lists";
import { createCoordinate } from "../../../services/replaceable-events";
import { getSharableEventAddress } from "../../../helpers/nip19";
import UserAvatarLink from "../../user-avatar-link";
import UserLink from "../../user-link";
import UserAvatarLink from "../../user/user-avatar-link";
import UserLink from "../../user/user-link";
import ListFeedButton from "../../../views/lists/components/list-feed-button";
import { ListCardContent } from "../../../views/lists/components/list-card";
import { createCoordinate } from "../../../classes/batch-kind-loader";
export default function EmbeddedList({ list, ...props }: Omit<CardProps, "children"> & { list: NostrEvent }) {
const link = isSpecialListKind(list.kind) ? createCoordinate(list.kind, list.pubkey) : getSharableEventAddress(list);

View File

@ -3,14 +3,14 @@ import { Card, CardProps, Flex, LinkBox, Spacer } from "@chakra-ui/react";
import { Link as RouterLink } from "react-router-dom";
import { NostrEvent } from "../../../types/nostr-event";
import UserAvatarLink from "../../user-avatar-link";
import UserLink from "../../user-link";
import { UserDnsIdentityIcon } from "../../user-dns-identity-icon";
import UserAvatarLink from "../../user/user-avatar-link";
import UserLink from "../../user/user-link";
import { UserDnsIdentityIcon } from "../../user/user-dns-identity-icon";
import useSubject from "../../../hooks/use-subject";
import appSettings from "../../../services/settings/app-settings";
import EventVerificationIcon from "../../event-verification-icon";
import EventVerificationIcon from "../../common-event/event-verification-icon";
import { TrustProvider } from "../../../providers/local/trust";
import { NoteLink } from "../../note-link";
import { NoteLink } from "../../note/note-link";
import Timestamp from "../../timestamp";
import { getSharableEventAddress } from "../../../helpers/nip19";
import { CompactNoteContent } from "../../compact-note-content";

View File

@ -2,11 +2,11 @@ import { Card, CardProps, Flex, LinkBox, Spacer, Text } from "@chakra-ui/react";
import { NostrEvent } from "../../../types/nostr-event";
import { TrustProvider } from "../../../providers/local/trust";
import UserAvatarLink from "../../user-avatar-link";
import UserLink from "../../user-link";
import UserAvatarLink from "../../user/user-avatar-link";
import UserLink from "../../user/user-link";
import Timestamp from "../../timestamp";
import ReactionIcon from "../../event-reactions/reaction-icon";
import { NoteLink } from "../../note-link";
import { NoteLink } from "../../note/note-link";
import { nip25 } from "nostr-tools";
export default function EmbeddedReaction({ event, ...props }: Omit<CardProps, "children"> & { event: NostrEvent }) {

View File

@ -12,17 +12,17 @@ import {
} from "@chakra-ui/react";
import { NostrEvent } from "../../../types/nostr-event";
import UserAvatarLink from "../../user-avatar-link";
import UserLink from "../../user-link";
import UserAvatarLink from "../../user/user-avatar-link";
import UserLink from "../../user/user-link";
import { CompactNoteContent } from "../../compact-note-content";
import { getHashtags } from "../../../helpers/nostr/stemstr";
import { ReplyIcon } from "../../icons";
import NoteZapButton from "../../note/note-zap-button";
import QuoteRepostButton from "../../note/components/quote-repost-button";
import Timestamp from "../../timestamp";
import TrackStemstrButton from "../../../views/tracks/components/track-stemstr-button";
import TrackDownloadButton from "../../../views/tracks/components/track-download-button";
import TrackPlayer from "../../../views/tracks/components/track-player";
import QuoteRepostButton from "../../note/quote-repost-button";
import NoteZapButton from "../../note/note-zap-button";
// example nevent1qqst32cnyhhs7jt578u7vp3y047dduuwjquztpvwqc43f3nvg8dh28gpzamhxue69uhhyetvv9ujuum5v4khxarj9eshquq4rxdxa
export default function EmbeddedStemstrTrack({ track, ...props }: Omit<CardProps, "children"> & { track: NostrEvent }) {

View File

@ -2,8 +2,8 @@ import { Box, Card, CardProps, Divider, Flex, Link, Text } from "@chakra-ui/reac
import { Link as RouterLink } from "react-router-dom";
import { NostrEvent, isATag } from "../../../types/nostr-event";
import UserLink from "../../user-link";
import UserAvatar from "../../user-avatar";
import UserLink from "../../user/user-link";
import UserAvatar from "../../user/user-avatar";
import ChatMessageContent from "../../../views/streams/stream/stream-chat/chat-message-content";
import useReplaceableEvent from "../../../hooks/use-replaceable-event";
import { parseStreamEvent } from "../../../helpers/nostr/stream";

View File

@ -4,8 +4,8 @@ import { Link as RouterLink, useNavigate } from "react-router-dom";
import { parseStreamEvent } from "../../../helpers/nostr/stream";
import { NostrEvent } from "../../../types/nostr-event";
import StreamStatusBadge from "../../../views/streams/components/status-badge";
import UserLink from "../../user-link";
import UserAvatar from "../../user-avatar";
import UserLink from "../../user/user-link";
import UserAvatar from "../../user/user-avatar";
import useEventNaddr from "../../../hooks/use-event-naddr";
import Timestamp from "../../timestamp";
import { useBreakpointValue } from "../../../providers/global/breakpoint-provider";

View File

@ -2,16 +2,16 @@ import { Card, CardProps, Flex, LinkBox, Spacer, Text } from "@chakra-ui/react";
import { Link as RouterLink } from "react-router-dom";
import { NostrEvent } from "../../../types/nostr-event";
import UserAvatarLink from "../../user-avatar-link";
import UserLink from "../../user-link";
import UserAvatarLink from "../../user/user-avatar-link";
import UserLink from "../../user/user-link";
import useSubject from "../../../hooks/use-subject";
import appSettings from "../../../services/settings/app-settings";
import EventVerificationIcon from "../../event-verification-icon";
import EventVerificationIcon from "../../common-event/event-verification-icon";
import { TrustProvider } from "../../../providers/local/trust";
import Timestamp from "../../timestamp";
import { CompactNoteContent } from "../../compact-note-content";
import HoverLinkOverlay from "../../hover-link-overlay";
import { getThreadReferences } from "../../../helpers/nostr/events";
import { getThreadReferences } from "../../../helpers/nostr/event";
import useSingleEvent from "../../../hooks/use-single-event";
import { getTorrentTitle } from "../../../helpers/nostr/torrents";
import { useNavigateInDrawer } from "../../../providers/drawer-sub-view-provider";

View File

@ -17,8 +17,8 @@ import {
import { Link as RouterLink } from "react-router-dom";
import { getSharableEventAddress } from "../../../helpers/nip19";
import UserAvatarLink from "../../user-avatar-link";
import UserLink from "../../user-link";
import UserAvatarLink from "../../user/user-avatar-link";
import UserLink from "../../user/user-link";
import { NostrEvent } from "../../../types/nostr-event";
import Timestamp from "../../timestamp";
import Magnet from "../../icons/magnet";

View File

@ -3,10 +3,10 @@ import { Box, Button, ButtonGroup, Card, CardBody, CardHeader, CardProps, Link,
import { getSharableEventAddress } from "../../../helpers/nip19";
import { NostrEvent } from "../../../types/nostr-event";
import UserAvatarLink from "../../user-avatar-link";
import UserLink from "../../user-link";
import UserAvatarLink from "../../user/user-avatar-link";
import UserLink from "../../user/user-link";
import { buildAppSelectUrl } from "../../../helpers/nostr/apps";
import { UserDnsIdentityIcon } from "../../user-dns-identity-icon";
import { UserDnsIdentityIcon } from "../../user/user-dns-identity-icon";
import {
embedEmoji,
embedNostrHashtags,

View File

@ -2,7 +2,7 @@ import { lazy } from "react";
import { EmbedableContent, embedJSX } from "../../helpers/embeds";
import { getMatchCashu } from "../../helpers/regexp";
const InlineCachuCard = lazy(() => import("../inline-cashu-card"));
const InlineCachuCard = lazy(() => import("../cashu/inline-cashu-card"));
export function embedCashuTokens(content: EmbedableContent) {
return embedJSX(content, {

View File

@ -1,7 +1,7 @@
import { Link } from "@chakra-ui/react";
import OpenGraphCard from "../open-graph-card";
import OpenGraphLink from "../open-graph-link";
import OpenGraphCard from "../open-graph/open-graph-card";
import OpenGraphLink from "../open-graph/open-graph-link";
export function renderGenericUrl(match: URL) {
return (

View File

@ -10,3 +10,5 @@ export * from "./cashu";
export * from "./video";
export * from "./simplex";
export * from "./reddit";
export * from "./model";
export * from "./audio";

View File

@ -1,5 +1,5 @@
import { EmbedableContent, embedJSX } from "../../helpers/embeds";
import { InlineInvoiceCard } from "../inline-invoice-card";
import { InlineInvoiceCard } from "../lightning/inline-invoice-card";
export function embedLightningInvoice(content: EmbedableContent) {
return embedJSX(content, {

View File

@ -3,7 +3,7 @@ import { Link as RouterLink } from "react-router-dom";
import { EmbedableContent, embedJSX } from "../../helpers/embeds";
import { DraftNostrEvent, NostrEvent } from "../../types/nostr-event";
import UserLink from "../user-link";
import UserLink from "../user/user-link";
import { getMatchHashtag, getMatchNostrLink, stripInvisibleChar } from "../../helpers/regexp";
import { safeDecode } from "../../helpers/nip19";
import { EmbedEventPointer } from "../embed-event";

View File

@ -15,15 +15,15 @@ import {
} from "@chakra-ui/react";
import { NostrEvent } from "../../types/nostr-event";
import UserAvatarLink from "../user-avatar-link";
import UserLink from "../user-link";
import UserAvatarLink from "../user/user-avatar-link";
import UserLink from "../user/user-link";
import { LightningIcon } from "../icons";
import { ParsedZap } from "../../helpers/nostr/zaps";
import { readablizeSats } from "../../helpers/bolt11";
import useEventReactions from "../../hooks/use-event-reactions";
import useEventZaps from "../../hooks/use-event-zaps";
import Timestamp from "../timestamp";
import { getEventUID } from "../../helpers/nostr/events";
import { getEventUID } from "../../helpers/nostr/event";
import ReactionDetails from "./reaction-details";
import RepostDetails from "./repost-details";

View File

@ -3,8 +3,8 @@ import { useMemo } from "react";
import { NostrEvent } from "../../types/nostr-event";
import { groupReactions } from "../../helpers/nostr/reactions";
import UserAvatarLink from "../user-avatar-link";
import UserLink from "../user-link";
import UserAvatarLink from "../user/user-avatar-link";
import UserLink from "../user/user-link";
import ReactionIcon from "../event-reactions/reaction-icon";
function ShowMoreGrid({

View File

@ -2,8 +2,8 @@ import { Flex, Text } from "@chakra-ui/react";
import { kinds } from "nostr-tools";
import { NostrEvent } from "../../types/nostr-event";
import UserAvatarLink from "../user-avatar-link";
import UserLink from "../user-link";
import UserAvatarLink from "../user/user-avatar-link";
import UserLink from "../user/user-link";
import useTimelineLoader from "../../hooks/use-timeline-loader";
import { useReadRelays } from "../../hooks/use-client-relays";
import useSubject from "../../hooks/use-subject";

View File

@ -16,7 +16,7 @@ import clientRelaysService from "../../services/client-relays";
import { getZapSplits } from "../../helpers/nostr/zaps";
import { unique } from "../../helpers/array";
import relayScoreboardService from "../../services/relay-scoreboard";
import { getEventCoordinate, isReplaceable } from "../../helpers/nostr/events";
import { getEventCoordinate, isReplaceable } from "../../helpers/nostr/event";
import { EmbedProps } from "../embed-event";
import userMailboxesService from "../../services/user-mailboxes";
import InputStep from "./input-step";
@ -26,7 +26,7 @@ import signingService from "../../services/signing";
import accountService from "../../services/account";
import PayStep from "./pay-step";
import { getInvoiceFromCallbackUrl } from "../../helpers/lnurl";
import UserLink from "../user-link";
import UserLink from "../user/user-link";
import relayHintService from "../../services/event-relay-hint";
export type PayRequest = { invoice?: string; pubkey: string; error?: any };

View File

@ -9,8 +9,8 @@ import { getZapSplits } from "../../helpers/nostr/zaps";
import { EmbedEvent, EmbedProps } from "../embed-event";
import useAppSettings from "../../hooks/use-app-settings";
import CustomZapAmountOptions from "./zap-options";
import UserAvatar from "../user-avatar";
import UserLink from "../user-link";
import UserAvatar from "../user/user-avatar";
import UserLink from "../user/user-link";
function UserCard({ pubkey, percent }: { pubkey: string; percent?: number }) {
const { address } = useUserLNURLMetadata(pubkey);

View File

@ -2,8 +2,8 @@ import { useMount } from "react-use";
import { Alert, Button, ButtonGroup, Flex, IconButton, Spacer, useDisclosure, useToast } from "@chakra-ui/react";
import { PayRequest } from ".";
import UserAvatar from "../user-avatar";
import UserLink from "../user-link";
import UserAvatar from "../user/user-avatar";
import UserLink from "../user/user-link";
import { ChevronDownIcon, ChevronUpIcon, CheckIcon, ErrorIcon, LightningIcon } from "../icons";
import { InvoiceModalContent } from "../invoice-modal";
import { PropsWithChildren, useEffect, useState } from "react";

View File

@ -14,7 +14,7 @@ import {
} from "@chakra-ui/react";
import { ExternalLinkIcon, QrCodeIcon } from "./icons";
import QrCodeSvg from "./qr-code-svg";
import QrCodeSvg from "./qr-code/qr-code-svg";
import { CopyIconButton } from "./copy-icon-button";
type CommonProps = { invoice: string; onPaid: () => void };

View File

@ -2,12 +2,12 @@ import { CloseIcon } from "@chakra-ui/icons";
import { useNavigate } from "react-router-dom";
import { Box, Button, Flex, IconButton, Text, useDisclosure } from "@chakra-ui/react";
import { getUserDisplayName } from "../../helpers/user-metadata";
import { getUserDisplayName } from "../../helpers/nostr/user-metadata";
import useSubject from "../../hooks/use-subject";
import { useUserMetadata } from "../../hooks/use-user-metadata";
import accountService, { Account } from "../../services/account";
import { AddIcon, ChevronDownIcon, ChevronUpIcon } from "../icons";
import UserAvatar from "../user-avatar";
import UserAvatar from "../user/user-avatar";
import AccountInfoBadge from "../account-info-badge";
import useCurrentAccount from "../../hooks/use-current-account";

View File

@ -8,8 +8,8 @@ import dayjs from "dayjs";
import useCurrentAccount from "../../hooks/use-current-account";
import useSubject from "../../hooks/use-subject";
import accountService from "../../services/account";
import UserAvatar from "../user-avatar";
import UserLink from "../user-link";
import UserAvatar from "../user/user-avatar";
import UserLink from "../user/user-link";
import { GhostIcon } from "../icons";
import useTimelineLoader from "../../hooks/use-timeline-loader";
import { useReadRelays } from "../../hooks/use-client-relays";

View File

@ -5,7 +5,7 @@ import { useLocation, useNavigate } from "react-router-dom";
import useCurrentAccount from "../../hooks/use-current-account";
import { PostModalContext } from "../../providers/route/post-modal-provider";
import { DirectMessagesIcon, NotesIcon, NotificationsIcon, PlusCircleIcon, SearchIcon } from "../icons";
import UserAvatar from "../user-avatar";
import UserAvatar from "../user/user-avatar";
import MobileSideDrawer from "./mobile-side-drawer";
import Rocket02 from "../icons/rocket-02";

View File

@ -30,9 +30,9 @@ declare module "yet-another-react-lightbox" {
}
import { NostrEvent } from "../types/nostr-event";
import UserAvatarLink from "./user-avatar-link";
import UserLink from "./user-link";
import { UserDnsIdentityIcon } from "./user-dns-identity-icon";
import UserAvatarLink from "./user/user-avatar-link";
import UserLink from "./user/user-link";
import { UserDnsIdentityIcon } from "./user/user-dns-identity-icon";
import styled from "@emotion/styled";
import { getSharableEventAddress } from "../helpers/nip19";

View File

@ -4,8 +4,8 @@ import dayjs from "dayjs";
import { requestProvider } from "webln";
import { Box, BoxProps, Button, ButtonGroup, IconButton, Text } from "@chakra-ui/react";
import { parsePaymentRequest, readablizeSats } from "../helpers/bolt11";
import { CopyToClipboardIcon } from "./icons";
import { parsePaymentRequest, readablizeSats } from "../../helpers/bolt11";
import { CopyToClipboardIcon } from "../icons";
export type InvoiceButtonProps = {
paymentRequest: string;

View File

@ -22,7 +22,7 @@ import { useSet } from "react-use";
import { ExternalLinkIcon, SearchIcon } from "./icons";
import { buildAppSelectUrl } from "../helpers/nostr/apps";
import UserLink from "./user-link";
import UserLink from "./user/user-link";
import { encodeDecodeResult } from "../helpers/nip19";
import relayPoolService from "../services/relay-pool";

View File

@ -12,8 +12,8 @@ import { matchSorter } from "match-sorter";
import { Emoji, useContextEmojis } from "../providers/global/emoji-provider";
import { useUserSearchDirectoryContext } from "../providers/global/user-directory-provider";
import UserAvatar from "./user-avatar";
import { UserDnsIdentityIcon } from "./user-dns-identity-icon";
import UserAvatar from "./user/user-avatar";
import { UserDnsIdentityIcon } from "./user/user-dns-identity-icon";
export type PeopleToken = { pubkey: string; names: string[] };
type Token = Emoji | PeopleToken;

View File

@ -1,11 +1,11 @@
import { CardProps, Flex } from "@chakra-ui/react";
import useCurrentAccount from "../hooks/use-current-account";
import { NostrEvent } from "../types/nostr-event";
import useCurrentAccount from "../../hooks/use-current-account";
import { NostrEvent } from "../../types/nostr-event";
import MessageBubble, { MessageBubbleProps } from "./message-bubble";
import { useThreadsContext } from "../providers/local/thread-provider";
import ThreadButton from "../views/dms/components/thread-button";
import UserAvatarLink from "./user-avatar-link";
import { useThreadsContext } from "../../providers/local/thread-provider";
import ThreadButton from "../../views/dms/components/thread-button";
import UserAvatarLink from "../user/user-avatar-link";
function MessageBubbleWithThread({ message, showThreadButton = true, ...props }: MessageBubbleProps) {
const { threads } = useThreadsContext();

View File

@ -1,17 +1,17 @@
import { ReactNode, useRef } from "react";
import { ButtonGroup, Card, CardBody, CardFooter, CardHeader, CardProps } from "@chakra-ui/react";
import { NostrEvent } from "../types/nostr-event";
import { useRegisterIntersectionEntity } from "../providers/local/intersection-observer";
import { getEventUID } from "../helpers/nostr/events";
import Timestamp from "./timestamp";
import NoteZapButton from "./note/note-zap-button";
import UserLink from "./user-link";
import { UserDnsIdentityIcon } from "./user-dns-identity-icon";
import useEventReactions from "../hooks/use-event-reactions";
import AddReactionButton from "./note/components/add-reaction-button";
import EventReactionButtons from "./event-reactions/event-reactions";
import { IconThreadButton } from "../views/dms/components/thread-button";
import { NostrEvent } from "../../types/nostr-event";
import { useRegisterIntersectionEntity } from "../../providers/local/intersection-observer";
import { getEventUID } from "../../helpers/nostr/event";
import Timestamp from "../timestamp";
import UserLink from "../user/user-link";
import { UserDnsIdentityIcon } from "../user/user-dns-identity-icon";
import useEventReactions from "../../hooks/use-event-reactions";
import EventReactionButtons from "../event-reactions/event-reactions";
import { IconThreadButton } from "../../views/dms/components/thread-button";
import AddReactionButton from "../note/timeline-note/components/add-reaction-button";
import NoteZapButton from "../note/note-zap-button";
export type MessageBubbleProps = {
message: NostrEvent;

View File

@ -12,21 +12,21 @@ import {
useDisclosure,
} from "@chakra-ui/react";
import useCurrentAccount from "../../../hooks/use-current-account";
import useUserLists from "../../../hooks/use-user-lists";
import useCurrentAccount from "../../hooks/use-current-account";
import useUserLists from "../../hooks/use-user-lists";
import {
NOTE_LIST_KIND,
listAddEvent,
listRemoveEvent,
getEventPointersFromList,
getListName,
} from "../../../helpers/nostr/lists";
import { NostrEvent } from "../../../types/nostr-event";
import { getEventCoordinate } from "../../../helpers/nostr/events";
import { BookmarkIcon, BookmarkedIcon, PlusCircleIcon } from "../../icons";
import NewListModal from "../../../views/lists/components/new-list-modal";
import useEventBookmarkActions from "../../../hooks/use-event-bookmark-actions";
import { usePublishEvent } from "../../../providers/global/publish-provider";
} from "../../helpers/nostr/lists";
import { NostrEvent } from "../../types/nostr-event";
import { getEventCoordinate } from "../../helpers/nostr/event";
import { BookmarkIcon, BookmarkedIcon, PlusCircleIcon } from "../icons";
import NewListModal from "../../views/lists/components/new-list-modal";
import useEventBookmarkActions from "../../hooks/use-event-bookmark-actions";
import { usePublishEvent } from "../../providers/global/publish-provider";
export default function BookmarkButton({ event, ...props }: { event: NostrEvent } & Omit<IconButtonProps, "icon">) {
const publish = usePublishEvent();

View File

@ -1,18 +1,14 @@
import { memo } from "react";
import { NostrEvent } from "nostr-tools";
import { getEventRelays } from "../../services/event-relays";
import { NostrEvent } from "../../types/nostr-event";
import useSubject from "../../hooks/use-subject";
import { RelayIconStack, RelayIconStackProps } from "../relay-icon-stack";
import { getEventUID } from "../../helpers/nostr/events";
import { getEventUID } from "../../helpers/nostr/event";
import { useBreakpointValue } from "../../providers/global/breakpoint-provider";
export type NoteRelaysProps = {
event: NostrEvent;
};
export const EventRelays = memo(
({ event, ...props }: NoteRelaysProps & Omit<RelayIconStackProps, "relays" | "maxRelays">) => {
({ event, ...props }: { event: NostrEvent } & Omit<RelayIconStackProps, "relays" | "maxRelays">) => {
const maxRelays = useBreakpointValue({ base: 3, md: undefined });
const eventRelays = useSubject(getEventRelays(getEventUID(event)));

View File

@ -2,15 +2,15 @@ import { useMemo } from "react";
import { Link, LinkProps } from "@chakra-ui/react";
import { Link as RouterLink } from "react-router-dom";
import { truncatedId } from "../helpers/nostr/events";
import relayHintService from "../services/event-relay-hint";
import { truncatedId } from "../../helpers/nostr/event";
import relayHintService from "../../services/event-relay-hint";
import { nip19 } from "nostr-tools";
export type NoteLinkProps = LinkProps & {
noteId: string;
};
export const NoteLink = ({ children, noteId, color = "blue.500", ...props }: NoteLinkProps) => {
export function NoteLink({ children, noteId, color = "blue.500", ...props }: NoteLinkProps) {
const nevent = useMemo(() => {
const relays = relayHintService.getEventPointerRelayHints(noteId).slice(0, 2);
return nip19.neventEncode({ id: noteId, relays });
@ -21,4 +21,6 @@ export const NoteLink = ({ children, noteId, color = "blue.500", ...props }: Not
{children || truncatedId(nevent)}
</Link>
);
};
}
export default NoteLink;

View File

@ -4,7 +4,7 @@ import { Link as RouterLink } from "react-router-dom";
import { BroadcastEventIcon } from "../icons";
import { NostrEvent } from "../../types/nostr-event";
import { CustomMenuIconButton, MenuIconButtonProps } from "../menu-icon-button";
import { DotsMenuButton, MenuIconButtonProps } from "../dots-menu-button";
import NoteTranslationModal from "../../views/tools/transform-note/translation";
import Translate01 from "../icons/translate-01";
import InfoCircle from "../icons/info-circle";
@ -33,7 +33,7 @@ export default function NoteMenu({
return (
<>
<CustomMenuIconButton {...props}>
<DotsMenuButton {...props}>
<OpenInAppMenuItem event={event} />
<CopyShareLinkMenuItem event={event} />
<CopyEmbedCodeMenuItem event={event} />
@ -65,7 +65,7 @@ export default function NoteMenu({
</MenuItem>
)}
<DebugEventMenuItem event={event} />
</CustomMenuIconButton>
</DotsMenuButton>
{translationsModal.isOpen && <NoteTranslationModal isOpen onClose={translationsModal.onClose} note={event} />}
</>

View File

@ -10,7 +10,7 @@ import { NostrEvent } from "../../types/nostr-event";
import { LightningIcon } from "../icons";
import ZapModal from "../event-zap-modal";
import useUserLNURLMetadata from "../../hooks/use-user-lnurl-metadata";
import { getEventUID } from "../../helpers/nostr/events";
import { getEventUID } from "../../helpers/nostr/event";
export type NoteZapButtonProps = Omit<ButtonProps, "children"> & {
event: NostrEvent;

View File

@ -2,8 +2,8 @@ import { MouseEventHandler, useCallback } from "react";
import { IconButton, IconButtonProps } from "@chakra-ui/react";
import { To } from "react-router-dom";
import { DrawerIcon } from "./icons";
import { useNavigateInDrawer } from "../providers/drawer-sub-view-provider";
import { DrawerIcon } from "../icons";
import { useNavigateInDrawer } from "../../providers/drawer-sub-view-provider";
export default function OpenInDrawerButton({
to,

View File

@ -1,10 +1,10 @@
import { useContext } from "react";
import { ButtonProps, IconButton } from "@chakra-ui/react";
import { NostrEvent } from "nostr-tools";
import { NostrEvent } from "../../../types/nostr-event";
import { QuoteRepostIcon } from "../../icons";
import { PostModalContext } from "../../../providers/route/post-modal-provider";
import { getSharableEventAddress } from "../../../helpers/nip19";
import { QuoteRepostIcon } from "../icons";
import { PostModalContext } from "../../providers/route/post-modal-provider";
import { getSharableEventAddress } from "../../helpers/nip19";
export type QuoteRepostButtonProps = Omit<ButtonProps, "children" | "onClick"> & {
event: NostrEvent;

View File

@ -1,3 +1,4 @@
import { useState } from "react";
import {
ButtonProps,
IconButton,
@ -9,15 +10,14 @@ import {
Portal,
useBoolean,
} from "@chakra-ui/react";
import { NostrEvent } from "nostr-tools";
import useEventReactions from "../../../hooks/use-event-reactions";
import { NostrEvent } from "../../../types/nostr-event";
import { AddReactionIcon } from "../../icons";
import ReactionPicker from "../../reaction-picker";
import { draftEventReaction } from "../../../helpers/nostr/reactions";
import { getEventUID } from "../../../helpers/nostr/events";
import { useState } from "react";
import { usePublishEvent } from "../../../providers/global/publish-provider";
import useEventReactions from "../../../../hooks/use-event-reactions";
import { AddReactionIcon } from "../../../icons";
import ReactionPicker from "../../../reaction-picker";
import { draftEventReaction } from "../../../../helpers/nostr/reactions";
import { getEventUID } from "../../../../helpers/nostr/event";
import { usePublishEvent } from "../../../../providers/global/publish-provider";
export default function AddReactionButton({
event,

View File

@ -1,10 +1,10 @@
import { IconButton, IconButtonProps } from "@chakra-ui/react";
import { NostrEvent } from "nostr-tools";
import { NostrEvent } from "../../../types/nostr-event";
import InfoCircle from "../../icons/info-circle";
import useEventReactions from "../../../hooks/use-event-reactions";
import { getEventUID } from "../../../helpers/nostr/events";
import useEventZaps from "../../../hooks/use-event-zaps";
import InfoCircle from "../../../icons/info-circle";
import useEventReactions from "../../../../hooks/use-event-reactions";
import { getEventUID } from "../../../../helpers/nostr/event";
import useEventZaps from "../../../../hooks/use-event-zaps";
export function NoteDetailsButton({
event,

View File

@ -1,7 +1,8 @@
import { IconButton, IconButtonProps, Link } from "@chakra-ui/react";
import { ExternalLinkIcon } from "../../icons";
import { useMemo } from "react";
import { NostrEvent } from "../../../types/nostr-event";
import { NostrEvent } from "nostr-tools";
import { ExternalLinkIcon } from "../../../icons";
export default function NoteProxyLink({
event,

View File

@ -1,10 +1,10 @@
import { ButtonGroup, ButtonGroupProps, Divider } from "@chakra-ui/react";
import { NostrEvent } from "nostr-tools";
import { NostrEvent } from "../../../types/nostr-event";
import AddReactionButton from "./add-reaction-button";
import EventReactionButtons from "../../event-reactions/event-reactions";
import useEventReactions from "../../../hooks/use-event-reactions";
import { useBreakpointValue } from "../../../providers/global/breakpoint-provider";
import EventReactionButtons from "../../../event-reactions/event-reactions";
import { useBreakpointValue } from "../../../../providers/global/breakpoint-provider";
import useEventReactions from "../../../../hooks/use-event-reactions";
export default function NoteReactions({ event, ...props }: Omit<ButtonGroupProps, "children"> & { event: NostrEvent }) {
const reactions = useEventReactions(event.id) ?? [];

View File

@ -1,12 +1,12 @@
import { Button, IconButton, useDisclosure } from "@chakra-ui/react";
import { kinds } from "nostr-tools";
import { NostrEvent } from "../../../types/nostr-event";
import { RepostIcon } from "../../icons";
import useEventCount from "../../../hooks/use-event-count";
import { NostrEvent } from "../../../../types/nostr-event";
import { RepostIcon } from "../../../icons";
import useEventCount from "../../../../hooks/use-event-count";
import useEventExists from "../../../../hooks/use-event-exists";
import useCurrentAccount from "../../../../hooks/use-current-account";
import RepostModal from "./repost-modal";
import useEventExists from "../../../hooks/use-event-exists";
import useCurrentAccount from "../../../hooks/use-current-account";
export default function RepostButton({ event }: { event: NostrEvent }) {
const { isOpen, onClose, onOpen } = useDisclosure();

View File

@ -12,20 +12,19 @@ import {
SimpleGrid,
useDisclosure,
} from "@chakra-ui/react";
import { kinds } from "nostr-tools";
import { EventTemplate, NostrEvent, kinds } from "nostr-tools";
import dayjs from "dayjs";
import type { AddressPointer } from "nostr-tools/lib/types/nip19";
import { DraftNostrEvent, NostrEvent } from "../../../types/nostr-event";
import { EmbedEvent } from "../../embed-event";
import { ChevronDownIcon, ChevronUpIcon, ExternalLinkIcon } from "../../icons";
import useUserCommunitiesList from "../../../hooks/use-user-communities-list";
import useCurrentAccount from "../../../hooks/use-current-account";
import { createCoordinate } from "../../../services/replaceable-events";
import relayHintService from "../../../services/event-relay-hint";
import { usePublishEvent } from "../../../providers/global/publish-provider";
import { ChevronDownIcon, ChevronUpIcon, ExternalLinkIcon } from "../../../icons";
import relayHintService from "../../../../services/event-relay-hint";
import { usePublishEvent } from "../../../../providers/global/publish-provider";
import useCurrentAccount from "../../../../hooks/use-current-account";
import useUserCommunitiesList from "../../../../hooks/use-user-communities-list";
import { createCoordinate } from "../../../../classes/batch-kind-loader";
import { EmbedEvent } from "../../../embed-event";
function buildRepost(event: NostrEvent): DraftNostrEvent {
function buildRepost(event: NostrEvent): EventTemplate {
const hint = relayHintService.getEventRelayHint(event);
const tags: NostrEvent["tags"] = [];
tags.push(["e", event.id, hint ?? ""]);

View File

@ -14,44 +14,44 @@ import {
Text,
useDisclosure,
} from "@chakra-ui/react";
import { NostrEvent } from "../../types/nostr-event";
import UserAvatarLink from "../user-avatar-link";
import { NostrEvent } from "../../../types/nostr-event";
import UserAvatarLink from "../../user/user-avatar-link";
import { Link as RouterLink } from "react-router-dom";
import NoteMenu from "./note-menu";
import UserLink from "../user-link";
import { UserDnsIdentityIcon } from "../user-dns-identity-icon";
import NoteZapButton from "./note-zap-button";
import { ExpandProvider } from "../../providers/local/expanded";
import useSubject from "../../hooks/use-subject";
import appSettings from "../../services/settings/app-settings";
import EventVerificationIcon from "../event-verification-icon";
import NoteMenu from "../note-menu";
import UserLink from "../../user/user-link";
import { UserDnsIdentityIcon } from "../../user/user-dns-identity-icon";
import NoteZapButton from "../note-zap-button";
import { ExpandProvider } from "../../../providers/local/expanded";
import useSubject from "../../../hooks/use-subject";
import appSettings from "../../../services/settings/app-settings";
import EventVerificationIcon from "../../common-event/event-verification-icon";
import RepostButton from "./components/repost-button";
import QuoteRepostButton from "./components/quote-repost-button";
import { ReplyIcon } from "../icons";
import QuoteRepostButton from "../quote-repost-button";
import { ReplyIcon } from "../../icons";
import NoteContentWithWarning from "./note-content-with-warning";
import { TrustProvider } from "../../providers/local/trust";
import { useRegisterIntersectionEntity } from "../../providers/local/intersection-observer";
import BookmarkButton from "./components/bookmark-button";
import useCurrentAccount from "../../hooks/use-current-account";
import { TrustProvider } from "../../../providers/local/trust";
import { useRegisterIntersectionEntity } from "../../../providers/local/intersection-observer";
import BookmarkButton from "../bookmark-button";
import useCurrentAccount from "../../../hooks/use-current-account";
import NoteReactions from "./components/note-reactions";
import ReplyForm from "../../views/thread/components/reply-form";
import { getThreadReferences, truncatedId } from "../../helpers/nostr/events";
import Timestamp from "../timestamp";
import ReplyForm from "../../../views/thread/components/reply-form";
import { getThreadReferences, truncatedId } from "../../../helpers/nostr/event";
import Timestamp from "../../timestamp";
import OpenInDrawerButton from "../open-in-drawer-button";
import { getSharableEventAddress } from "../../helpers/nip19";
import { useBreakpointValue } from "../../providers/global/breakpoint-provider";
import HoverLinkOverlay from "../hover-link-overlay";
import { getSharableEventAddress } from "../../../helpers/nip19";
import { useBreakpointValue } from "../../../providers/global/breakpoint-provider";
import HoverLinkOverlay from "../../hover-link-overlay";
import NoteCommunityMetadata from "./note-community-metadata";
import useSingleEvent from "../../hooks/use-single-event";
import { CompactNoteContent } from "../compact-note-content";
import useSingleEvent from "../../../hooks/use-single-event";
import { CompactNoteContent } from "../../compact-note-content";
import NoteProxyLink from "./components/note-proxy-link";
import { NoteDetailsButton } from "./components/note-details-button";
import EventInteractionDetailsModal from "../event-interactions-modal";
import singleEventService from "../../services/single-event";
import EventInteractionDetailsModal from "../../event-interactions-modal";
import singleEventService from "../../../services/single-event";
import { AddressPointer, EventPointer } from "nostr-tools/lib/types/nip19";
import { nip19 } from "nostr-tools";
import POWIcon from "../pow-icon";
import POWIcon from "../../pow/pow-icon";
function ReplyToE({ pointer }: { pointer: EventPointer }) {
const event = useSingleEvent(pointer.id, pointer.relays);
@ -111,7 +111,7 @@ export type NoteProps = Omit<CardProps, "children"> & {
registerIntersectionEntity?: boolean;
clickable?: boolean;
};
export function Note({
export function TimelineNote({
event,
variant = "outline",
showReplyButton,
@ -211,4 +211,4 @@ export function Note({
);
}
export default memo(Note);
export default memo(TimelineNote);

View File

@ -1,9 +1,9 @@
import { useMemo } from "react";
import { Link as RouterLink } from "react-router-dom";
import { Link, Text, TextProps } from "@chakra-ui/react";
import { NostrEvent } from "nostr-tools";
import { NostrEvent } from "../../types/nostr-event";
import { getEventCommunityPointer } from "../../helpers/nostr/communities";
import { getEventCommunityPointer } from "../../../helpers/nostr/communities";
export default function NoteCommunityMetadata({
event,

View File

@ -1,9 +1,9 @@
import { NostrEvent } from "../../types/nostr-event";
import { NostrEvent } from "nostr-tools";
import { NoteContents } from "./text-note-contents";
import { useExpand } from "../../providers/local/expanded";
import SensitiveContentWarning from "../sensitive-content-warning";
import useAppSettings from "../../hooks/use-app-settings";
import { TextNoteContents } from "./text-note-contents";
import { useExpand } from "../../../providers/local/expanded";
import SensitiveContentWarning from "../../sensitive-content-warning";
import useAppSettings from "../../../hooks/use-app-settings";
export default function NoteContentWithWarning({ event }: { event: NostrEvent }) {
const expand = useExpand();
@ -15,6 +15,6 @@ export default function NoteContentWithWarning({ event }: { event: NostrEvent })
return showContentWarning ? (
<SensitiveContentWarning description={contentWarningTag?.[1]} />
) : (
<NoteContents px="2" event={event} />
<TextNoteContents px="2" event={event} />
);
}

View File

@ -1,8 +1,8 @@
import React, { Suspense } from "react";
import { Box, BoxProps, Spinner } from "@chakra-ui/react";
import { EventTemplate, NostrEvent } from "nostr-tools";
import { DraftNostrEvent, NostrEvent } from "../../types/nostr-event";
import { EmbedableContent, embedUrls, truncateEmbedableContent } from "../../helpers/embeds";
import { EmbedableContent, embedUrls, truncateEmbedableContent } from "../../../helpers/embeds";
import {
embedLightningInvoice,
embedNostrLinks,
@ -27,12 +27,12 @@ import {
renderSimpleXLink,
renderRedditUrl,
embedNipDefinitions,
} from "../embed-types";
import { LightboxProvider } from "../lightbox-provider";
import { renderModelUrl } from "../embed-types/model";
import { renderAudioUrl } from "../embed-types/audio";
renderAudioUrl,
renderModelUrl,
} from "../../embed-types";
import { LightboxProvider } from "../../lightbox-provider";
function buildContents(event: NostrEvent | DraftNostrEvent, simpleLinks = false) {
function buildContents(event: NostrEvent | EventTemplate, simpleLinks = false) {
let content: EmbedableContent = [event.content.trim()];
// image gallery
@ -74,14 +74,14 @@ function buildContents(event: NostrEvent | DraftNostrEvent, simpleLinks = false)
return content;
}
export type NoteContentsProps = {
event: NostrEvent | DraftNostrEvent;
export type TextNoteContentsProps = {
event: NostrEvent | EventTemplate;
noOpenGraphLinks?: boolean;
maxLength?: number;
};
export const NoteContents = React.memo(
({ event, noOpenGraphLinks, maxLength, ...props }: NoteContentsProps & Omit<BoxProps, "children">) => {
export const TextNoteContents = React.memo(
({ event, noOpenGraphLinks, maxLength, ...props }: TextNoteContentsProps & Omit<BoxProps, "children">) => {
let content = buildContents(event, noOpenGraphLinks);
if (maxLength !== undefined) {
@ -99,3 +99,5 @@ export const NoteContents = React.memo(
);
},
);
export default TextNoteContents;

View File

@ -5,7 +5,7 @@ import { nip19 } from "nostr-tools";
import { useUserSearchDirectoryContext } from "../providers/global/user-directory-provider";
import userMetadataService from "../services/user-metadata";
import { getUserDisplayName } from "../helpers/user-metadata";
import { getUserDisplayName } from "../helpers/nostr/user-metadata";
const NpubAutocomplete = forwardRef<HTMLInputElement, InputProps>(({ value, ...props }, ref) => {
const getDirectory = useUserSearchDirectoryContext();

View File

@ -11,8 +11,8 @@ import {
LinkOverlay,
Text,
} from "@chakra-ui/react";
import useOpenGraphData from "../hooks/use-open-graph-data";
import { useBreakpointValue } from "../providers/global/breakpoint-provider";
import useOpenGraphData from "../../hooks/use-open-graph-data";
import { useBreakpointValue } from "../../providers/global/breakpoint-provider";
export default function OpenGraphCard({ url, ...props }: { url: URL } & Omit<CardProps, "children">) {
const { value: data } = useOpenGraphData(url);

View File

@ -1,5 +1,5 @@
import { Link, LinkProps } from "@chakra-ui/react";
import useOpenGraphData from "../hooks/use-open-graph-data";
import useOpenGraphData from "../../hooks/use-open-graph-data";
export default function OpenGraphLink({ url, ...props }: { url: URL } & Omit<LinkProps, "children">) {
const { value: data } = useOpenGraphData(url);

View File

@ -1,137 +0,0 @@
import { Button, ButtonGroup, ButtonProps, IconButton } from "@chakra-ui/react";
import { useMemo } from "react";
import { usePaginatedList } from "../hooks/use-paginated-list";
import { ChevronLeftIcon, ChevronRightIcon } from "./icons";
const range = (start: number, end: number) => {
let length = end - start + 1;
return Array.from({ length }, (_, idx) => idx + start);
};
export type PaginationControlsProps = ReturnType<typeof usePaginatedList> & {
buttonSize?: ButtonProps["size"];
siblingCount?: number;
};
export const PaginationControls = ({
pageCount,
currentPage,
setPage,
next,
previous,
buttonSize,
siblingCount = 1,
}: PaginationControlsProps) => {
const renderPageButton = (pageNumber: number) => (
<Button
key={pageNumber}
variant={pageNumber - 1 === currentPage ? "solid" : "link"}
title={`page ${pageNumber}`}
size={buttonSize}
onClick={() => setPage(pageNumber - 1)}
>
{pageNumber}
</Button>
);
// copied from https://www.freecodecamp.org/news/build-a-custom-pagination-component-in-react/
const renderPageButtons = () => {
// Pages count is determined as siblingCount + firstPage + lastPage + currentPage + 2*DOTS
const totalPageNumbers = siblingCount + 5;
/*
Case 1:
If the number of pages is less than the page numbers we want to show in our
paginationComponent, we return the range [1..pageCount]
*/
if (totalPageNumbers >= pageCount) {
return range(1, pageCount).map(renderPageButton);
}
/*
Calculate left and right sibling index and make sure they are within range 1 and pageCount
*/
const leftSiblingIndex = Math.max(currentPage + 1 - siblingCount, 1);
const rightSiblingIndex = Math.min(currentPage + 1 + siblingCount, pageCount);
/*
We do not show dots just when there is just one page number to be inserted between the extremes of sibling and the page limits i.e 1 and pageCount. Hence we are using leftSiblingIndex > 2 and rightSiblingIndex < pageCount - 2
*/
const shouldShowLeftDots = leftSiblingIndex > 3;
const shouldShowRightDots = rightSiblingIndex < pageCount - 2;
const firstPageIndex = 1;
const lastPageIndex = pageCount;
/*
Case 2: No left dots to show, but rights dots to be shown
*/
if (!shouldShowLeftDots && shouldShowRightDots) {
let leftItemCount = 3 + 2 * siblingCount;
let leftRange = range(1, leftItemCount);
return [
...leftRange.map(renderPageButton),
<Button key="left-dots" size={buttonSize} variant="link">
...
</Button>,
renderPageButton(lastPageIndex),
];
}
/*
Case 3: No right dots to show, but left dots to be shown
*/
if (shouldShowLeftDots && !shouldShowRightDots) {
let rightItemCount = 3 + 2 * siblingCount;
let rightRange = range(pageCount - rightItemCount + 1, pageCount);
return [
renderPageButton(firstPageIndex),
<Button key="right-dots" size={buttonSize} variant="link">
...
</Button>,
...rightRange.map(renderPageButton),
];
}
/*
Case 4: Both left and right dots to be shown
*/
if (shouldShowLeftDots && shouldShowRightDots) {
let middleRange = range(leftSiblingIndex, rightSiblingIndex);
return [
renderPageButton(firstPageIndex),
<Button key="left-dots" size={buttonSize} variant="link">
...
</Button>,
...middleRange.map(renderPageButton),
<Button key="right-dots" size={buttonSize} variant="link">
...
</Button>,
renderPageButton(lastPageIndex),
];
}
};
return (
<ButtonGroup>
<IconButton
icon={<ChevronLeftIcon />}
aria-label="previous"
title="previous"
size={buttonSize}
onClick={previous}
isDisabled={currentPage === 0}
/>
{renderPageButtons()}
<IconButton
icon={<ChevronRightIcon />}
aria-label="next"
title="next"
size={buttonSize}
onClick={next}
isDisabled={currentPage === pageCount - 1}
/>
</ButtonGroup>
);
};

View File

@ -18,15 +18,15 @@ import { usePeopleListContext } from "../../providers/local/people-list-provider
import useUserLists from "../../hooks/use-user-lists";
import useCurrentAccount from "../../hooks/use-current-account";
import { PEOPLE_LIST_KIND, getListName, getPubkeysFromList } from "../../helpers/nostr/lists";
import { getEventCoordinate, getEventUID } from "../../helpers/nostr/events";
import { getEventCoordinate, getEventUID } from "../../helpers/nostr/event";
import useFavoriteLists from "../../hooks/use-favorite-lists";
import { NostrEvent } from "../../types/nostr-event";
import { useCallback, useState } from "react";
import useUserContactList from "../../hooks/use-user-contact-list";
import { useUserSearchDirectoryContext } from "../../providers/global/user-directory-provider";
import { matchSorter } from "match-sorter";
import UserAvatar from "../user-avatar";
import UserName from "../user-name";
import UserAvatar from "../user/user-avatar";
import UserName from "../user/user-name";
function ListCard({ list, ...props }: { list: NostrEvent } & Omit<ButtonProps, "children`">) {
return (

View File

@ -6,7 +6,7 @@ import useCurrentAccount from "../../hooks/use-current-account";
import { getCommunityName } from "../../helpers/nostr/communities";
import { AddressPointer } from "nostr-tools/lib/types/nip19";
import useReplaceableEvent from "../../hooks/use-replaceable-event";
import { getEventCoordinate } from "../../helpers/nostr/events";
import { getEventCoordinate } from "../../helpers/nostr/event";
function CommunityOption({ pointer }: { pointer: AddressPointer }) {
const community = useReplaceableEvent(pointer);

View File

@ -29,7 +29,6 @@ import { kinds } from "nostr-tools";
import { ChevronDownIcon, ChevronUpIcon, UploadImageIcon } from "../icons";
import NostrPublishAction from "../../classes/nostr-publish-action";
import { NoteContents } from "../note/text-note-contents";
import { PublishDetails } from "../publish-details";
import { TrustProvider } from "../../providers/local/trust";
import {
@ -50,10 +49,11 @@ import useCurrentAccount from "../../hooks/use-current-account";
import useCacheForm from "../../hooks/use-cache-form";
import { useTextAreaUploadFileWithForm } from "../../hooks/use-textarea-upload-file";
import { useThrottle } from "react-use";
import MinePOW from "../mine-pow";
import MinePOW from "../pow/mine-pow";
import useAppSettings from "../../hooks/use-app-settings";
import { ErrorBoundary } from "../error-boundary";
import { usePublishEvent } from "../../providers/global/publish-provider";
import { TextNoteContents } from "../note/timeline-note/text-note-contents";
type FormValues = {
subject: string;
@ -199,7 +199,7 @@ export default function PostModal({
<Box borderWidth={1} borderRadius="md" p="2">
<ErrorBoundary>
<TrustProvider trust>
<NoteContents event={previewDraft} />
<TextNoteContents event={previewDraft} />
</TrustProvider>
</ErrorBoundary>
</Box>

View File

@ -16,8 +16,8 @@ import { useForm } from "react-hook-form";
import { EventSplit } from "../../helpers/nostr/zaps";
import { AddIcon } from "../icons";
import { normalizeToHexPubkey } from "../../helpers/nip19";
import UserAvatar from "../user-avatar";
import UserLink from "../user-link";
import UserAvatar from "../user/user-avatar";
import UserLink from "../user/user-link";
import NpubAutocomplete from "../npub-autocomplete";
function getRemainingPercent(split: EventSplit) {

View File

@ -2,8 +2,8 @@ import { useRef, useState } from "react";
import { Button, ButtonGroup, Flex, Heading, Progress, Text } from "@chakra-ui/react";
import { getEventHash, nip13 } from "nostr-tools";
import { DraftNostrEvent } from "../types/nostr-event";
import CheckCircle from "./icons/check-circle";
import { DraftNostrEvent } from "../../types/nostr-event";
import CheckCircle from "../icons/check-circle";
import { useMount } from "react-use";
const BATCH_NUMBER = 1000;

View File

@ -1,12 +1,12 @@
import { IconProps, Tooltip } from "@chakra-ui/react";
import { NostrEvent } from "../types/nostr-event";
import { NostrEvent } from "../../types/nostr-event";
import { nip13 } from "nostr-tools";
import Dice1 from "./icons/dice-1";
import Dice2 from "./icons/dice-2";
import Dice3 from "./icons/dice-3";
import Dice4 from "./icons/dice-4";
import Dice5 from "./icons/dice-5";
import Dice6 from "./icons/dice-6";
import Dice1 from "../icons/dice-1";
import Dice2 from "../icons/dice-2";
import Dice3 from "../icons/dice-3";
import Dice4 from "../icons/dice-4";
import Dice5 from "../icons/dice-5";
import Dice6 from "../icons/dice-6";
export default function POWIcon({ event, ...props }: IconProps & { event: NostrEvent }) {
const pow = nip13.getPow(event.id);

View File

@ -1,6 +1,6 @@
import { IconButton, Spinner, useDisclosure } from "@chakra-ui/react";
import { type QrScannerModalProps } from "./qr-scanner-modal";
import { QrCodeIcon } from "./icons";
import { QrCodeIcon } from "../icons";
import { Suspense, lazy } from "react";
const QrScannerModal = lazy(() => import("./qr-scanner-modal"));

View File

@ -1,7 +1,7 @@
import { useMemo } from "react";
import { drawSvgPath } from "../helpers/qrcode";
import { Ecc, QrCode } from "../lib/qrcodegen";
import { drawSvgPath } from "../../helpers/qrcode";
import { Ecc, QrCode } from "../../lib/qrcodegen";
export default function QrCodeSvg({
content,

View File

@ -14,7 +14,7 @@ import {
import { isRTag } from "../types/nostr-event";
import useCurrentAccount from "../hooks/use-current-account";
import useUserRelaySets from "../hooks/use-user-relay-sets";
import { getEventCoordinate } from "../helpers/nostr/events";
import { getEventCoordinate } from "../helpers/nostr/event";
import { getListName } from "../helpers/nostr/lists";
import { relayListAddRelay, relayListRemoveRelay } from "../helpers/nostr/relay-list";
import { AddIcon, CheckIcon, ChevronDownIcon, InboxIcon, OutboxIcon, PlusCircleIcon } from "./icons";

View File

@ -30,7 +30,7 @@ import { RelayFavicon } from "../relay-favicon";
import useUserRelaySets from "../../hooks/use-user-relay-sets";
import useCurrentAccount from "../../hooks/use-current-account";
import { getListName } from "../../helpers/nostr/lists";
import { getEventCoordinate } from "../../helpers/nostr/events";
import { getEventCoordinate } from "../../helpers/nostr/event";
import AddRelayForm from "../../views/relays/app/add-relay-form";
import { SaveRelaySetForm } from "./save-relay-set-form";

View File

@ -4,7 +4,7 @@ import { useForm } from "react-hook-form";
import { getListDescription, getListName, setListDescription, setListName } from "../../helpers/nostr/lists";
import { isRTag } from "../../types/nostr-event";
import { cloneEvent, ensureDTag } from "../../helpers/nostr/events";
import { cloneEvent, ensureDTag } from "../../helpers/nostr/event";
import { createRTagsFromRelaySets } from "../../helpers/nostr/mailbox";
import { usePublishEvent } from "../../providers/global/publish-provider";

View File

@ -1,22 +0,0 @@
import { ButtonProps, IconButton, useDisclosure } from "@chakra-ui/react";
import { RelayIcon } from "../icons";
import RelayManagementDrawer from "../relay-management-drawer";
/** @deprecated */
export default function RelaySelectionButton({ ...props }: ButtonProps) {
const relaysModal = useDisclosure();
return (
<>
<IconButton
icon={<RelayIcon />}
onClick={relaysModal.onOpen}
aria-label="Relays"
title="Relays"
variant="ghost"
{...props}
/>
<RelayManagementDrawer isOpen={relaysModal.isOpen} onClose={relaysModal.onClose} />
</>
);
}

View File

@ -1,118 +0,0 @@
import { useState } from "react";
import {
Button,
ButtonGroup,
Checkbox,
CheckboxGroup,
Flex,
Modal,
ModalBody,
ModalCloseButton,
ModalContent,
ModalFooter,
ModalHeader,
ModalOverlay,
useToast,
} from "@chakra-ui/react";
import { useReadRelays } from "../../hooks/use-client-relays";
import { RelayFavicon } from "../relay-favicon";
import { RelayUrlInput } from "../relay-url-input";
import { unique } from "../../helpers/array";
import relayScoreboardService from "../../services/relay-scoreboard";
import { normalizeRelayURL } from "../../helpers/relay";
function AddRelayForm({ onSubmit }: { onSubmit: (relay: string) => void }) {
const [url, setUrl] = useState("");
const toast = useToast();
return (
<Flex
as="form"
onSubmit={(e) => {
try {
e.preventDefault();
onSubmit(normalizeRelayURL(url));
setUrl("");
} catch (err) {
if (err instanceof Error) {
toast({ status: "error", description: err.message });
}
}
}}
gap="2"
mb="4"
>
<RelayUrlInput value={url} onChange={(e) => setUrl(e.target.value)} />
<Button type="submit">Add</Button>
</Flex>
);
}
const manuallyAddedRelays = new Set<string>();
export default function RelaySelectionModal({
selected,
onClose,
onSubmit,
}: {
selected: string[];
onSubmit: (relays: string[]) => void;
onClose: () => void;
}) {
const [newSelected, setSelected] = useState<string[]>(selected);
const relays = useReadRelays([...selected, ...newSelected, ...Array.from(manuallyAddedRelays)]);
return (
<Modal isOpen={true} onClose={onClose}>
<ModalOverlay />
<ModalContent>
<ModalHeader>Select Relays</ModalHeader>
<ModalCloseButton />
<ModalBody py="0">
<AddRelayForm
onSubmit={(newRelay) => {
setSelected(unique([newRelay, ...newSelected]));
manuallyAddedRelays.add(newRelay);
}}
/>
<CheckboxGroup value={newSelected} onChange={(urls) => setSelected(urls.map(String))}>
<Flex direction="column" gap="2" mb="2">
{relays.urls.map((url) => (
<Checkbox key={url} value={url}>
<RelayFavicon relay={url} size="xs" /> {url}
</Checkbox>
))}
</Flex>
</CheckboxGroup>
<ButtonGroup>
<Button onClick={() => setSelected(Array.from(relays))} size="sm">
All
</Button>
<Button onClick={() => setSelected([])} size="sm">
None
</Button>
<Button onClick={() => setSelected(relayScoreboardService.getRankedRelays(relays).slice(0, 4))} size="sm">
4 Fastest
</Button>
</ButtonGroup>
</ModalBody>
<ModalFooter>
<Button onClick={onClose} mr="2">
Cancel
</Button>
<Button
colorScheme="primary"
onClick={() => {
onSubmit(newSelected);
onClose();
}}
>
Set relays
</Button>
</ModalFooter>
</ModalContent>
</Modal>
);
}

View File

@ -1,5 +1,5 @@
import { IconButton, IconButtonProps } from "@chakra-ui/react";
import { ChevronLeftIcon } from "./icons";
import { ChevronLeftIcon } from "../icons";
import { useNavigate } from "react-router-dom";
export default function BackButton({ ...props }: Omit<IconButtonProps, "onClick" | "children" | "aria-label">) {

View File

@ -6,9 +6,9 @@ import { matchSorter } from "match-sorter";
import { nip19 } from "nostr-tools";
import { useUserSearchDirectoryContext } from "../../providers/global/user-directory-provider";
import UserAvatar from "../user-avatar";
import UserAvatar from "../user/user-avatar";
import { useUserMetadata } from "../../hooks/use-user-metadata";
import { getUserDisplayName } from "../../helpers/user-metadata";
import { getUserDisplayName } from "../../helpers/nostr/user-metadata";
function UserOption({ pubkey }: { pubkey: string }) {
const metadata = useUserMetadata(pubkey);

View File

@ -1,40 +0,0 @@
import { useEffect } from "react";
import {
Button,
Modal,
ModalBody,
ModalCloseButton,
ModalContent,
ModalFooter,
ModalHeader,
ModalOverlay,
useDisclosure,
} from "@chakra-ui/react";
import { useReadRelays } from "../../hooks/use-client-relays";
export default function Setup() {
const relaysModal = useDisclosure();
const readRelays = useReadRelays();
useEffect(() => (readRelays.size === 0 ? relaysModal.onOpen() : relaysModal.onClose()), [readRelays]);
return (
<>
<Modal isOpen={relaysModal.isOpen} onClose={relaysModal.onClose}>
<ModalOverlay />
<ModalContent>
<ModalHeader>Setup Relays</ModalHeader>
<ModalCloseButton />
<ModalBody></ModalBody>
<ModalFooter>
<Button colorScheme="blue" mr={3} onClick={relaysModal.onClose}>
Close
</Button>
<Button variant="ghost">Use Default</Button>
</ModalFooter>
</ModalContent>
</Modal>
</>
);
}

View File

@ -4,7 +4,7 @@ import { Box } from "@chakra-ui/react";
import { NostrEvent } from "../../../types/nostr-event";
import EmbeddedArticle from "../../embed-event/event-types/embedded-article";
import { useRegisterIntersectionEntity } from "../../../providers/local/intersection-observer";
import { getEventUID } from "../../../helpers/nostr/events";
import { getEventUID } from "../../../helpers/nostr/event";
function ArticleNote({ article }: { article: NostrEvent }) {
const ref = useRef<HTMLDivElement | null>(null);

View File

@ -6,7 +6,7 @@ import { useLocation } from "react-router-dom";
import useSubject from "../../../hooks/use-subject";
import TimelineLoader from "../../../classes/timeline-loader";
import { NostrEvent } from "../../../types/nostr-event";
import { getEventUID } from "../../../helpers/nostr/events";
import { getEventUID } from "../../../helpers/nostr/event";
import {
ExtendedIntersectionObserverEntry,
useIntersectionObserver,

View File

@ -2,8 +2,8 @@ import { useRef } from "react";
import { Flex, Text } from "@chakra-ui/react";
import { NostrEvent } from "../../../types/nostr-event";
import UserAvatar from "../../user-avatar";
import UserLink from "../../user-link";
import UserAvatar from "../../user/user-avatar";
import UserLink from "../../user/user-link";
import RelayCard from "../../../views/relays/components/relay-card";
import { useRegisterIntersectionEntity } from "../../../providers/local/intersection-observer";
import { safeRelayUrl } from "../../../helpers/relay";

View File

@ -2,7 +2,7 @@ import { memo, useRef } from "react";
import { NostrEvent } from "../../../types/nostr-event";
import { useRegisterIntersectionEntity } from "../../../providers/local/intersection-observer";
import Note from "../../note";
import TimelineNote from "../../note/timeline-note";
import { getEventUID } from "nostr-idb";
function ReplyNote({ event }: { event: NostrEvent }) {
@ -11,7 +11,7 @@ function ReplyNote({ event }: { event: NostrEvent }) {
return (
<div ref={ref}>
<Note event={event} showReplyButton showReplyLine />
<TimelineNote event={event} showReplyButton showReplyLine />
</div>
);
}

View File

@ -4,19 +4,19 @@ import { kinds, nip18 } from "nostr-tools";
import { Link as RouterLink } from "react-router-dom";
import { NostrEvent } from "../../../types/nostr-event";
import { Note } from "../../note";
import NoteMenu from "../../note/note-menu";
import UserAvatar from "../../user-avatar";
import { UserDnsIdentityIcon } from "../../user-dns-identity-icon";
import UserLink from "../../user-link";
import TimelineNote from "../../note/timeline-note";
import UserAvatar from "../../user/user-avatar";
import { UserDnsIdentityIcon } from "../../user/user-dns-identity-icon";
import UserLink from "../../user/user-link";
import { TrustProvider } from "../../../providers/local/trust";
import { useRegisterIntersectionEntity } from "../../../providers/local/intersection-observer";
import useSingleEvent from "../../../hooks/use-single-event";
import { EmbedEvent } from "../../embed-event";
import useUserMuteFilter from "../../../hooks/use-user-mute-filter";
import { parseHardcodedNoteContent } from "../../../helpers/nostr/events";
import { parseHardcodedNoteContent } from "../../../helpers/nostr/event";
import { getEventCommunityPointer } from "../../../helpers/nostr/communities";
import LoadingNostrLink from "../../loading-nostr-link";
import NoteMenu from "../../note/note-menu";
function RepostEvent({ event }: { event: NostrEvent }) {
const muteFilter = useUserMuteFilter();
@ -60,7 +60,7 @@ function RepostEvent({ event }: { event: NostrEvent }) {
<LoadingNostrLink link={{ type: "nevent", data: pointer }} />
) : note.kind === kinds.ShortTextNote ? (
// NOTE: tell the note not to register itself with the intersection observer. since this is an older note it will break the order of the timeline
<Note event={note} showReplyButton registerIntersectionEntity={false} />
<TimelineNote event={note} showReplyButton registerIntersectionEntity={false} />
) : (
<EmbedEvent event={note} />
)}

View File

@ -20,13 +20,13 @@ import { NostrEvent } from "../../../types/nostr-event";
import { parseStreamEvent } from "../../../helpers/nostr/stream";
import useEventNaddr from "../../../hooks/use-event-naddr";
import { useRegisterIntersectionEntity } from "../../../providers/local/intersection-observer";
import UserAvatar from "../../user-avatar";
import UserLink from "../../user-link";
import UserAvatar from "../../user/user-avatar";
import UserLink from "../../user/user-link";
import StreamStatusBadge from "../../../views/streams/components/status-badge";
import { EventRelays } from "../../note/note-relays";
import { useAsync } from "react-use";
import { getEventUID } from "../../../helpers/nostr/events";
import { getEventUID } from "../../../helpers/nostr/event";
import Timestamp from "../../timestamp";
import { EventRelays } from "../../note/event-relays";
export default function StreamNote({ event, ...props }: CardProps & { event: NostrEvent }) {
const { value: stream, error } = useAsync(async () => parseStreamEvent(event), [event]);

View File

@ -4,18 +4,18 @@ import { Box, Text } from "@chakra-ui/react";
import { ErrorBoundary } from "../../error-boundary";
import ReplyNote from "./reply-note";
import Note from "../../note";
import RepostEvent from "./repost-event";
import ArticleNote from "./article-note";
import StreamNote from "./stream-note";
import RelayRecommendation from "./relay-recommendation";
import BadgeAwardCard from "../../../views/badges/components/badge-award-card";
import { useRegisterIntersectionEntity } from "../../../providers/local/intersection-observer";
import { getEventUID, isReply } from "../../../helpers/nostr/events";
import { getEventUID, isReply } from "../../../helpers/nostr/event";
import { STREAM_KIND } from "../../../helpers/nostr/stream";
import { NostrEvent } from "../../../types/nostr-event";
import { FLARE_VIDEO_KIND } from "../../../helpers/nostr/flare";
import EmbeddedFlareVideo from "../../embed-event/event-types/embedded-flare-video";
import { TimelineNote } from "../../note/timeline-note";
function TimelineItem({ event, visible, minHeight }: { event: NostrEvent; visible: boolean; minHeight?: number }) {
const ref = useRef<HTMLDivElement | null>(null);
@ -24,7 +24,7 @@ function TimelineItem({ event, visible, minHeight }: { event: NostrEvent; visibl
let content: ReactNode | null = null;
switch (event.kind) {
case kinds.ShortTextNote:
content = isReply(event) ? <ReplyNote event={event} /> : <Note event={event} showReplyButton />;
content = isReply(event) ? <ReplyNote event={event} /> : <TimelineNote event={event} showReplyButton />;
break;
case kinds.Repost:
case kinds.GenericRepost:

View File

@ -12,7 +12,7 @@ import { TrustProvider } from "../../../providers/local/trust";
import PhotoGallery, { PhotoWithoutSize } from "../../photo-gallery";
import { useRegisterIntersectionEntity } from "../../../providers/local/intersection-observer";
import { NostrEvent } from "../../../types/nostr-event";
import { getEventUID } from "../../../helpers/nostr/events";
import { getEventUID } from "../../../helpers/nostr/event";
import { useBreakpointValue } from "../../../providers/global/breakpoint-provider";
function CustomGalleryImage({ event, ...props }: EmbeddedImageProps & { event: NostrEvent }) {

View File

@ -21,9 +21,9 @@ import { getEventRelays } from "../../../services/event-relays";
import { NostrEvent } from "../../../types/nostr-event";
import { useRegisterIntersectionEntity } from "../../../providers/local/intersection-observer";
import { RelayFavicon } from "../../relay-favicon";
import { NoteLink } from "../../note-link";
import { NoteLink } from "../../note/note-link";
import { BroadcastEventIcon } from "../../icons";
import { getEventUID } from "../../../helpers/nostr/events";
import { getEventUID } from "../../../helpers/nostr/event";
import Timestamp from "../../timestamp";
import { usePublishEvent } from "../../../providers/global/publish-provider";

View File

@ -2,13 +2,13 @@ import { forwardRef, memo, useMemo } from "react";
import { Avatar, AvatarProps } from "@chakra-ui/react";
import { useAsync } from "react-use";
import { useUserMetadata } from "../hooks/use-user-metadata";
import { getIdenticon } from "../helpers/identicon";
import { safeUrl } from "../helpers/parse";
import { Kind0ParsedContent, getUserDisplayName } from "../helpers/user-metadata";
import useAppSettings from "../hooks/use-app-settings";
import useCurrentAccount from "../hooks/use-current-account";
import { buildImageProxyURL } from "../helpers/image";
import { useUserMetadata } from "../../hooks/use-user-metadata";
import { getIdenticon } from "../../helpers/identicon";
import { safeUrl } from "../../helpers/parse";
import { Kind0ParsedContent, getUserDisplayName } from "../../helpers/nostr/user-metadata";
import useAppSettings from "../../hooks/use-app-settings";
import useCurrentAccount from "../../hooks/use-current-account";
import { buildImageProxyURL } from "../../helpers/image";
export const UserIdenticon = memo(({ pubkey }: { pubkey: string }) => {
const { value: identicon } = useAsync(() => getIdenticon(pubkey), [pubkey]);

View File

@ -1,8 +1,8 @@
import { Text, Tooltip } from "@chakra-ui/react";
import { useDnsIdentity } from "../hooks/use-dns-identity";
import { useUserMetadata } from "../hooks/use-user-metadata";
import { VerificationFailed, VerificationMissing, VerifiedIcon } from "./icons";
import { useDnsIdentity } from "../../hooks/use-dns-identity";
import { useUserMetadata } from "../../hooks/use-user-metadata";
import { VerificationFailed, VerificationMissing, VerifiedIcon } from "../icons";
export const UserDnsIdentityIcon = ({ pubkey, onlyIcon }: { pubkey: string; onlyIcon?: boolean }) => {
const metadata = useUserMetadata(pubkey);

View File

@ -12,9 +12,9 @@ import {
useDisclosure,
} from "@chakra-ui/react";
import useCurrentAccount from "../hooks/use-current-account";
import { ChevronDownIcon, FollowIcon, MuteIcon, PlusCircleIcon, UnfollowIcon, UnmuteIcon } from "./icons";
import useUserLists from "../hooks/use-user-lists";
import useCurrentAccount from "../../hooks/use-current-account";
import { ChevronDownIcon, FollowIcon, MuteIcon, PlusCircleIcon, UnfollowIcon, UnmuteIcon } from "../icons";
import useUserLists from "../../hooks/use-user-lists";
import {
PEOPLE_LIST_KIND,
createEmptyContactList,
@ -23,15 +23,15 @@ import {
getListName,
getPubkeysFromList,
isPubkeyInList,
} from "../helpers/nostr/lists";
import { getEventCoordinate } from "../helpers/nostr/events";
import { useSigningContext } from "../providers/global/signing-provider";
import useUserContactList from "../hooks/use-user-contact-list";
import useAsyncErrorHandler from "../hooks/use-async-error-handler";
import NewListModal from "../views/lists/components/new-list-modal";
import useUserMuteActions from "../hooks/use-user-mute-actions";
import { useMuteModalContext } from "../providers/route/mute-modal-provider";
import { usePublishEvent } from "../providers/global/publish-provider";
} from "../../helpers/nostr/lists";
import { getEventCoordinate } from "../../helpers/nostr/event";
import { useSigningContext } from "../../providers/global/signing-provider";
import useUserContactList from "../../hooks/use-user-contact-list";
import useAsyncErrorHandler from "../../hooks/use-async-error-handler";
import NewListModal from "../../views/lists/components/new-list-modal";
import useUserMuteActions from "../../hooks/use-user-mute-actions";
import { useMuteModalContext } from "../../providers/route/mute-modal-provider";
import { usePublishEvent } from "../../providers/global/publish-provider";
function UsersLists({ pubkey }: { pubkey: string }) {
const publish = usePublishEvent();

Some files were not shown because too many files have changed in this diff Show More